@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.
@@ -72862,10 +72862,22 @@ const useListScrollSync = ({
72862
72862
  visibleCount: position.visibleCount
72863
72863
  };
72864
72864
  };
72865
- const reportPosition = () => {
72865
+ // A position read at a scroll event is read before the window has drawn what
72866
+ // the scroll brought on screen: the items below the top one can still be
72867
+ // fillers then, and `visibleCount` counts the items drawn. So it is read
72868
+ // again once the screen is better known — a window change on screen, items
72869
+ // landing or resizing — and said again when it reads differently (`ifChanged`):
72870
+ // the same scroll, the screen said right.
72871
+ const announcedRef = useRef(null);
72872
+ const reportPosition = ({
72873
+ ifChanged
72874
+ } = {}) => {
72866
72875
  if (!ref.current) {
72867
72876
  return;
72868
72877
  }
72878
+ if (ifChanged && !announcedRef.current) {
72879
+ return;
72880
+ }
72869
72881
  const remember = rememberScrollRef.current;
72870
72882
  const onScrolledChange = onScrolledChangeRef.current;
72871
72883
  const position = captureListAnchor(remember || Boolean(onScrolledChange));
@@ -72877,6 +72889,10 @@ const useListScrollSync = ({
72877
72889
  return;
72878
72890
  }
72879
72891
  const scrolledNow = toScrolledPosition(position);
72892
+ if (ifChanged && isSamePosition(scrolledNow, announcedRef.current)) {
72893
+ return;
72894
+ }
72895
+ announcedRef.current = scrolledNow;
72880
72896
  if (remember) {
72881
72897
  rememberScrollerPosition(listId, scrolledNow);
72882
72898
  }
@@ -72888,8 +72904,15 @@ const useListScrollSync = ({
72888
72904
  // laid out, its items have arrived, one of them grew. A list read where it
72889
72905
  // opened would otherwise come back with nothing kept — opening again as a
72890
72906
  // fresh arrival does, all of its window drawn in the first commit instead of
72891
- // the items that were on screen. Kept, and told to nobody: nobody scrolled.
72907
+ // the items that were on screen. Kept, and told to nobody while nobody
72908
+ // scrolled; once a position was said, it is said again (see reportPosition).
72892
72909
  const rememberPosition = () => {
72910
+ if (announcedRef.current) {
72911
+ reportPosition({
72912
+ ifChanged: true
72913
+ });
72914
+ return;
72915
+ }
72893
72916
  if (!rememberScrollRef.current || !ref.current) {
72894
72917
  return;
72895
72918
  }
@@ -73375,6 +73398,15 @@ const useListScrollSync = ({
73375
73398
  };
73376
73399
  }, [scrollerElResolved]);
73377
73400
  holdWindow();
73401
+ const {
73402
+ start: windowStart,
73403
+ end: windowEnd
73404
+ } = renderWindowRef.current;
73405
+ useLayoutEffect(() => {
73406
+ reportPosition({
73407
+ ifChanged: true
73408
+ });
73409
+ }, [windowStart, windowEnd]);
73378
73410
  return {
73379
73411
  virtualItemSizeSignal,
73380
73412
  renderWindow: renderWindowRef.current,
@@ -73848,6 +73880,18 @@ const captureScrollAnchor = ({
73848
73880
  }
73849
73881
  return fallbackAnchor;
73850
73882
  };
73883
+ // Two positions handed out say the same thing (see reportPosition): the same
73884
+ // item, as far below the top within a pixel, as many items on screen.
73885
+ const isSamePosition = (a, b) => {
73886
+ if (a.id !== b.id || a.index !== b.index) {
73887
+ return false;
73888
+ }
73889
+ if (a.visibleCount !== b.visibleCount) {
73890
+ return false;
73891
+ }
73892
+ const offsetDelta = a.offset - b.offset;
73893
+ return offsetDelta > -0.5 && offsetDelta < 0.5;
73894
+ };
73851
73895
  // How many of the items from `fromIndex` on start before `to` along the scroll
73852
73896
  // axis — the ones on screen, when `to` is where the view ends.
73853
73897
  const countItemsStartingBefore = (itemEls, fromIndex, to, horizontal) => {
@@ -76557,9 +76601,12 @@ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, Li
76557
76601
  * @param {(scrolled: {id: string, index: number, offset: number, visibleCount: number}) => void} [props.onScrolledChange]
76558
76602
  * Where the list is, as the user scrolls: the item at the top of the view and
76559
76603
  * how far below the place an item lands on its own (see `defaultScrolled`) it
76560
- * starts, and how many items are on screen from that one on. Keep it whole to
76561
- * come back to it later through `scrolled`/`defaultScrolled` — an index alone
76562
- * would not do, since items get inserted while a list is being read.
76604
+ * starts, and how many items are on screen from that one on. Said again for
76605
+ * the same scroll when the screen reads differently once the items it
76606
+ * brought are drawn, or once items landing change what it shows: the last
76607
+ * one said is the one to keep. Keep it whole to come back to it later
76608
+ * through `scrolled`/`defaultScrolled` — an index alone would not do, since
76609
+ * items get inserted while a list is being read.
76563
76610
  * @param {number|string|{initial?: number|string, after?: number|string}} [props.renderBudget="100item"]
76564
76611
  * How much of a `<List.Items>` run is in the DOM at once: the render window,
76565
76612
  * which slides as the user scrolls while fillers hold the room of the items