@legendapp/list 2.0.12 → 2.0.13

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/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 2.0.13
2
+ - Feat: Allow returning undefined in getFixedItemSize to fall back to estimated size
3
+ - Fix: scrollToIndex viewOffset was being subtracted twice, causing incorrect scroll positioning
4
+ - Fix: Initial container allocation was not applying maintainVisibleContentPosition calculations
5
+ - Fix: updateItemSize was providing full data array to getEstimatedItemSize and getFixedItemSize instead of individual item
6
+
1
7
  ## 2.0.12
2
8
  - Fix: Scroll velocity calculation was sometimes incorrect when item sizes were very different from estimate
3
9
  - Fix: onScroll while scrolling was updating positions without maintainVisibleContentPosition calculations, which was breaking scroll position maintenance
package/index.d.mts CHANGED
@@ -275,7 +275,7 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
275
275
  */
276
276
  stickyIndices?: number[];
277
277
  getItemType?: (item: ItemT, index: number) => TItemType;
278
- getFixedItemSize?: (index: number, item: ItemT, type: TItemType) => number;
278
+ getFixedItemSize?: (index: number, item: ItemT, type: TItemType) => number | undefined;
279
279
  itemsAreEqual?: (itemPrevious: ItemT, item: ItemT, index: number, data: readonly ItemT[]) => boolean;
280
280
  }
281
281
  type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView> | ComponentProps<typeof Animated$1.ScrollView>, TItemType extends string | undefined = string | undefined> = BaseScrollViewProps<TScrollView> & LegendListSpecificProps<ItemT, TItemType> & (DataModeProps<ItemT, TItemType> | ChildrenModeProps);
package/index.d.ts CHANGED
@@ -275,7 +275,7 @@ interface LegendListSpecificProps<ItemT, TItemType extends string | undefined> {
275
275
  */
276
276
  stickyIndices?: number[];
277
277
  getItemType?: (item: ItemT, index: number) => TItemType;
278
- getFixedItemSize?: (index: number, item: ItemT, type: TItemType) => number;
278
+ getFixedItemSize?: (index: number, item: ItemT, type: TItemType) => number | undefined;
279
279
  itemsAreEqual?: (itemPrevious: ItemT, item: ItemT, index: number, data: readonly ItemT[]) => boolean;
280
280
  }
281
281
  type LegendListPropsBase<ItemT, TScrollView extends ComponentProps<typeof ScrollView> | ComponentProps<typeof Animated.ScrollView> | ComponentProps<typeof Animated$1.ScrollView>, TItemType extends string | undefined = string | undefined> = BaseScrollViewProps<TScrollView> & LegendListSpecificProps<ItemT, TItemType> & (DataModeProps<ItemT, TItemType> | ChildrenModeProps);
