@jsenv/navi 0.29.421 → 0.29.423

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) => {
@@ -74118,9 +74162,12 @@ const readRoomAround = ({
74118
74162
  // too — and an item not drawn is taken to weigh what the drawn items at that
74119
74163
  // edge of the window weigh. Items of one kind come together (the one-line
74120
74164
  // items of the past, the cards ahead), and an item misjudged is weighed again
74121
- // once it is drawn (see "after slide"): weighing it at the average of all
74122
- // items would draw the cards next to one-line items at the one-line size, and
74123
- // a few dozen of them.
74165
+ // once it is drawn (see "after slide"): a window that came up short is
74166
+ // extended on the next frame, from what it measured. Weighing an item not drawn
74167
+ // at the average of all items, or at the smallest an item can be so that the
74168
+ // window never comes up short, walks into the cards at the one-line size,
74169
+ // several at a time — the latter measured in wematch: no blank spared, 50–65 ms
74170
+ // tasks while reading down through the cards.
74124
74171
  const EDGE_SAMPLE_ITEM_COUNT = 8;
74125
74172
  const createItemSizeReader = (items, start, end, itemSize) => {
74126
74173
  const sizeByIndex = new Map();
@@ -76557,9 +76604,12 @@ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, Li
76557
76604
  * @param {(scrolled: {id: string, index: number, offset: number, visibleCount: number}) => void} [props.onScrolledChange]
76558
76605
  * Where the list is, as the user scrolls: the item at the top of the view and
76559
76606
  * 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.
76607
+ * starts, and how many items are on screen from that one on. Said again for
76608
+ * the same scroll when the screen reads differently once the items it
76609
+ * brought are drawn, or once items landing change what it shows: the last
76610
+ * one said is the one to keep. Keep it whole to come back to it later
76611
+ * through `scrolled`/`defaultScrolled` — an index alone would not do, since
76612
+ * items get inserted while a list is being read.
76563
76613
  * @param {number|string|{initial?: number|string, after?: number|string}} [props.renderBudget="100item"]
76564
76614
  * How much of a `<List.Items>` run is in the DOM at once: the render window,
76565
76615
  * which slides as the user scrolls while fillers hold the room of the items
@@ -76590,11 +76640,18 @@ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, Li
76590
76640
  * source for is a page (see `<List.Items pageSize>`), whatever either says,
76591
76641
  * so the first picture costs no second request.
76592
76642
  * @param {number} [props.virtualItemSize]
76593
- * The size of one item along the scroll axis, in px, when every item has the
76594
- * same: what the fillers are sized with and what a scroll position is
76595
- * estimated from. Left out, the list measures its items — once when it
76596
- * mounts, again when a popup around it opens, and after each commit while
76597
- * items are held off screen. Given, it never measures.
76643
+ * The room an item not drawn is held at, in px along the scroll axis: what
76644
+ * the fillers hold for each item outside the render window, what a scroll
76645
+ * position inside them is read with, and the least an item on its way takes
76646
+ * (see `renderSkeleton`). Left out, it is the average of the items measured
76647
+ * so far — once when the list mounts, again when a popup around it opens,
76648
+ * and after each commit while items are held off screen. Given, it is the
76649
+ * worst case: the size every item has, or, in a list whose items differ, the
76650
+ * smallest an item can be (a thread of one-line items and cards: the
76651
+ * one-line size) — an item guessed too small builds one more, an item
76652
+ * guessed too big leaves a blank (see docs/scroll.md, "What the list knows,
76653
+ * and what it guesses"). The items drawn are measured either way: the render
76654
+ * window is sized on them.
76598
76655
  * @param {"self"|"parent"|"document"|Element|{current: Element}} [props.scroller="self"]
76599
76656
  * Which box scrolls — and with it, which box the render window follows and
76600
76657
  * which box a scroll position is read from (`onScrolledChange`). `"self"`