@legendapp/list 3.3.4 → 3.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 3.3.5
2
+
3
+ - Fix: Changing `dataKey` no longer leaves the new dataset invisible. #519
4
+ - Fix: `maintainScrollAtEnd` stays pinned as newly inserted rows are measured, and scroll corrections preserve `anchoredEndSpace` padding. #520
5
+ - Fix: Programmatic scrolls no longer throw in browsers, get lost when they replace unfinished initial scrolling, or stop working after a previous request is canceled. #518
6
+
1
7
  ## 3.3.4
2
8
 
3
9
  - Feat: `getState().indexByKey(key)` looks up an item’s current index by key.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@legendapp/list",
3
- "version": "3.3.4",
3
+ "version": "3.3.5",
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,
package/react-native.js CHANGED
@@ -457,6 +457,28 @@ var EDGE_POSITION_EPSILON = 1;
457
457
  var ENABLE_DEVMODE = IS_DEV && false;
458
458
  var ENABLE_DEBUG_VIEW = IS_DEV && false;
459
459
 
460
+ // src/core/cancelImperativeScroll.ts
461
+ function cancelScrollCompletionChecks({ scheduledWork }) {
462
+ scheduledWork.cancel("checkFinishedScrollFrame");
463
+ scheduledWork.cancel("checkFinishedScrollRetryFrame");
464
+ scheduledWork.cancel("checkFinishedScrollFallback");
465
+ scheduledWork.cancel("platformScrollCompletion");
466
+ }
467
+ function settlePendingImperativeScroll(state) {
468
+ var _a3, _b;
469
+ const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
470
+ state.pendingScrollResolve = void 0;
471
+ state.pendingScrollToEnd = void 0;
472
+ resolvePendingScroll == null ? void 0 : resolvePendingScroll();
473
+ }
474
+ function cancelImperativeScroll(state) {
475
+ cancelScrollCompletionChecks(state);
476
+ state.scheduledWork.cancel("imperativeScrollReady");
477
+ state.scrollingTo = void 0;
478
+ state.scrollTargetPinnedRange = void 0;
479
+ settlePendingImperativeScroll(state);
480
+ }
481
+
460
482
  // src/core/deferredPublicOnScroll.ts
461
483
  function withResolvedContentOffset(state, event, resolvedOffset) {
462
484
  return {
@@ -964,6 +986,24 @@ function clearPreservedInitialScrollTarget(state) {
964
986
  state.initialScroll = void 0;
965
987
  setInitialScrollSession(state);
966
988
  }
989
+ function supersedeInitialScroll(ctx) {
990
+ var _a3, _b, _c;
991
+ const state = ctx.state;
992
+ const bootstrapInitialScroll = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
993
+ if (state.initialScroll || bootstrapInitialScroll || ((_b = state.scrollingTo) == null ? void 0 : _b.isInitialScroll)) {
994
+ if ((bootstrapInitialScroll == null ? void 0 : bootstrapInitialScroll.frameHandle) !== void 0 && typeof cancelAnimationFrame === "function") {
995
+ cancelAnimationFrame(bootstrapInitialScroll.frameHandle);
996
+ }
997
+ if ((_c = state.scrollingTo) == null ? void 0 : _c.isInitialScroll) {
998
+ cancelScrollCompletionChecks(state);
999
+ state.scrollingTo = void 0;
1000
+ state.scrollTargetPinnedRange = void 0;
1001
+ }
1002
+ initialScrollCompletion.resetFlags(state);
1003
+ setInitialScrollSession(state, { bootstrap: null });
1004
+ finishInitialScroll(ctx);
1005
+ }
1006
+ }
967
1007
  function finishInitialScroll(ctx, options) {
968
1008
  var _a3, _b, _c;
969
1009
  const state = ctx.state;
@@ -1279,29 +1319,6 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
1279
1319
  return clampedOffset;
1280
1320
  }
1281
1321
 
1282
- // src/core/cancelImperativeScroll.ts
1283
- function cancelScrollCompletionChecks({ scheduledWork }) {
1284
- scheduledWork.cancel("checkFinishedScrollFrame");
1285
- scheduledWork.cancel("checkFinishedScrollRetryFrame");
1286
- scheduledWork.cancel("checkFinishedScrollFallback");
1287
- scheduledWork.cancel("platformScrollCompletion");
1288
- }
1289
- function settlePendingImperativeScroll(state) {
1290
- var _a3, _b;
1291
- const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
1292
- state.pendingScrollResolve = void 0;
1293
- state.pendingScrollToEnd = void 0;
1294
- resolvePendingScroll == null ? void 0 : resolvePendingScroll();
1295
- }
1296
- function cancelImperativeScroll(state) {
1297
- cancelScrollCompletionChecks(state);
1298
- state.scheduledWork.cancel("imperativeScrollReady");
1299
- state.runPendingScrollToEnd = void 0;
1300
- state.scrollingTo = void 0;
1301
- state.scrollTargetPinnedRange = void 0;
1302
- settlePendingImperativeScroll(state);
1303
- }
1304
-
1305
1322
  // src/core/finishScrollTo.ts
1306
1323
  function finishScrollTo(ctx) {
1307
1324
  var _a3, _b;
@@ -4833,7 +4850,7 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
4833
4850
  if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
4834
4851
  needsRecalculate = true;
4835
4852
  }
4836
- if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
4853
+ if (prevSizeKnown === void 0 || Math.abs(prevSizeKnown - size) > 5) {
4837
4854
  shouldMaintainScrollAtEnd = true;
4838
4855
  }
4839
4856
  onItemSizeChanged == null ? void 0 : onItemSizeChanged({
@@ -5683,13 +5700,11 @@ var ContainerSlot = typedMemo(function ContainerSlot2(props) {
5683
5700
  return /* @__PURE__ */ React2__namespace.createElement(ContainerSlotBase, { ...props });
5684
5701
  });
5685
5702
  function useFreshDataTransitionVisibility(readyToRender, transitionEpoch) {
5686
- const completedTransitionEpoch = React2.useRef(transitionEpoch);
5687
- const isTransitionPending = completedTransitionEpoch.current !== transitionEpoch;
5703
+ const [completedTransitionEpoch, setCompletedTransitionEpoch] = React2.useState(transitionEpoch);
5704
+ const isTransitionPending = completedTransitionEpoch !== transitionEpoch;
5688
5705
  React2.useLayoutEffect(() => {
5689
- if (!readyToRender) {
5690
- completedTransitionEpoch.current = transitionEpoch;
5691
- }
5692
- }, [readyToRender, transitionEpoch]);
5706
+ setCompletedTransitionEpoch(transitionEpoch);
5707
+ }, [transitionEpoch]);
5693
5708
  return readyToRender && !isTransitionPending;
5694
5709
  }
5695
5710
 
@@ -6402,7 +6417,8 @@ var ScheduledWork = class {
6402
6417
  const work = this.work.get(key);
6403
6418
  if (work) {
6404
6419
  this.work.delete(key);
6405
- work[1](work[0]);
6420
+ const [handle, cancel] = work;
6421
+ cancel(handle);
6406
6422
  }
6407
6423
  }
6408
6424
  has(key) {
@@ -6655,6 +6671,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
6655
6671
  };
6656
6672
  const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
6657
6673
  const token = startImperativeScroll(resolve);
6674
+ supersedeInitialScroll(ctx);
6658
6675
  runScrollRequest(token, resolve, run, isReady);
6659
6676
  });
