@legendapp/list 3.0.0-beta.10 → 3.0.0-beta.12

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.native.mjs CHANGED
@@ -390,48 +390,70 @@ function useInit(cb) {
390
390
 
391
391
  // src/state/ContextContainer.ts
392
392
  var ContextContainer = createContext(null);
393
+ function useContextContainer() {
394
+ return useContext(ContextContainer);
395
+ }
393
396
  function useViewability(callback, configId) {
394
397
  const ctx = useStateContext();
395
- const { containerId } = useContext(ContextContainer);
396
- const key = containerId + (configId != null ? configId : "");
398
+ const containerContext = useContextContainer();
397
399
  useInit(() => {
400
+ if (!containerContext) {
401
+ return;
402
+ }
403
+ const { containerId } = containerContext;
404
+ const key = containerId + (configId != null ? configId : "");
398
405
  const value = ctx.mapViewabilityValues.get(key);
399
406
  if (value) {
400
407
  callback(value);
401
408
  }
402
409
  });
403
- ctx.mapViewabilityCallbacks.set(key, callback);
404
- useEffect(
405
- () => () => {
410
+ useEffect(() => {
411
+ if (!containerContext) {
412
+ return;
413
+ }
414
+ const { containerId } = containerContext;
415
+ const key = containerId + (configId != null ? configId : "");
416
+ ctx.mapViewabilityCallbacks.set(key, callback);
417
+ return () => {
406
418
  ctx.mapViewabilityCallbacks.delete(key);
407
- },
408
- []
409
- );
419
+ };
420
+ }, [ctx, callback, configId, containerContext]);
410
421
  }
411
422
  function useViewabilityAmount(callback) {
412
423
  const ctx = useStateContext();
413
- const { containerId } = useContext(ContextContainer);
424
+ const containerContext = useContextContainer();
414
425
  useInit(() => {
426
+ if (!containerContext) {
427
+ return;
428
+ }
429
+ const { containerId } = containerContext;
415
430
  const value = ctx.mapViewabilityAmountValues.get(containerId);
416
431
  if (value) {
417
432
  callback(value);
418
433
  }
419
434
  });
420
- ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
421
- useEffect(
422
- () => () => {
435
+ useEffect(() => {
436
+ if (!containerContext) {
437
+ return;
438
+ }
439
+ const { containerId } = containerContext;
440
+ ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
441
+ return () => {
423
442
  ctx.mapViewabilityAmountCallbacks.delete(containerId);
424
- },
425
- []
426
- );
443
+ };
444
+ }, [ctx, callback, containerContext]);
427
445
  }
428
446
  function useRecyclingEffect(effect) {
429
- const { index, value } = useContext(ContextContainer);
447
+ const containerContext = useContextContainer();
430
448
  const prevValues = useRef({
431
449
  prevIndex: void 0,
432
450
  prevItem: void 0
433
451
  });
434
452
  useEffect(() => {
453
+ if (!containerContext) {
454
+ return;
455
+ }
456
+ const { index, value } = containerContext;
435
457
  let ret;
436
458
  if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
437
459
  ret = effect({
@@ -446,38 +468,58 @@ function useRecyclingEffect(effect) {
446
468
  prevItem: value
447
469
  };
448
470
  return ret;
449
- }, [index, value, effect]);
471
+ }, [effect, containerContext]);
450
472
  }
451
473
  function useRecyclingState(valueOrFun) {
452
- const { index, value, itemKey, triggerLayout } = useContext(ContextContainer);
453
- const refState = useRef({
454
- itemKey: null,
455
- value: null
474
+ var _a3, _b;
475
+ const containerContext = useContextContainer();
476
+ const computeValue = (ctx) => {
477
+ if (isFunction(valueOrFun)) {
478
+ const initializer = valueOrFun;
479
+ return ctx ? initializer({
480
+ index: ctx.index,
481
+ item: ctx.value,
482
+ prevIndex: void 0,
483
+ prevItem: void 0
484
+ }) : initializer();
485
+ }
486
+ return valueOrFun;
487
+ };
488
+ const [stateValue, setStateValue] = useState(() => {
489
+ return computeValue(containerContext);
456
490
  });
457
- const [_, setRenderNum] = useState(0);
458
- const state = refState.current;
459
- if (state.itemKey !== itemKey) {
460
- state.itemKey = itemKey;
461
- state.value = isFunction(valueOrFun) ? valueOrFun({
462
- index,
463
- item: value,
464
- prevIndex: void 0,
465
- prevItem: void 0
466
- }) : valueOrFun;
491
+ const prevItemKeyRef = useRef((_a3 = containerContext == null ? void 0 : containerContext.itemKey) != null ? _a3 : null);
492
+ const currentItemKey = (_b = containerContext == null ? void 0 : containerContext.itemKey) != null ? _b : null;
493
+ if (currentItemKey !== null && prevItemKeyRef.current !== currentItemKey) {
494
+ prevItemKeyRef.current = currentItemKey;
495
+ setStateValue(computeValue(containerContext));
467
496
  }
497
+ const triggerLayout = containerContext == null ? void 0 : containerContext.triggerLayout;
468
498
  const setState = useCallback(
469
499
  (newState) => {
470
- state.value = isFunction(newState) ? newState(state.value) : newState;
471
- setRenderNum((v) => v + 1);
500
+ if (!triggerLayout) {
501
+ return;
502
+ }
503
+ setStateValue((prevValue) => {
504
+ return isFunction(newState) ? newState(prevValue) : newState;
505
+ });
472
506
  triggerLayout();
473
507
  },
474
- [triggerLayout, state]
508
+ [triggerLayout]
475
509
  );
476
- return [state.value, setState];
510
+ return [stateValue, setState];
477
511
  }
478
512
  function useIsLastItem() {
479
- const { itemKey } = useContext(ContextContainer);
480
- const isLast = useSelector$("lastItemKeys", (lastItemKeys) => (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false);
513
+ const containerContext = useContextContainer();
514
+ const isLast = useSelector$("lastItemKeys", (lastItemKeys) => {
515
+ if (containerContext) {
516
+ const { itemKey } = containerContext;
517
+ if (!isNullOrUndefined(itemKey)) {
518
+ return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
519
+ }
520
+ }
521
+ return false;
522
+ });
481
523
  return isLast;
482
524
  }
483
525
  function useListScrollSize() {
@@ -487,8 +529,9 @@ function useListScrollSize() {
487
529
  var noop = () => {
488
530
  };
489
531
  function useSyncLayout() {
490
- if (IsNewArchitecture) {
491
- const { triggerLayout: syncLayout } = useContext(ContextContainer);
532
+ const containerContext = useContextContainer();
533
+ if (IsNewArchitecture && containerContext) {
534
+ const { triggerLayout: syncLayout } = containerContext;
492
535
  return syncLayout;
493
536
  } else {
494
537
  return noop;
@@ -848,7 +891,6 @@ var ListComponent = typedMemo(function ListComponent2({
848
891
  getRenderedItem: getRenderedItem2,
849
892
  updateItemSize: updateItemSize2,
850
893
  refScrollView,
851
- maintainVisibleContentPosition,
852
894
  renderScrollComponent,
853
895
  scrollAdjustHandler,
854
896
  onLayoutHeader,
@@ -857,6 +899,7 @@ var ListComponent = typedMemo(function ListComponent2({
857
899
  ...rest
858
900
  }) {
859
901
  const ctx = useStateContext();
902
+ const maintainVisibleContentPosition = ctx.state.props.maintainVisibleContentPosition;
860
903
  const ScrollComponent = renderScrollComponent ? useMemo(
861
904
  () => React2.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
862
905
  [renderScrollComponent]
@@ -874,7 +917,7 @@ var ListComponent = typedMemo(function ListComponent2({
874
917
  ],
875
918
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
876
919
  horizontal,
877
- maintainVisibleContentPosition: maintainVisibleContentPosition ? { minIndexForVisible: 0 } : void 0,
920
+ maintainVisibleContentPosition: maintainVisibleContentPosition.scroll || maintainVisibleContentPosition.dataChanges ? { minIndexForVisible: 0 } : void 0,
878
921
  onLayout,
879
922
  onScroll: onScroll2,
880
923
  ref: refScrollView,
@@ -1145,7 +1188,7 @@ function checkFinishedScrollFrame(ctx) {
1145
1188
  if (scrollingTo) {
1146
1189
  const { state } = ctx;
1147
1190
  state.animFrameCheckFinishedScroll = void 0;
1148
- const scroll = state.scroll;
1191
+ const scroll = state.scrollPending;
1149
1192
  const adjust = state.scrollAdjustHandler.getAdjust();
1150
1193
  const clampedTargetOffset = clampScrollOffset(ctx, scrollingTo.offset - (scrollingTo.viewOffset || 0));
1151
1194
  const maxOffset = clampScrollOffset(ctx, scroll);
@@ -1500,14 +1543,16 @@ function ensureInitialAnchor(ctx) {
1500
1543
  function prepareMVCP(ctx, dataChanged) {
1501
1544
  const state = ctx.state;
1502
1545
  const { idsInView, positions, props } = state;
1503
- const { maintainVisibleContentPosition } = props;
1546
+ const {
1547
+ maintainVisibleContentPosition: { dataChanges: mvcpDataChanges, scroll: mvcpScroll }
1548
+ } = props;
1504
1549
  const scrollingTo = state.scrollingTo;
1505
1550
  let prevPosition;
1506
1551
  let targetId;
1507
1552
  const idsInViewWithPositions = [];
1508
1553
  const scrollTarget = scrollingTo == null ? void 0 : scrollingTo.index;
1509
1554
  const scrollingToViewPosition = scrollingTo == null ? void 0 : scrollingTo.viewPosition;
1510
- const shouldMVCP = !dataChanged || maintainVisibleContentPosition;
1555
+ const shouldMVCP = dataChanged ? mvcpDataChanges : mvcpScroll;
1511
1556
  const indexByKey = state.indexByKey;
1512
1557
  if (shouldMVCP) {
1513
1558
  if (scrollTarget !== void 0) {
@@ -1533,7 +1578,7 @@ function prepareMVCP(ctx, dataChanged) {
1533
1578
  }
1534
1579
  return () => {
1535
1580
  let positionDiff = 0;
1536
- if (dataChanged && targetId === void 0 && maintainVisibleContentPosition) {
1581
+ if (dataChanged && targetId === void 0 && mvcpDataChanges) {
1537
1582
  for (let i = 0; i < idsInViewWithPositions.length; i++) {
1538
1583
  const { id, position } = idsInViewWithPositions[i];
1539
1584
  const newPosition = positions.get(id);
@@ -1570,7 +1615,7 @@ function prepareMVCP(ctx, dataChanged) {
1570
1615
  }
1571
1616
  }
1572
1617
  if (Math.abs(positionDiff) > 0.1) {
1573
- requestAdjust(ctx, positionDiff, dataChanged && maintainVisibleContentPosition);
1618
+ requestAdjust(ctx, positionDiff, dataChanged && mvcpDataChanges);
1574
1619
  }
1575
1620
  };
1576
1621
  }
@@ -1667,39 +1712,40 @@ function updateTotalSize(ctx) {
1667
1712
  // src/utils/getScrollVelocity.ts
1668
1713
  var getScrollVelocity = (state) => {
1669
1714
  const { scrollHistory } = state;
1670
- let velocity = 0;
1671
- if (scrollHistory.length >= 1) {
1672
- const newest = scrollHistory[scrollHistory.length - 1];
1673
- let oldest;
1674
- let start = 0;
1675
- const now = Date.now();
1676
- for (let i = 0; i < scrollHistory.length - 1; i++) {
1677
- const entry = scrollHistory[i];
1678
- const nextEntry = scrollHistory[i + 1];
1679
- if (i > 0) {
1680
- const prevEntry = scrollHistory[i - 1];
1681
- const prevDirection = entry.scroll - prevEntry.scroll;
1682
- const currentDirection = nextEntry.scroll - entry.scroll;
1683
- if (prevDirection > 0 && currentDirection < 0 || prevDirection < 0 && currentDirection > 0) {
1684
- start = i;
1685
- break;
1686
- }
1687
- }
1715
+ const newestIndex = scrollHistory.length - 1;
1716
+ if (newestIndex < 1) {
1717
+ return 0;
1718
+ }
1719
+ const newest = scrollHistory[newestIndex];
1720
+ const now = Date.now();
1721
+ let direction = 0;
1722
+ for (let i = newestIndex; i > 0; i--) {
1723
+ const delta = scrollHistory[i].scroll - scrollHistory[i - 1].scroll;
1724
+ if (delta !== 0) {
1725
+ direction = Math.sign(delta);
1726
+ break;
1688
1727
  }
1689
- for (let i = start; i < scrollHistory.length - 1; i++) {
1690
- const entry = scrollHistory[i];
1691
- if (now - entry.time <= 1e3) {
1692
- oldest = entry;
1693
- break;
1694
- }
1728
+ }
1729
+ if (direction === 0) {
1730
+ return 0;
1731
+ }
1732
+ let oldest = newest;
1733
+ for (let i = newestIndex - 1; i >= 0; i--) {
1734
+ const current = scrollHistory[i];
1735
+ const next = scrollHistory[i + 1];
1736
+ const delta = next.scroll - current.scroll;
1737
+ const deltaSign = Math.sign(delta);
1738
+ if (deltaSign !== 0 && deltaSign !== direction) {
1739
+ break;
1695
1740
  }
1696
- if (oldest && oldest !== newest) {
1697
- const scrollDiff = newest.scroll - oldest.scroll;
1698
- const timeDiff = newest.time - oldest.time;
1699
- velocity = timeDiff > 0 ? scrollDiff / timeDiff : 0;
1741
+ if (now - current.time > 1e3) {
1742
+ break;
1700
1743
  }
1744
+ oldest = current;
1701
1745
  }
1702
- return velocity;
1746
+ const scrollDiff = newest.scroll - oldest.scroll;
1747
+ const timeDiff = newest.time - oldest.time;
1748
+ return timeDiff > 0 ? scrollDiff / timeDiff : 0;
1703
1749
  };
1704
1750
 
1705
1751
  // src/utils/updateSnapToOffsets.ts
@@ -2858,7 +2904,6 @@ function onScroll(ctx, event) {
2858
2904
  return;
2859
2905
  }
2860
2906
  let newScroll = event.nativeEvent.contentOffset[state.props.horizontal ? "x" : "y"];
2861
- state.scrollPending = newScroll;
2862
2907
  if (state.scrollingTo) {
2863
2908
  const maxOffset = clampScrollOffset(ctx, newScroll);
2864
2909
  if (newScroll !== maxOffset && Math.abs(newScroll - maxOffset) > 1) {
@@ -2872,8 +2917,11 @@ function onScroll(ctx, event) {
2872
2917
  return;
2873
2918
  }
2874
2919
  }
2920
+ state.scrollPending = newScroll;
2875
2921
  updateScroll(ctx, newScroll);
2876
- checkFinishedScroll(ctx);
2922
+ if (state.scrollingTo) {
2923
+ checkFinishedScroll(ctx);
2924
+ }
2877
2925
  onScrollProp == null ? void 0 : onScrollProp(event);
2878
2926
  }
2879
2927
 
@@ -3227,6 +3275,24 @@ function getRenderedItem(ctx, key) {
3227
3275
  }
3228
3276
  return { index, item: data[index], renderedItem };
3229
3277
  }
3278
+
3279
+ // src/utils/normalizeMaintainVisibleContentPosition.ts
3280
+ function normalizeMaintainVisibleContentPosition(value) {
3281
+ var _a3, _b;
3282
+ if (value === true) {
3283
+ return { dataChanges: true, scroll: true };
3284
+ }
3285
+ if (value && typeof value === "object") {
3286
+ return {
3287
+ dataChanges: (_a3 = value.dataChanges) != null ? _a3 : false,
3288
+ scroll: (_b = value.scroll) != null ? _b : true
3289
+ };
3290
+ }
3291
+ if (value === false) {
3292
+ return { dataChanges: false, scroll: false };
3293
+ }
3294
+ return { dataChanges: false, scroll: true };
3295
+ }
3230
3296
  function useThrottleDebounce(mode) {
3231
3297
  const timeoutRef = useRef(null);
3232
3298
  const lastCallTimeRef = useRef(0);
@@ -3321,7 +3387,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3321
3387
  ListHeaderComponent,
3322
3388
  maintainScrollAtEnd = false,
3323
3389
  maintainScrollAtEndThreshold = 0.1,
3324
- maintainVisibleContentPosition = false,
3390
+ maintainVisibleContentPosition: maintainVisibleContentPositionProp,
3325
3391
  numColumns: numColumnsProp = 1,
3326
3392
  onEndReached,
3327
3393
  onEndReachedThreshold = 0.5,
@@ -3359,6 +3425,9 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3359
3425
  const style = { ...StyleSheet.flatten(styleProp) };
3360
3426
  const stylePaddingTopState = extractPadding(style, contentContainerStyle, "Top");
3361
3427
  const stylePaddingBottomState = extractPadding(style, contentContainerStyle, "Bottom");
3428
+ const maintainVisibleContentPositionConfig = normalizeMaintainVisibleContentPosition(
3429
+ maintainVisibleContentPositionProp
3430
+ );
3362
3431
  const [renderNum, setRenderNum] = useState(0);
3363
3432
  const initialScrollProp = initialScrollAtEnd ? { index: Math.max(0, dataProp.length - 1), viewOffset: -stylePaddingBottomState } : initialScrollIndexProp || initialScrollOffsetProp ? typeof initialScrollIndexProp === "object" ? { index: initialScrollIndexProp.index || 0, viewOffset: initialScrollIndexProp.viewOffset || 0 } : { index: initialScrollIndexProp || 0, viewOffset: initialScrollOffsetProp || 0 } : void 0;
3364
3433
  const [canRender, setCanRender] = React2.useState(!IsNewArchitecture);
@@ -3443,7 +3512,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3443
3512
  };
3444
3513
  const internalState = ctx.state;
3445
3514
  internalState.triggerCalculateItemsInView = (params) => calculateItemsInView(ctx, params);
3446
- set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPosition);
3515
+ set$(ctx, "maintainVisibleContentPosition", maintainVisibleContentPositionConfig);
3447
3516
  set$(ctx, "extraData", extraData);
3448
3517
  }
3449
3518
  refState.current = ctx.state;
@@ -3474,7 +3543,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3474
3543
  keyExtractor,
3475
3544
  maintainScrollAtEnd,
3476
3545
  maintainScrollAtEndThreshold,
3477
- maintainVisibleContentPosition,
3546
+ maintainVisibleContentPosition: maintainVisibleContentPositionConfig,
3478
3547
  numColumns: numColumnsProp,
3479
3548
  onEndReached,
3480
3549
  onEndReachedThreshold,
@@ -3509,7 +3578,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3509
3578
  setPaddingTop(ctx, { stylePaddingTop: stylePaddingTopState });
3510
3579
  refState.current.props.stylePaddingBottom = stylePaddingBottomState;
3511
3580
  let paddingDiff = stylePaddingTopState - prevPaddingTop;
3512
- if (paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3581
+ if (maintainVisibleContentPositionConfig.scroll && paddingDiff && prevPaddingTop !== void 0 && Platform2.OS === "ios") {
3513
3582
  if (state.scroll < 0) {
3514
3583
  paddingDiff += state.scroll;
3515
3584
  }
@@ -3554,7 +3623,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3554
3623
  value = 0;
3555
3624
  }
3556
3625
  if (!value) {
3557
- state.didFinishInitialScroll = true;
3626
+ setInitialRenderState(ctx, { didInitialScroll: true });
3558
3627
  }
3559
3628
  return value;
3560
3629
  }, [renderNum]);
@@ -3683,7 +3752,6 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
3683
3752
  initialContentOffset,
3684
3753
  ListEmptyComponent: dataProp.length === 0 ? ListEmptyComponent : void 0,
3685
3754
  ListHeaderComponent,
3686
- maintainVisibleContentPosition,
3687
3755
  onLayout,
3688
3756
  onLayoutHeader,
3689
3757
  onMomentumScrollEnd: fns.onMomentumScrollEnd,
package/keyboard.js CHANGED
@@ -87,8 +87,7 @@ var KeyboardAvoidingLegendList = React.forwardRef(function KeyboardAvoidingLegen
87
87
  const setScrollProcessingEnabled = React.useCallback(
88
88
  (enabled) => {
89
89
  var _a;
90
- console.log("setScrollProcessingEnabled", enabled);
91
- (_a = refLegendList.current) == null ? void 0 : _a.setScrollProcessingEnabled(enabled);
90
+ return (_a = refLegendList.current) == null ? void 0 : _a.setScrollProcessingEnabled(enabled);
92
91
  },
93
92
  [refLegendList]
94
93
  );
package/keyboard.mjs CHANGED
@@ -66,8 +66,7 @@ var KeyboardAvoidingLegendList = forwardRef(function KeyboardAvoidingLegendList2
66
66
  const setScrollProcessingEnabled = useCallback(
67
67
  (enabled) => {
68
68
  var _a;
69
- console.log("setScrollProcessingEnabled", enabled);
70
- (_a = refLegendList.current) == null ? void 0 : _a.setScrollProcessingEnabled(enabled);
69
+ return (_a = refLegendList.current) == null ? void 0 : _a.setScrollProcessingEnabled(enabled);
71
70
  },
72
71
  [refLegendList]
73
72
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/list",
3
- "version": "3.0.0-beta.10",
3
+ "version": "3.0.0-beta.12",
4
4
  "description": "Legend List is a drop-in replacement for FlatList with much better performance and supporting dynamically sized items.",
5
5
  "sideEffects": false,
6
6
  "private": false,
@@ -1,7 +1,7 @@
1
1
  import * as react_native from 'react-native';
2
2
  import { SectionListData, SectionBase, SectionListRenderItemInfo, SectionListScrollParams } from 'react-native';
3
3
  import * as React from 'react';
4
- import { a as LegendListRef, L as LegendListProps } from './types-1Hgg1rTO.mjs';
4
+ import { a as LegendListRef, L as LegendListProps } from './types-C83aU7VI.mjs';
5
5
  import 'react-native-reanimated';
6
6
 
7
7
  type SectionListSeparatorProps<ItemT, SectionT> = {
package/section-list.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_native from 'react-native';
2
2
  import { SectionListData, SectionBase, SectionListRenderItemInfo, SectionListScrollParams } from 'react-native';
3
3
  import * as React from 'react';
4
- import { a as LegendListRef, L as LegendListProps } from './types-1Hgg1rTO.js';
4
+ import { a as LegendListRef, L as LegendListProps } from './types-C83aU7VI.js';
5
5
  import 'react-native-reanimated';
6
6
 
7
7
  type SectionListSeparatorProps<ItemT, SectionT> = {