@jsenv/navi 0.29.514 → 0.29.515

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.
@@ -10568,6 +10568,19 @@ const recallScrollerPosition = (name) => {
10568
10568
  return positionByName.get(name);
10569
10569
  };
10570
10570
 
10571
+ // Said by a scroller sent back to its start while it stays mounted: where it
10572
+ // was is a place in what it no longer shows, so nothing is carried and nothing
10573
+ // is come back to under this address until it says where it is again. What it
10574
+ // said under another address stays, for the way back to that address.
10575
+ const forgetScrollerPosition = (name) => {
10576
+ loadStore();
10577
+ saidByScrollerName.delete(name);
10578
+ const positionByName = scrollerPositionsByUrl.get(readShownUrl());
10579
+ if (positionByName) {
10580
+ positionByName.delete(name);
10581
+ }
10582
+ };
10583
+
10571
10584
  // Said by a scroller as it unmounts. Its page is being left when the url is
10572
10585
  // already another one — the history is written before the page it names is
10573
10586
  // taken down — and then its position is kept for the way back. The url still
@@ -84055,6 +84068,7 @@ const ListUI = props => {
84055
84068
  scroller = "self",
84056
84069
  hoverWhileScrolling = false,
84057
84070
  scrollResetOnNavigation = false,
84071
+ scrollResetKey,
84058
84072
  lockSize,
84059
84073
  columns,
84060
84074
  itemColumns,
@@ -84173,6 +84187,7 @@ const ListUI = props => {
84173
84187
  scrolled,
84174
84188
  defaultScrolled,
84175
84189
  onScrolledChange,
84190
+ scrollResetKey,
84176
84191
  rememberScroll,
84177
84192
  listId: rest.id,
84178
84193
  scroller,
@@ -84504,6 +84519,7 @@ const useListScrollSync = ({
84504
84519
  scrolled,
84505
84520
  defaultScrolled,
84506
84521
  onScrolledChange,
84522
+ scrollResetKey,
84507
84523
  rememberScroll,
84508
84524
  listId,
84509
84525
  scroller,
@@ -84512,6 +84528,8 @@ const useListScrollSync = ({
84512
84528
  columns
84513
84529
  }) => {
84514
84530
  const debugScroll = useDebugScroll();
84531
+ // The offset a search gives back once emptied (see below).
84532
+ const savedScrollRef = useRef(null);
84515
84533
  // Where the list must be: what the caller holds it at (`scrolled`), or where
84516
84534
  // it opens and then lets go (`defaultScrolled`). A `scrolled` that changes is
84517
84535
  // the caller moving the list, so the hold is armed again — that is what makes
@@ -84520,7 +84538,9 @@ const useListScrollSync = ({
84520
84538
  // one kept from the previous visit): followed for as long as nobody has
84521
84539
  // moved the list, and compared by value, since it is said at every render.
84522
84540
  // Nothing to hold it at (a position not saved yet) is not a position: the
84523
- // list opens where it opens.
84541
+ // list opens where it opens. A `scrollResetKey` that changes sends it back to
84542
+ // its start ("back_to_start", see placeBackAtStart), unless a `scrolled`
84543
+ // changing in the same render says where it goes.
84524
84544
  const startPlaceRef = useRef(null);
84525
84545
  if (startPlaceRef.current === null) {
84526
84546
  startPlaceRef.current = {
@@ -84528,6 +84548,7 @@ const useListScrollSync = ({
84528
84548
  wanted: scrolled ?? defaultScrolled,
84529
84549
  scrolled,
84530
84550
  defaultScrolled,
84551
+ scrollResetKey,
84531
84552
  way: null,
84532
84553
  arrived: false,
84533
84554
  // Whether the hold's writes glide (--navi-scroll:smooth).
@@ -84535,6 +84556,20 @@ const useListScrollSync = ({
84535
84556
  };
84536
84557
  } else {
84537
84558
  const place = startPlaceRef.current;
84559
+ if (!compareTwoJsValues(place.scrollResetKey, scrollResetKey)) {
84560
+ place.scrollResetKey = scrollResetKey;
84561
+ place.wanted = "back_to_start";
84562
+ place.userTookOver = false;
84563
+ place.way = null;
84564
+ place.arrived = false;
84565
+ place.smooth = false;
84566
+ // What the list said it was reading, and what a search would give back,
84567
+ // are places in what it no longer shows.
84568
+ savedScrollRef.current = null;
84569
+ if (rememberScroll) {
84570
+ forgetScrollerPosition(listId);
84571
+ }
84572
+ }
84538
84573
  if (place.scrolled !== scrolled) {
84539
84574
  place.scrolled = scrolled;
84540
84575
  place.defaultScrolled = defaultScrolled;
@@ -84543,7 +84578,7 @@ const useListScrollSync = ({
84543
84578
  place.smooth = false;
84544
84579
  } else if ((scrolled === undefined || scrolled === null) && !compareTwoJsValues(place.defaultScrolled, defaultScrolled)) {
84545
84580
  place.defaultScrolled = defaultScrolled;
84546
- if (!place.userTookOver) {
84581
+ if (!place.userTookOver && place.wanted !== "back_to_start") {
84547
84582
  place.wanted = defaultScrolled;
84548
84583
  // Placed again from where it stands: the way to the previous place
84549
84584
  // says nothing about whose the next scrolls are.
@@ -84876,6 +84911,8 @@ const useListScrollSync = ({
84876
84911
  wantedStart = total - windowSize;
84877
84912
  } else if (typeof scrolledWanted === "number") {
84878
84913
  heldItem = scrolledWanted;
84914
+ } else if (scrolledWanted === "back_to_start") {
84915
+ heldItem = 0;
84879
84916
  } else if (scrolledWanted && scrolledWanted.id !== undefined) {
84880
84917
  const itemIndex = listItems.locateItem(scrolledWanted.id);
84881
84918
  if (itemIndex !== null) {
@@ -85110,7 +85147,6 @@ const useListScrollSync = ({
85110
85147
  // Lorsqu'on selectionne quelque chose pendant une recherche, alors ensuite meme si on clear
85111
85148
  // on veut pas revenir a la position scroll précédente car on veut garde l'item qu'on a selectionné visible
85112
85149
  // (pour l'instant pas grave car on travaille pour le mode select qui fermera le dialog au select)
85113
- const savedScrollRef = useRef(null);
85114
85150
  const topMatchScoresKeyRef = useRef("");
85115
85151
  const restoreScrollRafRef = useRef(null);
85116
85152
  useLayoutEffect(() => {
@@ -85219,6 +85255,10 @@ const useListScrollSync = ({
85219
85255
  if (scrolledWanted === "start" || scrolledWanted === undefined || startPlaceRef.current.userTookOver || !ref.current) {
85220
85256
  return;
85221
85257
  }
85258
+ if (scrolledWanted === "back_to_start") {
85259
+ placeBackAtStart();
85260
+ return;
85261
+ }
85222
85262
  if (listItems.totalSignal.peek() === 0 || virtualItemSizeSignal.peek() === 0) {
85223
85263
  return;
85224
85264
  }
@@ -85317,6 +85357,24 @@ const useListScrollSync = ({
85317
85357
  }
85318
85358
  sendHeldScroll(scrollNow + delta);
85319
85359
  };
85360
+ // The start of the list, what comes before its first item included, not an
85361
+ // item: a box of its own goes to 0. A box the list is further down of also
85362
+ // shows what stands above it, the control that asked for this among others, so
85363
+ // the list is brought back to the box's start and never sent forward to it.
85364
+ const placeBackAtStart = () => {
85365
+ const scrollerEl = getScroller();
85366
+ if (ref.current.contains(scrollerEl)) {
85367
+ sendHeldScroll(0);
85368
+ return;
85369
+ }
85370
+ const scale = readScrollerScale(scrollerEl, horizontal);
85371
+ const viewportRect = getScrollerViewportRect(scrollerEl);
85372
+ const listRect = ref.current.getBoundingClientRect();
85373
+ const offsetNow = (horizontal ? listRect.left - viewportRect.left : listRect.top - viewportRect.top) / scale;
85374
+ const delta = offsetNow - getItemScrollInset(scrollerEl, ref.current, horizontal);
85375
+ const scrollNow = horizontal ? scrollerEl.scrollLeft : scrollerEl.scrollTop;
85376
+ sendHeldScroll(delta < 0 ? scrollNow + delta : scrollNow);
85377
+ };
85320
85378
  // Every placement goes through here, the ones that find the list in place
85321
85379
  // too: it keeps the way from where the scroller was to where it is sent,
85322
85380
  // which is how a scroll event tells the hold's own scrolls from anyone
@@ -90034,6 +90092,7 @@ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, Li
90034
90092
  * scroller?: "self" | "parent" | "document" | Element | {current: Element},
90035
90093
  * hoverWhileScrolling?: boolean,
90036
90094
  * scrollResetOnNavigation?: boolean,
90095
+ * scrollResetKey?: any,
90037
90096
  * fallback?: import("preact").ComponentChildren,
90038
90097
  * searchFallback?: import("preact").ComponentChildren,
90039
90098
  * searchText?: string,
@@ -90278,6 +90337,15 @@ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, Li
90278
90337
  * overwrite each other (see docs/scroll.md). A fresh arrival at the page
90279
90338
  * opens at `defaultScrolled` either way, and so does a list the caller holds
90280
90339
  * through `scrolled`.
90340
+ * @param {any} [props.scrollResetKey]
90341
+ * What the list shows, said as a value: another order, another filter. When
90342
+ * it changes after mount (compared by value: `[order, filter]` can be written
90343
+ * at every render) the list goes back to its start before the paint, in
90344
+ * whichever box `scroller` names, and is held there until the user reaches
90345
+ * for it. A list whose start is in view in a box that also shows what stands
90346
+ * above it does not move. A `scrolled` changing in the same render wins. The
90347
+ * position remembered under the `id` for the address shown is dropped; see
90348
+ * docs/scroll.md.
90281
90349
  * @param {boolean} [props.deselectable]
90282
90350
  * A single-select list allowed to hold nothing: the selected item, pressed
90283
90351
  * again, lets go. Without it the list is a radio group — a choice, once