6660
6677
  state.runPendingScrollToEnd = () => {
@@ -6781,9 +6798,9 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
6781
6798
  resolve,
6782
6799
  token
6783
6800
  };
6784
- if (scheduleImperativeScrollCommit) {
6785
- scheduleImperativeScrollCommit();
6786
- } else {
6801
+ scheduleImperativeScrollCommit == null ? void 0 : scheduleImperativeScrollCommit();
6802
+ supersedeInitialScroll(ctx);
6803
+ if (!scheduleImperativeScrollCommit) {
6787
6804
  (_a3 = state.runPendingScrollToEnd) == null ? void 0 : _a3.call(state);
6788
6805
  }
6789
6806
  }),
package/react-native.mjs CHANGED
@@ -436,6 +436,28 @@ var EDGE_POSITION_EPSILON = 1;
436
436
  var ENABLE_DEVMODE = IS_DEV && false;
437
437
  var ENABLE_DEBUG_VIEW = IS_DEV && false;
438
438
 
439
+ // src/core/cancelImperativeScroll.ts
440
+ function cancelScrollCompletionChecks({ scheduledWork }) {
441
+ scheduledWork.cancel("checkFinishedScrollFrame");
442
+ scheduledWork.cancel("checkFinishedScrollRetryFrame");
443
+ scheduledWork.cancel("checkFinishedScrollFallback");
444
+ scheduledWork.cancel("platformScrollCompletion");
445
+ }
446
+ function settlePendingImperativeScroll(state) {
447
+ var _a3, _b;
448
+ const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
449
+ state.pendingScrollResolve = void 0;
450
+ state.pendingScrollToEnd = void 0;
451
+ resolvePendingScroll == null ? void 0 : resolvePendingScroll();
452
+ }
453
+ function cancelImperativeScroll(state) {
454
+ cancelScrollCompletionChecks(state);
455
+ state.scheduledWork.cancel("imperativeScrollReady");
456
+ state.scrollingTo = void 0;
457
+ state.scrollTargetPinnedRange = void 0;
458
+ settlePendingImperativeScroll(state);
459
+ }
460
+
439
461
  // src/core/deferredPublicOnScroll.ts
440
462
  function withResolvedContentOffset(state, event, resolvedOffset) {
441
463
  return {
@@ -943,6 +965,24 @@ function clearPreservedInitialScrollTarget(state) {
943
965
  state.initialScroll = void 0;
944
966
  setInitialScrollSession(state);
945
967
  }
968
+ function supersedeInitialScroll(ctx) {
969
+ var _a3, _b, _c;
970
+ const state = ctx.state;
971
+ const bootstrapInitialScroll = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
972
+ if (state.initialScroll || bootstrapInitialScroll || ((_b = state.scrollingTo) == null ? void 0 : _b.isInitialScroll)) {
973
+ if ((bootstrapInitialScroll == null ? void 0 : bootstrapInitialScroll.frameHandle) !== void 0 && typeof cancelAnimationFrame === "function") {
974
+ cancelAnimationFrame(bootstrapInitialScroll.frameHandle);
975
+ }
976
+ if ((_c = state.scrollingTo) == null ? void 0 : _c.isInitialScroll) {
977
+ cancelScrollCompletionChecks(state);
978
+ state.scrollingTo = void 0;
979
+ state.scrollTargetPinnedRange = void 0;
980
+ }
981
+ initialScrollCompletion.resetFlags(state);
982
+ setInitialScrollSession(state, { bootstrap: null });
983
+ finishInitialScroll(ctx);
984
+ }
985
+ }
946
986
  function finishInitialScroll(ctx, options) {
947
987
  var _a3, _b, _c;
948
988
  const state = ctx.state;
@@ -1258,29 +1298,6 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
1258
1298
  return clampedOffset;
1259
1299
  }
1260
1300
 
1261
- // src/core/cancelImperativeScroll.ts
1262
- function cancelScrollCompletionChecks({ scheduledWork }) {
1263
- scheduledWork.cancel("checkFinishedScrollFrame");
1264
- scheduledWork.cancel("checkFinishedScrollRetryFrame");
1265
- scheduledWork.cancel("checkFinishedScrollFallback");
1266
- scheduledWork.cancel("platformScrollCompletion");
1267
- }
1268
- function settlePendingImperativeScroll(state) {
1269
- var _a3, _b;
1270
- const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
1271
- state.pendingScrollResolve = void 0;
1272
- state.pendingScrollToEnd = void 0;
1273
- resolvePendingScroll == null ? void 0 : resolvePendingScroll();
1274
- }
1275
- function cancelImperativeScroll(state) {
1276
- cancelScrollCompletionChecks(state);
1277
- state.scheduledWork.cancel("imperativeScrollReady");
1278
- state.runPendingScrollToEnd = void 0;
1279
- state.scrollingTo = void 0;
1280
- state.scrollTargetPinnedRange = void 0;
1281
- settlePendingImperativeScroll(state);
1282
- }
1283
-
1284
1301
  // src/core/finishScrollTo.ts
1285
1302
  function finishScrollTo(ctx) {
1286
1303
  var _a3, _b;
@@ -4812,7 +4829,7 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
4812
4829
  if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
4813
4830
  needsRecalculate = true;
4814
4831
  }
4815
- if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
4832
+ if (prevSizeKnown === void 0 || Math.abs(prevSizeKnown - size) > 5) {
4816
4833
  shouldMaintainScrollAtEnd = true;
4817
4834
  }
4818
4835
  onItemSizeChanged == null ? void 0 : onItemSizeChanged({
@@ -5662,13 +5679,11 @@ var ContainerSlot = typedMemo(function ContainerSlot2(props) {
5662
5679
  return /* @__PURE__ */ React2.createElement(ContainerSlotBase, { ...props });
5663
5680
  });
5664
5681
  function useFreshDataTransitionVisibility(readyToRender, transitionEpoch) {
5665
- const completedTransitionEpoch = useRef(transitionEpoch);
5666
- const isTransitionPending = completedTransitionEpoch.current !== transitionEpoch;
5682
+ const [completedTransitionEpoch, setCompletedTransitionEpoch] = useState(transitionEpoch);
5683
+ const isTransitionPending = completedTransitionEpoch !== transitionEpoch;
5667
5684
  useLayoutEffect(() => {
5668
- if (!readyToRender) {
5669
- completedTransitionEpoch.current = transitionEpoch;
5670
- }
5671
- }, [readyToRender, transitionEpoch]);
5685
+ setCompletedTransitionEpoch(transitionEpoch);
5686
+ }, [transitionEpoch]);
5672
5687
  return readyToRender && !isTransitionPending;
5673
5688
  }
5674
5689
 
@@ -6381,7 +6396,8 @@ var ScheduledWork = class {
6381
6396
  const work = this.work.get(key);
6382
6397
  if (work) {
6383
6398
  this.work.delete(key);
6384
- work[1](work[0]);
6399
+ const [handle, cancel] = work;
6400
+ cancel(handle);
6385
6401
  }
6386
6402
  }
6387
6403
  has(key) {
@@ -6634,6 +6650,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
6634
6650
  };
6635
6651
  const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
6636
6652
  const token = startImperativeScroll(resolve);
6653
+ supersedeInitialScroll(ctx);
6637
6654
  runScrollRequest(token, resolve, run, isReady);
6638
6655
  });
