@legendapp/list 3.3.1 → 3.3.2

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.
@@ -31,7 +31,7 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
31
31
  shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
32
32
  }
33
33
 
34
- type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
34
+ type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemInfo${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
35
35
  type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
36
36
  type ListenerTypeValueMap = {
37
37
  activeStickyIndex: number;
@@ -71,6 +71,8 @@ type ListenerTypeValueMap = {
71
71
  [K in ListenerType as K extends `containerItemKey${number}` ? K : never]: string;
72
72
  } & {
73
73
  [K in ListenerType as K extends `containerItemData${number}` ? K : never]: any;
74
+ } & {
75
+ [K in ListenerType as K extends `containerItemInfo${number}` ? K : never]: ContainerItemInfo;
74
76
  } & {
75
77
  [K in ListenerType as K extends `containerPosition${number}` ? K : never]: number;
76
78
  } & {
@@ -80,6 +82,11 @@ type ListenerTypeValueMap = {
80
82
  } & {
81
83
  [K in ListenerType as K extends `containerSticky${number}` ? K : never]: boolean;
82
84
  };
85
+ interface ContainerItemInfo {
86
+ index: number;
87
+ itemKey: string;
88
+ value: any;
89
+ }
83
90
 
84
91
  interface Insets {
85
92
  top: number;
@@ -148,6 +148,7 @@ var createAnimatedValue = (value) => value;
148
148
 
149
149
  // src/state/state.tsx
150
150
  var ContextState = React3__namespace.createContext(null);
151
+ var SIGNAL_NAMES_SEPARATOR = "\0";
151
152
  var contextNum = 0;
152
153
  function StateProvider({ children }) {
153
154
  const [value] = React3__namespace.useState(() => ({
@@ -219,6 +220,12 @@ function createSelectorFunctionsArr(ctx, signalNames) {
219
220
  }
220
221
  };
221
222
  }
223
+ function getSignalNamesKey(signalNames) {
224
+ return signalNames.length === 1 ? signalNames[0] : signalNames.join(SIGNAL_NAMES_SEPARATOR);
225
+ }
226
+ function getSignalNamesFromKey(signalNamesKey) {
227
+ return signalNamesKey.split(SIGNAL_NAMES_SEPARATOR);
228
+ }
222
229
  function listen$(ctx, signalName, cb) {
223
230
  const { listeners } = ctx;
224
231
  let setListeners = listeners.get(signalName);
@@ -266,7 +273,11 @@ function notifyPosition$(ctx, key, value) {
266
273
  }
267
274
  function useArr$(signalNames) {
268
275
  const ctx = React3__namespace.useContext(ContextState);
269
- const { subscribe, get } = React3__namespace.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
276
+ const signalNamesKey = getSignalNamesKey(signalNames);
277
+ const { subscribe, get } = React3__namespace.useMemo(
278
+ () => createSelectorFunctionsArr(ctx, getSignalNamesFromKey(signalNamesKey)),
279
+ [ctx, signalNamesKey]
280
+ );
270
281
  const value = shim.useSyncExternalStore(subscribe, get, get);
271
282
  return value;
272
283
  }
@@ -553,9 +564,22 @@ function useInit(cb) {
553
564
 
554
565
  // src/state/ContextContainer.ts
555
566
  var ContextContainer = React3.createContext(null);
567
+ var NO_CONTAINER_ID = -1;
556
568
  function useContextContainer() {
557
569
  return React3.useContext(ContextContainer);
558
570
  }
571
+ function useContainerItemInfo(containerContext) {
572
+ var _a3;
573
+ const containerId = (_a3 = containerContext == null ? void 0 : containerContext.containerId) != null ? _a3 : NO_CONTAINER_ID;
574
+ const [itemInfo] = useArr$([`containerItemInfo${containerId}`]);
575
+ return containerContext ? itemInfo : void 0;
576
+ }
577
+ function useContainerItemKey(containerContext) {
578
+ var _a3;
579
+ const containerId = (_a3 = containerContext == null ? void 0 : containerContext.containerId) != null ? _a3 : NO_CONTAINER_ID;
580
+ const [itemKey] = useArr$([`containerItemKey${containerId}`]);
581
+ return containerContext ? itemKey : void 0;
582
+ }
559
583
  function useAdaptiveRender() {
560
584
  const [mode] = useArr$(["adaptiveRender"]);
561
585
  return mode;
@@ -626,40 +650,35 @@ function useViewabilityAmount(callback) {
626
650
  }
627
651
  function useRecyclingEffect(effect) {
628
652
  const containerContext = useContextContainer();
629
- const prevValues = React3.useRef({
630
- prevIndex: void 0,
631
- prevItem: void 0
632
- });
653
+ const itemInfo = useContainerItemInfo(containerContext);
654
+ const prevInfo = React3.useRef(void 0);
633
655
  React3.useEffect(() => {
634
- if (!containerContext) {
656
+ if (!itemInfo) {
635
657
  return;
636
658
  }
637
- const { index, value } = containerContext;
638
659
  let ret;
639
- if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
660
+ if (prevInfo.current) {
640
661
  ret = effect({
641
- index,
642
- item: value,
643
- prevIndex: prevValues.current.prevIndex,
644
- prevItem: prevValues.current.prevItem
662
+ index: itemInfo.index,
663
+ item: itemInfo.value,
664
+ prevIndex: prevInfo.current.index,
665
+ prevItem: prevInfo.current.value
645
666
  });
646
667
  }
647
- prevValues.current = {
648
- prevIndex: index,
649
- prevItem: value
650
- };
668
+ prevInfo.current = itemInfo;
651
669
  return ret;
652
- }, [effect, containerContext]);
670
+ }, [effect, itemInfo]);
653
671
  }
654
672
  function useRecyclingState(valueOrFun) {
655
- var _a3, _b;
673
+ var _a3;
656
674
  const containerContext = useContextContainer();
657
- const computeValue = (ctx) => {
675
+ const itemInfo = useContainerItemInfo(containerContext);
676
+ const computeValue = (info) => {
658
677
  if (isFunction(valueOrFun)) {
659
678
  const initializer = valueOrFun;
660
- return ctx ? initializer({
661
- index: ctx.index,
662
- item: ctx.value,
679
+ return info ? initializer({
680
+ index: info.index,
681
+ item: info.value,
663
682
  prevIndex: void 0,
664
683
  prevItem: void 0
665
684
  }) : initializer();
@@ -667,13 +686,12 @@ function useRecyclingState(valueOrFun) {
667
686
  return valueOrFun;
668
687
  };
669
688
  const [stateValue, setStateValue] = React3.useState(() => {
670
- return computeValue(containerContext);
689
+ return computeValue(itemInfo);
671
690
  });
672
- const prevItemKeyRef = React3.useRef((_a3 = containerContext == null ? void 0 : containerContext.itemKey) != null ? _a3 : null);
673
- const currentItemKey = (_b = containerContext == null ? void 0 : containerContext.itemKey) != null ? _b : null;
674
- if (currentItemKey !== null && prevItemKeyRef.current !== currentItemKey) {
675
- prevItemKeyRef.current = currentItemKey;
676
- setStateValue(computeValue(containerContext));
691
+ const prevItemKeyRef = React3.useRef((_a3 = itemInfo == null ? void 0 : itemInfo.itemKey) != null ? _a3 : null);
692
+ if (itemInfo && prevItemKeyRef.current !== itemInfo.itemKey) {
693
+ prevItemKeyRef.current = itemInfo.itemKey;
694
+ setStateValue(computeValue(itemInfo));
677
695
  }
678
696
  const triggerLayout = containerContext == null ? void 0 : containerContext.triggerLayout;
679
697
  const setState = React3.useCallback(
@@ -692,12 +710,10 @@ function useRecyclingState(valueOrFun) {
692
710
  }
693
711
  function useIsLastItem() {
694
712
  const containerContext = useContextContainer();
713
+ const itemKey = useContainerItemKey(containerContext);
695
714
  const isLast = useSelector$("lastItemKeys", (lastItemKeys) => {
696
- if (containerContext) {
697
- const { itemKey } = containerContext;
698
- if (!isNullOrUndefined(itemKey)) {
699
- return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
700
- }
715
+ if (containerContext && !isNullOrUndefined(itemKey)) {
716
+ return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
701
717
  }
702
718
  return false;
703
719
  });
@@ -711,12 +727,7 @@ var noop = () => {
711
727
  };
712
728
  function useSyncLayout() {
713
729
  const containerContext = useContextContainer();
714
- if (containerContext) {
715
- const { triggerLayout: syncLayout } = containerContext;
716
- return syncLayout;
717
- } else {
718
- return noop;
719
- }
730
+ return containerContext ? containerContext.triggerLayout : noop;
720
731
  }
721
732
 
722
733
  // src/components/Separator.tsx
@@ -3356,22 +3367,28 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3356
3367
  set$(ctx, `containerSpan${containerIndex}`, span);
3357
3368
  }
3358
3369
  }
3370
+ const prevItemInfo = peek$(ctx, `containerItemInfo${containerIndex}`);
3359
3371
  const prevData = peek$(ctx, `containerItemData${containerIndex}`);
3372
+ let itemInfoValue = prevData;
3373
+ let didChangeItemInfo = (prevItemInfo == null ? void 0 : prevItemInfo.itemKey) !== itemKey || (prevItemInfo == null ? void 0 : prevItemInfo.index) !== itemIndex || (prevItemInfo == null ? void 0 : prevItemInfo.value) !== prevData;
3374
+ const updateData = () => {
3375
+ set$(ctx, `containerItemData${containerIndex}`, item);
3376
+ itemInfoValue = item;
3377
+ didChangeItemInfo = true;
3378
+ didRefreshData = true;
3379
+ };
3360
3380
  if (prevData !== item) {
3361
3381
  const pendingDataComparison = ((_e = state.pendingDataComparison) == null ? void 0 : _e.previousData) === state.previousData && ((_f = state.pendingDataComparison) == null ? void 0 : _f.nextData) === data ? state.pendingDataComparison : void 0;
3362
3382
  const cachedComparison = (_g = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _g : 0;
3363
3383
  if (cachedComparison === 2) {
3364
- set$(ctx, `containerItemData${containerIndex}`, item);
3365
- didRefreshData = true;
3384
+ updateData();
3366
3385
  } else if (cachedComparison !== 1) {
3367
3386
  const nextItemKey = (_h = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _h : itemKey;
3368
3387
  const prevKey = keyExtractor == null ? void 0 : keyExtractor(prevData, itemIndex);
3369
3388
  if (prevData === void 0 || !keyExtractor || prevKey !== nextItemKey) {
3370
- set$(ctx, `containerItemData${containerIndex}`, item);
3371
- didRefreshData = true;
3389
+ updateData();
3372
3390
  } else if (!itemsAreEqual) {
3373
- set$(ctx, `containerItemData${containerIndex}`, item);
3374
- didRefreshData = true;
3391
+ updateData();
3375
3392
  } else {
3376
3393
  const isEqual = itemsAreEqual(prevData, item, itemIndex, data);
3377
3394
  if (!state.pendingDataComparison || state.pendingDataComparison.previousData !== state.previousData || state.pendingDataComparison.nextData !== data) {
@@ -3387,12 +3404,18 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3387
3404
  state.pendingDataComparison.byIndex[itemIndex] = isEqual ? 1 : 2;
3388
3405
  }
3389
3406
  if (!isEqual) {
3390
- set$(ctx, `containerItemData${containerIndex}`, item);
3391
- didRefreshData = true;
3407
+ updateData();
3392
3408
  }
3393
3409
  }
3394
3410
  }
3395
3411
  }
3412
+ if (didChangeItemInfo) {
3413
+ set$(ctx, `containerItemInfo${containerIndex}`, {
3414
+ index: itemIndex,
3415
+ itemKey,
3416
+ value: itemInfoValue
3417
+ });
3418
+ }
3396
3419
  return { didChangePosition, didRefreshData };
3397
3420
  }
3398
3421
 
@@ -4638,6 +4661,11 @@ function calculateItemsInView(ctx, params = {}) {
4638
4661
  }
4639
4662
  set$(ctx, `containerItemKey${containerIndex}`, id);
4640
4663
  set$(ctx, `containerItemData${containerIndex}`, data[i]);
4664
+ set$(ctx, `containerItemInfo${containerIndex}`, {
4665
+ index: i,
4666
+ itemKey: id,
4667
+ value: data[i]
4668
+ });
4641
4669
  if (allocation.itemType !== void 0) {
4642
4670
  state.containerItemTypes.set(containerIndex, allocation.itemType);
4643
4671
  }
@@ -4704,6 +4732,7 @@ function calculateItemsInView(ctx, params = {}) {
4704
4732
  }
4705
4733
  set$(ctx, `containerItemKey${i}`, void 0);
4706
4734
  set$(ctx, `containerItemData${i}`, void 0);
4735
+ set$(ctx, `containerItemInfo${i}`, void 0);
4707
4736
  set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
4708
4737
  set$(ctx, `containerColumn${i}`, -1);
4709
4738
  set$(ctx, `containerSpan${i}`, 1);
@@ -5324,12 +5353,9 @@ var Container = typedMemo(function Container2({
5324
5353
  ctx.viewRefs.set(id, ref);
5325
5354
  return {
5326
5355
  containerId: id,
5327
- index,
5328
- itemKey,
5329
- triggerLayout,
5330
- value: data
5356
+ triggerLayout
5331
5357
  };
5332
- }, [id, itemKey, index, data, triggerLayout]);
5358
+ }, [id, triggerLayout]);
5333
5359
  React3.useLayoutEffect(() => {
5334
5360
  ctx.containerLayoutTriggers.set(id, triggerLayout);
5335
5361
  return () => {
@@ -127,6 +127,7 @@ var createAnimatedValue = (value) => value;
127
127
 
128
128
  // src/state/state.tsx
129
129
  var ContextState = React3.createContext(null);
130
+ var SIGNAL_NAMES_SEPARATOR = "\0";
130
131
  var contextNum = 0;
131
132
  function StateProvider({ children }) {
132
133
  const [value] = React3.useState(() => ({
@@ -198,6 +199,12 @@ function createSelectorFunctionsArr(ctx, signalNames) {
198
199
  }
199
200
  };
200
201
  }
202
+ function getSignalNamesKey(signalNames) {
203
+ return signalNames.length === 1 ? signalNames[0] : signalNames.join(SIGNAL_NAMES_SEPARATOR);
204
+ }
205
+ function getSignalNamesFromKey(signalNamesKey) {
206
+ return signalNamesKey.split(SIGNAL_NAMES_SEPARATOR);
207
+ }
201
208
  function listen$(ctx, signalName, cb) {
202
209
  const { listeners } = ctx;
203
210
  let setListeners = listeners.get(signalName);
@@ -245,7 +252,11 @@ function notifyPosition$(ctx, key, value) {
245
252
  }
246
253
  function useArr$(signalNames) {
247
254
  const ctx = React3.useContext(ContextState);
248
- const { subscribe, get } = React3.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
255
+ const signalNamesKey = getSignalNamesKey(signalNames);
256
+ const { subscribe, get } = React3.useMemo(
257
+ () => createSelectorFunctionsArr(ctx, getSignalNamesFromKey(signalNamesKey)),
258
+ [ctx, signalNamesKey]
259
+ );
249
260
  const value = useSyncExternalStore(subscribe, get, get);
250
261
  return value;
251
262
  }
@@ -532,9 +543,22 @@ function useInit(cb) {
532
543
 
533
544
  // src/state/ContextContainer.ts
534
545
  var ContextContainer = createContext(null);
546
+ var NO_CONTAINER_ID = -1;
535
547
  function useContextContainer() {
536
548
  return useContext(ContextContainer);
537
549
  }
550
+ function useContainerItemInfo(containerContext) {
551
+ var _a3;
552
+ const containerId = (_a3 = containerContext == null ? void 0 : containerContext.containerId) != null ? _a3 : NO_CONTAINER_ID;
553
+ const [itemInfo] = useArr$([`containerItemInfo${containerId}`]);
554
+ return containerContext ? itemInfo : void 0;
555
+ }
556
+ function useContainerItemKey(containerContext) {
557
+ var _a3;
558
+ const containerId = (_a3 = containerContext == null ? void 0 : containerContext.containerId) != null ? _a3 : NO_CONTAINER_ID;
559
+ const [itemKey] = useArr$([`containerItemKey${containerId}`]);
560
+ return containerContext ? itemKey : void 0;
561
+ }
538
562
  function useAdaptiveRender() {
539
563
  const [mode] = useArr$(["adaptiveRender"]);
540
564
  return mode;
@@ -605,40 +629,35 @@ function useViewabilityAmount(callback) {
605
629
  }
606
630
  function useRecyclingEffect(effect) {
607
631
  const containerContext = useContextContainer();
608
- const prevValues = useRef({
609
- prevIndex: void 0,
610
- prevItem: void 0
611
- });
632
+ const itemInfo = useContainerItemInfo(containerContext);
633
+ const prevInfo = useRef(void 0);
612
634
  useEffect(() => {
613
- if (!containerContext) {
635
+ if (!itemInfo) {
614
636
  return;
615
637
  }
616
- const { index, value } = containerContext;
617
638
  let ret;
618
- if (prevValues.current.prevIndex !== void 0 && prevValues.current.prevItem !== void 0) {
639
+ if (prevInfo.current) {
619
640
  ret = effect({
620
- index,
621
- item: value,
622
- prevIndex: prevValues.current.prevIndex,
623
- prevItem: prevValues.current.prevItem
641
+ index: itemInfo.index,
642
+ item: itemInfo.value,
643
+ prevIndex: prevInfo.current.index,
644
+ prevItem: prevInfo.current.value
624
645
  });
625
646
  }
626
- prevValues.current = {
627
- prevIndex: index,
628
- prevItem: value
629
- };
647
+ prevInfo.current = itemInfo;
630
648
  return ret;
631
- }, [effect, containerContext]);
649
+ }, [effect, itemInfo]);
632
650
  }
633
651
  function useRecyclingState(valueOrFun) {
634
- var _a3, _b;
652
+ var _a3;
635
653
  const containerContext = useContextContainer();
636
- const computeValue = (ctx) => {
654
+ const itemInfo = useContainerItemInfo(containerContext);
655
+ const computeValue = (info) => {
637
656
  if (isFunction(valueOrFun)) {
638
657
  const initializer = valueOrFun;
639
- return ctx ? initializer({
640
- index: ctx.index,
641
- item: ctx.value,
658
+ return info ? initializer({
659
+ index: info.index,
660
+ item: info.value,
642
661
  prevIndex: void 0,
643
662
  prevItem: void 0
644
663
  }) : initializer();
@@ -646,13 +665,12 @@ function useRecyclingState(valueOrFun) {
646
665
  return valueOrFun;
647
666
  };
648
667
  const [stateValue, setStateValue] = useState(() => {
649
- return computeValue(containerContext);
668
+ return computeValue(itemInfo);
650
669
  });
651
- const prevItemKeyRef = useRef((_a3 = containerContext == null ? void 0 : containerContext.itemKey) != null ? _a3 : null);
652
- const currentItemKey = (_b = containerContext == null ? void 0 : containerContext.itemKey) != null ? _b : null;
653
- if (currentItemKey !== null && prevItemKeyRef.current !== currentItemKey) {
654
- prevItemKeyRef.current = currentItemKey;
655
- setStateValue(computeValue(containerContext));
670
+ const prevItemKeyRef = useRef((_a3 = itemInfo == null ? void 0 : itemInfo.itemKey) != null ? _a3 : null);
671
+ if (itemInfo && prevItemKeyRef.current !== itemInfo.itemKey) {
672
+ prevItemKeyRef.current = itemInfo.itemKey;
673
+ setStateValue(computeValue(itemInfo));
656
674
  }
657
675
  const triggerLayout = containerContext == null ? void 0 : containerContext.triggerLayout;
658
676
  const setState = useCallback(
@@ -671,12 +689,10 @@ function useRecyclingState(valueOrFun) {
671
689
  }
672
690
  function useIsLastItem() {
673
691
  const containerContext = useContextContainer();
692
+ const itemKey = useContainerItemKey(containerContext);
674
693
  const isLast = useSelector$("lastItemKeys", (lastItemKeys) => {
675
- if (containerContext) {
676
- const { itemKey } = containerContext;
677
- if (!isNullOrUndefined(itemKey)) {
678
- return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
679
- }
694
+ if (containerContext && !isNullOrUndefined(itemKey)) {
695
+ return (lastItemKeys == null ? void 0 : lastItemKeys.includes(itemKey)) || false;
680
696
  }
681
697
  return false;
682
698
  });
@@ -690,12 +706,7 @@ var noop = () => {
690
706
  };
691
707
  function useSyncLayout() {
692
708
  const containerContext = useContextContainer();
693
- if (containerContext) {
694
- const { triggerLayout: syncLayout } = containerContext;
695
- return syncLayout;
696
- } else {
697
- return noop;
698
- }
709
+ return containerContext ? containerContext.triggerLayout : noop;
699
710
  }
700
711
 
701
712
  // src/components/Separator.tsx
@@ -3335,22 +3346,28 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3335
3346
  set$(ctx, `containerSpan${containerIndex}`, span);
3336
3347
  }
3337
3348
  }
3349
+ const prevItemInfo = peek$(ctx, `containerItemInfo${containerIndex}`);
3338
3350
  const prevData = peek$(ctx, `containerItemData${containerIndex}`);
3351
+ let itemInfoValue = prevData;
3352
+ let didChangeItemInfo = (prevItemInfo == null ? void 0 : prevItemInfo.itemKey) !== itemKey || (prevItemInfo == null ? void 0 : prevItemInfo.index) !== itemIndex || (prevItemInfo == null ? void 0 : prevItemInfo.value) !== prevData;
3353
+ const updateData = () => {
3354
+ set$(ctx, `containerItemData${containerIndex}`, item);
3355
+ itemInfoValue = item;
3356
+ didChangeItemInfo = true;
3357
+ didRefreshData = true;
3358
+ };
3339
3359
  if (prevData !== item) {
3340
3360
  const pendingDataComparison = ((_e = state.pendingDataComparison) == null ? void 0 : _e.previousData) === state.previousData && ((_f = state.pendingDataComparison) == null ? void 0 : _f.nextData) === data ? state.pendingDataComparison : void 0;
3341
3361
  const cachedComparison = (_g = pendingDataComparison == null ? void 0 : pendingDataComparison.byIndex[itemIndex]) != null ? _g : 0;
3342
3362
  if (cachedComparison === 2) {
3343
- set$(ctx, `containerItemData${containerIndex}`, item);
3344
- didRefreshData = true;
3363
+ updateData();
3345
3364
  } else if (cachedComparison !== 1) {
3346
3365
  const nextItemKey = (_h = peek$(ctx, `containerItemKey${containerIndex}`)) != null ? _h : itemKey;
3347
3366
  const prevKey = keyExtractor == null ? void 0 : keyExtractor(prevData, itemIndex);
3348
3367
  if (prevData === void 0 || !keyExtractor || prevKey !== nextItemKey) {
3349
- set$(ctx, `containerItemData${containerIndex}`, item);
3350
- didRefreshData = true;
3368
+ updateData();
3351
3369
  } else if (!itemsAreEqual) {
3352
- set$(ctx, `containerItemData${containerIndex}`, item);
3353
- didRefreshData = true;
3370
+ updateData();
3354
3371
  } else {
3355
3372
  const isEqual = itemsAreEqual(prevData, item, itemIndex, data);
3356
3373
  if (!state.pendingDataComparison || state.pendingDataComparison.previousData !== state.previousData || state.pendingDataComparison.nextData !== data) {
@@ -3366,12 +3383,18 @@ function syncMountedContainer(ctx, containerIndex, itemIndex, options) {
3366
3383
  state.pendingDataComparison.byIndex[itemIndex] = isEqual ? 1 : 2;
3367
3384
  }
3368
3385
  if (!isEqual) {
3369
- set$(ctx, `containerItemData${containerIndex}`, item);
3370
- didRefreshData = true;
3386
+ updateData();
3371
3387
  }
3372
3388
  }
3373
3389
  }
3374
3390
  }
3391
+ if (didChangeItemInfo) {
3392
+ set$(ctx, `containerItemInfo${containerIndex}`, {
3393
+ index: itemIndex,
3394
+ itemKey,
3395
+ value: itemInfoValue
3396
+ });
3397
+ }
3375
3398
  return { didChangePosition, didRefreshData };
3376
3399
  }
3377
3400
 
@@ -4617,6 +4640,11 @@ function calculateItemsInView(ctx, params = {}) {
4617
4640
  }
4618
4641
  set$(ctx, `containerItemKey${containerIndex}`, id);
4619
4642
  set$(ctx, `containerItemData${containerIndex}`, data[i]);
4643
+ set$(ctx, `containerItemInfo${containerIndex}`, {
4644
+ index: i,
4645
+ itemKey: id,
4646
+ value: data[i]
4647
+ });
4620
4648
  if (allocation.itemType !== void 0) {
4621
4649
  state.containerItemTypes.set(containerIndex, allocation.itemType);
4622
4650
  }
@@ -4683,6 +4711,7 @@ function calculateItemsInView(ctx, params = {}) {
4683
4711
  }
4684
4712
  set$(ctx, `containerItemKey${i}`, void 0);
4685
4713
  set$(ctx, `containerItemData${i}`, void 0);
4714
+ set$(ctx, `containerItemInfo${i}`, void 0);
4686
4715
  set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
4687
4716
  set$(ctx, `containerColumn${i}`, -1);
4688
4717
  set$(ctx, `containerSpan${i}`, 1);
@@ -5303,12 +5332,9 @@ var Container = typedMemo(function Container2({
5303
5332
  ctx.viewRefs.set(id, ref);
5304
5333
  return {
5305
5334
  containerId: id,
5306
- index,
5307
- itemKey,
5308
- triggerLayout,
5309
- value: data
5335
+ triggerLayout
5310
5336
  };
5311
- }, [id, itemKey, index, data, triggerLayout]);
5337
+ }, [id, triggerLayout]);
5312
5338
  useLayoutEffect(() => {
5313
5339
  ctx.containerLayoutTriggers.set(id, triggerLayout);
5314
5340
  return () => {
package/react.d.ts CHANGED
@@ -31,7 +31,7 @@ interface MaintainVisibleContentPositionNormalized<ItemT = any> {
31
31
  shouldRestorePosition?: (item: ItemT, index: number, data: readonly ItemT[]) => boolean;
32
32
  }
33
33
 
34
- type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
34
+ type ListenerType = "activeStickyIndex" | "alignItemsAtEndPadding" | "anchoredEndSpaceSize" | "debugComputedScroll" | "debugRawScroll" | "extraData" | "footerSize" | "headerSize" | "lastItemKeys" | "lastPositionUpdate" | "maintainVisibleContentPosition" | "numColumns" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "scrollAdjust" | "scrollAdjustPending" | "scrollAdjustUserOffset" | "scrollSize" | "snapToOffsets" | "stylePaddingTop" | "totalSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | `containerColumn${number}` | `containerSpan${number}` | `containerItemData${number}` | `containerItemInfo${number}` | `containerItemKey${number}` | `containerPosition${number}` | `containerSticky${number}`;
35
35
  type LegendListListenerType = Extract<ListenerType, "activeStickyIndex" | "anchoredEndSpaceSize" | "footerSize" | "headerSize" | "isAtEnd" | "isAtStart" | "isNearEnd" | "isNearStart" | "isWithinMaintainScrollAtEndThreshold" | "adaptiveRender" | "lastItemKeys" | "lastPositionUpdate" | "numContainers" | "numContainersPooled" | "otherAxisSize" | "readyToRender" | "snapToOffsets" | "totalSize">;
36
36
  type ListenerTypeValueMap = {
37
37
  activeStickyIndex: number;
@@ -71,6 +71,8 @@ type ListenerTypeValueMap = {
71
71
  [K in ListenerType as K extends `containerItemKey${number}` ? K : never]: string;
72
72
  } & {
73
73
  [K in ListenerType as K extends `containerItemData${number}` ? K : never]: any;
74
+ } & {
75
+ [K in ListenerType as K extends `containerItemInfo${number}` ? K : never]: ContainerItemInfo;
74
76
  } & {
75
77
  [K in ListenerType as K extends `containerPosition${number}` ? K : never]: number;
76
78
  } & {
@@ -80,6 +82,11 @@ type ListenerTypeValueMap = {
80
82
  } & {
81
83
  [K in ListenerType as K extends `containerSticky${number}` ? K : never]: boolean;
82
84
  };
85
+ interface ContainerItemInfo {
86
+ index: number;
87
+ itemKey: string;
88
+ value: any;
89
+ }
83
90
 
84
91
  interface Insets {
85
92
  top: number;