@legendapp/list 0.5.7 → 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.
Files changed (3) hide show
  1. package/index.js +144 -169
  2. package/index.mjs +128 -153
  3. package/package.json +1 -1
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,77 +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);
164
- const otherAxisSize = horizontal ? event.nativeEvent.layout.width : event.nativeEvent.layout.height;
165
- set$(ctx, "otherAxisSize", Math.max(otherAxisSize, peek$(ctx, "otherAxisSize") || 0));
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));
166
139
  const measured = peek$(ctx, `containerDidLayout${id}`);
167
140
  if (!measured) {
168
141
  requestAnimationFrame(() => {
@@ -172,20 +145,21 @@ var Container = ({
172
145
  }
173
146
  }
174
147
  },
175
- /* @__PURE__ */ React7__namespace.default.createElement(
176
- InnerContainer,
177
- {
178
- containerId: id,
179
- getRenderedItem,
180
- recycleItems,
181
- ItemSeparatorComponent
182
- }
183
- )
148
+ /* @__PURE__ */ React5__namespace.default.createElement(React5__namespace.default.Fragment, { key: recycleItems ? void 0 : itemKey }, renderedItem, renderedItem && ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent)
184
149
  );
185
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
+ }
186
160
 
187
161
  // src/Containers.tsx