6639
6656
  state.runPendingScrollToEnd = () => {
@@ -6760,9 +6777,9 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
6760
6777
  resolve,
6761
6778
  token
6762
6779
  };
6763
- if (scheduleImperativeScrollCommit) {
6764
- scheduleImperativeScrollCommit();
6765
- } else {
6780
+ scheduleImperativeScrollCommit == null ? void 0 : scheduleImperativeScrollCommit();
6781
+ supersedeInitialScroll(ctx);
6782
+ if (!scheduleImperativeScrollCommit) {
6766
6783
  (_a3 = state.runPendingScrollToEnd) == null ? void 0 : _a3.call(state);
6767
6784
  }
6768
6785
  }),
@@ -434,6 +434,28 @@ var EDGE_POSITION_EPSILON = 1;
434
434
  var ENABLE_DEVMODE = IS_DEV && false;
435
435
  var ENABLE_DEBUG_VIEW = IS_DEV && false;
436
436
 
437
+ // src/core/cancelImperativeScroll.ts
438
+ function cancelScrollCompletionChecks({ scheduledWork }) {
439
+ scheduledWork.cancel("checkFinishedScrollFrame");
440
+ scheduledWork.cancel("checkFinishedScrollRetryFrame");
441
+ scheduledWork.cancel("checkFinishedScrollFallback");
442
+ scheduledWork.cancel("platformScrollCompletion");
443
+ }
444
+ function settlePendingImperativeScroll(state) {
445
+ var _a3, _b;
446
+ const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
447
+ state.pendingScrollResolve = void 0;
448
+ state.pendingScrollToEnd = void 0;
449
+ resolvePendingScroll == null ? void 0 : resolvePendingScroll();
450
+ }
451
+ function cancelImperativeScroll(state) {
452
+ cancelScrollCompletionChecks(state);
453
+ state.scheduledWork.cancel("imperativeScrollReady");
454
+ state.scrollingTo = void 0;
455
+ state.scrollTargetPinnedRange = void 0;
456
+ settlePendingImperativeScroll(state);
457
+ }
458
+
437
459
  // src/core/deferredPublicOnScroll.ts
438
460
  function withResolvedContentOffset(state, event, resolvedOffset) {
439
461
  return {
@@ -935,6 +957,24 @@ function clearPreservedInitialScrollTarget(state) {
935
957
  state.initialScroll = void 0;
936
958
  setInitialScrollSession(state);
937
959
  }
960
+ function supersedeInitialScroll(ctx) {
961
+ var _a3, _b, _c;
962
+ const state = ctx.state;
963
+ const bootstrapInitialScroll = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
964
+ if (state.initialScroll || bootstrapInitialScroll || ((_b = state.scrollingTo) == null ? void 0 : _b.isInitialScroll)) {
965
+ if ((bootstrapInitialScroll == null ? void 0 : bootstrapInitialScroll.frameHandle) !== void 0 && typeof cancelAnimationFrame === "function") {
966
+ cancelAnimationFrame(bootstrapInitialScroll.frameHandle);
967
+ }
968
+ if ((_c = state.scrollingTo) == null ? void 0 : _c.isInitialScroll) {
969
+ cancelScrollCompletionChecks(state);
970
+ state.scrollingTo = void 0;
971
+ state.scrollTargetPinnedRange = void 0;
972
+ }
973
+ initialScrollCompletion.resetFlags(state);
974
+ setInitialScrollSession(state, { bootstrap: null });
975
+ finishInitialScroll(ctx);
976
+ }
977
+ }
938
978
  function finishInitialScroll(ctx, options) {
939
979
  var _a3, _b, _c;
940
980
  const state = ctx.state;
@@ -1248,29 +1288,6 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
1248
1288
  return clampedOffset;
1249
1289
  }
1250
1290
 
1251
- // src/core/cancelImperativeScroll.ts
1252
- function cancelScrollCompletionChecks({ scheduledWork }) {
1253
- scheduledWork.cancel("checkFinishedScrollFrame");
1254
- scheduledWork.cancel("checkFinishedScrollRetryFrame");
1255
- scheduledWork.cancel("checkFinishedScrollFallback");
1256
- scheduledWork.cancel("platformScrollCompletion");
1257
- }
1258
- function settlePendingImperativeScroll(state) {
1259
- var _a3, _b;
1260
- const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
1261
- state.pendingScrollResolve = void 0;
1262
- state.pendingScrollToEnd = void 0;
1263
- resolvePendingScroll == null ? void 0 : resolvePendingScroll();
1264
- }
1265
- function cancelImperativeScroll(state) {
1266
- cancelScrollCompletionChecks(state);
1267
- state.scheduledWork.cancel("imperativeScrollReady");
1268
- state.runPendingScrollToEnd = void 0;
1269
- state.scrollingTo = void 0;
1270
- state.scrollTargetPinnedRange = void 0;
1271
- settlePendingImperativeScroll(state);
1272
- }
1273
-
1274
1291
  // src/core/finishScrollTo.ts
1275
1292
  function finishScrollTo(ctx) {
1276
1293
  var _a3, _b;
@@ -4850,7 +4867,7 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
4850
4867
  if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
4851
4868
  needsRecalculate = true;
4852
4869
  }
4853
- if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
4870
+ if (prevSizeKnown === void 0 || Math.abs(prevSizeKnown - size) > 5) {
4854
4871
  shouldMaintainScrollAtEnd = true;
4855
4872
  }
4856
4873
  onItemSizeChanged == null ? void 0 : onItemSizeChanged({
@@ -5750,13 +5767,11 @@ function useDOMOrder(ref) {
5750
5767
  }, [ctx]);
5751
5768
  }
5752
5769
  function useFreshDataTransitionVisibility(readyToRender, transitionEpoch) {
5753
- const completedTransitionEpoch = React3.useRef(transitionEpoch);
5754
- const isTransitionPending = completedTransitionEpoch.current !== transitionEpoch;
5770
+ const [completedTransitionEpoch, setCompletedTransitionEpoch] = React3.useState(transitionEpoch);
5771
+ const isTransitionPending = completedTransitionEpoch !== transitionEpoch;
5755
5772
  React3.useLayoutEffect(() => {
5756
- if (!readyToRender) {
5757
- completedTransitionEpoch.current = transitionEpoch;
5758
- }
5759
- }, [readyToRender, transitionEpoch]);
5773
+ setCompletedTransitionEpoch(transitionEpoch);
5774
+ }, [transitionEpoch]);
5760
5775
  return readyToRender && !isTransitionPending;
5761
5776
  }
5762
5777
 
