@legendapp/list 0.4.4 → 0.4.5

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
@@ -1,7 +1,7 @@
1
1
  import { ComponentProps, ReactNode, ForwardedRef, ReactElement } from 'react';
2
2
  import { ScrollView, StyleProp, ViewStyle, ScrollViewComponent, ScrollResponderMixin } from 'react-native';
3
3
 
4
- type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset'> & {
4
+ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, "contentOffset"> & {
5
5
  data: ArrayLike<any> & T[];
6
6
  initialScrollOffset?: number;
7
7
  initialScrollIndex?: number;
@@ -52,6 +52,7 @@ interface InternalState {
52
52
  totalSize: number;
53
53
  timeouts: Set<number>;
54
54
  viewabilityConfigCallbackPairs: ViewabilityConfigCallbackPairs;
55
+ renderItem: (props: LegendListRenderItemProps<any>) => ReactNode;
55
56
  }
56
57
  interface ViewableRange<T> {
57
58
  startBuffered: number;
package/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ComponentProps, ReactNode, ForwardedRef, ReactElement } from 'react';
2
2
  import { ScrollView, StyleProp, ViewStyle, ScrollViewComponent, ScrollResponderMixin } from 'react-native';
3
3
 
4
- type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, 'contentOffset'> & {
4
+ type LegendListProps<T> = Omit<ComponentProps<typeof ScrollView>, "contentOffset"> & {
5
5
  data: ArrayLike<any> & T[];
6
6
  initialScrollOffset?: number;
7
7
  initialScrollIndex?: number;
@@ -52,6 +52,7 @@ interface InternalState {
52
52
  totalSize: number;
53
53
  timeouts: Set<number>;
54
54
  viewabilityConfigCallbackPairs: ViewabilityConfigCallbackPairs;
55
+ renderItem: (props: LegendListRenderItemProps<any>) => ReactNode;
55
56
  }
56
57
  interface ViewableRange<T> {
57
58
  startBuffered: number;
package/index.js CHANGED
@@ -33,7 +33,11 @@ function StateProvider({ children }) {
33
33
  const [value] = React6__namespace.useState(() => ({
34
34
  hooks: /* @__PURE__ */ new Map(),
35
35
  listeners: /* @__PURE__ */ new Map(),
36
- values: /* @__PURE__ */ new Map()
36
+ values: /* @__PURE__ */ new Map(),
37
+ mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
38
+ mapViewabilityValues: /* @__PURE__ */ new Map(),
39
+ mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
40
+ mapViewabilityAmountValues: /* @__PURE__ */ new Map()
37
41
  }));
38
42
  return /* @__PURE__ */ React6__namespace.createElement(ContextState.Provider, { value }, children);
39
43
  }
@@ -256,13 +260,7 @@ var ListComponent = React6__namespace.memo(function ListComponent2({
256
260
  },
257
261
  getComponent(ListHeaderComponent)
258
262
  ),
259
- ListEmptyComponent && /* @__PURE__ */ React6__namespace.createElement(
260
- reactNative.View,
261
- {
262
- style: ListEmptyComponentStyle
263
- },
264
- getComponent(ListEmptyComponent)
265
- ),
263
+ ListEmptyComponent && /* @__PURE__ */ React6__namespace.createElement(reactNative.View, { style: ListEmptyComponentStyle }, getComponent(ListEmptyComponent)),
266
264
  /* @__PURE__ */ React6__namespace.createElement(
267
265
  Containers,
268
266
  {
@@ -276,17 +274,26 @@ var ListComponent = React6__namespace.memo(function ListComponent2({
276
274
  ListFooterComponent && /* @__PURE__ */ React6__namespace.createElement(reactNative.View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
277
275
  );
278
276
  });
277
+ var symbolFirst = Symbol();
278
+ function useInit(cb) {
279
+ const refValue = React6.useRef(symbolFirst);
280
+ if (refValue.current === symbolFirst) {
281
+ refValue.current = cb();
282
+ }
283
+ return refValue.current;
284
+ }
279
285
 
280
286
  // src/viewability.ts
281
287
  var mapViewabilityConfigCallbackPairs = /* @__PURE__ */ new Map();
282
- var mapViewabilityCallbacks = /* @__PURE__ */ new Map();
283
- var mapViewabilityValues = /* @__PURE__ */ new Map();
284
- var mapViewabilityAmountCallbacks = /* @__PURE__ */ new Map();
285
- var mapViewabilityAmountValues = /* @__PURE__ */ new Map();
286
288
  function setupViewability(props) {
287
289
  let { viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged } = props;
288
290
  viewabilityConfigCallbackPairs = viewabilityConfigCallbackPairs || [
289
- { viewabilityConfig: viewabilityConfig || { viewAreaCoveragePercentThreshold: 0 }, onViewableItemsChanged }
291
+ {
292
+ viewabilityConfig: viewabilityConfig || {
293
+ viewAreaCoveragePercentThreshold: 0
294
+ },
295
+ onViewableItemsChanged
296
+ }
290
297
  ];
291
298
  if (viewabilityConfigCallbackPairs) {
292
299
  for (const pair of viewabilityConfigCallbackPairs) {
@@ -352,12 +359,16 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
352
359
  }
353
360
  }
354
361
  }
355
- Object.assign(viewabilityState, { viewableItems, previousStart: start, previousEnd: end });
362
+ Object.assign(viewabilityState, {
363
+ viewableItems,
364
+ previousStart: start,
365
+ previousEnd: end
366
+ });
356
367
  if (changed.length > 0) {
357
368
  viewabilityState.viewableItems = viewableItems;
358
369
  for (let i = 0; i < changed.length; i++) {
359
370
  const change = changed[i];
360
- maybeUpdateViewabilityCallback(configId, change);
371
+ maybeUpdateViewabilityCallback(ctx, configId, change);
361
372
  }
362
373
  if (onViewableItemsChanged) {
363
374
  onViewableItemsChanged({ viewableItems, changed });
@@ -392,8 +403,8 @@ function isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, index)
392
403
  position: top,
393
404
  scrollSize
394
405
  };
395
- mapViewabilityAmountValues.set(containerId, value);
396
- const cb = mapViewabilityAmountCallbacks.get(containerId);
406
+ ctx.mapViewabilityAmountValues.set(containerId, value);
407
+ const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
397
408
  if (cb) {
398
409
  cb(value);
399
410
  }
@@ -409,25 +420,12 @@ function findContainerId(state, ctx, index) {
409
420
  }
410
421
  return -1;
411
422
  }
412
- function maybeUpdateViewabilityCallback(configId, viewToken) {
423
+ function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
413
424
  const key = viewToken.key + configId;
414
- mapViewabilityValues.set(key, viewToken);
415
- const cb = mapViewabilityCallbacks.get(key);
425
+ ctx.mapViewabilityValues.set(key, viewToken);
426
+ const cb = ctx.mapViewabilityCallbacks.get(key);
416
427
  cb == null ? void 0 : cb(viewToken);
417
428
  }
418
- function registerViewabilityCallback(containerId, configId, callback) {
419
- const key = containerId + configId;
420
- mapViewabilityCallbacks.set(key, callback);
421
- return () => {
422
- mapViewabilityCallbacks.delete(key);
423
- };
424
- }
425
- function registerViewabilityAmountCallback(containerId, callback) {
426
- mapViewabilityAmountCallbacks.set(containerId, callback);
427
- return () => {
428
- mapViewabilityAmountCallbacks.delete(containerId);
429
- };
430
- }
431
429
 
432
430
  // src/LegendList.tsx
433
431
  var DEFAULT_SCROLL_BUFFER = 0;
@@ -522,11 +520,13 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
522
520
  scroll: initialContentOffset || 0,
523
521
  totalSize: 0,
524
522
  timeouts: /* @__PURE__ */ new Set(),
525
- viewabilityConfigCallbackPairs: void 0
523
+ viewabilityConfigCallbackPairs: void 0,
524
+ renderItem: void 0
526
525
  };
527
526
  refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
528
527
  }
529
528
  refState.current.data = data;
529
+ refState.current.renderItem = renderItem;
530
530
  set$(ctx, "numItems", data.length);
531
531
  set$(ctx, "stylePaddingTop", (_b = (_a = styleFlattened == null ? void 0 : styleFlattened.paddingTop) != null ? _a : contentContainerStyleFlattened == null ? void 0 : contentContainerStyleFlattened.paddingTop) != null ? _b : 0);
532
532
  const addTotalSize = React6.useCallback((add) => {
@@ -548,83 +548,93 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
548
548
  refState.current.animFrameTotalSize = requestAnimationFrame(doAdd);
549
549
  }
550
550
  }, []);
551
- const getRenderedItem = React6.useCallback(
552
- (index, containerIndex) => {
553
- var _a2;
554
- const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
555
- if (!data2) {
556
- return null;
557
- }
558
- const useViewability = (configId, callback) => {
559
- React6.useMemo(() => {
560
- const value = mapViewabilityValues.get(containerIndex + configId);
561
- if (value) {
562
- callback(value);
563
- }
564
- }, []);
565
- React6.useEffect(() => registerViewabilityCallback(containerIndex, configId, callback), []);
566
- };
567
- const useViewabilityAmount = (callback) => {
568
- React6.useMemo(() => {
569
- const value = mapViewabilityAmountValues.get(containerIndex);
570
- if (value) {
571
- callback(value);
572
- }
573
- }, []);
574
- React6.useEffect(() => registerViewabilityAmountCallback(containerIndex, callback), []);
575
- };
576
- const useRecyclingEffect = (effect) => {
577
- React6.useEffect(() => {
578
- let prevIndex = index;
579
- let prevItem = data2[index];
580
- const signal = `containerIndex${containerIndex}`;
581
- listen$(ctx, signal, () => {
582
- var _a3;
583
- const data3 = (_a3 = refState.current) == null ? void 0 : _a3.data;
584
- if (data3) {
585
- const newIndex = peek$(ctx, signal);
586
- const newItem = data3[newIndex];
587
- if (newItem) {
588
- effect({
589
- index: newIndex,
590
- item: newItem,
591
- prevIndex,
592
- prevItem
593
- });
594
- }
595
- prevIndex = newIndex;
596
- prevItem = newItem;
551
+ const getRenderedItem = React6.useCallback((index, containerIndex) => {
552
+ var _a2, _b2, _c;
553
+ const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
554
+ if (!data2) {
555
+ return null;
556
+ }
557
+ const useViewability = (configId, callback) => {
558
+ const key = containerIndex + configId;
559
+ useInit(() => {
560
+ const value = ctx.mapViewabilityValues.get(key);
561
+ if (value) {
562
+ callback(value);
563
+ }
564
+ });
565
+ ctx.mapViewabilityCallbacks.set(key, callback);
566
+ React6.useEffect(
567
+ () => () => {
568
+ ctx.mapViewabilityCallbacks.delete(key);
569
+ },
570
+ []
571
+ );
572
+ };
573
+ const useViewabilityAmount = (callback) => {
574
+ useInit(() => {
575
+ const value = ctx.mapViewabilityAmountValues.get(containerIndex);
576
+ if (value) {
577
+ callback(value);
578
+ }
579
+ });
580
+ ctx.mapViewabilityAmountCallbacks.set(containerIndex, callback);
581
+ React6.useEffect(
582
+ () => () => {
583
+ ctx.mapViewabilityAmountCallbacks.delete(containerIndex);
584
+ },
585
+ []
586
+ );
587
+ };
588
+ const useRecyclingEffect = (effect) => {
589
+ React6.useEffect(() => {
590
+ const state = refState.current;
591
+ let prevIndex = index;
592
+ let prevItem = state.data[index];
593
+ const signal = `containerIndex${containerIndex}`;
594
+ listen$(ctx, signal, () => {
595
+ const data3 = state.data;
596
+ if (data3) {
597
+ const newIndex = peek$(ctx, signal);
598
+ const newItem = data3[newIndex];
599
+ if (newItem) {
600
+ effect({
601
+ index: newIndex,
602
+ item: newItem,
603
+ prevIndex,
604
+ prevItem
605
+ });
597
606
  }
598
- });
599
- }, []);
600
- };
601
- const useRecyclingState = (updateState) => {
602
- const stateInfo = React6.useState(
603
- () => updateState({
604
- index,
605
- item: data2[index],
606
- prevIndex: void 0,
607
- prevItem: void 0
608
- })
609
- );
610
- useRecyclingEffect((state) => {
611
- const newState = updateState(state);
612
- stateInfo[1](newState);
607
+ prevIndex = newIndex;
608
+ prevItem = newItem;
609
+ }
613
610
  });
614
- return stateInfo;
615
- };
616
- const renderedItem = renderItem == null ? void 0 : renderItem({
617
- item: data2[index],
618
- index,
619
- useViewability,
620
- useViewabilityAmount,
621
- useRecyclingEffect,
622
- useRecyclingState
611
+ }, []);
612
+ };
613
+ const useRecyclingState = (updateState) => {
614
+ const stateInfo = React6.useState(
615
+ () => updateState({
616
+ index,
617
+ item: refState.current.data[index],
618
+ prevIndex: void 0,
619
+ prevItem: void 0
620
+ })
621
+ );
622
+ useRecyclingEffect((state) => {
623
+ const newState = updateState(state);
624
+ stateInfo[1](newState);
623
625
  });
624
- return renderedItem;
625
- },
626
- [renderItem]
627
- );
626
+ return stateInfo;
627
+ };
628
+ const renderedItem = (_c = (_b2 = refState.current).renderItem) == null ? void 0 : _c.call(_b2, {
629
+ item: data2[index],
630
+ index,
631
+ useViewability,
632
+ useViewabilityAmount,
633
+ useRecyclingEffect,
634
+ useRecyclingState
635
+ });
636
+ return renderedItem;
637
+ }, []);
628
638
  const calculateItemsInView = React6.useCallback(() => {
629
639
  reactNative.unstable_batchedUpdates(() => {
630
640
  var _a2, _b2, _c;
@@ -775,7 +785,7 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
775
785
  }
776
786
  });
777
787
  }, []);
778
- React6.useMemo(() => {
788
+ useInit(() => {
779
789
  var _a2, _b2;
780
790
  refState.current.viewabilityConfigCallbackPairs = setupViewability(props);
781
791
  const scrollLength = refState.current.scrollLength;
@@ -794,7 +804,7 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
794
804
  totalSize += (_b2 = sizes.get(id)) != null ? _b2 : getItemSize(i, data[i]);
795
805
  }
796
806
  addTotalSize(totalSize);
797
- }, []);
807
+ });
798
808
  const checkAtBottom = () => {
799
809
  var _a2;
800
810
  const { scrollLength, scroll } = refState.current;
@@ -887,31 +897,35 @@ var LegendListInner = React6.forwardRef(function LegendListInner2(props, forward
887
897
  },
888
898
  []
889
899
  );
890
- React6.useImperativeHandle(forwardedRef, () => {
891
- const scrollToIndex = ({ index, animated }) => {
892
- const offsetObj = calculateInitialOffset(index);
893
- const offset = horizontal ? { x: offsetObj, y: 0 } : { x: 0, y: offsetObj };
894
- refScroller.current.scrollTo({ ...offset, animated });
895
- };
896
- return {
897
- getNativeScrollRef: () => refScroller.current,
898
- getScrollableNode: refScroller.current.getScrollableNode,
899
- getScrollResponder: refScroller.current.getScrollResponder,
900
- flashScrollIndicators: refScroller.current.flashScrollIndicators,
901
- scrollToIndex,
902
- scrollToOffset: ({ offset, animated }) => {
903
- const offsetObj = horizontal ? { x: offset, y: 0 } : { x: 0, y: offset };
904
- refScroller.current.scrollTo({ ...offsetObj, animated });
905
- },
906
- scrollToItem: ({ item, animated }) => {
907
- const index = data.indexOf(item);
908
- if (index !== -1) {
909
- scrollToIndex({ index, animated });
910
- }
911
- },
912
- scrollToEnd: refScroller.current.scrollToEnd
913
- };
914
- }, []);
900
+ React6.useImperativeHandle(
901
+ forwardedRef,
902
+ () => {
903
+ const scrollToIndex = ({ index, animated }) => {
904
+ const offsetObj = calculateInitialOffset(index);
905
+ const offset = horizontal ? { x: offsetObj, y: 0 } : { x: 0, y: offsetObj };
906
+ refScroller.current.scrollTo({ ...offset, animated });
907
+ };
908
+ return {
909
+ getNativeScrollRef: () => refScroller.current,
910
+ getScrollableNode: refScroller.current.getScrollableNode,
911
+ getScrollResponder: refScroller.current.getScrollResponder,
912
+ flashScrollIndicators: refScroller.current.flashScrollIndicators,
913
+ scrollToIndex,
914
+ scrollToOffset: ({ offset, animated }) => {
915
+ const offsetObj = horizontal ? { x: offset, y: 0 } : { x: 0, y: offset };
916
+ refScroller.current.scrollTo({ ...offsetObj, animated });
917
+ },
918
+ scrollToItem: ({ item, animated }) => {
919
+ const index = data.indexOf(item);
920
+ if (index !== -1) {
921
+ scrollToIndex({ index, animated });
922
+ }
923
+ },
924
+ scrollToEnd: refScroller.current.scrollToEnd
925
+ };
926
+ },
927
+ []
928
+ );
915
929
  return /* @__PURE__ */ React6__namespace.createElement(
916
930
  ListComponent,
917
931
  {
package/index.mjs CHANGED
@@ -12,7 +12,11 @@ function StateProvider({ children }) {
12
12
  const [value] = React6.useState(() => ({
13
13
  hooks: /* @__PURE__ */ new Map(),
14
14
  listeners: /* @__PURE__ */ new Map(),
15
- values: /* @__PURE__ */ new Map()
15
+ values: /* @__PURE__ */ new Map(),
16
+ mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
17
+ mapViewabilityValues: /* @__PURE__ */ new Map(),
18
+ mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
19
+ mapViewabilityAmountValues: /* @__PURE__ */ new Map()
16
20
  }));
17
21
  return /* @__PURE__ */ React6.createElement(ContextState.Provider, { value }, children);
18
22
  }
@@ -235,13 +239,7 @@ var ListComponent = React6.memo(function ListComponent2({
235
239
  },
236
240
  getComponent(ListHeaderComponent)
237
241
  ),
238
- ListEmptyComponent && /* @__PURE__ */ React6.createElement(
239
- View,
240
- {
241
- style: ListEmptyComponentStyle
242
- },
243
- getComponent(ListEmptyComponent)
244
- ),
242
+ ListEmptyComponent && /* @__PURE__ */ React6.createElement(View, { style: ListEmptyComponentStyle }, getComponent(ListEmptyComponent)),
245
243
  /* @__PURE__ */ React6.createElement(
246
244
  Containers,
247
245
  {
@@ -255,17 +253,26 @@ var ListComponent = React6.memo(function ListComponent2({
255
253
  ListFooterComponent && /* @__PURE__ */ React6.createElement(View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
256
254
  );
257
255
  });
256
+ var symbolFirst = Symbol();
257
+ function useInit(cb) {
258
+ const refValue = useRef(symbolFirst);
259
+ if (refValue.current === symbolFirst) {
260
+ refValue.current = cb();
261
+ }
262
+ return refValue.current;
263
+ }
258
264
 
259
265
  // src/viewability.ts
260
266
  var mapViewabilityConfigCallbackPairs = /* @__PURE__ */ new Map();
261
- var mapViewabilityCallbacks = /* @__PURE__ */ new Map();
262
- var mapViewabilityValues = /* @__PURE__ */ new Map();
263
- var mapViewabilityAmountCallbacks = /* @__PURE__ */ new Map();
264
- var mapViewabilityAmountValues = /* @__PURE__ */ new Map();
265
267
  function setupViewability(props) {
266
268
  let { viewabilityConfig, viewabilityConfigCallbackPairs, onViewableItemsChanged } = props;
267
269
  viewabilityConfigCallbackPairs = viewabilityConfigCallbackPairs || [
268
- { viewabilityConfig: viewabilityConfig || { viewAreaCoveragePercentThreshold: 0 }, onViewableItemsChanged }
270
+ {
271
+ viewabilityConfig: viewabilityConfig || {
272
+ viewAreaCoveragePercentThreshold: 0
273
+ },
274
+ onViewableItemsChanged
275
+ }
269
276
  ];
270
277
  if (viewabilityConfigCallbackPairs) {
271
278
  for (const pair of viewabilityConfigCallbackPairs) {
@@ -331,12 +338,16 @@ function updateViewableItemsWithConfig(data, viewabilityConfigCallbackPair, getI
331
338
  }
332
339
  }
333
340
  }
334
- Object.assign(viewabilityState, { viewableItems, previousStart: start, previousEnd: end });
341
+ Object.assign(viewabilityState, {
342
+ viewableItems,
343
+ previousStart: start,
344
+ previousEnd: end
345
+ });
335
346
  if (changed.length > 0) {
336
347
  viewabilityState.viewableItems = viewableItems;
337
348
  for (let i = 0; i < changed.length; i++) {
338
349
  const change = changed[i];
339
- maybeUpdateViewabilityCallback(configId, change);
350
+ maybeUpdateViewabilityCallback(ctx, configId, change);
340
351
  }
341
352
  if (onViewableItemsChanged) {
342
353
  onViewableItemsChanged({ viewableItems, changed });
@@ -371,8 +382,8 @@ function isViewable(state, ctx, viewabilityConfig, key, scrollSize, item, index)
371
382
  position: top,
372
383
  scrollSize
373
384
  };
374
- mapViewabilityAmountValues.set(containerId, value);
375
- const cb = mapViewabilityAmountCallbacks.get(containerId);
385
+ ctx.mapViewabilityAmountValues.set(containerId, value);
386
+ const cb = ctx.mapViewabilityAmountCallbacks.get(containerId);
376
387
  if (cb) {
377
388
  cb(value);
378
389
  }
@@ -388,25 +399,12 @@ function findContainerId(state, ctx, index) {
388
399
  }
389
400
  return -1;
390
401
  }
391
- function maybeUpdateViewabilityCallback(configId, viewToken) {
402
+ function maybeUpdateViewabilityCallback(ctx, configId, viewToken) {
392
403
  const key = viewToken.key + configId;
393
- mapViewabilityValues.set(key, viewToken);
394
- const cb = mapViewabilityCallbacks.get(key);
404
+ ctx.mapViewabilityValues.set(key, viewToken);
405
+ const cb = ctx.mapViewabilityCallbacks.get(key);
395
406
  cb == null ? void 0 : cb(viewToken);
396
407
  }
397
- function registerViewabilityCallback(containerId, configId, callback) {
398
- const key = containerId + configId;
399
- mapViewabilityCallbacks.set(key, callback);
400
- return () => {
401
- mapViewabilityCallbacks.delete(key);
402
- };
403
- }
404
- function registerViewabilityAmountCallback(containerId, callback) {
405
- mapViewabilityAmountCallbacks.set(containerId, callback);
406
- return () => {
407
- mapViewabilityAmountCallbacks.delete(containerId);
408
- };
409
- }
410
408
 
411
409
  // src/LegendList.tsx
412
410
  var DEFAULT_SCROLL_BUFFER = 0;
@@ -501,11 +499,13 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
501
499
  scroll: initialContentOffset || 0,
502
500
  totalSize: 0,
503
501
  timeouts: /* @__PURE__ */ new Set(),
504
- viewabilityConfigCallbackPairs: void 0
502
+ viewabilityConfigCallbackPairs: void 0,
503
+ renderItem: void 0
505
504
  };
506
505
  refState.current.idsInFirstRender = new Set(data.map((_, i) => getId(i)));
507
506
  }
508
507
  refState.current.data = data;
508
+ refState.current.renderItem = renderItem;
509
509
  set$(ctx, "numItems", data.length);
510
510
  set$(ctx, "stylePaddingTop", (_b = (_a = styleFlattened == null ? void 0 : styleFlattened.paddingTop) != null ? _a : contentContainerStyleFlattened == null ? void 0 : contentContainerStyleFlattened.paddingTop) != null ? _b : 0);
511
511
  const addTotalSize = useCallback((add) => {
@@ -527,83 +527,93 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
527
527
  refState.current.animFrameTotalSize = requestAnimationFrame(doAdd);
528
528
  }
529
529
  }, []);
530
- const getRenderedItem = useCallback(
531
- (index, containerIndex) => {
532
- var _a2;
533
- const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
534
- if (!data2) {
535
- return null;
536
- }
537
- const useViewability = (configId, callback) => {
538
- useMemo(() => {
539
- const value = mapViewabilityValues.get(containerIndex + configId);
540
- if (value) {
541
- callback(value);
542
- }
543
- }, []);
544
- useEffect(() => registerViewabilityCallback(containerIndex, configId, callback), []);
545
- };
546
- const useViewabilityAmount = (callback) => {
547
- useMemo(() => {
548
- const value = mapViewabilityAmountValues.get(containerIndex);
549
- if (value) {
550
- callback(value);
551
- }
552
- }, []);
553
- useEffect(() => registerViewabilityAmountCallback(containerIndex, callback), []);
554
- };
555
- const useRecyclingEffect = (effect) => {
556
- useEffect(() => {
557
- let prevIndex = index;
558
- let prevItem = data2[index];
559
- const signal = `containerIndex${containerIndex}`;
560
- listen$(ctx, signal, () => {
561
- var _a3;
562
- const data3 = (_a3 = refState.current) == null ? void 0 : _a3.data;
563
- if (data3) {
564
- const newIndex = peek$(ctx, signal);
565
- const newItem = data3[newIndex];
566
- if (newItem) {
567
- effect({
568
- index: newIndex,
569
- item: newItem,
570
- prevIndex,
571
- prevItem
572
- });
573
- }
574
- prevIndex = newIndex;
575
- prevItem = newItem;
530
+ const getRenderedItem = useCallback((index, containerIndex) => {
531
+ var _a2, _b2, _c;
532
+ const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
533
+ if (!data2) {
534
+ return null;
535
+ }
536
+ const useViewability = (configId, callback) => {
537
+ const key = containerIndex + configId;
538
+ useInit(() => {
539
+ const value = ctx.mapViewabilityValues.get(key);
540
+ if (value) {
541
+ callback(value);
542
+ }
543
+ });
544
+ ctx.mapViewabilityCallbacks.set(key, callback);
545
+ useEffect(
546
+ () => () => {
547
+ ctx.mapViewabilityCallbacks.delete(key);
548
+ },
549
+ []
550
+ );
551
+ };
552
+ const useViewabilityAmount = (callback) => {
553
+ useInit(() => {
554
+ const value = ctx.mapViewabilityAmountValues.get(containerIndex);
555
+ if (value) {
556
+ callback(value);
557
+ }
558
+ });
559
+ ctx.mapViewabilityAmountCallbacks.set(containerIndex, callback);
560
+ useEffect(
561
+ () => () => {
562
+ ctx.mapViewabilityAmountCallbacks.delete(containerIndex);
563
+ },
564
+ []
565
+ );
566
+ };
567
+ const useRecyclingEffect = (effect) => {
568
+ useEffect(() => {
569
+ const state = refState.current;
570
+ let prevIndex = index;
571
+ let prevItem = state.data[index];
572
+ const signal = `containerIndex${containerIndex}`;
573
+ listen$(ctx, signal, () => {
574
+ const data3 = state.data;
575
+ if (data3) {
576
+ const newIndex = peek$(ctx, signal);
577
+ const newItem = data3[newIndex];
578
+ if (newItem) {
579
+ effect({
580
+ index: newIndex,
581
+ item: newItem,
582
+ prevIndex,
583
+ prevItem
584
+ });
576
585
  }
577
- });
578
- }, []);
579
- };
580
- const useRecyclingState = (updateState) => {
581
- const stateInfo = useState(
582
- () => updateState({
583
- index,
584
- item: data2[index],
585
- prevIndex: void 0,
586
- prevItem: void 0
587
- })
588
- );
589
- useRecyclingEffect((state) => {
590
- const newState = updateState(state);
591
- stateInfo[1](newState);
586
+ prevIndex = newIndex;
587
+ prevItem = newItem;
588
+ }
592
589
  });
593
- return stateInfo;
594
- };
595
- const renderedItem = renderItem == null ? void 0 : renderItem({
596
- item: data2[index],
597
- index,
598
- useViewability,
599
- useViewabilityAmount,
600
- useRecyclingEffect,
601
- useRecyclingState
590
+ }, []);
591
+ };
592
+ const useRecyclingState = (updateState) => {
593
+ const stateInfo = useState(
594
+ () => updateState({
595
+ index,
596
+ item: refState.current.data[index],
597
+ prevIndex: void 0,
598
+ prevItem: void 0
599
+ })
600
+ );
601
+ useRecyclingEffect((state) => {
602
+ const newState = updateState(state);
603
+ stateInfo[1](newState);
602
604
  });
603
- return renderedItem;
604
- },
605
- [renderItem]
606
- );
605
+ return stateInfo;
606
+ };
607
+ const renderedItem = (_c = (_b2 = refState.current).renderItem) == null ? void 0 : _c.call(_b2, {
608
+ item: data2[index],
609
+ index,
610
+ useViewability,
611
+ useViewabilityAmount,
612
+ useRecyclingEffect,
613
+ useRecyclingState
614
+ });
615
+ return renderedItem;
616
+ }, []);
607
617
  const calculateItemsInView = useCallback(() => {
608
618
  unstable_batchedUpdates(() => {
609
619
  var _a2, _b2, _c;
@@ -754,7 +764,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
754
764
  }
755
765
  });
756
766
  }, []);
757
- useMemo(() => {
767
+ useInit(() => {
758
768
  var _a2, _b2;
759
769
  refState.current.viewabilityConfigCallbackPairs = setupViewability(props);
760
770
  const scrollLength = refState.current.scrollLength;
@@ -773,7 +783,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
773
783
  totalSize += (_b2 = sizes.get(id)) != null ? _b2 : getItemSize(i, data[i]);
774
784
  }
775
785
  addTotalSize(totalSize);
776
- }, []);
786
+ });
777
787
  const checkAtBottom = () => {
778
788
  var _a2;
779
789
  const { scrollLength, scroll } = refState.current;
@@ -866,31 +876,35 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
866
876
  },
867
877
  []
868
878
  );
869
- useImperativeHandle(forwardedRef, () => {
870
- const scrollToIndex = ({ index, animated }) => {
871
- const offsetObj = calculateInitialOffset(index);
872
- const offset = horizontal ? { x: offsetObj, y: 0 } : { x: 0, y: offsetObj };
873
- refScroller.current.scrollTo({ ...offset, animated });
874
- };
875
- return {
876
- getNativeScrollRef: () => refScroller.current,
877
- getScrollableNode: refScroller.current.getScrollableNode,
878
- getScrollResponder: refScroller.current.getScrollResponder,
879
- flashScrollIndicators: refScroller.current.flashScrollIndicators,
880
- scrollToIndex,
881
- scrollToOffset: ({ offset, animated }) => {
882
- const offsetObj = horizontal ? { x: offset, y: 0 } : { x: 0, y: offset };
883
- refScroller.current.scrollTo({ ...offsetObj, animated });
884
- },
885
- scrollToItem: ({ item, animated }) => {
886
- const index = data.indexOf(item);
887
- if (index !== -1) {
888
- scrollToIndex({ index, animated });
889
- }
890
- },
891
- scrollToEnd: refScroller.current.scrollToEnd
892
- };
893
- }, []);
879
+ useImperativeHandle(
880
+ forwardedRef,
881
+ () => {
882
+ const scrollToIndex = ({ index, animated }) => {
883
+ const offsetObj = calculateInitialOffset(index);
884
+ const offset = horizontal ? { x: offsetObj, y: 0 } : { x: 0, y: offsetObj };
885
+ refScroller.current.scrollTo({ ...offset, animated });
886
+ };
887
+ return {
888
+ getNativeScrollRef: () => refScroller.current,
889
+ getScrollableNode: refScroller.current.getScrollableNode,
890
+ getScrollResponder: refScroller.current.getScrollResponder,
891
+ flashScrollIndicators: refScroller.current.flashScrollIndicators,
892
+ scrollToIndex,
893
+ scrollToOffset: ({ offset, animated }) => {
894
+ const offsetObj = horizontal ? { x: offset, y: 0 } : { x: 0, y: offset };
895
+ refScroller.current.scrollTo({ ...offsetObj, animated });
896
+ },
897
+ scrollToItem: ({ item, animated }) => {
898
+ const index = data.indexOf(item);
899
+ if (index !== -1) {
900
+ scrollToIndex({ index, animated });
901
+ }
902
+ },
903
+ scrollToEnd: refScroller.current.scrollToEnd
904
+ };
905
+ },
906
+ []
907
+ );
894
908
  return /* @__PURE__ */ React6.createElement(
895
909
  ListComponent,
896
910
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/list",
3
- "version": "0.4.4",
3
+ "version": "0.4.5",
4
4
  "description": "legend-list",
5
5
  "sideEffects": false,
6
6
  "private": false,