188
- var Containers = React7__namespace.memo(function Containers2({
162
+ var Containers = React5__namespace.memo(function Containers2({
189
163
  horizontal,
190
164
  recycleItems,
191
165
  ItemSeparatorComponent,
@@ -194,10 +168,11 @@ var Containers = React7__namespace.memo(function Containers2({
194
168
  }) {
195
169
  const ctx = useStateContext();
196
170
  const numContainers = use$("numContainersPooled");
171
+ const animSize = useValue$("totalSize", (v) => v + peek$(ctx, "scrollAdjust"));
197
172
  const containers = [];
198
173
  for (let i = 0; i < numContainers; i++) {
199
174
  containers.push(
200
- /* @__PURE__ */ React7__namespace.createElement(
175
+ /* @__PURE__ */ React5__namespace.createElement(
201
176
  Container,
202
177
  {
203
178
  id: i,
@@ -205,41 +180,27 @@ var Containers = React7__namespace.memo(function Containers2({
205
180
  recycleItems,
206
181
  horizontal,
207
182
  getRenderedItem,
208
- onLayout: updateItemSize,
183
+ updateItemSize,
209
184
  ItemSeparatorComponent
210
185
  }
211
186
  )
212
187
  );
213
188
  }
214
- return /* @__PURE__ */ React7__namespace.createElement(
215
- $View,
216
- {
217
- $key: "totalSize",
218
- $key2: "scrollAdjust",
219
- $style: () => {
220
- const size = peek$(ctx, "totalSize") + peek$(ctx, "scrollAdjust");
221
- return horizontal ? {
222
- width: size
223
- } : {
224
- height: size
225
- };
226
- }
227
- },
228
- containers
229
- );
189
+ const style = horizontal ? { width: animSize } : { height: animSize };
190
+ return /* @__PURE__ */ React5__namespace.createElement(reactNative.Animated.View, { style }, containers);
230
191
  });
231
192
 
232
193
  // src/ListComponent.tsx
233
194
  var getComponent = (Component) => {
234
- if (React7__namespace.isValidElement(Component)) {
195
+ if (React5__namespace.isValidElement(Component)) {
235
196
  return Component;
236
197
  }
237
198
  if (Component) {
238
- return /* @__PURE__ */ React7__namespace.createElement(Component, null);
199
+ return /* @__PURE__ */ React5__namespace.createElement(Component, null);
239
200
  }
240
201
  return null;
241
202
  };
242
- var ListComponent = React7__namespace.memo(function ListComponent2({
203
+ var ListComponent = React5__namespace.memo(function ListComponent2({
243
204
  style,
244
205
  contentContainerStyle,
245
206
  horizontal,
@@ -262,8 +223,9 @@ var ListComponent = React7__namespace.memo(function ListComponent2({
262
223
  ...rest
263
224
  }) {
264
225
  const ctx = useStateContext();
265
- use$("otherAxisSize") || 0;
266
- return /* @__PURE__ */ React7__namespace.createElement(
226
+ const animPaddingTop = useValue$("paddingTop");
227
+ const animScrollAdjust = useValue$("scrollAdjust");
228
+ return /* @__PURE__ */ React5__namespace.createElement(
267
229
  $ScrollView,
268
230
  {
269
231
  ...rest,
@@ -280,12 +242,13 @@ var ListComponent = React7__namespace.memo(function ListComponent2({
280
242
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
281
243
  ref: refScroller
282
244
  },
283
- alignItemsAtEnd && /* @__PURE__ */ React7__namespace.createElement($View, { $key: "paddingTop", $style: () => ({ height: peek$(ctx, "paddingTop") }) }),
284
- ListHeaderComponent && /* @__PURE__ */ React7__namespace.createElement(
285
- $View,
245
+ alignItemsAtEnd && /* @__PURE__ */ React5__namespace.createElement(reactNative.Animated.View, { style: { height: animPaddingTop } }),
246
+ ListHeaderComponent && /* @__PURE__ */ React5__namespace.createElement(
247
+ reactNative.Animated.View,
286
248
  {
287
- $key: "scrollAdjust",
288
- $style: () => reactNative.StyleSheet.compose(ListHeaderComponentStyle, { top: peek$(ctx, "scrollAdjust") }),
249
+ style: reactNative.StyleSheet.compose(ListHeaderComponentStyle, {
250
+ top: animScrollAdjust
251
+ }),
289
252
  onLayout: (event) => {
290
253
  const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
291
254
  const prevSize = peek$(ctx, "headerSize") || 0;
@@ -296,15 +259,16 @@ var ListComponent = React7__namespace.memo(function ListComponent2({
296
259
  },
297
260
  getComponent(ListHeaderComponent)
298
261
  ),
299
- ListEmptyComponent && /* @__PURE__ */ React7__namespace.createElement(
300
- $View,
262
+ ListEmptyComponent && /* @__PURE__ */ React5__namespace.createElement(
263
+ reactNative.Animated.View,
301
264
  {
302
- $key: "scrollAdjust",
303
- $style: () => reactNative.StyleSheet.compose(ListEmptyComponentStyle, { top: peek$(ctx, "scrollAdjust") })
265
+ style: reactNative.StyleSheet.compose(ListEmptyComponentStyle, {
266
+ top: animScrollAdjust
267
+ })
304
268
  },
305
269
  getComponent(ListEmptyComponent)
306
270
  ),
307
- /* @__PURE__ */ React7__namespace.createElement(
271
+ /* @__PURE__ */ React5__namespace.createElement(
308
272
  Containers,
309
273
  {
310
274
  horizontal,
@@ -314,12 +278,12 @@ var ListComponent = React7__namespace.memo(function ListComponent2({
314
278
  updateItemSize
315
279
  }
316
280
  ),
317
- ListFooterComponent && /* @__PURE__ */ React7__namespace.createElement(reactNative.View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
281
+ ListFooterComponent && /* @__PURE__ */ React5__namespace.createElement(reactNative.View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
318
282
  );
319
283
  });
320
284
  var symbolFirst = Symbol();
321
285
  function useInit(cb) {
322
- const refValue = React7.useRef(symbolFirst);
286
+ const refValue = React5.useRef(symbolFirst);
323
287
  if (refValue.current === symbolFirst) {
324
288
  refValue.current = cb();
325
289
  }
@@ -478,11 +442,11 @@ var DEFAULT_DRAW_DISTANCE = 250;
478
442
  var INITIAL_SCROLL_ADJUST = 1e4;
479
443
  var POSITION_OUT_OF_VIEW = -1e7;
480
444
  var DEFAULT_ITEM_SIZE = 100;
481
- var LegendList = React7.forwardRef(function LegendList2(props, forwardedRef) {
482
- 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 }));
483
447
  });
484
- var LegendListInner = React7.forwardRef(function LegendListInner2(props, forwardedRef) {
485
- var _a, _b, _c, _d, _e;
448
+ var LegendListInner = React5.forwardRef(function LegendListInner2(props, forwardedRef) {
449
+ var _a, _b, _c, _d, _e, _f;
486
450
  const {
487
451
  data,
488
452
  initialScrollIndex,
@@ -499,7 +463,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
499
463
  maintainVisibleContentPosition = false,
500
464
  onScroll: onScrollProp,
501
465
  numColumns: numColumnsProp = 1,
502
- keyExtractor,
466
+ keyExtractor: keyExtractorProp,
503
467
  renderItem,
504
468
  estimatedItemSize,
505
469
  getEstimatedItemSize,
@@ -510,10 +474,11 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
510
474
  } = props;
511
475
  const { style, contentContainerStyle } = props;
512
476
  const ctx = useStateContext();
513
- const internalRef = React7.useRef(null);
477
+ const internalRef = React5.useRef(null);
514
478
  const refScroller = internalRef;
515
479
  const scrollBuffer = drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE;
516
- const refState = React7.useRef();
480
+ const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
481
+ const refState = React5.useRef();
517
482
  const getId = (index) => {
518
483
  var _a2;
519
484
  const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
@@ -547,7 +512,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
547
512
  }
548
513
  return void 0;
549
514
  };
550
- const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React7.useMemo(calculateInitialOffset, []);
515
+ const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : React5.useMemo(calculateInitialOffset, []);
551
516
  if (!refState.current) {
552
517
  refState.current = {
553
518
  sizes: /* @__PURE__ */ new Map(),
@@ -593,7 +558,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
593
558
  refState.current.scrollAdjustPending -= diff;
594
559
  }
595
560
  };
596
- const addTotalSize = React7.useCallback((key, add) => {
561
+ const addTotalSize = React5.useCallback((key, add) => {
597
562
  const state = refState.current;
598
563
  const index = key === null ? 0 : state.indexByKey.get(key);
599
564
  const isAbove = key !== null && index < (state.startNoBuffer || 0);
@@ -620,7 +585,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
620
585
  state.animFrameTotalSize = requestAnimationFrame(doAdd);
621
586
  }
622
587
  }, []);
623
- const calculateItemsInView = React7.useCallback((speed = 0) => {
588
+ const calculateItemsInView = React5.useCallback((speed = 0) => {
624
589
  var _a2, _b2, _c2;
625
590
  const state = refState.current;
626
591
  const {
@@ -641,7 +606,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
641
606
  }
642
607
  const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
643
608
  const scrollAdjustPending = (_a2 = state.scrollAdjustPending) != null ? _a2 : 0;
644
- const scrollExtra = Math.max(-16, Math.min(16, speed)) * 32;
609
+ const scrollExtra = Math.max(-16, Math.min(16, speed)) * 16;
645
610
  const scroll = Math.max(
646
611
  0,
647
612
  scrollState - topPad - (USE_CONTENT_INSET ? scrollAdjustPending : 0) + scrollExtra
@@ -835,19 +800,22 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
835
800
  return;
836
801
  }
837
802
  const { scrollLength, scroll, contentSize } = refState.current;
838
- const distanceFromEnd = contentSize[horizontal ? "width" : "height"] - scroll - scrollLength;
839
- if (refState.current) {
840
- refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
841
- }
842
- if (onEndReached) {
843
- if (!refState.current.isEndReached) {
844
- if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
845
- refState.current.isEndReached = true;
846
- onEndReached({ distanceFromEnd });
847
- }
848
- } else {
849
- if (distanceFromEnd >= onEndReachedThreshold * scrollLength) {
850
- 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
+ }
851
819
  }
852
820
  }
853
821
  }
@@ -875,7 +843,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
875
843
  };
876
844
  const isFirst = !refState.current.renderItem;
877
845
  if (isFirst || data !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
878
- if (!keyExtractor && !isFirst && data !== refState.current.data) {
846
+ if (!keyExtractorProp && !isFirst && data !== refState.current.data) {
879
847
  refState.current.sizes.clear();
880
848
  refState.current.positions.clear();
881
849
  }
@@ -916,11 +884,14 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
916
884
  refState.current.isEndReached = false;
917
885
  const numContainers = peek$(ctx, "numContainers");
918
886
  for (let i = 0; i < numContainers; i++) {
919
- set$(ctx, `containerItemKey${i}`, void 0);
920
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
921
- 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
+ }
922
893
  }
923
- if (!keyExtractor) {
894
+ if (!keyExtractorProp) {
924
895
  refState.current.sizes.clear();
925
896
  refState.current.positions;
926
897
  }
@@ -936,9 +907,9 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
936
907
  set$(
937
908
  ctx,
938
909
  "stylePaddingTop",
939
- (_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
940
911
  );
941
- const getRenderedItem = React7.useCallback((key, containerId) => {
912
+ const getRenderedItem = React5.useCallback((key, containerId) => {
942
913
  var _a2, _b2;
943
914
  const state = refState.current;
944
915
  if (!state) {
@@ -958,7 +929,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
958
929
  }
959
930
  });
960
931
  ctx.mapViewabilityCallbacks.set(key2, callback);
961
- React7.useEffect(
932
+ React5.useEffect(
962
933
  () => () => {
963
934
  ctx.mapViewabilityCallbacks.delete(key2);
964
935
  },
@@ -973,7 +944,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
973
944
  }
974
945
  });
975
946
  ctx.mapViewabilityAmountCallbacks.set(containerId, callback);
976
- React7.useEffect(
947
+ React5.useEffect(
977
948
  () => () => {
978
949
  ctx.mapViewabilityAmountCallbacks.delete(containerId);
979
950
  },
@@ -981,7 +952,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
981
952
  );
982
953
  };
983
954
  const useRecyclingEffect = (effect) => {
984
- React7.useEffect(() => {
955
+ React5.useEffect(() => {
985
956
  const state2 = refState.current;
986
957
  let prevIndex = index;
987
958
  let prevItem = state2.data[index];
@@ -1009,7 +980,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1009
980
  }, []);
1010
981
  };
1011
982
  const useRecyclingState = (valueOrFun) => {
1012
- const stateInfo = React7.useState(
983
+ const stateInfo = React5.useState(
1013
984
  () => typeof valueOrFun === "function" ? valueOrFun({
1014
985
  index,
1015
986
  item: refState.current.data[index],
@@ -1047,7 +1018,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1047
1018
  set$(ctx, "numContainersPooled", numContainers * 2);
1048
1019
  calculateItemsInView();
1049
1020
  });
1050
- const updateItemSize = React7.useCallback((key, size) => {
1021
+ const updateItemSize = React5.useCallback((containerId, itemKey, size) => {
1051
1022
  var _a2;
1052
1023
  const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
1053
1024
  if (!data2) {
@@ -1055,14 +1026,14 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1055
1026
  }
1056
1027
  const state = refState.current;
1057
1028
  const { sizes, indexByKey, idsInFirstRender, columns, sizesLaidOut } = state;
1058
- const index = indexByKey.get(key);
1059
- const wasInFirstRender = idsInFirstRender.has(key);
1060
- 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);
1061
1032
  if (!prevSize || Math.abs(prevSize - size) > 0.5) {
1062
1033
  let diff;
1063
1034
  const numColumns = peek$(ctx, "numColumns");
1064
1035
  if (numColumns > 1) {
1065
- const column = columns.get(key);
1036
+ const column = columns.get(itemKey);
1066
1037
  const loopStart = index - (column - 1);
1067
1038
  let prevMaxSizeInRow = 0;
1068
1039
  for (let i = loopStart; i < loopStart + numColumns; i++) {
@@ -1070,7 +1041,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1070
1041
  const size2 = getItemSize(id, i, data2[i]);
1071
1042
  prevMaxSizeInRow = Math.max(prevMaxSizeInRow, size2);
1072
1043
  }
1073
- sizes.set(key, size);
1044
+ sizes.set(itemKey, size);
1074
1045
  let nextMaxSizeInRow = 0;
1075
1046
  for (let i = loopStart; i < loopStart + numColumns; i++) {
1076
1047
  const id = getId(i);
@@ -1079,11 +1050,11 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1079
1050
  }
1080
1051
  diff = nextMaxSizeInRow - prevMaxSizeInRow;
1081
1052
  } else {
1082
- sizes.set(key, size);
1053
+ sizes.set(itemKey, size);
1083
1054
  diff = size - prevSize;
1084
1055
  }
1085
1056
  if (__DEV__ && !estimatedItemSize && !getEstimatedItemSize) {
1086
- sizesLaidOut.set(key, size);
1057
+ sizesLaidOut.set(itemKey, size);
1087
1058
  if (state.timeoutSizeMessage) {
1088
1059
  clearTimeout(state.timeoutSizeMessage);
1089
1060
  }
@@ -1091,7 +1062,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1091
1062
  state.timeoutSizeMessage = void 0;
1092
1063
  let total = 0;
1093
1064
  let num = 0;
1094
- for (const [key2, size2] of sizesLaidOut) {
1065
+ for (const [key, size2] of sizesLaidOut) {
1095
1066
  num++;
1096
1067
  total += size2;
1097
1068
  }
@@ -1101,18 +1072,22 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1101
1072
  );
1102
1073
  }, 1e3);
1103
1074
  }
1104
- addTotalSize(key, diff);
1075
+ addTotalSize(itemKey, diff);
1105
1076
  doMaintainScrollAtEnd(true);
1106
1077
  const scrollVelocity = state.scrollVelocity;
1107
1078
  if (!state.animFrameLayout && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
1108
- state.animFrameLayout = requestAnimationFrame(() => {
1109
- state.animFrameLayout = null;
1079
+ if (!peek$(ctx, `containerDidLayout${containerId}`)) {
1080
+ state.animFrameLayout = requestAnimationFrame(() => {
1081
+ state.animFrameLayout = null;
1082
+ calculateItemsInView(state.scrollVelocity);
1083
+ });
1084
+ } else {
1110
1085
  calculateItemsInView(state.scrollVelocity);
1111
- });
1086
+ }
1112
1087
  }
1113
1088
  }
1114
1089
  }, []);
1115
- const handleScrollDebounced = React7.useCallback((velocity) => {
1090
+ const handleScrollDebounced = React5.useCallback((velocity) => {
1116
1091
  var _a2, _b2;
1117
1092
  const scrollAdjustPending = (_b2 = (_a2 = refState.current) == null ? void 0 : _a2.scrollAdjustPending) != null ? _b2 : 0;
1118
1093
  set$(ctx, "scrollAdjust", scrollAdjustPending);
@@ -1120,7 +1095,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1120
1095
  checkAtBottom();
1121
1096
  checkAtTop();
1122
1097
  }, []);
1123
- const onLayout = React7.useCallback((event) => {
1098
+ const onLayout = React5.useCallback((event) => {
1124
1099
  let scrollLength = event.nativeEvent.layout[horizontal ? "width" : "height"];
1125
1100
  if (!USE_CONTENT_INSET) {
1126
1101
  scrollLength += event.nativeEvent.layout[horizontal ? "x" : "y"];
@@ -1142,7 +1117,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1142
1117
  }
1143
1118
  }
1144
1119
  }, []);
1145
- const handleScroll = React7.useCallback(
1120
+ const handleScroll = React5.useCallback(
1146
1121
  (event, fromSelf) => {
1147
1122
  var _a2, _b2, _c2;
1148
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) {
@@ -1177,7 +1152,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1177
1152
  },
1178
1153
  []
1179
1154
  );
1180
- React7.useImperativeHandle(
1155
+ React5.useImperativeHandle(
1181
1156
  forwardedRef,
1182
1157
  () => {
1183
1158
  const scrollToIndex = ({ index, animated }) => {
@@ -1206,7 +1181,7 @@ var LegendListInner = React7.forwardRef(function LegendListInner2(props, forward
1206
1181
  },
1207
1182
  []
1208
1183
  );
1209
- return /* @__PURE__ */ React7__namespace.createElement(
1184
+ return /* @__PURE__ */ React5__namespace.createElement(
1210
1185
  ListComponent,
1211
1186
  {
1212
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,77 +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);
143
- const otherAxisSize = horizontal ? event.nativeEvent.layout.width : event.nativeEvent.layout.height;
144
- set$(ctx, "otherAxisSize", Math.max(otherAxisSize, peek$(ctx, "otherAxisSize") || 0));
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));
145
118
  const measured = peek$(ctx, `containerDidLayout${id}`);
146
119
  if (!measured) {
147
120
  requestAnimationFrame(() => {
@@ -151,20 +124,21 @@ var Container = ({
151
124
  }
152
125
  }
153
126
  },
154
- /* @__PURE__ */ React7__default.createElement(
155
- InnerContainer,
156
- {
157
- containerId: id,
158
- getRenderedItem,
159
- recycleItems,
160
- ItemSeparatorComponent
161
- }
162
- )
127
+ /* @__PURE__ */ React5__default.createElement(React5__default.Fragment, { key: recycleItems ? void 0 : itemKey }, renderedItem, renderedItem && ItemSeparatorComponent && itemKey !== lastItemKey && ItemSeparatorComponent)
163
128
  );
164
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
+ }
165
139
 
166
140
  // src/Containers.tsx
167
- var Containers = React7.memo(function Containers2({
141
+ var Containers = React5.memo(function Containers2({
168
142
  horizontal,
169
143
  recycleItems,
170
144
  ItemSeparatorComponent,
@@ -173,10 +147,11 @@ var Containers = React7.memo(function Containers2({
173
147
  }) {
174
148
  const ctx = useStateContext();
175
149
  const numContainers = use$("numContainersPooled");
150
+ const animSize = useValue$("totalSize", (v) => v + peek$(ctx, "scrollAdjust"));
176
151
  const containers = [];
177
152
  for (let i = 0; i < numContainers; i++) {
178
153
  containers.push(
179
- /* @__PURE__ */ React7.createElement(
154
+ /* @__PURE__ */ React5.createElement(
180
155
  Container,
181
156
  {
182
157
  id: i,
@@ -184,41 +159,27 @@ var Containers = React7.memo(function Containers2({
184
159
  recycleItems,
185
160
  horizontal,
186
161
  getRenderedItem,
187
- onLayout: updateItemSize,
162
+ updateItemSize,
188
163
  ItemSeparatorComponent
189
164
  }
190
165
  )
191
166
  );
192
167
  }
193
- return /* @__PURE__ */ React7.createElement(
194
- $View,
195
- {
196
- $key: "totalSize",
197
- $key2: "scrollAdjust",
198
- $style: () => {
199
- const size = peek$(ctx, "totalSize") + peek$(ctx, "scrollAdjust");
200
- return horizontal ? {
201
- width: size
202
- } : {
203
- height: size
204
- };
205
- }
206
- },
207
- containers
208
- );
168
+ const style = horizontal ? { width: animSize } : { height: animSize };
169
+ return /* @__PURE__ */ React5.createElement(Animated.View, { style }, containers);
209
170
  });
210
171
 
211
172
  // src/ListComponent.tsx
212
173
  var getComponent = (Component) => {
213
- if (React7.isValidElement(Component)) {
174
+ if (React5.isValidElement(Component)) {
214
175
  return Component;
215
176
  }
216
177
  if (Component) {
217
- return /* @__PURE__ */ React7.createElement(Component, null);
178
+ return /* @__PURE__ */ React5.createElement(Component, null);
218
179
  }
219
180
  return null;
220
181
  };
221
- var ListComponent = React7.memo(function ListComponent2({
182
+ var ListComponent = React5.memo(function ListComponent2({
222
183
  style,
223
184
  contentContainerStyle,
224
185
  horizontal,
@@ -241,8 +202,9 @@ var ListComponent = React7.memo(function ListComponent2({
241
202
  ...rest
242
203
  }) {
243
204
  const ctx = useStateContext();
244
- use$("otherAxisSize") || 0;
245
- return /* @__PURE__ */ React7.createElement(
205
+ const animPaddingTop = useValue$("paddingTop");
206
+ const animScrollAdjust = useValue$("scrollAdjust");
207
+ return /* @__PURE__ */ React5.createElement(
246
208
  $ScrollView,
247
209
  {
248
210
  ...rest,
@@ -259,12 +221,13 @@ var ListComponent = React7.memo(function ListComponent2({
259
221
  contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
260
222
  ref: refScroller
261
223
  },
262
- alignItemsAtEnd && /* @__PURE__ */ React7.createElement($View, { $key: "paddingTop", $style: () => ({ height: peek$(ctx, "paddingTop") }) }),
263
- ListHeaderComponent && /* @__PURE__ */ React7.createElement(
264
- $View,
224
+ alignItemsAtEnd && /* @__PURE__ */ React5.createElement(Animated.View, { style: { height: animPaddingTop } }),
225
+ ListHeaderComponent && /* @__PURE__ */ React5.createElement(
226
+ Animated.View,
265
227
  {
266
- $key: "scrollAdjust",
267
- $style: () => StyleSheet.compose(ListHeaderComponentStyle, { top: peek$(ctx, "scrollAdjust") }),
228
+ style: StyleSheet.compose(ListHeaderComponentStyle, {
229
+ top: animScrollAdjust
230
+ }),
268
231
  onLayout: (event) => {
269
232
  const size = event.nativeEvent.layout[horizontal ? "width" : "height"];
270
233
  const prevSize = peek$(ctx, "headerSize") || 0;
@@ -275,15 +238,16 @@ var ListComponent = React7.memo(function ListComponent2({
275
238
  },
276
239
  getComponent(ListHeaderComponent)
277
240
  ),
278
- ListEmptyComponent && /* @__PURE__ */ React7.createElement(
279
- $View,
241
+ ListEmptyComponent && /* @__PURE__ */ React5.createElement(
242
+ Animated.View,
280
243
  {
281
- $key: "scrollAdjust",
282
- $style: () => StyleSheet.compose(ListEmptyComponentStyle, { top: peek$(ctx, "scrollAdjust") })
244
+ style: StyleSheet.compose(ListEmptyComponentStyle, {
245
+ top: animScrollAdjust
246
+ })
283
247
  },
284
248
  getComponent(ListEmptyComponent)
285
249
  ),
286
- /* @__PURE__ */ React7.createElement(
250
+ /* @__PURE__ */ React5.createElement(
287
251
  Containers,
288
252
  {
289
253
  horizontal,
@@ -293,7 +257,7 @@ var ListComponent = React7.memo(function ListComponent2({
293
257
  updateItemSize
294
258
  }
295
259
  ),
296
- ListFooterComponent && /* @__PURE__ */ React7.createElement(View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
260
+ ListFooterComponent && /* @__PURE__ */ React5.createElement(View, { style: ListFooterComponentStyle }, getComponent(ListFooterComponent))
297
261
  );
298
262
  });
299
263
  var symbolFirst = Symbol();
@@ -458,10 +422,10 @@ var INITIAL_SCROLL_ADJUST = 1e4;
458
422
  var POSITION_OUT_OF_VIEW = -1e7;
459
423
  var DEFAULT_ITEM_SIZE = 100;
460
424
  var LegendList = forwardRef(function LegendList2(props, forwardedRef) {
461
- 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 }));
462
426
  });
463
427
  var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef) {
464
- var _a, _b, _c, _d, _e;
428
+ var _a, _b, _c, _d, _e, _f;
465
429
  const {
466
430
  data,
467
431
  initialScrollIndex,
@@ -478,7 +442,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
478
442
  maintainVisibleContentPosition = false,
479
443
  onScroll: onScrollProp,
480
444
  numColumns: numColumnsProp = 1,
481
- keyExtractor,
445
+ keyExtractor: keyExtractorProp,
482
446
  renderItem,
483
447
  estimatedItemSize,
484
448
  getEstimatedItemSize,
@@ -492,6 +456,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
492
456
  const internalRef = useRef(null);
493
457
  const refScroller = internalRef;
494
458
  const scrollBuffer = drawDistance != null ? drawDistance : DEFAULT_DRAW_DISTANCE;
459
+ const keyExtractor = keyExtractorProp != null ? keyExtractorProp : (item, index) => index.toString();
495
460
  const refState = useRef();
496
461
  const getId = (index) => {
497
462
  var _a2;
@@ -620,7 +585,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
620
585
  }
621
586
  const topPad = (peek$(ctx, "stylePaddingTop") || 0) + (peek$(ctx, "headerSize") || 0);
622
587
  const scrollAdjustPending = (_a2 = state.scrollAdjustPending) != null ? _a2 : 0;
623
- const scrollExtra = Math.max(-16, Math.min(16, speed)) * 32;
588
+ const scrollExtra = Math.max(-16, Math.min(16, speed)) * 16;
624
589
  const scroll = Math.max(
625
590
  0,
626
591
  scrollState - topPad - (USE_CONTENT_INSET ? scrollAdjustPending : 0) + scrollExtra
@@ -814,19 +779,22 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
814
779
  return;
815
780
  }
816
781
  const { scrollLength, scroll, contentSize } = refState.current;
817
- const distanceFromEnd = contentSize[horizontal ? "width" : "height"] - scroll - scrollLength;
818
- if (refState.current) {
819
- refState.current.isAtBottom = distanceFromEnd < scrollLength * maintainScrollAtEndThreshold;
820
- }
821
- if (onEndReached) {
822
- if (!refState.current.isEndReached) {
823
- if (distanceFromEnd < onEndReachedThreshold * scrollLength) {
824
- refState.current.isEndReached = true;
825
- onEndReached({ distanceFromEnd });
826
- }
827
- } else {
828
- if (distanceFromEnd >= onEndReachedThreshold * scrollLength) {
829
- 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
+ }
830
798
  }
831
799
  }
832
800
  }
@@ -854,7 +822,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
854
822
  };
855
823
  const isFirst = !refState.current.renderItem;
856
824
  if (isFirst || data !== refState.current.data || numColumnsProp !== peek$(ctx, "numColumns")) {
857
- if (!keyExtractor && !isFirst && data !== refState.current.data) {
825
+ if (!keyExtractorProp && !isFirst && data !== refState.current.data) {
858
826
  refState.current.sizes.clear();
859
827
  refState.current.positions.clear();
860
828
  }
@@ -895,11 +863,14 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
895
863
  refState.current.isEndReached = false;
896
864
  const numContainers = peek$(ctx, "numContainers");
897
865
  for (let i = 0; i < numContainers; i++) {
898
- set$(ctx, `containerItemKey${i}`, void 0);
899
- set$(ctx, `containerPosition${i}`, POSITION_OUT_OF_VIEW);
900
- 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
+ }
901
872
  }
902
- if (!keyExtractor) {
873
+ if (!keyExtractorProp) {
903
874
  refState.current.sizes.clear();
904
875
  refState.current.positions;
905
876
  }
@@ -915,7 +886,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
915
886
  set$(
916
887
  ctx,
917
888
  "stylePaddingTop",
918
- (_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
919
890
  );
920
891
  const getRenderedItem = useCallback((key, containerId) => {
921
892
  var _a2, _b2;
@@ -1026,7 +997,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1026
997
  set$(ctx, "numContainersPooled", numContainers * 2);
1027
998
  calculateItemsInView();
1028
999
  });
1029
- const updateItemSize = useCallback((key, size) => {
1000
+ const updateItemSize = useCallback((containerId, itemKey, size) => {
1030
1001
  var _a2;
1031
1002
  const data2 = (_a2 = refState.current) == null ? void 0 : _a2.data;
1032
1003
  if (!data2) {
@@ -1034,14 +1005,14 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1034
1005
  }
1035
1006
  const state = refState.current;
1036
1007
  const { sizes, indexByKey, idsInFirstRender, columns, sizesLaidOut } = state;
1037
- const index = indexByKey.get(key);
1038
- const wasInFirstRender = idsInFirstRender.has(key);
1039
- 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);
1040
1011
  if (!prevSize || Math.abs(prevSize - size) > 0.5) {
1041
1012
  let diff;
1042
1013
  const numColumns = peek$(ctx, "numColumns");
1043
1014
  if (numColumns > 1) {
1044
- const column = columns.get(key);
1015
+ const column = columns.get(itemKey);
1045
1016
  const loopStart = index - (column - 1);
1046
1017
  let prevMaxSizeInRow = 0;
1047
1018
  for (let i = loopStart; i < loopStart + numColumns; i++) {
@@ -1049,7 +1020,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1049
1020
  const size2 = getItemSize(id, i, data2[i]);
1050
1021
  prevMaxSizeInRow = Math.max(prevMaxSizeInRow, size2);
1051
1022
  }
1052
- sizes.set(key, size);
1023
+ sizes.set(itemKey, size);
1053
1024
  let nextMaxSizeInRow = 0;
1054
1025
  for (let i = loopStart; i < loopStart + numColumns; i++) {
1055
1026
  const id = getId(i);
@@ -1058,11 +1029,11 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1058
1029
  }
1059
1030
  diff = nextMaxSizeInRow - prevMaxSizeInRow;
1060
1031
  } else {
1061
- sizes.set(key, size);
1032
+ sizes.set(itemKey, size);
1062
1033
  diff = size - prevSize;
1063
1034
  }
1064
1035
  if (__DEV__ && !estimatedItemSize && !getEstimatedItemSize) {
1065
- sizesLaidOut.set(key, size);
1036
+ sizesLaidOut.set(itemKey, size);
1066
1037
  if (state.timeoutSizeMessage) {
1067
1038
  clearTimeout(state.timeoutSizeMessage);
1068
1039
  }
@@ -1070,7 +1041,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1070
1041
  state.timeoutSizeMessage = void 0;
1071
1042
  let total = 0;
1072
1043
  let num = 0;
1073
- for (const [key2, size2] of sizesLaidOut) {
1044
+ for (const [key, size2] of sizesLaidOut) {
1074
1045
  num++;
1075
1046
  total += size2;
1076
1047
  }
@@ -1080,14 +1051,18 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1080
1051
  );
1081
1052
  }, 1e3);
1082
1053
  }
1083
- addTotalSize(key, diff);
1054
+ addTotalSize(itemKey, diff);
1084
1055
  doMaintainScrollAtEnd(true);
1085
1056
  const scrollVelocity = state.scrollVelocity;
1086
1057
  if (!state.animFrameLayout && (Number.isNaN(scrollVelocity) || Math.abs(scrollVelocity) < 1)) {
1087
- state.animFrameLayout = requestAnimationFrame(() => {
1088
- state.animFrameLayout = null;
1058
+ if (!peek$(ctx, `containerDidLayout${containerId}`)) {
1059
+ state.animFrameLayout = requestAnimationFrame(() => {
1060
+ state.animFrameLayout = null;
1061
+ calculateItemsInView(state.scrollVelocity);
1062
+ });
1063
+ } else {
1089
1064
  calculateItemsInView(state.scrollVelocity);
1090
- });
1065
+ }
1091
1066
  }
1092
1067
  }
1093
1068
  }, []);
@@ -1185,7 +1160,7 @@ var LegendListInner = forwardRef(function LegendListInner2(props, forwardedRef)
1185
1160
  },
1186
1161
  []
1187
1162
  );
1188
- return /* @__PURE__ */ React7.createElement(
1163
+ return /* @__PURE__ */ React5.createElement(
1189
1164
  ListComponent,
1190
1165
  {
1191
1166
  ...rest,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/list",
3
- "version": "0.5.7",
3
+ "version": "0.5.8",
4
4
  "description": "legend-list",
5
5
  "sideEffects": false,
6
6
  "private": false,