@@ -6397,10 +6412,9 @@ function ScrollAdjust() {
6397
6412
  const lastScrollOffsetRef = React3__namespace.useRef(0);
6398
6413
  const lastScrollAdjustUserOffsetRef = React3__namespace.useRef(0);
6399
6414
  const resetPaddingRafRef = React3__namespace.useRef(void 0);
6400
- const resetPaddingBaselineRef = React3__namespace.useRef(void 0);
6415
+ const temporaryPaddingRef = React3__namespace.useRef(void 0);
6401
6416
  const contentNodeRef = React3__namespace.useRef(null);
6402
6417
  const callback = React3__namespace.useCallback(() => {
6403
- var _a3;
6404
6418
  const scrollAdjust = peek$(ctx, "scrollAdjust");
6405
6419
  const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
6406
6420
  const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
@@ -6424,19 +6438,28 @@ function ScrollAdjust() {
6424
6438
  const nextScroll = currentScroll + scrollDelta;
6425
6439
  const needsTemporaryPadding = scrollDelta > 0 && !ctx.state.adjustingFromInitialMount && totalSize < nextScroll + viewportSize;
6426
6440
  if (needsTemporaryPadding) {
6427
- const previousPaddingEnd = (_a3 = resetPaddingBaselineRef.current) != null ? _a3 : contentNode.style[axis.paddingEndProp];
6428
- resetPaddingBaselineRef.current = previousPaddingEnd;
6441
+ const currentInlinePaddingEnd = contentNode.style[axis.paddingEndProp];
6442
+ const previousTemporaryPadding = temporaryPaddingRef.current;
6443
+ const baselinePaddingEnd = (previousTemporaryPadding == null ? void 0 : previousTemporaryPadding.value) === currentInlinePaddingEnd ? previousTemporaryPadding.baseline : currentInlinePaddingEnd;
6429
6444
  const pad = (nextScroll + viewportSize - totalSize) * 2;
6430
- contentNode.style[axis.paddingEndProp] = `${pad}px`;
6445
+ const currentPaddingEnd = Number.parseFloat(
6446
+ window.getComputedStyle(contentNode)[axis.paddingEndProp]
6447
+ );
6448
+ const temporaryPaddingEnd = `${(currentPaddingEnd || 0) + pad}px`;
6449
+ temporaryPaddingRef.current = { baseline: baselinePaddingEnd, value: temporaryPaddingEnd };
6450
+ contentNode.style[axis.paddingEndProp] = temporaryPaddingEnd;
6431
6451
  void contentNode.offsetHeight;
6432
6452
  scrollBy();
6433
6453
  if (resetPaddingRafRef.current !== void 0) {
6434
6454
  cancelAnimationFrame(resetPaddingRafRef.current);
6435
6455
  }
6436
6456
  resetPaddingRafRef.current = requestAnimationFrame(() => {
6457
+ const temporaryPadding = temporaryPaddingRef.current;
6437
6458
  resetPaddingRafRef.current = void 0;
6438
- resetPaddingBaselineRef.current = void 0;
6439
- contentNode.style[axis.paddingEndProp] = previousPaddingEnd;
6459
+ temporaryPaddingRef.current = void 0;
6460
+ if (contentNode.style[axis.paddingEndProp] === (temporaryPadding == null ? void 0 : temporaryPadding.value)) {
6461
+ contentNode.style[axis.paddingEndProp] = temporaryPadding.baseline;
6462
+ }
6440
6463
  });
6441
6464
  } else {
6442
6465
  scrollBy();
@@ -7054,7 +7077,8 @@ var ScheduledWork = class {
7054
7077
  const work = this.work.get(key);
7055
7078
  if (work) {
7056
7079
  this.work.delete(key);
7057
- work[1](work[0]);
7080
+ const [handle, cancel] = work;
7081
+ cancel(handle);
7058
7082
  }
7059
7083
  }
7060
7084
  has(key) {
@@ -7291,6 +7315,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
7291
7315
  };
7292
7316
  const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
7293
7317
  const token = startImperativeScroll(resolve);
7318
+ supersedeInitialScroll(ctx);
7294
7319
  runScrollRequest(token, resolve, run, isReady);
7295
7320
  });
7296
7321
  state.runPendingScrollToEnd = () => {
@@ -7417,9 +7442,9 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
7417
7442
  resolve,
7418
7443
  token
7419
7444
  };
7420
- if (scheduleImperativeScrollCommit) {
7421
- scheduleImperativeScrollCommit();
7422
- } else {
7445
+ scheduleImperativeScrollCommit == null ? void 0 : scheduleImperativeScrollCommit();
7446
+ supersedeInitialScroll(ctx);
7447
+ if (!scheduleImperativeScrollCommit) {
7423
7448
  (_a3 = state.runPendingScrollToEnd) == null ? void 0 : _a3.call(state);
7424
7449
  }
7425
7450
  }),
@@ -413,6 +413,28 @@ var EDGE_POSITION_EPSILON = 1;
413
413
  var ENABLE_DEVMODE = IS_DEV && false;
414
414
  var ENABLE_DEBUG_VIEW = IS_DEV && false;
415
415
 
416
+ // src/core/cancelImperativeScroll.ts
417
+ function cancelScrollCompletionChecks({ scheduledWork }) {
418
+ scheduledWork.cancel("checkFinishedScrollFrame");
419
+ scheduledWork.cancel("checkFinishedScrollRetryFrame");
420
+ scheduledWork.cancel("checkFinishedScrollFallback");
421
+ scheduledWork.cancel("platformScrollCompletion");
422
+ }
423
+ function settlePendingImperativeScroll(state) {
424
+ var _a3, _b;
425
+ const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
426
+ state.pendingScrollResolve = void 0;
427
+ state.pendingScrollToEnd = void 0;
428
+ resolvePendingScroll == null ? void 0 : resolvePendingScroll();
429
+ }
430
+ function cancelImperativeScroll(state) {
431
+ cancelScrollCompletionChecks(state);
432
+ state.scheduledWork.cancel("imperativeScrollReady");
433
+ state.scrollingTo = void 0;
434
+ state.scrollTargetPinnedRange = void 0;
435
+ settlePendingImperativeScroll(state);
436
+ }
437
+
416
438
  // src/core/deferredPublicOnScroll.ts
417
439
  function withResolvedContentOffset(state, event, resolvedOffset) {
418
440
  return {
@@ -914,6 +936,24 @@ function clearPreservedInitialScrollTarget(state) {
914
936
  state.initialScroll = void 0;
915
937
  setInitialScrollSession(state);
916
938
  }
939
+ function supersedeInitialScroll(ctx) {
940
+ var _a3, _b, _c;
941
+ const state = ctx.state;
942
+ const bootstrapInitialScroll = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
943
+ if (state.initialScroll || bootstrapInitialScroll || ((_b = state.scrollingTo) == null ? void 0 : _b.isInitialScroll)) {
944
+ if ((bootstrapInitialScroll == null ? void 0 : bootstrapInitialScroll.frameHandle) !== void 0 && typeof cancelAnimationFrame === "function") {
945
+ cancelAnimationFrame(bootstrapInitialScroll.frameHandle);
946
+ }
947
+ if ((_c = state.scrollingTo) == null ? void 0 : _c.isInitialScroll) {
948
+ cancelScrollCompletionChecks(state);
949
+ state.scrollingTo = void 0;
950
+ state.scrollTargetPinnedRange = void 0;
951
+ }
952
+ initialScrollCompletion.resetFlags(state);
953
+ setInitialScrollSession(state, { bootstrap: null });
954
+ finishInitialScroll(ctx);
955
+ }
956
+ }
917
957
  function finishInitialScroll(ctx, options) {
918
958
  var _a3, _b, _c;
919
959
  const state = ctx.state;
@@ -1227,29 +1267,6 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
1227
1267
  return clampedOffset;
1228
1268
  }
1229
1269
 
1230
- // src/core/cancelImperativeScroll.ts
1231
- function cancelScrollCompletionChecks({ scheduledWork }) {
1232
- scheduledWork.cancel("checkFinishedScrollFrame");
1233
- scheduledWork.cancel("checkFinishedScrollRetryFrame");
1234
- scheduledWork.cancel("checkFinishedScrollFallback");
1235
- scheduledWork.cancel("platformScrollCompletion");
1236
- }
1237
- function settlePendingImperativeScroll(state) {
1238
- var _a3, _b;
1239
- const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
1240
- state.pendingScrollResolve = void 0;
1241
- state.pendingScrollToEnd = void 0;
1242
- resolvePendingScroll == null ? void 0 : resolvePendingScroll();
1243
- }
1244
- function cancelImperativeScroll(state) {
1245
- cancelScrollCompletionChecks(state);
1246
- state.scheduledWork.cancel("imperativeScrollReady");
1247
- state.runPendingScrollToEnd = void 0;
1248
- state.scrollingTo = void 0;
1249
- state.scrollTargetPinnedRange = void 0;
1250
- settlePendingImperativeScroll(state);
1251
- }
1252
-
1253
1270
  // src/core/finishScrollTo.ts
1254
1271
  function finishScrollTo(ctx) {
1255
1272
  var _a3, _b;
@@ -4829,7 +4846,7 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
4829
4846
  if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
4830
4847
  needsRecalculate = true;
4831
4848
  }
4832
- if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
4849
+ if (prevSizeKnown === void 0 || Math.abs(prevSizeKnown - size) > 5) {
4833
4850
  shouldMaintainScrollAtEnd = true;
4834
4851
  }
4835
4852
  onItemSizeChanged == null ? void 0 : onItemSizeChanged({
@@ -5729,13 +5746,11 @@ function useDOMOrder(ref) {
5729
5746
  }, [ctx]);
5730
5747
  }
5731
5748
  function useFreshDataTransitionVisibility(readyToRender, transitionEpoch) {
5732
- const completedTransitionEpoch = useRef(transitionEpoch);
5733
- const isTransitionPending = completedTransitionEpoch.current !== transitionEpoch;
5749
+ const [completedTransitionEpoch, setCompletedTransitionEpoch] = useState(transitionEpoch);
5750
+ const isTransitionPending = completedTransitionEpoch !== transitionEpoch;
5734
5751
  useLayoutEffect(() => {
5735
- if (!readyToRender) {
5736
- completedTransitionEpoch.current = transitionEpoch;
5737
- }
5738
- }, [readyToRender, transitionEpoch]);
5752
+ setCompletedTransitionEpoch(transitionEpoch);
5753
+ }, [transitionEpoch]);
5739
5754
  return readyToRender && !isTransitionPending;
5740
5755
  }
5741
5756
 
@@ -6376,10 +6391,9 @@ function ScrollAdjust() {
6376
6391
  const lastScrollOffsetRef = React3.useRef(0);
6377
6392
  const lastScrollAdjustUserOffsetRef = React3.useRef(0);
6378
6393
  const resetPaddingRafRef = React3.useRef(void 0);
6379
- const resetPaddingBaselineRef = React3.useRef(void 0);
6394
+ const temporaryPaddingRef = React3.useRef(void 0);
6380
6395
  const contentNodeRef = React3.useRef(null);
6381
6396
  const callback = React3.useCallback(() => {
6382
- var _a3;
6383
6397
  const scrollAdjust = peek$(ctx, "scrollAdjust");
6384
6398
  const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
6385
6399
  const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
@@ -6403,19 +6417,28 @@ function ScrollAdjust() {
6403
6417
  const nextScroll = currentScroll + scrollDelta;
6404
6418
  const needsTemporaryPadding = scrollDelta > 0 && !ctx.state.adjustingFromInitialMount && totalSize < nextScroll + viewportSize;
6405
6419
  if (needsTemporaryPadding) {
6406
- const previousPaddingEnd = (_a3 = resetPaddingBaselineRef.current) != null ? _a3 : contentNode.style[axis.paddingEndProp];
6407
- resetPaddingBaselineRef.current = previousPaddingEnd;
6420
+ const currentInlinePaddingEnd = contentNode.style[axis.paddingEndProp];
6421
+ const previousTemporaryPadding = temporaryPaddingRef.current;
6422
+ const baselinePaddingEnd = (previousTemporaryPadding == null ? void 0 : previousTemporaryPadding.value) === currentInlinePaddingEnd ? previousTemporaryPadding.baseline : currentInlinePaddingEnd;
6408
6423
  const pad = (nextScroll + viewportSize - totalSize) * 2;
6409
- contentNode.style[axis.paddingEndProp] = `${pad}px`;
6424
+ const currentPaddingEnd = Number.parseFloat(
6425
+ window.getComputedStyle(contentNode)[axis.paddingEndProp]
6426
+ );
6427
+ const temporaryPaddingEnd = `${(currentPaddingEnd || 0) + pad}px`;
6428
+ temporaryPaddingRef.current = { baseline: baselinePaddingEnd, value: temporaryPaddingEnd };
6429
+ contentNode.style[axis.paddingEndProp] = temporaryPaddingEnd;
6410
6430
  void contentNode.offsetHeight;
6411
6431
  scrollBy();
6412
6432
  if (resetPaddingRafRef.current !== void 0) {
6413
6433
  cancelAnimationFrame(resetPaddingRafRef.current);
6414
6434
  }
6415
6435
  resetPaddingRafRef.current = requestAnimationFrame(() => {
6436
+ const temporaryPadding = temporaryPaddingRef.current;
6416
6437
  resetPaddingRafRef.current = void 0;
6417
- resetPaddingBaselineRef.current = void 0;
6418
- contentNode.style[axis.paddingEndProp] = previousPaddingEnd;
6438
+ temporaryPaddingRef.current = void 0;
6439
+ if (contentNode.style[axis.paddingEndProp] === (temporaryPadding == null ? void 0 : temporaryPadding.value)) {
6440
+ contentNode.style[axis.paddingEndProp] = temporaryPadding.baseline;
6441
+ }
6419
6442
  });
6420
6443
  } else {
6421
6444
  scrollBy();
@@ -7033,7 +7056,8 @@ var ScheduledWork = class {
7033
7056
  const work = this.work.get(key);
7034
7057
  if (work) {
7035
7058
  this.work.delete(key);
7036
- work[1](work[0]);
7059
+ const [handle, cancel] = work;
7060
+ cancel(handle);
7037
7061
  }
7038
7062
  }
7039
7063
  has(key) {
@@ -7270,6 +7294,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
7270
7294
  };
7271
7295
  const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
7272
7296
  const token = startImperativeScroll(resolve);
7297
+ supersedeInitialScroll(ctx);
7273
7298
  runScrollRequest(token, resolve, run, isReady);
7274
7299
  });
7275
7300
  state.runPendingScrollToEnd = () => {
@@ -7396,9 +7421,9 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
7396
7421
  resolve,
7397
7422
  token
7398
7423
  };
7399
- if (scheduleImperativeScrollCommit) {
7400
- scheduleImperativeScrollCommit();
7401
- } else {
7424
+ scheduleImperativeScrollCommit == null ? void 0 : scheduleImperativeScrollCommit();
7425
+ supersedeInitialScroll(ctx);
7426
+ if (!scheduleImperativeScrollCommit) {
7402
7427
  (_a3 = state.runPendingScrollToEnd) == null ? void 0 : _a3.call(state);
7403
7428
  }
7404
7429
  }),
package/react.js CHANGED
@@ -434,6 +434,28 @@ var EDGE_POSITION_EPSILON = 1;
434
434
  var ENABLE_DEVMODE = IS_DEV && false;
435
435
  var ENABLE_DEBUG_VIEW = IS_DEV && false;
436
436
 
437
+ // src/core/cancelImperativeScroll.ts
438
+ function cancelScrollCompletionChecks({ scheduledWork }) {
439
+ scheduledWork.cancel("checkFinishedScrollFrame");
440
+ scheduledWork.cancel("checkFinishedScrollRetryFrame");
441
+ scheduledWork.cancel("checkFinishedScrollFallback");
442
+ scheduledWork.cancel("platformScrollCompletion");
443
+ }
444
+ function settlePendingImperativeScroll(state) {
445
+ var _a3, _b;
446
+ const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
447
+ state.pendingScrollResolve = void 0;
448
+ state.pendingScrollToEnd = void 0;
449
+ resolvePendingScroll == null ? void 0 : resolvePendingScroll();
450
+ }
451
+ function cancelImperativeScroll(state) {
452
+ cancelScrollCompletionChecks(state);
453
+ state.scheduledWork.cancel("imperativeScrollReady");
454
+ state.scrollingTo = void 0;
455
+ state.scrollTargetPinnedRange = void 0;
456
+ settlePendingImperativeScroll(state);
457
+ }
458
+
437
459
  // src/core/deferredPublicOnScroll.ts
438
460
  function withResolvedContentOffset(state, event, resolvedOffset) {
439
461
  return {
@@ -935,6 +957,24 @@ function clearPreservedInitialScrollTarget(state) {
935
957
  state.initialScroll = void 0;
936
958
  setInitialScrollSession(state);
937
959
  }
960
+ function supersedeInitialScroll(ctx) {
961
+ var _a3, _b, _c;
962
+ const state = ctx.state;
963
+ const bootstrapInitialScroll = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
964
+ if (state.initialScroll || bootstrapInitialScroll || ((_b = state.scrollingTo) == null ? void 0 : _b.isInitialScroll)) {
965
+ if ((bootstrapInitialScroll == null ? void 0 : bootstrapInitialScroll.frameHandle) !== void 0 && typeof cancelAnimationFrame === "function") {
966
+ cancelAnimationFrame(bootstrapInitialScroll.frameHandle);
967
+ }
968
+ if ((_c = state.scrollingTo) == null ? void 0 : _c.isInitialScroll) {
969
+ cancelScrollCompletionChecks(state);
970
+ state.scrollingTo = void 0;
971
+ state.scrollTargetPinnedRange = void 0;
972
+ }
973
+ initialScrollCompletion.resetFlags(state);
974
+ setInitialScrollSession(state, { bootstrap: null });
975
+ finishInitialScroll(ctx);
976
+ }
977
+ }
938
978
  function finishInitialScroll(ctx, options) {
939
979
  var _a3, _b, _c;
940
980
  const state = ctx.state;
@@ -1248,29 +1288,6 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
1248
1288
  return clampedOffset;
1249
1289
  }
1250
1290
 
1251
- // src/core/cancelImperativeScroll.ts
1252
- function cancelScrollCompletionChecks({ scheduledWork }) {
1253
- scheduledWork.cancel("checkFinishedScrollFrame");
1254
- scheduledWork.cancel("checkFinishedScrollRetryFrame");
1255
- scheduledWork.cancel("checkFinishedScrollFallback");
1256
- scheduledWork.cancel("platformScrollCompletion");
1257
- }
1258
- function settlePendingImperativeScroll(state) {
1259
- var _a3, _b;
1260
- const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
1261
- state.pendingScrollResolve = void 0;
1262
- state.pendingScrollToEnd = void 0;
1263
- resolvePendingScroll == null ? void 0 : resolvePendingScroll();
1264
- }
1265
- function cancelImperativeScroll(state) {
1266
- cancelScrollCompletionChecks(state);
1267
- state.scheduledWork.cancel("imperativeScrollReady");
1268
- state.runPendingScrollToEnd = void 0;
1269
- state.scrollingTo = void 0;
1270
- state.scrollTargetPinnedRange = void 0;
1271
- settlePendingImperativeScroll(state);
1272
- }
1273
-
1274
1291
  // src/core/finishScrollTo.ts
1275
1292
  function finishScrollTo(ctx) {
1276
1293
  var _a3, _b;
@@ -4850,7 +4867,7 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
4850
4867
  if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
4851
4868
  needsRecalculate = true;
4852
4869
  }
4853
- if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
4870
+ if (prevSizeKnown === void 0 || Math.abs(prevSizeKnown - size) > 5) {
4854
4871
  shouldMaintainScrollAtEnd = true;
4855
4872
  }
4856
4873
  onItemSizeChanged == null ? void 0 : onItemSizeChanged({
@@ -5750,13 +5767,11 @@ function useDOMOrder(ref) {
5750
5767
  }, [ctx]);
5751
5768
  }
5752
5769
  function useFreshDataTransitionVisibility(readyToRender, transitionEpoch) {
5753
- const completedTransitionEpoch = React3.useRef(transitionEpoch);
5754
- const isTransitionPending = completedTransitionEpoch.current !== transitionEpoch;
5770
+ const [completedTransitionEpoch, setCompletedTransitionEpoch] = React3.useState(transitionEpoch);
5771
+ const isTransitionPending = completedTransitionEpoch !== transitionEpoch;
5755
5772
  React3.useLayoutEffect(() => {
5756
- if (!readyToRender) {
5757
- completedTransitionEpoch.current = transitionEpoch;
5758
- }
5759
- }, [readyToRender, transitionEpoch]);
5773
+ setCompletedTransitionEpoch(transitionEpoch);
5774
+ }, [transitionEpoch]);
5760
5775
  return readyToRender && !isTransitionPending;
5761
5776
  }
5762
5777
 
@@ -6397,10 +6412,9 @@ function ScrollAdjust() {
6397
6412
  const lastScrollOffsetRef = React3__namespace.useRef(0);
6398
6413
  const lastScrollAdjustUserOffsetRef = React3__namespace.useRef(0);
6399
6414
  const resetPaddingRafRef = React3__namespace.useRef(void 0);
6400
- const resetPaddingBaselineRef = React3__namespace.useRef(void 0);
6415
+ const temporaryPaddingRef = React3__namespace.useRef(void 0);
6401
6416
  const contentNodeRef = React3__namespace.useRef(null);
6402
6417
  const callback = React3__namespace.useCallback(() => {
6403
- var _a3;
6404
6418
  const scrollAdjust = peek$(ctx, "scrollAdjust");
6405
6419
  const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
6406
6420
  const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
@@ -6424,19 +6438,28 @@ function ScrollAdjust() {
6424
6438
  const nextScroll = currentScroll + scrollDelta;
6425
6439
  const needsTemporaryPadding = scrollDelta > 0 && !ctx.state.adjustingFromInitialMount && totalSize < nextScroll + viewportSize;
6426
6440
  if (needsTemporaryPadding) {
6427
- const previousPaddingEnd = (_a3 = resetPaddingBaselineRef.current) != null ? _a3 : contentNode.style[axis.paddingEndProp];
6428
- resetPaddingBaselineRef.current = previousPaddingEnd;
6441
+ const currentInlinePaddingEnd = contentNode.style[axis.paddingEndProp];
6442
+ const previousTemporaryPadding = temporaryPaddingRef.current;
6443
+ const baselinePaddingEnd = (previousTemporaryPadding == null ? void 0 : previousTemporaryPadding.value) === currentInlinePaddingEnd ? previousTemporaryPadding.baseline : currentInlinePaddingEnd;
6429
6444
  const pad = (nextScroll + viewportSize - totalSize) * 2;
6430
- contentNode.style[axis.paddingEndProp] = `${pad}px`;
6445
+ const currentPaddingEnd = Number.parseFloat(
6446
+ window.getComputedStyle(contentNode)[axis.paddingEndProp]
6447
+ );
6448
+ const temporaryPaddingEnd = `${(currentPaddingEnd || 0) + pad}px`;
6449
+ temporaryPaddingRef.current = { baseline: baselinePaddingEnd, value: temporaryPaddingEnd };
6450
+ contentNode.style[axis.paddingEndProp] = temporaryPaddingEnd;
6431
6451
  void contentNode.offsetHeight;
6432
6452
  scrollBy();
6433
6453
  if (resetPaddingRafRef.current !== void 0) {
6434
6454
  cancelAnimationFrame(resetPaddingRafRef.current);
6435
6455
  }
6436
6456
  resetPaddingRafRef.current = requestAnimationFrame(() => {
6457
+ const temporaryPadding = temporaryPaddingRef.current;
6437
6458
  resetPaddingRafRef.current = void 0;
6438
- resetPaddingBaselineRef.current = void 0;
6439
- contentNode.style[axis.paddingEndProp] = previousPaddingEnd;
6459
+ temporaryPaddingRef.current = void 0;
6460
+ if (contentNode.style[axis.paddingEndProp] === (temporaryPadding == null ? void 0 : temporaryPadding.value)) {
6461
+ contentNode.style[axis.paddingEndProp] = temporaryPadding.baseline;
6462
+ }
6440
6463
  });
6441
6464
  } else {
6442
6465
  scrollBy();
@@ -7054,7 +7077,8 @@ var ScheduledWork = class {
7054
7077
  const work = this.work.get(key);
7055
7078
  if (work) {
7056
7079
  this.work.delete(key);
7057
- work[1](work[0]);
7080
+ const [handle, cancel] = work;
7081
+ cancel(handle);
7058
7082
  }
7059
7083
  }
7060
7084
  has(key) {
@@ -7291,6 +7315,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
7291
7315
  };
7292
7316
  const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
7293
7317
  const token = startImperativeScroll(resolve);
7318
+ supersedeInitialScroll(ctx);
7294
7319
  runScrollRequest(token, resolve, run, isReady);
7295
7320
  });
7296
7321
  state.runPendingScrollToEnd = () => {
@@ -7417,9 +7442,9 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
7417
7442
  resolve,
7418
7443
  token
7419
7444
  };
7420
- if (scheduleImperativeScrollCommit) {
7421
- scheduleImperativeScrollCommit();
7422
- } else {
7445
+ scheduleImperativeScrollCommit == null ? void 0 : scheduleImperativeScrollCommit();
7446
+ supersedeInitialScroll(ctx);
7447
+ if (!scheduleImperativeScrollCommit) {
7423
7448
  (_a3 = state.runPendingScrollToEnd) == null ? void 0 : _a3.call(state);
7424
7449
  }
7425
7450
  }),
package/react.mjs CHANGED
@@ -413,6 +413,28 @@ var EDGE_POSITION_EPSILON = 1;
413
413
  var ENABLE_DEVMODE = IS_DEV && false;
414
414
  var ENABLE_DEBUG_VIEW = IS_DEV && false;
415
415
 
416
+ // src/core/cancelImperativeScroll.ts
417
+ function cancelScrollCompletionChecks({ scheduledWork }) {
418
+ scheduledWork.cancel("checkFinishedScrollFrame");
419
+ scheduledWork.cancel("checkFinishedScrollRetryFrame");
420
+ scheduledWork.cancel("checkFinishedScrollFallback");
421
+ scheduledWork.cancel("platformScrollCompletion");
422
+ }
423
+ function settlePendingImperativeScroll(state) {
424
+ var _a3, _b;
425
+ const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
426
+ state.pendingScrollResolve = void 0;
427
+ state.pendingScrollToEnd = void 0;
428
+ resolvePendingScroll == null ? void 0 : resolvePendingScroll();
429
+ }
430
+ function cancelImperativeScroll(state) {
431
+ cancelScrollCompletionChecks(state);
432
+ state.scheduledWork.cancel("imperativeScrollReady");
433
+ state.scrollingTo = void 0;
434
+ state.scrollTargetPinnedRange = void 0;
435
+ settlePendingImperativeScroll(state);
436
+ }
437
+
416
438
  // src/core/deferredPublicOnScroll.ts
417
439
  function withResolvedContentOffset(state, event, resolvedOffset) {
418
440
  return {
@@ -914,6 +936,24 @@ function clearPreservedInitialScrollTarget(state) {
914
936
  state.initialScroll = void 0;
915
937
  setInitialScrollSession(state);
916
938
  }
939
+ function supersedeInitialScroll(ctx) {
940
+ var _a3, _b, _c;
941
+ const state = ctx.state;
942
+ const bootstrapInitialScroll = ((_a3 = state.initialScrollSession) == null ? void 0 : _a3.kind) === "bootstrap" ? state.initialScrollSession.bootstrap : void 0;
943
+ if (state.initialScroll || bootstrapInitialScroll || ((_b = state.scrollingTo) == null ? void 0 : _b.isInitialScroll)) {
944
+ if ((bootstrapInitialScroll == null ? void 0 : bootstrapInitialScroll.frameHandle) !== void 0 && typeof cancelAnimationFrame === "function") {
945
+ cancelAnimationFrame(bootstrapInitialScroll.frameHandle);
946
+ }
947
+ if ((_c = state.scrollingTo) == null ? void 0 : _c.isInitialScroll) {
948
+ cancelScrollCompletionChecks(state);
949
+ state.scrollingTo = void 0;
950
+ state.scrollTargetPinnedRange = void 0;
951
+ }
952
+ initialScrollCompletion.resetFlags(state);
953
+ setInitialScrollSession(state, { bootstrap: null });
954
+ finishInitialScroll(ctx);
955
+ }
956
+ }
917
957
  function finishInitialScroll(ctx, options) {
918
958
  var _a3, _b, _c;
919
959
  const state = ctx.state;
@@ -1227,29 +1267,6 @@ function clampScrollOffset(ctx, offset, scrollTarget) {
1227
1267
  return clampedOffset;
1228
1268
  }
1229
1269
 
1230
- // src/core/cancelImperativeScroll.ts
1231
- function cancelScrollCompletionChecks({ scheduledWork }) {
1232
- scheduledWork.cancel("checkFinishedScrollFrame");
1233
- scheduledWork.cancel("checkFinishedScrollRetryFrame");
1234
- scheduledWork.cancel("checkFinishedScrollFallback");
1235
- scheduledWork.cancel("platformScrollCompletion");
1236
- }
1237
- function settlePendingImperativeScroll(state) {
1238
- var _a3, _b;
1239
- const resolvePendingScroll = (_b = state.pendingScrollResolve) != null ? _b : (_a3 = state.pendingScrollToEnd) == null ? void 0 : _a3.resolve;
1240
- state.pendingScrollResolve = void 0;
1241
- state.pendingScrollToEnd = void 0;
1242
- resolvePendingScroll == null ? void 0 : resolvePendingScroll();
1243
- }
1244
- function cancelImperativeScroll(state) {
1245
- cancelScrollCompletionChecks(state);
1246
- state.scheduledWork.cancel("imperativeScrollReady");
1247
- state.runPendingScrollToEnd = void 0;
1248
- state.scrollingTo = void 0;
1249
- state.scrollTargetPinnedRange = void 0;
1250
- settlePendingImperativeScroll(state);
1251
- }
1252
-
1253
1270
  // src/core/finishScrollTo.ts
1254
1271
  function finishScrollTo(ctx) {
1255
1272
  var _a3, _b;
@@ -4829,7 +4846,7 @@ function applyItemSize(ctx, itemKey, sizeObj, resolvedMeasurementItem) {
4829
4846
  if (!needsRecalculate && state.containerItemKeys.has(itemKey)) {
4830
4847
  needsRecalculate = true;
4831
4848
  }
4832
- if (prevSizeKnown !== void 0 && Math.abs(prevSizeKnown - size) > 5) {
4849
+ if (prevSizeKnown === void 0 || Math.abs(prevSizeKnown - size) > 5) {
4833
4850
  shouldMaintainScrollAtEnd = true;
4834
4851
  }
4835
4852
  onItemSizeChanged == null ? void 0 : onItemSizeChanged({
@@ -5729,13 +5746,11 @@ function useDOMOrder(ref) {
5729
5746
  }, [ctx]);
5730
5747
  }
5731
5748
  function useFreshDataTransitionVisibility(readyToRender, transitionEpoch) {
5732
- const completedTransitionEpoch = useRef(transitionEpoch);
5733
- const isTransitionPending = completedTransitionEpoch.current !== transitionEpoch;
5749
+ const [completedTransitionEpoch, setCompletedTransitionEpoch] = useState(transitionEpoch);
5750
+ const isTransitionPending = completedTransitionEpoch !== transitionEpoch;
5734
5751
  useLayoutEffect(() => {
5735
- if (!readyToRender) {
5736
- completedTransitionEpoch.current = transitionEpoch;
5737
- }
5738
- }, [readyToRender, transitionEpoch]);
5752
+ setCompletedTransitionEpoch(transitionEpoch);
5753
+ }, [transitionEpoch]);
5739
5754
  return readyToRender && !isTransitionPending;
5740
5755
  }
5741
5756
 
@@ -6376,10 +6391,9 @@ function ScrollAdjust() {
6376
6391
  const lastScrollOffsetRef = React3.useRef(0);
6377
6392
  const lastScrollAdjustUserOffsetRef = React3.useRef(0);
6378
6393
  const resetPaddingRafRef = React3.useRef(void 0);
6379
- const resetPaddingBaselineRef = React3.useRef(void 0);
6394
+ const temporaryPaddingRef = React3.useRef(void 0);
6380
6395
  const contentNodeRef = React3.useRef(null);
6381
6396
  const callback = React3.useCallback(() => {
6382
- var _a3;
6383
6397
  const scrollAdjust = peek$(ctx, "scrollAdjust");
6384
6398
  const scrollAdjustUserOffset = peek$(ctx, "scrollAdjustUserOffset");
6385
6399
  const scrollOffset = (scrollAdjust || 0) + (scrollAdjustUserOffset || 0);
@@ -6403,19 +6417,28 @@ function ScrollAdjust() {
6403
6417
  const nextScroll = currentScroll + scrollDelta;
6404
6418
  const needsTemporaryPadding = scrollDelta > 0 && !ctx.state.adjustingFromInitialMount && totalSize < nextScroll + viewportSize;
6405
6419
  if (needsTemporaryPadding) {
6406
- const previousPaddingEnd = (_a3 = resetPaddingBaselineRef.current) != null ? _a3 : contentNode.style[axis.paddingEndProp];
6407
- resetPaddingBaselineRef.current = previousPaddingEnd;
6420
+ const currentInlinePaddingEnd = contentNode.style[axis.paddingEndProp];
6421
+ const previousTemporaryPadding = temporaryPaddingRef.current;
6422
+ const baselinePaddingEnd = (previousTemporaryPadding == null ? void 0 : previousTemporaryPadding.value) === currentInlinePaddingEnd ? previousTemporaryPadding.baseline : currentInlinePaddingEnd;
6408
6423
  const pad = (nextScroll + viewportSize - totalSize) * 2;
6409
- contentNode.style[axis.paddingEndProp] = `${pad}px`;
6424
+ const currentPaddingEnd = Number.parseFloat(
6425
+ window.getComputedStyle(contentNode)[axis.paddingEndProp]
6426
+ );
6427
+ const temporaryPaddingEnd = `${(currentPaddingEnd || 0) + pad}px`;
6428
+ temporaryPaddingRef.current = { baseline: baselinePaddingEnd, value: temporaryPaddingEnd };
6429
+ contentNode.style[axis.paddingEndProp] = temporaryPaddingEnd;
6410
6430
  void contentNode.offsetHeight;
6411
6431
  scrollBy();
6412
6432
  if (resetPaddingRafRef.current !== void 0) {
6413
6433
  cancelAnimationFrame(resetPaddingRafRef.current);
6414
6434
  }
6415
6435
  resetPaddingRafRef.current = requestAnimationFrame(() => {
6436
+ const temporaryPadding = temporaryPaddingRef.current;
6416
6437
  resetPaddingRafRef.current = void 0;
6417
- resetPaddingBaselineRef.current = void 0;
6418
- contentNode.style[axis.paddingEndProp] = previousPaddingEnd;
6438
+ temporaryPaddingRef.current = void 0;
6439
+ if (contentNode.style[axis.paddingEndProp] === (temporaryPadding == null ? void 0 : temporaryPadding.value)) {
6440
+ contentNode.style[axis.paddingEndProp] = temporaryPadding.baseline;
6441
+ }
6419
6442
  });
6420
6443
  } else {
6421
6444
  scrollBy();
@@ -7033,7 +7056,8 @@ var ScheduledWork = class {
7033
7056
  const work = this.work.get(key);
7034
7057
  if (work) {
7035
7058
  this.work.delete(key);
7036
- work[1](work[0]);
7059
+ const [handle, cancel] = work;
7060
+ cancel(handle);
7037
7061
  }
7038
7062
  }
7039
7063
  has(key) {
@@ -7270,6 +7294,7 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
7270
7294
  };
7271
7295
  const runScrollWithPromise = (run, isReady = () => true) => new Promise((resolve) => {
7272
7296
  const token = startImperativeScroll(resolve);
7297
+ supersedeInitialScroll(ctx);
7273
7298
  runScrollRequest(token, resolve, run, isReady);
7274
7299
  });
7275
7300
  state.runPendingScrollToEnd = () => {
@@ -7396,9 +7421,9 @@ function createImperativeHandle(ctx, scheduleImperativeScrollCommit) {
7396
7421
  resolve,
7397
7422
  token
7398
7423
  };
7399
- if (scheduleImperativeScrollCommit) {
7400
- scheduleImperativeScrollCommit();
7401
- } else {
7424
+ scheduleImperativeScrollCommit == null ? void 0 : scheduleImperativeScrollCommit();
7425
+ supersedeInitialScroll(ctx);
7426
+ if (!scheduleImperativeScrollCommit) {
7402
7427
  (_a3 = state.runPendingScrollToEnd) == null ? void 0 : _a3.call(state);
7403
7428
  }
7404
7429
  }),