@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.
@@ -10973,6 +10973,19 @@ const recallScrollerPosition = (name) => {
10973
10973
  return positionByName.get(name);
10974
10974
  };
10975
10975
 
10976
+ // Said by a scroller sent back to its start while it stays mounted: where it
10977
+ // was is a place in what it no longer shows, so nothing is carried and nothing
10978
+ // is come back to under this address until it says where it is again. What it
10979
+ // said under another address stays, for the way back to that address.
10980
+ const forgetScrollerPosition = (name) => {
10981
+ loadStore();
10982
+ saidByScrollerName.delete(name);
10983
+ const positionByName = scrollerPositionsByUrl.get(readShownUrl());
10984
+ if (positionByName) {
10985
+ positionByName.delete(name);
10986
+ }
10987
+ };
10988
+
10976
10989
  // Said by a scroller as it unmounts. Its page is being left when the url is
10977
10990
  // already another one — the history is written before the page it names is
10978
10991
  // taken down — and then its position is kept for the way back. The url still
@@ -85860,6 +85873,7 @@ const ListUI = props => {
85860
85873
  scroller = "self",
85861
85874
  hoverWhileScrolling = false,
85862
85875
  scrollResetOnNavigation = false,
85876
+ scrollResetKey,
85863
85877
  lockSize,
85864
85878
  columns,
85865
85879
  itemColumns,
@@ -85978,6 +85992,7 @@ const ListUI = props => {
85978
85992
  scrolled,
85979
85993
  defaultScrolled,
85980
85994
  onScrolledChange,
85995
+ scrollResetKey,
85981
85996
  rememberScroll,
85982
85997
  listId: rest.id,
85983
85998
  scroller,
@@ -86348,6 +86363,7 @@ const useListScrollSync = ({
86348
86363
  scrolled,
86349
86364
  defaultScrolled,
86350
86365
  onScrolledChange,
86366
+ scrollResetKey,
86351
86367
  rememberScroll,
86352
86368
  listId,
86353
86369
  scroller,
@@ -86356,6 +86372,8 @@ const useListScrollSync = ({
86356
86372
  columns
86357
86373
  }) => {
86358
86374
  const debugScroll = useDebugScroll();
86375
+ // The offset a search gives back once emptied (see below).
86376
+ const savedScrollRef = useRef(null);
86359
86377
  // Where the list must be: what the caller holds it at (`scrolled`), or where
86360
86378
  // it opens and then lets go (`defaultScrolled`). A `scrolled` that changes is
86361
86379
  // the caller moving the list, so the hold is armed again — that is what makes
@@ -86364,7 +86382,9 @@ const useListScrollSync = ({
86364
86382
  // one kept from the previous visit): followed for as long as nobody has
86365
86383
  // moved the list, and compared by value, since it is said at every render.
86366
86384
  // Nothing to hold it at (a position not saved yet) is not a position: the
86367
- // list opens where it opens.
86385
+ // list opens where it opens. A `scrollResetKey` that changes sends it back to
86386
+ // its start ("back_to_start", see placeBackAtStart), unless a `scrolled`
86387
+ // changing in the same render says where it goes.
86368
86388
  const startPlaceRef = useRef(null);
86369
86389
  if (startPlaceRef.current === null) {
86370
86390
  startPlaceRef.current = {
@@ -86372,6 +86392,7 @@ const useListScrollSync = ({
86372
86392
  wanted: scrolled ?? defaultScrolled,
86373
86393
  scrolled,
86374
86394
  defaultScrolled,
86395
+ scrollResetKey,
86375
86396
  way: null,
86376
86397
  arrived: false,
86377
86398
  // Whether the hold's writes glide (--navi-scroll:smooth).
@@ -86379,6 +86400,20 @@ const useListScrollSync = ({
86379
86400
  };
86380
86401
  } else {
86381
86402
  const place = startPlaceRef.current;
86403
+ if (!compareTwoJsValues(place.scrollResetKey, scrollResetKey)) {
86404
+ place.scrollResetKey = scrollResetKey;
86405
+ place.wanted = "back_to_start";
86406
+ place.userTookOver = false;
86407
+ place.way = null;
86408
+ place.arrived = false;
86409
+ place.smooth = false;
86410
+ // What the list said it was reading, and what a search would give back,
86411
+ // are places in what it no longer shows.
86412
+ savedScrollRef.current = null;
86413
+ if (rememberScroll) {
86414
+ forgetScrollerPosition(listId);
86415
+ }
86416
+ }
86382
86417
  if (place.scrolled !== scrolled) {
86383
86418
  place.scrolled = scrolled;
86384
86419
  place.defaultScrolled = defaultScrolled;
@@ -86387,7 +86422,7 @@ const useListScrollSync = ({
86387
86422
  place.smooth = false;
86388
86423
  } else if ((scrolled === undefined || scrolled === null) && !compareTwoJsValues(place.defaultScrolled, defaultScrolled)) {
86389
86424
  place.defaultScrolled = defaultScrolled;
86390
- if (!place.userTookOver) {
86425
+ if (!place.userTookOver && place.wanted !== "back_to_start") {
86391
86426
  place.wanted = defaultScrolled;
86392
86427
  // Placed again from where it stands: the way to the previous place
86393
86428
  // says nothing about whose the next scrolls are.
@@ -86731,6 +86766,8 @@ const useListScrollSync = ({
86731
86766
  wantedStart = total - windowSize;
86732
86767
  } else if (typeof scrolledWanted === "number") {
86733
86768
  heldItem = scrolledWanted;
86769
+ } else if (scrolledWanted === "back_to_start") {
86770
+ heldItem = 0;
86734
86771
  } else if (scrolledWanted && scrolledWanted.id !== undefined) {
86735
86772
  const itemIndex = listItems.locateItem(scrolledWanted.id);
86736
86773
  if (itemIndex !== null) {
@@ -86966,7 +87003,6 @@ const useListScrollSync = ({
86966
87003
  // Lorsqu'on selectionne quelque chose pendant une recherche, alors ensuite meme si on clear
86967
87004
  // on veut pas revenir a la position scroll précédente car on veut garde l'item qu'on a selectionné visible
86968
87005
  // (pour l'instant pas grave car on travaille pour le mode select qui fermera le dialog au select)
86969
- const savedScrollRef = useRef(null);
86970
87006
  const topMatchScoresKeyRef = useRef("");
86971
87007
  const restoreScrollRafRef = useRef(null);
86972
87008
  useLayoutEffect(() => {
@@ -87076,6 +87112,10 @@ const useListScrollSync = ({
87076
87112
  if (scrolledWanted === "start" || scrolledWanted === undefined || startPlaceRef.current.userTookOver || !ref.current) {
87077
87113
  return;
87078
87114
  }
87115
+ if (scrolledWanted === "back_to_start") {
87116
+ placeBackAtStart();
87117
+ return;
87118
+ }
87079
87119
  if (listItems.totalSignal.peek() === 0 || virtualItemSizeSignal.peek() === 0) {
87080
87120
  return;
87081
87121
  }
@@ -87174,6 +87214,24 @@ const useListScrollSync = ({
87174
87214
  }
87175
87215
  sendHeldScroll(scrollNow + delta);
87176
87216
  };
87217
+ // The start of the list, what comes before its first item included, not an
87218
+ // item: a box of its own goes to 0. A box the list is further down of also
87219
+ // shows what stands above it, the control that asked for this among others, so
87220
+ // the list is brought back to the box's start and never sent forward to it.
87221
+ const placeBackAtStart = () => {
87222
+ const scrollerEl = getScroller();
87223
+ if (ref.current.contains(scrollerEl)) {
87224
+ sendHeldScroll(0);
87225
+ return;
87226
+ }
87227
+ const scale = readScrollerScale(scrollerEl, horizontal);
87228
+ const viewportRect = getScrollerViewportRect(scrollerEl);
87229
+ const listRect = ref.current.getBoundingClientRect();
87230
+ const offsetNow = (horizontal ? listRect.left - viewportRect.left : listRect.top - viewportRect.top) / scale;
87231
+ const delta = offsetNow - getItemScrollInset(scrollerEl, ref.current, horizontal);
87232
+ const scrollNow = horizontal ? scrollerEl.scrollLeft : scrollerEl.scrollTop;
87233
+ sendHeldScroll(delta < 0 ? scrollNow + delta : scrollNow);
87234
+ };
87177
87235
  // Every placement goes through here, the ones that find the list in place
87178
87236
  // too: it keeps the way from where the scroller was to where it is sent,
87179
87237
  // which is how a scroll event tells the hold's own scrolls from anyone
@@ -92044,6 +92102,7 @@ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, Li
92044
92102
  * scroller?: "self" | "parent" | "document" | Element | {current: Element},
92045
92103
  * hoverWhileScrolling?: boolean,
92046
92104
  * scrollResetOnNavigation?: boolean,
92105
+ * scrollResetKey?: any,
92047
92106
  * fallback?: import("preact").ComponentChildren,
92048
92107
  * searchFallback?: import("preact").ComponentChildren,
92049
92108
  * searchText?: string,
@@ -92288,6 +92347,15 @@ const ListResolved = /*#__PURE__*/createComponentResolver([ListFirstResolver, Li
92288
92347
  * overwrite each other (see docs/scroll.md). A fresh arrival at the page
92289
92348
  * opens at `defaultScrolled` either way, and so does a list the caller holds
92290
92349
  * through `scrolled`.
92350
+ * @param {any} [props.scrollResetKey]
92351
+ * What the list shows, said as a value: another order, another filter. When
92352
+ * it changes after mount (compared by value: `[order, filter]` can be written
92353
+ * at every render) the list goes back to its start before the paint, in
92354
+ * whichever box `scroller` names, and is held there until the user reaches
92355
+ * for it. A list whose start is in view in a box that also shows what stands
92356
+ * above it does not move. A `scrolled` changing in the same render wins. The
92357
+ * position remembered under the `id` for the address shown is dropped; see
92358
+ * docs/scroll.md.
92291
92359
  * @param {boolean} [props.deselectable]
92292
92360
  * A single-select list allowed to hold nothing: the selected item, pressed
92293
92361
  * again, lets go. Without it the list is a radio group — a choice, once