package/index.js CHANGED
@@ -1050,7 +1050,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1050
1050
  if (newPosition !== void 0) {
1051
1051
  const totalSize = peek$(ctx, "totalSize");
1052
1052
  let diff = newPosition - prevPosition;
1053
- if (state.scroll + state.scrollLength > totalSize) {
1053
+ if (diff !== 0 && state.scroll + state.scrollLength > totalSize) {
1054
1054
  if (diff > 0) {
1055
1055
  diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
1056
1056
  } else {
@@ -1696,12 +1696,11 @@ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, vie
1696
1696
  if (isLast && viewPosition === void 0) {
1697
1697
  viewPosition = 1;
1698
1698
  }
1699
- const firstIndexScrollPostion = firstIndexOffset - viewOffset;
1700
1699
  state.scrollForNextCalculateItemsInView = void 0;
1701
1700
  scrollTo(state, {
1702
1701
  animated,
1703
1702
  index,
1704
- offset: firstIndexScrollPostion,
1703
+ offset: firstIndexOffset,
1705
1704
  viewOffset,
1706
1705
  viewPosition: viewPosition != null ? viewPosition : 0
1707
1706
  });
@@ -2307,7 +2306,7 @@ function checkResetContainers(ctx, state, isFirst, dataProp) {
2307
2306
 
2308
2307
  // src/core/doInitialAllocateContainers.ts
2309
2308
  function doInitialAllocateContainers(ctx, state) {
2310
- var _a;
2309
+ var _a, _b, _c;
2311
2310
  const {
2312
2311
  scrollLength,
2313
2312
  props: {
@@ -2323,14 +2322,13 @@ function doInitialAllocateContainers(ctx, state) {
2323
2322
  const hasContainers = peek$(ctx, "numContainers");
2324
2323
  if (scrollLength > 0 && data.length > 0 && !hasContainers) {
2325
2324
  let averageItemSize;
2326
- const fn = getFixedItemSize || getEstimatedItemSize;
2327
- if (fn) {
2325
+ if (getFixedItemSize || getEstimatedItemSize) {
2328
2326
  let totalSize = 0;
2329
2327
  const num = Math.min(20, data.length);
2330
2328
  for (let i = 0; i < num; i++) {
2331
2329
  const item = data[i];
2332
2330
  const itemType = getItemType ? (_a = getItemType(item, i)) != null ? _a : "" : "";
2333
- totalSize += fn(i, item, itemType);
2331
+ totalSize += (_c = (_b = getFixedItemSize == null ? void 0 : getFixedItemSize(i, item, itemType)) != null ? _b : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(i, item, itemType)) != null ? _c : estimatedItemSize;
2334
2332
  }
2335
2333
  averageItemSize = totalSize / num;
2336
2334
  } else {
@@ -2346,10 +2344,10 @@ function doInitialAllocateContainers(ctx, state) {
2346
2344
  if (!IsNewArchitecture || state.lastLayout) {
2347
2345
  if (state.props.initialScroll) {
2348
2346
  requestAnimationFrame(() => {
2349
- calculateItemsInView(ctx, state, { dataChanged: true });
2347
+ calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2350
2348
  });
2351
2349
  } else {
2352
- calculateItemsInView(ctx, state, { dataChanged: true });
2350
+ calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2353
2351
  }
2354
2352
  }
2355
2353
  return true;
@@ -2592,7 +2590,7 @@ function updateOneItemSize(state, itemKey, sizeObj) {
2592
2590
  } = state;
2593
2591
  if (!data) return 0;
2594
2592
  const index = indexByKey.get(itemKey);
2595
- const prevSize = getItemSize(state, itemKey, index, data);
2593
+ const prevSize = getItemSize(state, itemKey, index, data[index]);
2596
2594
  const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
2597
2595
  sizesKnown.set(itemKey, size);
2598
2596
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
package/index.mjs CHANGED
@@ -1029,7 +1029,7 @@ function prepareMVCP(ctx, state, dataChanged) {
1029
1029
  if (newPosition !== void 0) {
1030
1030
  const totalSize = peek$(ctx, "totalSize");
1031
1031
  let diff = newPosition - prevPosition;
1032
- if (state.scroll + state.scrollLength > totalSize) {
1032
+ if (diff !== 0 && state.scroll + state.scrollLength > totalSize) {
1033
1033
  if (diff > 0) {
1034
1034
  diff = Math.max(0, totalSize - state.scroll - state.scrollLength);
1035
1035
  } else {
@@ -1675,12 +1675,11 @@ function scrollToIndex(ctx, state, { index, viewOffset = 0, animated = true, vie
1675
1675
  if (isLast && viewPosition === void 0) {
1676
1676
  viewPosition = 1;
1677
1677
  }
1678
- const firstIndexScrollPostion = firstIndexOffset - viewOffset;
1679
1678
  state.scrollForNextCalculateItemsInView = void 0;
1680
1679
  scrollTo(state, {
1681
1680
  animated,
1682
1681
  index,
1683
- offset: firstIndexScrollPostion,
1682
+ offset: firstIndexOffset,
1684
1683
  viewOffset,
1685
1684
  viewPosition: viewPosition != null ? viewPosition : 0
1686
1685
  });
@@ -2286,7 +2285,7 @@ function checkResetContainers(ctx, state, isFirst, dataProp) {
2286
2285
 
2287
2286
  // src/core/doInitialAllocateContainers.ts
2288
2287
  function doInitialAllocateContainers(ctx, state) {
2289
- var _a;
2288
+ var _a, _b, _c;
2290
2289
  const {
2291
2290
  scrollLength,
2292
2291
  props: {
@@ -2302,14 +2301,13 @@ function doInitialAllocateContainers(ctx, state) {
2302
2301
  const hasContainers = peek$(ctx, "numContainers");
2303
2302
  if (scrollLength > 0 && data.length > 0 && !hasContainers) {
2304
2303
  let averageItemSize;
2305
- const fn = getFixedItemSize || getEstimatedItemSize;
2306
- if (fn) {
2304
+ if (getFixedItemSize || getEstimatedItemSize) {
2307
2305
  let totalSize = 0;
2308
2306
  const num = Math.min(20, data.length);
2309
2307
  for (let i = 0; i < num; i++) {
2310
2308
  const item = data[i];
2311
2309
  const itemType = getItemType ? (_a = getItemType(item, i)) != null ? _a : "" : "";
2312
- totalSize += fn(i, item, itemType);
2310
+ totalSize += (_c = (_b = getFixedItemSize == null ? void 0 : getFixedItemSize(i, item, itemType)) != null ? _b : getEstimatedItemSize == null ? void 0 : getEstimatedItemSize(i, item, itemType)) != null ? _c : estimatedItemSize;
2313
2311
  }
2314
2312
  averageItemSize = totalSize / num;
2315
2313
  } else {
@@ -2325,10 +2323,10 @@ function doInitialAllocateContainers(ctx, state) {
2325
2323
  if (!IsNewArchitecture || state.lastLayout) {
2326
2324
  if (state.props.initialScroll) {
2327
2325
  requestAnimationFrame(() => {
2328
- calculateItemsInView(ctx, state, { dataChanged: true });
2326
+ calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2329
2327
  });
2330
2328
  } else {
2331
- calculateItemsInView(ctx, state, { dataChanged: true });
2329
+ calculateItemsInView(ctx, state, { dataChanged: true, doMVCP: true });
2332
2330
  }
2333
2331
  }
2334
2332
  return true;
@@ -2571,7 +2569,7 @@ function updateOneItemSize(state, itemKey, sizeObj) {
2571
2569
  } = state;
2572
2570
  if (!data) return 0;
2573
2571
  const index = indexByKey.get(itemKey);
2574
- const prevSize = getItemSize(state, itemKey, index, data);
2572
+ const prevSize = getItemSize(state, itemKey, index, data[index]);
2575
2573
  const size = Math.floor((horizontal ? sizeObj.width : sizeObj.height) * 8) / 8;
2576
2574
  sizesKnown.set(itemKey, size);
2577
2575
  if (!getEstimatedItemSize && !getFixedItemSize && size > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/list",
3
- "version": "2.0.12",
3
+ "version": "2.0.13",
4
4
  "description": "Legend List is a drop-in replacement for FlatList with much better performance and supporting dynamically sized items.",
5
5
  "sideEffects": false,
6
6
  "private": false,