@jsenv/navi 0.29.131 → 0.29.133

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.
@@ -278,7 +278,9 @@ consistency across the app, not from any single call site.
278
278
  than a param, search params bound to signals, rendering with `<Route>`,
279
279
  tab rows (`Nav` / `Link` / `RouteTravel`), where a navigation lands
280
280
  (scroll: a push arrives at the top, a back or forward lands where the page
281
- was left), a back arrow that stays inside the app (`useCanNavBack()` /
281
+ was left, a replace moves nothing except in a `RouteTravel`, where each tab
282
+ is given back the offset it was read at, and only when the row owns the
283
+ document scroll), a back arrow that stays inside the app (`useCanNavBack()` /
282
284
  `navBack({ fallback })`), and the few cases where tabs are legitimately not
283
285
  URLs. Read it before writing any routing code — the
284
286
  position of the user belongs in the URL by default, and that decision is
@@ -473,7 +473,9 @@ coming up from below.
473
473
  A swipe **replaces** the current history entry, and a tab pressed says the same
474
474
  thing when its link asks for it (`<Link replace>`, see above) — the two gestures
475
475
  towards the same neighbour must not write two different histories. `onTravel`
476
- decides otherwise.
476
+ decides otherwise. A replace normally leaves the scroll where it is; a row of
477
+ tabs is the exception, and gives each tab back the offset it was read at — see
478
+ [A row of tabs, where a replace IS an arrival](#a-row-of-tabs-where-a-replace-is-an-arrival).
477
479
 
478
480
  Several `RouteTravel` boxes may live on one page — a section of the path and a
479
481
  search param of the root route are two rows of tabs, both live — and only the one
@@ -491,7 +493,7 @@ the two, never both: see [route_transitions.md](./route_transitions.md).
491
493
 
492
494
  ## Where a navigation lands: the scroll
493
495
 
494
- Three cases, and they are not a policy to configure but three different facts:
496
+ Four cases, and they are not a policy to configure but four different facts:
495
497
 
496
498
  - **Going somewhere new** (a `<Link>`, anything that pushes) lands at the top.
497
499
  It is an arrival: the offset one had elsewhere means nothing here, and left
@@ -503,6 +505,10 @@ Three cases, and they are not a policy to configure but three different facts:
503
505
  cannot do: it restores at the instant the entry changes, when the document
504
506
  still holds the page being left, so anything further down than that page is
505
507
  tall is clamped away.
508
+ - **Replacing the entry** (`<Link replace>`, `route.redirectTo()`, a param
509
+ settling, a state written) moves nothing. It is the same place said
510
+ differently, and the reader is still in the page they were reading — a row of
511
+ tabs is the one shape where that reading is wrong, see below.
506
512
  - **A reload** lands where one was, as it would have without navi.
507
513
 
508
514
  One consequence is softened where the browser exposes its stack (the
@@ -521,6 +527,39 @@ in a browser with no Navigation API — is `navBack()`. Where there may be
521
527
  nothing to go back to (a shared link opened cold), decide what the arrow does
522
528
  from the history, not from the link.
523
529
 
530
+ ### A row of tabs, where a replace IS an arrival
531
+
532
+ The tabs of a `<RouteTravel>` navigate by replacing, and yet each one is another
533
+ route. They also share a single scrollport — the document — and the tab on
534
+ screen is what makes it tall. So leaving the offset alone does not keep it: the
535
+ moment the arriving tab is shorter, the browser clamps, and the reader's place
536
+ is gone before anything of navi's is asked.
537
+
538
+ The row is the only thing that knows this, so the row is what says it. On every
539
+ travel — a tab pressed, a thumb dragging the pages, a wheel, a travel let go of
540
+ too early and put back:
541
+
542
+ - the arriving tab is given back the offset it was read at, once it is really
543
+ rendered;
544
+ - a tab never read opens at its **top**, rather than wherever its neighbour
545
+ happened to be;
546
+ - the clamp itself is never recorded. It is not the reader scrolling, and the
547
+ url it would be written against is already the arriving tab's — recorded, it
548
+ destroys that tab's own position, which is then what a later back or forward
549
+ hands out.
550
+
551
+ **Only where the row owns the document**: nothing between the travelling box and
552
+ the viewport may scroll or clip. A row inside a scroller of its own — a frame in
553
+ an article, a panel beside other content — shares nothing with the document, and
554
+ the offset there belongs to the page around it, which the reader never left; the
555
+ travel leaves it alone. An `overflow: hidden` or `clip` on any ancestor is
556
+ enough to put the row outside the document's scrollport, so a row that should
557
+ give positions back and does not is worth looking at from that angle first.
558
+
559
+ Pages that scroll inside themselves rather than scrolling the document are not
560
+ concerned either way: each one brings its own scrollport, which goes away with
561
+ the page and has nothing to give back.
562
+
524
563
  What is not covered: a page whose height depends on something still loading is
525
564
  not tall enough at the moment its position is put back, so a deep position is
526
565
  clamped as it was before. Only the page knows when it is whole.
package/docs/scroll.md CHANGED
@@ -3,6 +3,11 @@
3
3
  Where scrolling happens in a navi app, and how the pieces that live inside a
4
4
  scrolling area (`Box header/body/footer`, `List`, a popup) are told about it.
5
5
 
6
+ Where a navigation LANDS is another subject — a push at the top, a back or
7
+ forward where the page was left, a row of tabs giving each tab back the offset
8
+ it was read at: see
9
+ [navigation.md](./navigation.md#where-a-navigation-lands-the-scroll).
10
+
6
11
  - [What makes header/body/footer work: the overflow](#what-makes-headerbodyfooter-work-the-overflow)
7
12
  - [1. The document scrolls](#1-the-document-scrolls)
8
13
  - [2. A part of the document scrolls](#2-a-part-of-the-document-scrolls)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/navi",
3
- "version": "0.29.131",
3
+ "version": "0.29.133",
4
4
  "type": "module",
5
5
  "description": "Library of components including navigation to create frontend applications",
6
6
  "repository": {
@@ -29,7 +29,7 @@
29
29
  "prepublishOnly": "npm run build"
30
30
  },
31
31
  "dependencies": {
32
- "@jsenv/dom": "0.17.32",
32
+ "@jsenv/dom": "0.17.33",
33
33
  "@jsenv/humanize": "1.7.8",
34
34
  "@jsenv/validity": "0.4.3"
35
35
  },