@legendapp/list 0.5.6 → 0.5.8

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
@@ -155,7 +155,7 @@ interface ViewabilityConfig {
155
155
  /**
156
156
  * A unique ID to identify this viewability config
157
157
  */
158
- id: string;
158
+ id?: string;
159
159
  /**
160
160
  * Minimum amount of time (in milliseconds) that an item must be physically viewable before the
161
161
  * viewability callback will be fired. A high number means that scrolling through content without
package/index.d.ts CHANGED
@@ -155,7 +155,7 @@ interface ViewabilityConfig {
155
155
  /**
156
156
  * A unique ID to identify this viewability config
157
157
  */
158
- id: string;
158
+ id?: string;
159
159
  /**
160
160
  * Minimum amount of time (in milliseconds) that an item must be physically viewable before the
161
161
  * viewability callback will be fired. A high number means that scrolling through content without
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var React7 = require('react');
3
+ var React5 = require('react');
4
4
  var reactNative = require('react-native');
5
5
 
6
6
  function _interopNamespace(e) {
@@ -21,14 +21,13 @@ function _interopNamespace(e) {
21
21
  return Object.freeze(n);
22
22
  }
23
23
 
24
- var React7__namespace = /*#__PURE__*/_interopNamespace(React7);
24
+ var React5__namespace = /*#__PURE__*/_interopNamespace(React5);
25
25
 
26
26
  // src/LegendList.tsx
27
27
  var USE_CONTENT_INSET = reactNative.Platform.OS === "ios";
28
- var ContextState = React7__namespace.createContext(null);
28
+ var ContextState = React5__namespace.createContext(null);
29
29
  function StateProvider({ children }) {
30
- const [value] = React7__namespace.useState(() => ({
31
- hooks: /* @__PURE__ */ new Map(),
30
+ const [value] = React5__namespace.useState(() => ({
32
31
  listeners: /* @__PURE__ */ new Map(),
33
32
  values: /* @__PURE__ */ new Map(),
34
33
  mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
@@ -36,16 +35,18 @@ function StateProvider({ children }) {
36
35
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
37
36
  mapViewabilityAmountValues: /* @__PURE__ */ new Map()
38
37
  }));
39
- return /* @__PURE__ */ React7__namespace.createElement(ContextState.Provider, { value }, children);
38
+ return /* @__PURE__ */ React5__namespace.createElement(ContextState.Provider, { value }, children);
40
39
  }
41
40
  function useStateContext() {
42
- return React7__namespace.useContext(ContextState);
41
+ return React5__namespace.useContext(ContextState);
43
42
  }
44
43
  function use$(signalName) {
45
- const { hooks, values } = React7__namespace.useContext(ContextState);
46
- const [, forceUpdate] = React7__namespace.useReducer((x) => x + 1, 0);
47
- hooks.set(signalName, forceUpdate);
48
- return values.get(signalName);
44
+ const ctx = React5__namespace.useContext(ContextState);
45
+ const [, forceUpdate] = React5__namespace.useReducer((x) => x + 1, 0);
46
+ React5.useMemo(() => {
47
+ listen$(ctx, signalName, forceUpdate);
48
+ }, []);
49
+ return ctx.values.get(signalName);
49
50
  }
50
51
  function listen$(ctx, signalName, cb) {
51
52
  const { listeners } = ctx;
@@ -62,11 +63,9 @@ function peek$(ctx, signalName) {
62
63
  return values.get(signalName);
63
64
  }
64
65
  function set$(ctx, signalName, value) {
65
- var _a;
66
- const { listeners, hooks, values } = ctx;
66
+ const { listeners, values } = ctx;
67
67
  if (values.get(signalName) !== value) {
68
68
  values.set(signalName, value);
69
- (_a = hooks.get(signalName)) == null ? void 0 : _a();
70
69
  const setListeners = listeners.get(signalName);
71
70
  if (setListeners) {
72
71
  for (const listener of setListeners) {
@@ -78,7 +77,7 @@ function set$(ctx, signalName, value) {
78
77
 
79
78
  // src/$ScrollView.tsx
80
79
  var OFFSET_TEST = 0;
81
- var $ScrollView = React7__namespace.forwardRef(function $ScrollView2(props, ref) {
80
+ var $ScrollView = React5__namespace.forwardRef(function $ScrollView2(props, ref) {
82
81
  const { style, horizontal, ...rest } = props;
83
82
  const scrollAdjust = use$("scrollAdjust");
84
83
  const adjustProps = {};
@@ -92,75 +91,51 @@ var $ScrollView = React7__namespace.forwardRef(function $ScrollView2(props, ref)
92
91
  }
93
92
  }
94
93
  }
95
- return /* @__PURE__ */ React7__namespace.createElement(reactNative.ScrollView, { ...rest, style, horizontal, ...adjustProps, ref });
94
+ return /* @__PURE__ */ React5__namespace.createElement(reactNative.ScrollView, { ...rest, style, horizontal, ...adjustProps, ref });
96
95
  });
97
- var LeanView = React7__namespace.forwardRef((props, ref) => {
98
- return React7__namespace.createElement("RCTView", { ...props, ref });
99
- });
100
- LeanView.displayName = "RCTView";
101
-
102
- // src/$View.tsx
103
- function $View({ $key, $key2, $key3, $key4, $style, ...rest }) {
104
- use$($key);
105
- $key2 && use$($key2);
106
- $key3 && use$($key3);
107
- $key4 && use$($key4);
108
- const style = $style();
109
- return /* @__PURE__ */ React7__namespace.createElement(LeanView, { style, ...rest });
110
- }
111
- function InnerContainer({ containerId, getRenderedItem, recycleItems, ItemSeparatorComponent }) {
112
- const lastItemKey = use$("lastItemKey");
113
- const itemKey = use$(`containerItemKey${containerId}`);
114
- if (itemKey === void 0) {
115
- return null;
116
- }
117
- const renderedItem = getRenderedItem(itemKey, containerId);
118
- return /* @__PURE__ */ React7__namespace.default.createElement(React7__namespace.default.Fragment, { key: recycleItems ? void 0 : itemKey }, renderedItem, ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent);
119
- }
120
96
  var Container = ({
121
97
  id,
122
98
  recycleItems,
123
99
  horizontal,
124
100
  getRenderedItem,
125
- onLayout,
101
+ updateItemSize,
126
102
  ItemSeparatorComponent
127
103
  }) => {
128
104
  const ctx = useStateContext();
129
- const createStyle = () => {
130
- const position = peek$(ctx, `containerPosition${id}`);
131
- const column = peek$(ctx, `containerColumn${id}`) || 0;
132
- const visible = peek$(ctx, `containerDidLayout${id}`);
133
- const numColumns = peek$(ctx, "numColumns");
134
- const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
135
- const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
136
- return horizontal ? {
137
- flexDirection: "row",
138
- position: "absolute",
139
- top: visible ? otherAxisPos : -1e7,
140
- bottom: numColumns > 1 ? null : 0,
141
- height: otherAxisSize,
142
- left: position
143
- } : {
144
- position: "absolute",
145
- left: visible ? otherAxisPos : -1e7,
146
- right: numColumns > 1 ? null : 0,
147
- width: otherAxisSize,
148
- top: position
149
- };
105
+ const position = use$(`containerPosition${id}`);
106
+ const column = use$(`containerColumn${id}`) || 0;
107
+ const visible = use$(`containerDidLayout${id}`);
108
+ const numColumns = use$("numColumns");
109
+ const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
110
+ const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
111
+ const style = horizontal ? {
112
+ flexDirection: "row",
113
+ position: "absolute",
114
+ top: visible ? otherAxisPos : -1e7,
115
+ bottom: numColumns > 1 ? null : 0,
116
+ height: otherAxisSize,
117
+ left: position
118
+ } : {
119
+ position: "absolute",
120
+ left: visible ? otherAxisPos : -1e7,
121
+ right: numColumns > 1 ? null : 0,
122
+ width: otherAxisSize,
123
+ top: position
150
124
  };
151
- return /* @__PURE__ */ React7__namespace.default.createElement(
152
- $View,
125
+ const lastItemKey = use$("lastItemKey");
126
+ const itemKey = use$(`containerItemKey${id}`);
127
+ const renderedItem = React5.useMemo(() => itemKey !== void 0 && getRenderedItem(itemKey, id), [itemKey]);
128
+ return /* @__PURE__ */ React5__namespace.default.createElement(
129
+ reactNative.View,
153
130
  {
154
- $key: `containerPosition${id}`,
155
- $key2: `containerDidLayout${id}`,
156
- $key3: `containerColumn${id}`,
157
- $key4: "numColumns",
158
- $style: createStyle,
131
+ style,
159
132
  onLayout: (event) => {
160
133
  const key = peek$(ctx, `containerItemKey${id}`);
161
134
  if (key !== void 0) {
162
135
  const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
163
- onLayout(key, size);
136
+ updateItemSize(id, key, size);
137
+ const otherAxisSize2 = horizontal ? event.nativeEvent.layout.width : event.nativeEvent.layout.height;
138
+ set$(ctx, "otherAxisSize", Math.max(otherAxisSize2, peek$(ctx, "otherAxisSize") || 0));
164
139
  const measured = peek$(ctx, `containerDidLayout${id}`);
165
140
  if (!measured) {
166
141
  requestAnimationFrame(() => {
@@ -170,20 +145,21 @@ var Container = ({
170
145
  }
171
146
  }
172
147
  },
173
- /* @__PURE__ */ React7__namespace.default.createElement(
174
- InnerContainer,
175
- {
176
- containerId: id,
177
- getRenderedItem,
178
- recycleItems,
179
- ItemSeparatorComponent
180
- }
181
- )
148
+ /* @__PURE__ */ React5__namespace.default.createElement(React5__namespace.default.Fragment, { key: recycleItems ? void 0 : itemKey }, renderedItem, renderedItem && ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent)
182
149
  );
183
150
  };
151
+ function useValue$(key, getValue, key2) {
152
+ var _a;
153
+ const ctx = useStateContext();
154
+ const animValue = reactNative.useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
155
+ React5.useMemo(() => {
156
+ listen$(ctx, key, (v) => animValue.setValue(getValue ? getValue(v) : v));
157
+ }, []);
158
+ return animValue;
159
+ }
184
160
 
185
161
  // src/Containers.tsx
186
- var Containers = React7__namespace.memo(function Containers2({
162
+ var Containers = React5__namespace.memo(function Containers2({
187
163
  horizontal,
188
164
  recycleItems,
189
165
  ItemSeparatorComponent,
@@ -192,10 +168,11 @@ var Containers = React7__namespace.memo(function Containers2({
192
168
  }) {
193
169
  const ctx = useStateContext();
194
170
  const numContainers = use$("numContainersPooled");
171
+ const animSize = useValue$("totalSize", (v) => v + peek$(ctx, "scrollAdjust"));
195
172
  const containers = [];
196
173
  for (let i = 0; i < numContainers; i++) {
197
174
  containers.push(
198
- /* @__PURE__ */ React7__namespace.createElement(
175
+ /* @__PURE__ */ React5__namespace.createElement(
199
176
  Container,
200
177
  {
201
178
  id: i,
@@ -203,41 +180,27 @@ var Containers = React7__namespace.memo(function Containers2({
203
180
  recycleItems,
204
181
  horizontal,
205
182
  getRenderedItem,
206
- onLayout: updateItemSize,
183
+ updateItemSize,
207
184
  ItemSeparatorComponent
208
185
  }
209
186
  )
210
187
  );
211
188
  }
212
- return /* @__PURE__ */ React7__namespace.createElement(
213
- $View,
214
- {
215
- $key: "totalSize",
216
- $key2: "scrollAdjust",
217
- $style: () => {
218
- const size = peek$(ctx, "totalSize") + peek$(ctx, "scrollAdjust");
219
- return horizontal ? {
220
- width: size
221
- } : {
222
- height: size
223
- };
224
- }
225
- },
226
- containers
227
- );
189
+ const style = horizontal ? { width: animSize } : { height: animSize };
190
+ return /* @__PURE__ */ React5__namespace.createElement(reactNative.Animated.View, { style }, containers);
228
191
  });
229
192
 
230
193
  // src/ListComponent.tsx
231
194
  var getComponent = (Component) => {
232
- if (React7__namespace.isValidElement(Component)) {
195
+ if (React5__namespace.isValidElement(Component)) {
233
196
  return Component;
234
197
  }
235
198
  if (Component) {
236
- return /* @__PURE__ */ React7__namespace.createElement(Component, null);
199
+ return /* @__PURE__ */ React5__namespace.createElement(Component, null);
237
200
  }
238
201
  return null;
239
202
  };
240
- var ListComponent = React7__namespace.memo(function ListComponent2({
203
+ var ListComponent = React5__namespace.memo(function ListComponent2({
241
204
  style,
242
205
  contentContainerStyle,
243
206
  horizontal,
@@ -260,7 +223,9 @@ var ListComponent = React7__namespace.memo(function ListComponent2({
260
223
  ...rest
261
224
  }) {
262
225
  const ctx = useStateContext();
263
- return /* @__PURE__ */ React7__namespace.createElement(
226
+ const animPaddingTop = useValue$("paddingTop");
227
+ const animScrollAdjust = useValue$("scrollAdjust");
228
+ return /* @__PURE__ */ React5__namespace.createElement(
264
229
  $ScrollView,
265
230
  {
266
231
  ...rest,
@@ -277,12 +242,13 @@ var ListComponent = React7__namespace.memo(function ListComponent2({
277
242
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
278
243
  ref: refScroller
279
244
  },
280
- alignItemsAtEnd && /* @__PURE__ */ React7__namespace.createElement($View, { $key: "paddingTop", $style: () => ({ height: peek$(ctx, "paddingTop") }) }),
281
- ListHeaderComponent && /* @__PURE__ */ React7__namespace.createElement(
282
- $View,
245
+ alignItemsAtEnd && /* @__PURE__ */ React5__namespace.createElement(reactNative.Animated.View, { style: { height: animPaddingTop } }),
246
+ ListHeaderComponent && /* @__PURE__ */ React5__namespace.createElement(
247
+ reactNative.Animated.View,
283
248
  {
284
- $key: "scrollAdjust",
285
- $style: () => reactNative.StyleSheet.compose(ListHeaderComponentStyle, { top: peek$(ctx, "scrollAdjust") }),
249
+ style: reactNative.StyleSheet.compose(ListHeaderComponentStyle, {
250
+ top: animScrollAdjust
251
+ }),
286
252
  onLayout: (event) => {
287
253
  const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
288
254
  const prevSize = peek$(ctx, "headerSize") || 0;
@@ -293,15 +259,16 @@ var ListComponent = React7__namespace.memo(function ListComponent2({
293
259
  },
294
260
  getComponent(ListHeaderComponent)
295
261
  ),
296
- ListEmptyComponent && /* @__PURE__ */ React7__namespace.createElement(
297
- $View,
262
+ ListEmptyComponent && /* @__PURE__ */ React5__namespace.createElement(
263
+ reactNative.Animated.View,
298
264
  {
299
- $key: "scrollAdjust",
300
- $style: () => reactNative.StyleSheet.compose(ListEmptyComponentStyle, { top: peek$(ctx, "scrollAdjust") })
265
+ style: reactNative.StyleSheet.compose(ListEmptyComponentStyle, {
266
+ top: animScrollAdjust
267
+ })
301
268
  },
302
269
  getComponent(ListEmptyComponent)
303
270
  ),
304
- /* @__PURE__ */ React7__namespace.createElement(
271
+ /* @__PURE__ */ React5__namespace.createElement(
305
272
  Containers,
306
273
  {
307
274
  horizontal,
@@ -311,12 +278,12 @@ var ListComponent = React7__namespace.memo(function ListComponent2({
311
278
  updateItemSize
312
279
  }
313
280
  ),
314
- ListFooterComponent && /* @__PURE__ */ React7__namespace.createElement(reactNative.View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
281
+ ListFooterComponent && /* @__PURE__ */ React5__namespace.createElement(reactNative.View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
315
282
  );
316
283
  });
317
284
  var symbolFirst = Symbol();
318
285
  function useInit(cb) {
319
- const refValue = React7.useRef(symbolFirst);
286
+ const refValue = React5.useRef(symbolFirst);
320
287
  if (refValue.current === symbolFirst) {
321
288
  refValue.current = cb();
322
289
  }
@@ -475,11 +442,11 @@ var DEFAULT_DRAW_DISTANCE = 250;
475
442
  var INITIAL_SCROLL_ADJUST = 1e4;
476
443
  var POSITION_OUT_OF_VIEW = -1e7;
477
444
  var DEFAULT_ITEM_SIZE = 100;
478
- var LegendList = React7.forwardRef(function LegendList2(props, forwardedRef) {
479
- return /* @__PURE__ */ React7__namespace.createElement(StateProvider, null, /* @__PURE__ */ React7__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
445
+ var LegendList = React5.forwardRef(function LegendList2(props, forwardedRef) {
446
+ return /* @__PURE__ */ React5__namespace.createElement(StateProvider, null, /* @__PURE__ */ React5__namespace.createElement(LegendListInner, { ...props, ref: forwardedRef }));
480
447
  });
481
- var LegendListInner = React7.forwardRef(function LegendListInner2(props, forwardedRef) {
482
- var _a, _b, _c, _d, _e;
448
+ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forwardedRef) {
449
+ var _a, _b, _c, _d, _e, _f;
483
450
  const {
484
451
  data,
485
452
  initialScrollIndex,
@@ -496,8 +463,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
496
463
  maintainVisibleContentPosition = false,
497
464
  onScroll: onScrollProp,
498
465
  numColumns: numColumnsProp = 1,
499
- style: styleProp,
500
- keyExtractor,
466
+ keyExtractor: keyExtractorProp,
501
467
  renderItem,
502
468
  estimatedItemSize,
503
469
  getEstimatedItemSize,
@@ -506,12 +472,13 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
506
472
  ListEmptyComponent,
507
473
  ...rest
508
474
  } = props;
509
- const { contentContainerStyle } = props;
475
+ const { style, contentContainerStyle } = props;
510
476
  const ctx = useStateContext();
511
- const internalRef = React7.useRef(null);
477
+ const internalRef = React5.useRef(null);
512
478
  const refScroller = internalRef;
513
479
  const scrollBuffer = drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE;
514
- const refState = React7.useRef();
480
+ const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
481
+ const refState = React5.useRef();
515
482
  const getId = (index) => {
516
483
  var _a2;
517
484
  const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
@@ -545,7 +512,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
545
512
  }
546
513
  return void 0;
547
514
  };
548
- const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React7.useMemo(calculateInitialOffset, []);
515
+ const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React5.useMemo(calculateInitialOffset, []);
549
516
  if (!refState.current) {
550
517
  refState.current = {
551
518
  sizes: /* @__PURE__ */ new Map(),
@@ -591,7 +558,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
591
558
  refState.current.scrollAdjustPending -= diff;
592
559
  }
593
560
  };
594
- const addTotalSize = React7.useCallback((key, add) => {
561
+ const addTotalSize = React5.useCallback((key, add) => {
595
562
  const state = refState.current;
596
563
  const index = key === null ? 0 : state.indexByKey.get(key);
597
564
  const isAbove = key !== null && index < (state.startNoBuffer || 0);
@@ -618,7 +585,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
618
585
  state.animFrameTotalSize = requestAnimationFrame(doAdd);
619
586
  }
620
587
  }, []);
621
- const calculateItemsInView = React7.useCallback((speed = 0) => {
588
+ const calculateItemsInView = React5.useCallback((speed = 0) => {
622
589
  var _a2, _b2, _c2;
623
590
  const state = refState.current;
624
591
  const {
@@ -639,7 +606,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
639
606
  }
640
607
  const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
641
608
  const scrollAdjustPending = (_a2 = state.scrollAdjustPending) != null ? _a2 : 0;
642
- const scrollExtra = Math.max(-16, Math.min(16, speed)) * 32;
609
+ const scrollExtra = Math.max(-16, Math.min(16, speed)) * 16;
643
610
  const scroll = Math.max(
644
611
  0,
645
612
  scrollState - topPad - (USE_CONTENT_INSET ? scrollAdjustPending : 0) + scrollExtra
@@ -808,18 +775,6 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
808
775
  );
809
776
  }
810
777
  }, []);
811
- const style = React7.useMemo(() => {
812
- const extraStyle = {};
813
- if (data.length > 0) {
814
- const size = getItemSize(getId(0), 0, data[0]);
815
- if (horizontal) {
816
- extraStyle.minHeight = size;
817
- } else {
818
- extraStyle.minWidth = size;
819
- }
820
- }
821
- return reactNative.StyleSheet.compose(styleProp, extraStyle);
822
- }, []);
823
778
  const doUpdatePaddingTop = () => {
824
779
  if (alignItemsAtEnd) {
825
780
  const { scrollLength, totalSize } = refState.current;
@@ -845,19 +800,22 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
845
800
  return;
846
801
  }
847
802
  const { scrollLength, scroll, contentSize } = refState.current;
848
- const distanceFromEnd = contentSize[horizontal ? "width" : "height"] - scroll - scrollLength;
849
- if (refState.current) {
850
- refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
851
- }
852
- if (onEndReached) {
853
- if (!refState.current.isEndReached) {
854
- if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
855
- refState.current.isEndReached = true;
856
- onEndReached({ distanceFromEnd });
857
- }
858
- } else {
859
- if (distanceFromEnd >= onEndReachedThreshold * scrollLength) {
860
- refState.current.isEndReached = false;
803
+ const contentLength = contentSize[horizontal ? "width" : "height"];
804
+ if (scroll > 0 && contentLength > 0) {
805
+ const distanceFromEnd = contentLength - scroll - scrollLength;
806
+ if (refState.current) {
807
+ refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
808
+ }
809
+ if (onEndReached) {
810
+ if (!refState.current.isEndReached) {
811
+ if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
812
+ refState.current.isEndReached = true;
813
+ onEndReached({ distanceFromEnd });
814
+ }
815
+ } else {
816
+ if (distanceFromEnd >= onEndReachedThreshold * scrollLength) {
817
+ refState.current.isEndReached = false;
818
+ }
861
819
  }
862
820
  }
863
821
  }
@@ -885,7 +843,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
885
843
  };
886
844
  const isFirst = !refState.current.renderItem;
887
845
  if (isFirst || data !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
888
- if (!keyExtractor && !isFirst && data !== refState.current.data) {
846
+ if (!keyExtractorProp && !isFirst && data !== refState.current.data) {
889
847
  refState.current.sizes.clear();
890
848
  refState.current.positions.clear();
891
849
  }
@@ -926,11 +884,14 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
926
884
  refState.current.isEndReached = false;
927
885
  const numContainers = peek$(ctx, "numContainers");
928
886
  for (let i = 0; i < numContainers; i++) {
929
- set$(ctx, `containerItemKey${i}`, void 0);
930
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
931
- set$(ctx, `containerColumn${i}`, -1);
887
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
888
+ if (!keyExtractorProp || itemKey && ((_b = refState.current) == null ? void 0 : _b.indexByKey.get(itemKey)) === void 0) {
889
+ set$(ctx, `containerItemKey${i}`, void 0);
890
+ set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
891
+ set$(ctx, `containerColumn${i}`, -1);
892
+ }
932
893
  }
933
- if (!keyExtractor) {
894
+ if (!keyExtractorProp) {
934
895
  refState.current.sizes.clear();
935
896
  refState.current.positions;
936
897
  }
@@ -946,9 +907,9 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
946
907
  set$(
947
908
  ctx,
948
909
  "stylePaddingTop",
949
- (_e = (_d = (_b = reactNative.StyleSheet.flatten(style)) == null ? void 0 : _b.paddingTop) != null ? _d : (_c = reactNative.StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _c.paddingTop) != null ? _e : 0
910
+ (_f = (_e = (_c = reactNative.StyleSheet.flatten(style)) == null ? void 0 : _c.paddingTop) != null ? _e : (_d = reactNative.StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _d.paddingTop) != null ? _f : 0
950
911
  );
951
- const getRenderedItem = React7.useCallback((key, containerId) => {
912
+ const getRenderedItem = React5.useCallback((key, containerId) => {
952
913
  var _a2, _b2;
953
914
  const state = refState.current;
954
915
  if (!state) {
@@ -968,7 +929,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
968
929
  }
969
930
  });
970
931
  ctx.mapViewabilityCallbacks.set(key2, callback);
971
- React7.useEffect(
932
+ React5.useEffect(
972
933
  () => () => {
973
934
  ctx.mapViewabilityCallbacks.delete(key2);
974
935
  },
@@ -983,7 +944,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
983
944
  }
984
945
  });
985
946
  ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
986
- React7.useEffect(
947
+ React5.useEffect(
987
948
  () => () => {
988
949
  ctx.mapViewabilityAmountCallbacks.delete(containerId);
989
950
  },
@@ -991,7 +952,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
991
952
  );
992
953
  };
993
954
  const useRecyclingEffect = (effect) => {
994
- React7.useEffect(() => {
955
+ React5.useEffect(() => {
995
956
  const state2 = refState.current;
996
957
  let prevIndex = index;
997
958
  let prevItem = state2.data[index];
@@ -1019,7 +980,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1019
980
  }, []);
1020
981
  };
1021
982
  const useRecyclingState = (valueOrFun) => {
1022
- const stateInfo = React7.useState(
983
+ const stateInfo = React5.useState(
1023
984
  () => typeof valueOrFun === "function" ? valueOrFun({
1024
985
  index,
1025
986
  item: refState.current.data[index],
@@ -1057,7 +1018,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1057
1018
  set$(ctx, "numContainersPooled", numContainers * 2);
1058
1019
  calculateItemsInView();
1059
1020
  });
1060
- const updateItemSize = React7.useCallback((key, size) => {
1021
+ const updateItemSize = React5.useCallback((containerId, itemKey, size) => {
1061
1022
  var _a2;
1062
1023
  const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
1063
1024
  if (!data2) {
@@ -1065,14 +1026,14 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1065
1026
  }
1066
1027
  const state = refState.current;
1067
1028
  const { sizes, indexByKey, idsInFirstRender, columns, sizesLaidOut } = state;
1068
- const index = indexByKey.get(key);
1069
- const wasInFirstRender = idsInFirstRender.has(key);
1070
- const prevSize = sizes.get(key) || (wasInFirstRender ? getItemSize(key, index, data2[index]) : 0);
1029
+ const index = indexByKey.get(itemKey);
1030
+ const wasInFirstRender = idsInFirstRender.has(itemKey);
1031
+ const prevSize = sizes.get(itemKey) || (wasInFirstRender ? getItemSize(itemKey, index, data2[index]) : 0);
1071
1032
  if (!prevSize || Math.abs(prevSize - size) > 0.5) {
1072
1033
  let diff;
1073
1034
  const numColumns = peek$(ctx, "numColumns");
1074
1035
  if (numColumns > 1) {
1075
- const column = columns.get(key);
1036
+ const column = columns.get(itemKey);
1076
1037
  const loopStart = index - (column - 1);
1077
1038
  let prevMaxSizeInRow = 0;
1078
1039
  for (let i = loopStart; i < loopStart + numColumns; i++) {
@@ -1080,7 +1041,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1080
1041
  const size2 = getItemSize(id, i, data2[i]);
1081
1042
  prevMaxSizeInRow = Math.max(prevMaxSizeInRow, size2);
1082
1043
  }
1083
- sizes.set(key, size);
1044
+ sizes.set(itemKey, size);
1084
1045
  let nextMaxSizeInRow = 0;
1085
1046
  for (let i = loopStart; i < loopStart + numColumns; i++) {
1086
1047
  const id = getId(i);
@@ -1089,11 +1050,11 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1089
1050
  }
1090
1051
  diff = nextMaxSizeInRow - prevMaxSizeInRow;
1091
1052
  } else {
1092
- sizes.set(key, size);
1053
+ sizes.set(itemKey, size);
1093
1054
  diff = size - prevSize;
1094
1055
  }
1095
1056
  if (__DEV__ && !estimatedItemSize && !getEstimatedItemSize) {
1096
- sizesLaidOut.set(key, size);
1057
+ sizesLaidOut.set(itemKey, size);
1097
1058
  if (state.timeoutSizeMessage) {
1098
1059
  clearTimeout(state.timeoutSizeMessage);
1099
1060
  }
@@ -1101,7 +1062,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1101
1062
  state.timeoutSizeMessage = void 0;
1102
1063
  let total = 0;
1103
1064
  let num = 0;
1104
- for (const [key2, size2] of sizesLaidOut) {
1065
+ for (const [key, size2] of sizesLaidOut) {
1105
1066
  num++;
1106
1067
  total += size2;
1107
1068
  }
@@ -1111,18 +1072,22 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1111
1072
  );
1112
1073
  }, 1e3);
1113
1074
  }
1114
- addTotalSize(key, diff);
1075
+ addTotalSize(itemKey, diff);
1115
1076
  doMaintainScrollAtEnd(true);
1116
1077
  const scrollVelocity = state.scrollVelocity;
1117
1078
  if (!state.animFrameLayout && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
1118
- state.animFrameLayout = requestAnimationFrame(() => {
1119
- state.animFrameLayout = null;
1079
+ if (!peek$(ctx, `containerDidLayout${containerId}`)) {
1080
+ state.animFrameLayout = requestAnimationFrame(() => {
1081
+ state.animFrameLayout = null;
1082
+ calculateItemsInView(state.scrollVelocity);
1083
+ });
1084
+ } else {
1120
1085
  calculateItemsInView(state.scrollVelocity);
1121
- });
1086
+ }
1122
1087
  }
1123
1088
  }
1124
1089
  }, []);
1125
- const handleScrollDebounced = React7.useCallback((velocity) => {
1090
+ const handleScrollDebounced = React5.useCallback((velocity) => {
1126
1091
  var _a2, _b2;
1127
1092
  const scrollAdjustPending = (_b2 = (_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustPending) != null ? _b2 : 0;
1128
1093
  set$(ctx, "scrollAdjust", scrollAdjustPending);
@@ -1130,7 +1095,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1130
1095
  checkAtBottom();
1131
1096
  checkAtTop();
1132
1097
  }, []);
1133
- const onLayout = React7.useCallback((event) => {
1098
+ const onLayout = React5.useCallback((event) => {
1134
1099
  let scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
1135
1100
  if (!USE_CONTENT_INSET) {
1136
1101
  scrollLength += event.nativeEvent.layout[horizontal ? "x" : "y"];
@@ -1152,7 +1117,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1152
1117
  }
1153
1118
  }
1154
1119
  }, []);
1155
- const handleScroll = React7.useCallback(
1120
+ const handleScroll = React5.useCallback(
1156
1121
  (event, fromSelf) => {
1157
1122
  var _a2, _b2, _c2;
1158
1123
  if (((_b2 = (_a2 = event.nativeEvent) == null ? void 0 : _a2.contentSize) == null ? void 0 : _b2.height) === 0 && ((_c2 = event.nativeEvent.contentSize) == null ? void 0 : _c2.width) === 0) {
@@ -1187,7 +1152,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1187
1152
  },
1188
1153
  []
1189
1154
  );
1190
- React7.useImperativeHandle(
1155
+ React5.useImperativeHandle(
1191
1156
  forwardedRef,
1192
1157
  () => {
1193
1158
  const scrollToIndex = ({ index, animated }) => {
@@ -1216,7 +1181,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1216
1181
  },
1217
1182
  []
1218
1183
  );
1219
- return /* @__PURE__ */ React7__namespace.createElement(
1184
+ return /* @__PURE__ */ React5__namespace.createElement(
1220
1185
  ListComponent,
1221
1186
  {
1222
1187
  ...rest,
package/index.mjs CHANGED
@@ -1,13 +1,12 @@
1
- import * as React7 from 'react';
2
- import React7__default, { forwardRef, useRef, useMemo, useCallback, useImperativeHandle, useEffect, useState } from 'react';
3
- import { Platform, StyleSheet, ScrollView, View, Dimensions } from 'react-native';
1
+ import * as React5 from 'react';
2
+ import React5__default, { forwardRef, useRef, useMemo, useCallback, useImperativeHandle, useEffect, useState } from 'react';
3
+ import { Platform, StyleSheet, ScrollView, Animated, View, Dimensions, useAnimatedValue } from 'react-native';
4
4
 
5
5
  // src/LegendList.tsx
6
6
  var USE_CONTENT_INSET = Platform.OS === "ios";
7
- var ContextState = React7.createContext(null);
7
+ var ContextState = React5.createContext(null);
8
8
  function StateProvider({ children }) {
9
- const [value] = React7.useState(() => ({
10
- hooks: /* @__PURE__ */ new Map(),
9
+ const [value] = React5.useState(() => ({
11
10
  listeners: /* @__PURE__ */ new Map(),
12
11
  values: /* @__PURE__ */ new Map(),
13
12
  mapViewabilityCallbacks: /* @__PURE__ */ new Map(),
@@ -15,16 +14,18 @@ function StateProvider({ children }) {
15
14
  mapViewabilityAmountCallbacks: /* @__PURE__ */ new Map(),
16
15
  mapViewabilityAmountValues: /* @__PURE__ */ new Map()
17
16
  }));
18
- return /* @__PURE__ */ React7.createElement(ContextState.Provider, { value }, children);
17
+ return /* @__PURE__ */ React5.createElement(ContextState.Provider, { value }, children);
19
18
  }
20
19
  function useStateContext() {
21
- return React7.useContext(ContextState);
20
+ return React5.useContext(ContextState);
22
21
  }
23
22
  function use$(signalName) {
24
- const { hooks, values } = React7.useContext(ContextState);
25
- const [, forceUpdate] = React7.useReducer((x) => x + 1, 0);
26
- hooks.set(signalName, forceUpdate);
27
- return values.get(signalName);
23
+ const ctx = React5.useContext(ContextState);
24
+ const [, forceUpdate] = React5.useReducer((x) => x + 1, 0);
25
+ useMemo(() => {
26
+ listen$(ctx, signalName, forceUpdate);
27
+ }, []);
28
+ return ctx.values.get(signalName);
28
29
  }
29
30
  function listen$(ctx, signalName, cb) {
30
31
  const { listeners } = ctx;
@@ -41,11 +42,9 @@ function peek$(ctx, signalName) {
41
42
  return values.get(signalName);
42
43
  }
43
44
  function set$(ctx, signalName, value) {
44
- var _a;
45
- const { listeners, hooks, values } = ctx;
45
+ const { listeners, values } = ctx;
46
46
  if (values.get(signalName) !== value) {
47
47
  values.set(signalName, value);
48
- (_a = hooks.get(signalName)) == null ? void 0 : _a();
49
48
  const setListeners = listeners.get(signalName);
50
49
  if (setListeners) {
51
50
  for (const listener of setListeners) {
@@ -57,7 +56,7 @@ function set$(ctx, signalName, value) {
57
56
 
58
57
  // src/$ScrollView.tsx
59
58
  var OFFSET_TEST = 0;
60
- var $ScrollView = React7.forwardRef(function $ScrollView2(props, ref) {
59
+ var $ScrollView = React5.forwardRef(function $ScrollView2(props, ref) {
61
60
  const { style, horizontal, ...rest } = props;
62
61
  const scrollAdjust = use$("scrollAdjust");
63
62
  const adjustProps = {};
@@ -71,75 +70,51 @@ var $ScrollView = React7.forwardRef(function $ScrollView2(props, ref) {
71
70
  }
72
71
  }
73
72
  }
74
- return /* @__PURE__ */ React7.createElement(ScrollView, { ...rest, style, horizontal, ...adjustProps, ref });
73
+ return /* @__PURE__ */ React5.createElement(ScrollView, { ...rest, style, horizontal, ...adjustProps, ref });
75
74
  });
76
- var LeanView = React7.forwardRef((props, ref) => {
77
- return React7.createElement("RCTView", { ...props, ref });
78
- });
79
- LeanView.displayName = "RCTView";
80
-
81
- // src/$View.tsx
82
- function $View({ $key, $key2, $key3, $key4, $style, ...rest }) {
83
- use$($key);
84
- $key2 && use$($key2);
85
- $key3 && use$($key3);
86
- $key4 && use$($key4);
87
- const style = $style();
88
- return /* @__PURE__ */ React7.createElement(LeanView, { style, ...rest });
89
- }
90
- function InnerContainer({ containerId, getRenderedItem, recycleItems, ItemSeparatorComponent }) {
91
- const lastItemKey = use$("lastItemKey");
92
- const itemKey = use$(`containerItemKey${containerId}`);
93
- if (itemKey === void 0) {
94
- return null;
95
- }
96
- const renderedItem = getRenderedItem(itemKey, containerId);
97
- return /* @__PURE__ */ React7__default.createElement(React7__default.Fragment, { key: recycleItems ? void 0 : itemKey }, renderedItem, ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent);
98
- }
99
75
  var Container = ({
100
76
  id,
101
77
  recycleItems,
102
78
  horizontal,
103
79
  getRenderedItem,
104
- onLayout,
80
+ updateItemSize,
105
81
  ItemSeparatorComponent
106
82
  }) => {
107
83
  const ctx = useStateContext();
108
- const createStyle = () => {
109
- const position = peek$(ctx, `containerPosition${id}`);
110
- const column = peek$(ctx, `containerColumn${id}`) || 0;
111
- const visible = peek$(ctx, `containerDidLayout${id}`);
112
- const numColumns = peek$(ctx, "numColumns");
113
- const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
114
- const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
115
- return horizontal ? {
116
- flexDirection: "row",
117
- position: "absolute",
118
- top: visible ? otherAxisPos : -1e7,
119
- bottom: numColumns > 1 ? null : 0,
120
- height: otherAxisSize,
121
- left: position
122
- } : {
123
- position: "absolute",
124
- left: visible ? otherAxisPos : -1e7,
125
- right: numColumns > 1 ? null : 0,
126
- width: otherAxisSize,
127
- top: position
128
- };
84
+ const position = use$(`containerPosition${id}`);
85
+ const column = use$(`containerColumn${id}`) || 0;
86
+ const visible = use$(`containerDidLayout${id}`);
87
+ const numColumns = use$("numColumns");
88
+ const otherAxisPos = numColumns > 1 ? `${(column - 1) / numColumns * 100}%` : 0;
89
+ const otherAxisSize = numColumns > 1 ? `${1 / numColumns * 100}%` : void 0;
90
+ const style = horizontal ? {
91
+ flexDirection: "row",
92
+ position: "absolute",
93
+ top: visible ? otherAxisPos : -1e7,
94
+ bottom: numColumns > 1 ? null : 0,
95
+ height: otherAxisSize,
96
+ left: position
97
+ } : {
98
+ position: "absolute",
99
+ left: visible ? otherAxisPos : -1e7,
100
+ right: numColumns > 1 ? null : 0,
101
+ width: otherAxisSize,
102
+ top: position
129
103
  };
130
- return /* @__PURE__ */ React7__default.createElement(
131
- $View,
104
+ const lastItemKey = use$("lastItemKey");
105
+ const itemKey = use$(`containerItemKey${id}`);
106
+ const renderedItem = useMemo(() => itemKey !== void 0 && getRenderedItem(itemKey, id), [itemKey]);
107
+ return /* @__PURE__ */ React5__default.createElement(
108
+ View,
132
109
  {
133
- $key: `containerPosition${id}`,
134
- $key2: `containerDidLayout${id}`,
135
- $key3: `containerColumn${id}`,
136
- $key4: "numColumns",
137
- $style: createStyle,
110
+ style,
138
111
  onLayout: (event) => {
139
112
  const key = peek$(ctx, `containerItemKey${id}`);
140
113
  if (key !== void 0) {
141
114
  const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
142
- onLayout(key, size);
115
+ updateItemSize(id, key, size);
116
+ const otherAxisSize2 = horizontal ? event.nativeEvent.layout.width : event.nativeEvent.layout.height;
117
+ set$(ctx, "otherAxisSize", Math.max(otherAxisSize2, peek$(ctx, "otherAxisSize") || 0));
143
118
  const measured = peek$(ctx, `containerDidLayout${id}`);
144
119
  if (!measured) {
145
120
  requestAnimationFrame(() => {
@@ -149,20 +124,21 @@ var Container = ({
149
124
  }
150
125
  }
151
126
  },
152
- /* @__PURE__ */ React7__default.createElement(
153
- InnerContainer,
154
- {
155
- containerId: id,
156
- getRenderedItem,
157
- recycleItems,
158
- ItemSeparatorComponent
159
- }
160
- )
127
+ /* @__PURE__ */ React5__default.createElement(React5__default.Fragment, { key: recycleItems ? void 0 : itemKey }, renderedItem, renderedItem && ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent)
161
128
  );
162
129
  };
130
+ function useValue$(key, getValue, key2) {
131
+ var _a;
132
+ const ctx = useStateContext();
133
+ const animValue = useAnimatedValue((_a = getValue ? getValue(peek$(ctx, key)) : peek$(ctx, key)) != null ? _a : 0);
134
+ useMemo(() => {
135
+ listen$(ctx, key, (v) => animValue.setValue(getValue ? getValue(v) : v));
136
+ }, []);
137
+ return animValue;
138
+ }
163
139
 
164
140
  // src/Containers.tsx
165
- var Containers = React7.memo(function Containers2({
141
+ var Containers = React5.memo(function Containers2({
166
142
  horizontal,
167
143
  recycleItems,
168
144
  ItemSeparatorComponent,
@@ -171,10 +147,11 @@ var Containers = React7.memo(function Containers2({
171
147
  }) {
172
148
  const ctx = useStateContext();
173
149
  const numContainers = use$("numContainersPooled");
150
+ const animSize = useValue$("totalSize", (v) => v + peek$(ctx, "scrollAdjust"));
174
151
  const containers = [];
175
152
  for (let i = 0; i < numContainers; i++) {
176
153
  containers.push(
177
- /* @__PURE__ */ React7.createElement(
154
+ /* @__PURE__ */ React5.createElement(
178
155
  Container,
179
156
  {
180
157
  id: i,
@@ -182,41 +159,27 @@ var Containers = React7.memo(function Containers2({
182
159
  recycleItems,
183
160
  horizontal,
184
161
  getRenderedItem,
185
- onLayout: updateItemSize,
162
+ updateItemSize,
186
163
  ItemSeparatorComponent
187
164
  }
188
165
  )
189
166
  );
190
167
  }
191
- return /* @__PURE__ */ React7.createElement(
192
- $View,
193
- {
194
- $key: "totalSize",
195
- $key2: "scrollAdjust",
196
- $style: () => {
197
- const size = peek$(ctx, "totalSize") + peek$(ctx, "scrollAdjust");
198
- return horizontal ? {
199
- width: size
200
- } : {
201
- height: size
202
- };
203
- }
204
- },
205
- containers
206
- );
168
+ const style = horizontal ? { width: animSize } : { height: animSize };
169
+ return /* @__PURE__ */ React5.createElement(Animated.View, { style }, containers);
207
170
  });
208
171
 
209
172
  // src/ListComponent.tsx
210
173
  var getComponent = (Component) => {
211
- if (React7.isValidElement(Component)) {
174
+ if (React5.isValidElement(Component)) {
212
175
  return Component;
213
176
  }
214
177
  if (Component) {
215
- return /* @__PURE__ */ React7.createElement(Component, null);
178
+ return /* @__PURE__ */ React5.createElement(Component, null);
216
179
  }
217
180
  return null;
218
181
  };
219
- var ListComponent = React7.memo(function ListComponent2({
182
+ var ListComponent = React5.memo(function ListComponent2({
220
183
  style,
221
184
  contentContainerStyle,
222
185
  horizontal,
@@ -239,7 +202,9 @@ var ListComponent = React7.memo(function ListComponent2({
239
202
  ...rest
240
203
  }) {
241
204
  const ctx = useStateContext();
242
- return /* @__PURE__ */ React7.createElement(
205
+ const animPaddingTop = useValue$("paddingTop");
206
+ const animScrollAdjust = useValue$("scrollAdjust");
207
+ return /* @__PURE__ */ React5.createElement(
243
208
  $ScrollView,
244
209
  {
245
210
  ...rest,
@@ -256,12 +221,13 @@ var ListComponent = React7.memo(function ListComponent2({
256
221
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
257
222
  ref: refScroller
258
223
  },
259
- alignItemsAtEnd && /* @__PURE__ */ React7.createElement($View, { $key: "paddingTop", $style: () => ({ height: peek$(ctx, "paddingTop") }) }),
260
- ListHeaderComponent && /* @__PURE__ */ React7.createElement(
261
- $View,
224
+ alignItemsAtEnd && /* @__PURE__ */ React5.createElement(Animated.View, { style: { height: animPaddingTop } }),
225
+ ListHeaderComponent && /* @__PURE__ */ React5.createElement(
226
+ Animated.View,
262
227
  {
263
- $key: "scrollAdjust",
264
- $style: () => StyleSheet.compose(ListHeaderComponentStyle, { top: peek$(ctx, "scrollAdjust") }),
228
+ style: StyleSheet.compose(ListHeaderComponentStyle, {
229
+ top: animScrollAdjust
230
+ }),
265
231
  onLayout: (event) => {
266
232
  const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
267
233
  const prevSize = peek$(ctx, "headerSize") || 0;
@@ -272,15 +238,16 @@ var ListComponent = React7.memo(function ListComponent2({
272
238
  },
273
239
  getComponent(ListHeaderComponent)
274
240
  ),
275
- ListEmptyComponent && /* @__PURE__ */ React7.createElement(
276
- $View,
241
+ ListEmptyComponent && /* @__PURE__ */ React5.createElement(
242
+ Animated.View,
277
243
  {
278
- $key: "scrollAdjust",
279
- $style: () => StyleSheet.compose(ListEmptyComponentStyle, { top: peek$(ctx, "scrollAdjust") })
244
+ style: StyleSheet.compose(ListEmptyComponentStyle, {
245
+ top: animScrollAdjust
246
+ })
280
247
  },
281
248
  getComponent(ListEmptyComponent)
282
249
  ),
283
- /* @__PURE__ */ React7.createElement(
250
+ /* @__PURE__ */ React5.createElement(
284
251
  Containers,
285
252
  {
286
253
  horizontal,
@@ -290,7 +257,7 @@ var ListComponent = React7.memo(function ListComponent2({
290
257
  updateItemSize
291
258
  }
292
259
  ),
293
- ListFooterComponent && /* @__PURE__ */ React7.createElement(View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
260
+ ListFooterComponent && /* @__PURE__ */ React5.createElement(View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
294
261
  );
295
262
  });
296
263
  var symbolFirst = Symbol();
@@ -455,10 +422,10 @@ var INITIAL_SCROLL_ADJUST = 1e4;
455
422
  var POSITION_OUT_OF_VIEW = -1e7;
456
423
  var DEFAULT_ITEM_SIZE = 100;
457
424
  var LegendList = forwardRef(function LegendList2(props, forwardedRef) {
458
- return /* @__PURE__ */ React7.createElement(StateProvider, null, /* @__PURE__ */ React7.createElement(LegendListInner, { ...props, ref: forwardedRef }));
425
+ return /* @__PURE__ */ React5.createElement(StateProvider, null, /* @__PURE__ */ React5.createElement(LegendListInner, { ...props, ref: forwardedRef }));
459
426
  });
460
427
  var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef) {
461
- var _a, _b, _c, _d, _e;
428
+ var _a, _b, _c, _d, _e, _f;
462
429
  const {
463
430
  data,
464
431
  initialScrollIndex,
@@ -475,8 +442,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
475
442
  maintainVisibleContentPosition = false,
476
443
  onScroll: onScrollProp,
477
444
  numColumns: numColumnsProp = 1,
478
- style: styleProp,
479
- keyExtractor,
445
+ keyExtractor: keyExtractorProp,
480
446
  renderItem,
481
447
  estimatedItemSize,
482
448
  getEstimatedItemSize,
@@ -485,11 +451,12 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
485
451
  ListEmptyComponent,
486
452
  ...rest
487
453
  } = props;
488
- const { contentContainerStyle } = props;
454
+ const { style, contentContainerStyle } = props;
489
455
  const ctx = useStateContext();
490
456
  const internalRef = useRef(null);
491
457
  const refScroller = internalRef;
492
458
  const scrollBuffer = drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE;
459
+ const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
493
460
  const refState = useRef();
494
461
  const getId = (index) => {
495
462
  var _a2;
@@ -618,7 +585,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
618
585
  }
619
586
  const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
620
587
  const scrollAdjustPending = (_a2 = state.scrollAdjustPending) != null ? _a2 : 0;
621
- const scrollExtra = Math.max(-16, Math.min(16, speed)) * 32;
588
+ const scrollExtra = Math.max(-16, Math.min(16, speed)) * 16;
622
589
  const scroll = Math.max(
623
590
  0,
624
591
  scrollState - topPad - (USE_CONTENT_INSET ? scrollAdjustPending : 0) + scrollExtra
@@ -787,18 +754,6 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
787
754
  );
788
755
  }
789
756
  }, []);
790
- const style = useMemo(() => {
791
- const extraStyle = {};
792
- if (data.length > 0) {
793
- const size = getItemSize(getId(0), 0, data[0]);
794
- if (horizontal) {
795
- extraStyle.minHeight = size;
796
- } else {
797
- extraStyle.minWidth = size;
798
- }
799
- }
800
- return StyleSheet.compose(styleProp, extraStyle);
801
- }, []);
802
757
  const doUpdatePaddingTop = () => {
803
758
  if (alignItemsAtEnd) {
804
759
  const { scrollLength, totalSize } = refState.current;
@@ -824,19 +779,22 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
824
779
  return;
825
780
  }
826
781
  const { scrollLength, scroll, contentSize } = refState.current;
827
- const distanceFromEnd = contentSize[horizontal ? "width" : "height"] - scroll - scrollLength;
828
- if (refState.current) {
829
- refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
830
- }
831
- if (onEndReached) {
832
- if (!refState.current.isEndReached) {
833
- if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
834
- refState.current.isEndReached = true;
835
- onEndReached({ distanceFromEnd });
836
- }
837
- } else {
838
- if (distanceFromEnd >= onEndReachedThreshold * scrollLength) {
839
- refState.current.isEndReached = false;
782
+ const contentLength = contentSize[horizontal ? "width" : "height"];
783
+ if (scroll > 0 && contentLength > 0) {
784
+ const distanceFromEnd = contentLength - scroll - scrollLength;
785
+ if (refState.current) {
786
+ refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
787
+ }
788
+ if (onEndReached) {
789
+ if (!refState.current.isEndReached) {
790
+ if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
791
+ refState.current.isEndReached = true;
792
+ onEndReached({ distanceFromEnd });
793
+ }
794
+ } else {
795
+ if (distanceFromEnd >= onEndReachedThreshold * scrollLength) {
796
+ refState.current.isEndReached = false;
797
+ }
840
798
  }
841
799
  }
842
800
  }
@@ -864,7 +822,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
864
822
  };
865
823
  const isFirst = !refState.current.renderItem;
866
824
  if (isFirst || data !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
867
- if (!keyExtractor && !isFirst && data !== refState.current.data) {
825
+ if (!keyExtractorProp && !isFirst && data !== refState.current.data) {
868
826
  refState.current.sizes.clear();
869
827
  refState.current.positions.clear();
870
828
  }
@@ -905,11 +863,14 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
905
863
  refState.current.isEndReached = false;
906
864
  const numContainers = peek$(ctx, "numContainers");
907
865
  for (let i = 0; i < numContainers; i++) {
908
- set$(ctx, `containerItemKey${i}`, void 0);
909
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
910
- set$(ctx, `containerColumn${i}`, -1);
866
+ const itemKey = peek$(ctx, `containerItemKey${i}`);
867
+ if (!keyExtractorProp || itemKey && ((_b = refState.current) == null ? void 0 : _b.indexByKey.get(itemKey)) === void 0) {
868
+ set$(ctx, `containerItemKey${i}`, void 0);
869
+ set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
870
+ set$(ctx, `containerColumn${i}`, -1);
871
+ }
911
872
  }
912
- if (!keyExtractor) {
873
+ if (!keyExtractorProp) {
913
874
  refState.current.sizes.clear();
914
875
  refState.current.positions;
915
876
  }
@@ -925,7 +886,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
925
886
  set$(
926
887
  ctx,
927
888
  "stylePaddingTop",
928
- (_e = (_d = (_b = StyleSheet.flatten(style)) == null ? void 0 : _b.paddingTop) != null ? _d : (_c = StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _c.paddingTop) != null ? _e : 0
889
+ (_f = (_e = (_c = StyleSheet.flatten(style)) == null ? void 0 : _c.paddingTop) != null ? _e : (_d = StyleSheet.flatten(contentContainerStyle)) == null ? void 0 : _d.paddingTop) != null ? _f : 0
929
890
  );
930
891
  const getRenderedItem = useCallback((key, containerId) => {
931
892
  var _a2, _b2;
@@ -1036,7 +997,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1036
997
  set$(ctx, "numContainersPooled", numContainers * 2);
1037
998
  calculateItemsInView();
1038
999
  });
1039
- const updateItemSize = useCallback((key, size) => {
1000
+ const updateItemSize = useCallback((containerId, itemKey, size) => {
1040
1001
  var _a2;
1041
1002
  const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
1042
1003
  if (!data2) {
@@ -1044,14 +1005,14 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1044
1005
  }
1045
1006
  const state = refState.current;
1046
1007
  const { sizes, indexByKey, idsInFirstRender, columns, sizesLaidOut } = state;
1047
- const index = indexByKey.get(key);
1048
- const wasInFirstRender = idsInFirstRender.has(key);
1049
- const prevSize = sizes.get(key) || (wasInFirstRender ? getItemSize(key, index, data2[index]) : 0);
1008
+ const index = indexByKey.get(itemKey);
1009
+ const wasInFirstRender = idsInFirstRender.has(itemKey);
1010
+ const prevSize = sizes.get(itemKey) || (wasInFirstRender ? getItemSize(itemKey, index, data2[index]) : 0);
1050
1011
  if (!prevSize || Math.abs(prevSize - size) > 0.5) {
1051
1012
  let diff;
1052
1013
  const numColumns = peek$(ctx, "numColumns");
1053
1014
  if (numColumns > 1) {
1054
- const column = columns.get(key);
1015
+ const column = columns.get(itemKey);
1055
1016
  const loopStart = index - (column - 1);
1056
1017
  let prevMaxSizeInRow = 0;
1057
1018
  for (let i = loopStart; i < loopStart + numColumns; i++) {
@@ -1059,7 +1020,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1059
1020
  const size2 = getItemSize(id, i, data2[i]);
1060
1021
  prevMaxSizeInRow = Math.max(prevMaxSizeInRow, size2);
1061
1022
  }
1062
- sizes.set(key, size);
1023
+ sizes.set(itemKey, size);
1063
1024
  let nextMaxSizeInRow = 0;
1064
1025
  for (let i = loopStart; i < loopStart + numColumns; i++) {
1065
1026
  const id = getId(i);
@@ -1068,11 +1029,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1068
1029
  }
1069
1030
  diff = nextMaxSizeInRow - prevMaxSizeInRow;
1070
1031
  } else {
1071
- sizes.set(key, size);
1032
+ sizes.set(itemKey, size);
1072
1033
  diff = size - prevSize;
1073
1034
  }
1074
1035
  if (__DEV__ && !estimatedItemSize && !getEstimatedItemSize) {
1075
- sizesLaidOut.set(key, size);
1036
+ sizesLaidOut.set(itemKey, size);
1076
1037
  if (state.timeoutSizeMessage) {
1077
1038
  clearTimeout(state.timeoutSizeMessage);
1078
1039
  }
@@ -1080,7 +1041,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1080
1041
  state.timeoutSizeMessage = void 0;
1081
1042
  let total = 0;
1082
1043
  let num = 0;
1083
- for (const [key2, size2] of sizesLaidOut) {
1044
+ for (const [key, size2] of sizesLaidOut) {
1084
1045
  num++;
1085
1046
  total += size2;
1086
1047
  }
@@ -1090,14 +1051,18 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1090
1051
  );
1091
1052
  }, 1e3);
1092
1053
  }
1093
- addTotalSize(key, diff);
1054
+ addTotalSize(itemKey, diff);
1094
1055
  doMaintainScrollAtEnd(true);
1095
1056
  const scrollVelocity = state.scrollVelocity;
1096
1057
  if (!state.animFrameLayout && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
1097
- state.animFrameLayout = requestAnimationFrame(() => {
1098
- state.animFrameLayout = null;
1058
+ if (!peek$(ctx, `containerDidLayout${containerId}`)) {
1059
+ state.animFrameLayout = requestAnimationFrame(() => {
1060
+ state.animFrameLayout = null;
1061
+ calculateItemsInView(state.scrollVelocity);
1062
+ });
1063
+ } else {
1099
1064
  calculateItemsInView(state.scrollVelocity);
1100
- });
1065
+ }
1101
1066
  }
1102
1067
  }
1103
1068
  }, []);
@@ -1195,7 +1160,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1195
1160
  },
1196
1161
  []
1197
1162
  );
1198
- return /* @__PURE__ */ React7.createElement(
1163
+ return /* @__PURE__ */ React5.createElement(
1199
1164
  ListComponent,
1200
1165
  {
1201
1166
  ...rest,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/list",
3
- "version": "0.5.6",
3
+ "version": "0.5.8",
4
4
  "description": "legend-list",
5
5
  "sideEffects": false,
6
6
  "private": false,