@jsenv/navi 0.29.421 → 0.29.422

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.
@@ -74248,10 +74248,22 @@ const useListScrollSync = ({
74248
74248
  visibleCount: position.visibleCount
74249
74249
  };
74250
74250
  };
74251
- const reportPosition = () => {
74251
+ // A position read at a scroll event is read before the window has drawn what
74252
+ // the scroll brought on screen: the items below the top one can still be
74253
+ // fillers then, and `visibleCount` counts the items drawn. So it is read
74254
+ // again once the screen is better known — a window change on screen, items
74255
+ // landing or resizing — and said again when it reads differently (`ifChanged`):
74256
+ // the same scroll, the screen said right.
74257
+ const announcedRef = useRef(null);
74258
+ const reportPosition = ({
74259
+ ifChanged
74260
+ } = {}) => {
74252
74261
  if (!ref.current) {
74253
74262
  return;
74254
74263
  }
74264
+ if (ifChanged && !announcedRef.current) {
74265
+ return;
74266
+ }
74255
74267
  const remember = rememberScrollRef.current;
74256
74268
  const onScrolledChange = onScrolledChangeRef.current;
74257
74269
  const position = captureListAnchor(remember || Boolean(onScrolledChange));
@@ -74263,6 +74275,10 @@ const useListScrollSync = ({
74263
74275
  return;
74264
74276
  }
74265
74277
  const scrolledNow = toScrolledPosition(position);
74278
+ if (ifChanged && isSamePosition(scrolledNow, announcedRef.current)) {
74279
+ return;
74280
+ }
74281
+ announcedRef.current = scrolledNow;
74266
74282
  if (remember) {
74267
74283
  rememberScrollerPosition(listId, scrolledNow);
74268
74284
  }
@@ -74274,8 +74290,15 @@ const useListScrollSync = ({
74274
74290
  // laid out, its items have arrived, one of them grew. A list read where it
74275
74291
  // opened would otherwise come back with nothing kept — opening again as a
74276
74292
  // fresh arrival does, all of its window drawn in the first commit instead of
74277
- // the items that were on screen. Kept, and told to nobody: nobody scrolled.
74293
+ // the items that were on screen. Kept, and told to nobody while nobody
74294
+ // scrolled; once a position was said, it is said again (see reportPosition).
74278
74295
  const rememberPosition = () => {
74296
+ if (announcedRef.current) {
74297
+ reportPosition({
74298
+ ifChanged: true
74299
+ });
74300
+ return;
74301
+ }
74279
74302
  if (!rememberScrollRef.current || !ref.current) {
74280
74303
  return;
74281
74304
  }
@@ -74768,6 +74791,15 @@ const useListScrollSync = ({
74768
74791
  };
74769
74792
  }, [scrollerElResolved]);
74770
74793
  holdWindow();
74794
+ const {
74795
+ start: windowStart,
74796
+ end: windowEnd
74797
+ } = renderWindowRef.current;
74798
+ useLayoutEffect(() => {
74799
+ reportPosition({
74800
+ ifChanged: true
74801
+ });
74802
+ }, [windowStart, windowEnd]);
74771
74803
  return {
74772
74804
  virtualItemSizeSignal,
74773
74805
  renderWindow: renderWindowRef.current,
@@ -75326,6 +75358,18 @@ const captureScrollAnchor = ({
75326
75358
  }
75327
75359
  return fallbackAnchor;
75328
75360
  };
75361
+ // Two positions handed out say the same thing (see reportPosition): the same
75362
+ // item, as far below the top within a pixel, as many items on screen.
75363
+ const isSamePosition = (a, b) => {
75364
+ if (a.id !== b.id || a.index !== b.index) {
75365
+ return false;
75366
+ }
75367
+ if (a.visibleCount !== b.visibleCount) {
75368
+ return false;
75369
+ }
75370
+ const offsetDelta = a.offset - b.offset;
75371
+ return offsetDelta > -0.5 && offsetDelta < 0.5;
75372
+ };
75329
75373
  // How many of the items from `fromIndex` on start before `to` along the scroll
75330
75374
  // axis — the ones on screen, when `to` is where the view ends.
75331
75375
  const countItemsStartingBefore = (itemEls, fromIndex, to, horizontal) => {
@@ -78047,9 +78091,12 @@ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, Li
78047
78091
  * @param {(scrolled: {id: string, index: number, offset: number, visibleCount: number}) => void} [props.onScrolledChange]
78048
78092
  * Where the list is, as the user scrolls: the item at the top of the view and
78049
78093
  * how far below the place an item lands on its own (see `defaultScrolled`) it
78050
- * starts, and how many items are on screen from that one on. Keep it whole to
78051
- * come back to it later through `scrolled`/`defaultScrolled` — an index alone
78052
- * would not do, since items get inserted while a list is being read.
78094
+ * starts, and how many items are on screen from that one on. Said again for
78095
+ * the same scroll when the screen reads differently once the items it
78096
+ * brought are drawn, or once items landing change what it shows: the last
78097
+ * one said is the one to keep. Keep it whole to come back to it later
78098
+ * through `scrolled`/`defaultScrolled` — an index alone would not do, since
78099
+ * items get inserted while a list is being read.
78053
78100
  * @param {number|string|{initial?: number|string, after?: number|string}} [props.renderBudget="100item"]
78054
78101
  * How much of a `<List.Items>` run is in the DOM at once: the render window,
78055
78102
  * which slides as the user scrolls while fillers hold the room of the items