@jsenv/navi 0.29.418 → 0.29.419
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.
- package/README.md +1 -1
- package/dist/dev/jsenv_navi.js +192 -43
- package/dist/dev/jsenv_navi.js.map +10 -10
- package/dist/jsenv_navi.js +190 -41
- package/dist/jsenv_navi.js.map +10 -10
- package/docs/AI_INSTRUCTIONS.md +177 -261
- package/docs/actions.md +164 -251
- package/docs/autofocus.md +66 -83
- package/docs/control_object.md +117 -214
- package/docs/control_value.md +121 -185
- package/docs/create_and_edit.md +159 -254
- package/docs/css_architecture.md +196 -260
- package/docs/data_states.md +41 -44
- package/docs/dialog_shape.md +91 -134
- package/docs/drag_interactions.md +115 -174
- package/docs/drag_to_travel.md +10 -9
- package/docs/dynamic_import.md +119 -136
- package/docs/error_handling.md +75 -127
- package/docs/field_validation.md +49 -89
- package/docs/form_changed.md +61 -78
- package/docs/group.md +141 -0
- package/docs/i18n.md +31 -76
- package/docs/interactions.md +6 -4
- package/docs/list_action.md +36 -51
- package/docs/list_refresh.md +73 -115
- package/docs/mobile_touch.md +56 -62
- package/docs/navigation.md +377 -723
- package/docs/network_policy.md +61 -75
- package/docs/pan_zoom.md +62 -103
- package/docs/popup_backdrop.md +128 -168
- package/docs/popup_lift.md +179 -268
- package/docs/popup_open.md +380 -651
- package/docs/resource.md +228 -408
- package/docs/route_transitions.md +333 -482
- package/docs/safe_area.md +102 -89
- package/docs/scroll.md +175 -335
- package/docs/state_binding.md +2 -1
- package/docs/testid.md +18 -23
- package/docs/typography.md +111 -141
- package/docs/view_transitions.md +106 -104
- package/docs/z_index.md +61 -109
- package/package.json +2 -2
- package/docs/badge_list.md +0 -83
- package/docs/control_group.md +0 -168
- package/docs/mobile_layout_pitfalls.md +0 -145
|
@@ -70,24 +70,24 @@ do not ask**: what they return is not waited on, and preventing their event
|
|
|
70
70
|
calls nothing off.
|
|
71
71
|
|
|
72
72
|
**Where the position is kept is the answer's.** Until the release navi carries
|
|
73
|
-
the element with a translate of its own
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
declares [`moving`](#while-it-is-being-moved-moving).
|
|
73
|
+
the element with a translate of its own. An element drawn from state
|
|
74
|
+
(`left`/`top` computed from a position the application holds) is redrawn by the
|
|
75
|
+
`move` handler, and its layout owns the position from then on: navi sees it drawn
|
|
76
|
+
elsewhere and drops its translate, or it would land twice as far as the hand
|
|
77
|
+
went. A handler that draws nothing (a token on a free canvas) leaves the position
|
|
78
|
+
baked into the element; one whose draw comes later than its answer returns the
|
|
79
|
+
promise of that draw. Something that changes WHILE it is dragged, or must never
|
|
80
|
+
be translated, is [`moving`](#while-it-is-being-moved-moving).
|
|
82
81
|
|
|
83
82
|
**Where it may go.** A `move` stays inside what one can SEE of its scroll
|
|
84
83
|
container — the nearest ancestor whose `overflow` is `auto` or `scroll`, the
|
|
85
84
|
viewport when there is none — so a board that only cuts its content (`hidden`,
|
|
86
|
-
`clip`) does not hold it; a copy stays inside its scroll area,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
85
|
+
`clip`) does not hold it; a copy stays inside its scroll area, as a row belongs
|
|
86
|
+
to its list. `data-drag-free` on the element or a container lets it out, and
|
|
87
|
+
three things do on their own, each needing to get somewhere: a `toss` for the
|
|
88
|
+
copy it throws (kept inside its list, it covers no distance), a `leave` for
|
|
89
|
+
whatever it is declared on, and a `data-drop-container` (a place outside is only
|
|
90
|
+
reached from outside).
|
|
91
91
|
|
|
92
92
|
```jsx
|
|
93
93
|
<List.Item
|
|
@@ -108,15 +108,15 @@ only be reached from outside.
|
|
|
108
108
|
|
|
109
109
|
Every element declaring `reorder` marks itself, so the set of items IS the set of
|
|
110
110
|
elements that declared it — no selector to pass, and an item that must not move
|
|
111
|
-
simply does not declare it
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
name what moves.
|
|
111
|
+
simply does not declare it; one declaring only `toss` is not a place anything
|
|
112
|
+
lands. `toId` is null for a drop at the end. `syncCloneWithDropTarget` must be
|
|
113
|
+
called synchronously inside the transition callback, next to the state change,
|
|
114
|
+
so the copy is captured where it lands rather than where it was let go of;
|
|
115
|
+
returning the transition is what makes the landing continuous. Starting that
|
|
116
|
+
transition is the application's call, not navi's: a `view-transition-name` must
|
|
117
|
+
be unique per document (see
|
|
118
|
+
[view_transitions.md](./view_transitions.md#a-name-is-unique-per-document)), so
|
|
119
|
+
only the application can name what moves.
|
|
120
120
|
|
|
121
121
|
A throw is asked about before a landing: a hand that sent something across the
|
|
122
122
|
screen has not asked for it to swap places with whatever it flew over.
|
|
@@ -155,29 +155,25 @@ all along, and needs to be the one drawing.
|
|
|
155
155
|
Declaring it says both at once: the element is told where the hand has taken it
|
|
156
156
|
on every frame, and **navi moves nothing** — no translate, nothing to hand back
|
|
157
157
|
at the release. The numbers are counted from the grab, not steps since the last
|
|
158
|
-
frame (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
frames
|
|
168
|
-
is refused has no home to send the element to, so the state the frames wrote is
|
|
169
|
-
the caller's to put back.
|
|
158
|
+
frame (what `pan` gives, a surface having no grab to count from): a caller adding
|
|
159
|
+
up steps drifts, and has nothing to re-read after a frame it missed.
|
|
160
|
+
|
|
161
|
+
Told, not asked — a draw awaited before the next frame is a draw one frame late —
|
|
162
|
+
yet a complete declaration on its own, keeping everything the drag knows: the
|
|
163
|
+
axes, the threshold, the hold a finger owes, `data-drag-free`,
|
|
164
|
+
`grab`/`release`, `leave`, `"refuse"` to lock it. Write `move` beside it only
|
|
165
|
+
when the release settles something the frames did not. Nothing travels back: a
|
|
166
|
+
refused `move` or `leave` beside it has no home to send the element to, so what
|
|
167
|
+
the frames wrote is the caller's to put back.
|
|
170
168
|
|
|
171
169
|
### Let go of away from every place: `leave`
|
|
172
170
|
|
|
173
|
-
A throw is a **gesture
|
|
174
|
-
outside is a **place
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
row put back, not a row deleted: a list declares `toss`, a surface declares
|
|
180
|
-
`leave`.
|
|
171
|
+
A throw is a **gesture** — far and fast, judged before any landing. A release
|
|
172
|
+
outside is a **place** — nothing under the thing, judged after a landing was
|
|
173
|
+
looked for. Neither reads the other's rules: there is no speed to a release, a
|
|
174
|
+
fast drag that ends ON a plan has not asked for the thing to go, and a row pulled
|
|
175
|
+
sideways out of its list and let go is a row put back, not a row deleted — a list
|
|
176
|
+
declares `toss`, a surface declares `leave`.
|
|
181
177
|
|
|
182
178
|
```jsx
|
|
183
179
|
<div data-drop-container>
|
|
@@ -245,25 +241,10 @@ construction, so the answer is an insertion and putting a row back where it
|
|
|
245
241
|
already was is a no-op. A place of a board is a place of its own, which may
|
|
246
242
|
already be taken — so nothing is inserted, nothing is a no-op, and the answer is
|
|
247
243
|
simply "this one came down on that one". What that means is yours: take the
|
|
248
|
-
place, swap the two, refuse.
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
id={playerId}
|
|
253
|
-
interactions={{
|
|
254
|
-
land: (event) => {
|
|
255
|
-
const { fromId, toId, syncCloneWithDropTarget } = event.detail;
|
|
256
|
-
return document.startViewTransition(() => {
|
|
257
|
-
syncCloneWithDropTarget();
|
|
258
|
-
setLineup((previous) => swapPlaces(previous, fromId, toId));
|
|
259
|
-
}).finished;
|
|
260
|
-
},
|
|
261
|
-
}}
|
|
262
|
-
/>
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
`toId` always names an element and is **never null**: a copy over nothing is a
|
|
266
|
-
release that meant nothing, and the interaction does not happen at all.
|
|
244
|
+
place, swap the two, refuse. It is answered in the shape of a `reorder` (the
|
|
245
|
+
transition returned, `syncCloneWithDropTarget` inside it), and `toId` always names
|
|
246
|
+
an element — **never null**: a copy over nothing is a release that meant nothing,
|
|
247
|
+
and the interaction does not happen at all.
|
|
267
248
|
|
|
268
249
|
**Which elements are places: those marked `data-droppable`, and only those.**
|
|
269
250
|
Declaring `land` says an element can be CARRIED, which on a board is a different
|
|
@@ -325,54 +306,32 @@ itself — so the copy stays where the hand put it, over the thing appearing the
|
|
|
325
306
|
|
|
326
307
|
#### Naming what travels
|
|
327
308
|
|
|
328
|
-
**The copy is already named, and it
|
|
329
|
-
`syncCloneWithDropTarget` moves it onto the destination inside the callback
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
const { fromId, toId, syncCloneWithDropTarget } = event.detail;
|
|
355
|
-
const displacedId = playerAt(toId);
|
|
356
|
-
const roles = { [fromId]: OVER, [displacedId]: UNDER };
|
|
357
|
-
for (const id of Object.keys(roles)) {
|
|
358
|
-
document.getElementById(id).style.viewTransitionName = roles[id];
|
|
359
|
-
}
|
|
360
|
-
const transition = document.startViewTransition(() => {
|
|
361
|
-
syncCloneWithDropTarget(document.getElementById(displacedId));
|
|
362
|
-
setSwapRoles(roles); // the render inside the callback keeps the names
|
|
363
|
-
setLineup((previous) => swapPlaces(previous, fromId, toId));
|
|
364
|
-
});
|
|
365
|
-
transition.finished.then(() => setSwapRoles(null));
|
|
366
|
-
return transition.finished;
|
|
367
|
-
};
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
The roles are names because a `::view-transition` pseudo is selected by name and
|
|
371
|
-
by nothing else — which is how one piece is told to pass over the other, and the
|
|
372
|
-
travel given a length worth a card crossing a board. Address both
|
|
373
|
-
`::view-transition-group(…)` and `::view-transition-image-pair(…)`: the morph
|
|
374
|
-
lives in one, anything a style adds rides in the other. The whole board is in
|
|
375
|
-
`38_interactions_demo.html`.
|
|
309
|
+
**The copy is already named, and it does the visible travel**:
|
|
310
|
+
`syncCloneWithDropTarget` moves it onto the destination inside the callback. Each
|
|
311
|
+
copy has a name of its own, two being on screen at once while a `toss` is
|
|
312
|
+
answered, and all share the class `navi-drag-clone`, so
|
|
313
|
+
`::view-transition-group(.navi-drag-clone)` styles the landing (read from Chrome
|
|
314
|
+
125 on; before that only a rule written against the class goes unread).
|
|
315
|
+
|
|
316
|
+
What is left to name is the OTHER piece, the one standing there that goes the
|
|
317
|
+
other way. **A name rides the element that MOVES, and that element has to be
|
|
318
|
+
visible at both ends of the transition.** Never the source: it is
|
|
319
|
+
`visibility: hidden` until the promise `land` returned settles, which still gets
|
|
320
|
+
it captured, as an empty image — a name on it is a group fading in from nothing,
|
|
321
|
+
or out into nothing, over the copy doing the real travel. Where the places are
|
|
322
|
+
fixed and the pieces drawn into them, key each piece by WHO it is, so the same
|
|
323
|
+
node walks from one place to the other.
|
|
324
|
+
|
|
325
|
+
The name is written twice, and neither write is redundant: by hand on the DOM
|
|
326
|
+
before `startViewTransition` is called, because the old state is captured right
|
|
327
|
+
then, and from state, because the render inside the callback would put the plain
|
|
328
|
+
name straight back. Clear that state when `finished` resolves — a name left
|
|
329
|
+
behind is claimed twice by the next transition, and that one is dropped for it.
|
|
330
|
+
The names are roles (the piece passing over, the one passing under) because a
|
|
331
|
+
`::view-transition` pseudo is selected by name and by nothing else; address both
|
|
332
|
+
its group and its image pair — the morph lives in one, anything a style adds
|
|
333
|
+
rides in the other. The padel board in `38_interactions_demo.html` does all of
|
|
334
|
+
it.
|
|
376
335
|
|
|
377
336
|
The drop hint follows what a place is: a line drawn in the gap for `reorder`, the
|
|
378
337
|
place itself lit up for `land`. Both are drawn among the places — the parent, or
|
|
@@ -389,26 +348,15 @@ the board or the surface and reach them by inheritance:
|
|
|
389
348
|
### Saying the grab is acquired: `grab`
|
|
390
349
|
|
|
391
350
|
The outcomes answer the **release**. Between the press and the release there is
|
|
392
|
-
one instant that counts for the hand
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
}}
|
|
402
|
-
/>
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
It matters most where it is least visible. On a screen the held object is under
|
|
406
|
-
the thumb that hides it, so the only feedback available is the one that is felt;
|
|
407
|
-
without it the hand waits, doubts the press was heard, and lets go too early —
|
|
408
|
-
the whole gesture fails, not its decoration. (With a mouse the object has visibly
|
|
409
|
-
moved by then.) If the moment is for **paint**, no listener is needed: navi puts
|
|
410
|
-
`data-grabbed` on the element for as long as the gesture holds it. `grab` is for
|
|
411
|
-
what a stylesheet cannot do — a vibration, a state kept elsewhere, a counter.
|
|
351
|
+
one instant that counts for the hand — the object stops being pressed and starts
|
|
352
|
+
being held, whichever way the drag was entered — and `grab` is that instant:
|
|
353
|
+
`grab: () => navigator.vibrate?.(10)` beside the outcome. On a screen the held
|
|
354
|
+
object is under the thumb that hides it, so the only feedback available is the
|
|
355
|
+
one that is felt; without it the hand doubts the press was heard and lets go too
|
|
356
|
+
early — the whole gesture fails, not its decoration. For **paint** no listener
|
|
357
|
+
is needed: navi puts `data-grabbed` on the element for as long as the gesture
|
|
358
|
+
holds it. `grab` is for what a stylesheet cannot do — a vibration, a state kept
|
|
359
|
+
elsewhere, a counter.
|
|
412
360
|
|
|
413
361
|
It is not an interaction on its own: declared without an outcome or `moving`
|
|
414
362
|
there is no gesture for it to begin, and a dev warning says so — unless the
|
|
@@ -463,13 +411,13 @@ and says nothing reads as a broken screen, so the hand insists.
|
|
|
463
411
|
```
|
|
464
412
|
|
|
465
413
|
So the interaction stays declared and says `"refuse"` in place of what it does.
|
|
466
|
-
The threshold is the same
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
414
|
+
The threshold is the same — a mouse travelling, a finger holding still, a mouse's
|
|
415
|
+
few pixels inside a `data-drag-on-contact` — and at the instant the grab would
|
|
416
|
+
have been acquired there is none: nothing translates, no copy is made, no release
|
|
417
|
+
is answered. `refuse` is told then, where feedback is expected, with no
|
|
418
|
+
`gestureInfo` (there was no gesture) and the `pointerType` that says which hand
|
|
419
|
+
asked — a vibration for a finger, nothing extra for a mouse whose cursor has
|
|
420
|
+
already said it. One outcome refusing refuses the whole carry.
|
|
473
421
|
|
|
474
422
|
**It walks no axis, so it takes none.** Whatever reads what a drag source walks
|
|
475
423
|
to know what is left for itself — a box that travels, a surface that pans — steps
|
|
@@ -477,16 +425,15 @@ over an element that is refusing: a swipe starting on a locked row is the row of
|
|
|
477
425
|
slides' swipe, a drag starting on a pinned court pans the plan. A thing that
|
|
478
426
|
cannot be taken hold of is exactly the one a hand rests on without thinking, and
|
|
479
427
|
a surface with a dead zone the size of an object in the middle of it is wrong
|
|
480
|
-
every time. For the axes, `move: "refuse"` is `move: false
|
|
481
|
-
not
|
|
428
|
+
every time. For the axes, `move: "refuse"` is `move: false`; for the press it is
|
|
429
|
+
not.
|
|
482
430
|
|
|
483
431
|
**The press itself stays the element's**, settled there like any gesture settles
|
|
484
432
|
one: the pointer is taken, so a `longpress` declared beside the drag does not
|
|
485
|
-
answer afterwards, and the click the release leaves behind is swallowed.
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
anything — no pointer, no click, nothing prevented.
|
|
433
|
+
answer afterwards, and the click the release leaves behind is swallowed. The
|
|
434
|
+
exception is a box declaring `pan`/`zoom`, the one thing that takes a press whole
|
|
435
|
+
and in every direction: there the surface keeps it, and the refusal is told
|
|
436
|
+
without taking anything — no pointer, no click, nothing prevented.
|
|
490
437
|
|
|
491
438
|
### A press made elsewhere: `--navi-grab`
|
|
492
439
|
|
|
@@ -525,14 +472,13 @@ item plus whatever being carried changes.
|
|
|
525
472
|
|
|
526
473
|
**Which is also the trap, for anything positioned on a board.** The copy is a
|
|
527
474
|
deep clone put in a carrier box, so a geometry written in the style attribute
|
|
528
|
-
comes with it. navi
|
|
529
|
-
`translate`
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
the transition) and has to keep its size all the way down:
|
|
475
|
+
comes with it. navi resets where it stands (`position`, `inset`, `margin`,
|
|
476
|
+
`translate`) but not its size: `width: calc(50% - 2 * var(--gap))` then means
|
|
477
|
+
half of the carrier, and the piece is carried at the wrong size. Put what a piece
|
|
478
|
+
LOOKS like in a class, leave only which place it is inline (two custom properties
|
|
479
|
+
will do), and let it fill its carrier — said of what is inside the wrapper, not
|
|
480
|
+
of `[navi-drag-clone]`, which the copy loses as it lands (that is how it drops
|
|
481
|
+
its lift for the transition) while it has to keep its size all the way down:
|
|
536
482
|
|
|
537
483
|
```css
|
|
538
484
|
[navi-drag-clone-wrapper] .piece {
|
|
@@ -549,10 +495,10 @@ Read off the dragged element, so a whole list or a single item can answer:
|
|
|
549
495
|
| `--drag-clone-scale` | how much bigger it gets once picked up; `1` to keep its size |
|
|
550
496
|
|
|
551
497
|
**What stays behind is the source, not a hole.** The original keeps its place in
|
|
552
|
-
the layout, only `visibility: hidden`, until the answer settles —
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
498
|
+
the layout, only `visibility: hidden`, until the answer settles — it says where
|
|
499
|
+
the thing left from for as long as the question is open. A mark left there (an
|
|
500
|
+
imprint, a dashed outline) is drawn ON that element, and its parts say
|
|
501
|
+
`visibility: visible` to come back from the hidden source:
|
|
556
502
|
|
|
557
503
|
```css
|
|
558
504
|
.paper[navi-drag-clone-source]::after {
|
|
@@ -663,24 +609,19 @@ const onPointerDown = (pointerDownEvent) => {
|
|
|
663
609
|
|
|
664
610
|
An element that ends up somewhere is NOT this: that one is `move` — or `land`
|
|
665
611
|
when what it ends up on is a surface — and doing it by hand gives up the
|
|
666
|
-
constraint, the commit and the way back when the answer refuses.
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
- **A capture that goes was not necessarily given back.** `lostpointercapture`
|
|
680
|
-
reads the same whether the gesture handed the pointer over or the browser
|
|
681
|
-
dropped it mid-drag, which it does more often than the specification suggests.
|
|
682
|
-
The loop tells the two apart, and `gestureInfo.cancelled` is where it comes
|
|
683
|
-
out: a release nobody asked for must commit nothing.
|
|
612
|
+
constraint, the commit and the way back when the answer refuses.
|
|
613
|
+
|
|
614
|
+
**A touch has to be refusable before it is refused**, so `markDragSource` goes
|
|
615
|
+
down at mount, on the source itself, and what surrounds it keeps scrolling (the
|
|
616
|
+
two conditions are in
|
|
617
|
+
[mobile_touch.md](./mobile_touch.md#the-browser-decides-about-8px-in-and-does-not-wait)).
|
|
618
|
+
A blanket `touch-action: none` on the container buys the same drag by taking the
|
|
619
|
+
pan away, and the pan then has to be written by hand too. **A capture that goes
|
|
620
|
+
was not necessarily given back**: `lostpointercapture` reads the same whether the
|
|
621
|
+
gesture handed the pointer over or the browser dropped it mid-drag, which it does
|
|
622
|
+
more often than the specification suggests. The loop tells the two apart, and
|
|
623
|
+
`gestureInfo.cancelled` is where it comes out — a release nobody asked for must
|
|
624
|
+
commit nothing.
|
|
684
625
|
|
|
685
626
|
A gesture driven this way is outside the registry, so it says so itself to
|
|
686
627
|
whatever travels above it: `data-no-drag-travel` (see
|
package/docs/drag_to_travel.md
CHANGED
|
@@ -84,7 +84,8 @@ are read at the press, before the box moves:
|
|
|
84
84
|
so with `data-press-only`, and a travel starts there like anywhere else.
|
|
85
85
|
2. **A scroller in between with room left that way.** It keeps the gesture until
|
|
86
86
|
it has no room left, and only then hands the travel over — so a row that
|
|
87
|
-
scrolls sideways inside a page still scrolls sideways.
|
|
87
|
+
scrolls sideways inside a page still scrolls sideways. A row swiped with
|
|
88
|
+
`interactions` is the exception: its swipe does not ask.
|
|
88
89
|
3. **Another travelling box in between** — see
|
|
89
90
|
[Boxes inside boxes](#boxes-inside-boxes).
|
|
90
91
|
4. **Something in between that is picked up and carried** — see
|
|
@@ -192,14 +193,14 @@ A popup pushed back towards its edge and a swiped row are travels too, the
|
|
|
192
193
|
simple kind: one box, one direction, no neighbour to bring in. The two below
|
|
193
194
|
carry screens.
|
|
194
195
|
|
|
195
|
-
| | `SlideContainer`
|
|
196
|
-
| ----------------------- |
|
|
197
|
-
| what the screens are | `<Slide>`s in one box, all mounted
|
|
198
|
-
| what says which is here | a `signal`, `current` / a command
|
|
199
|
-
| what the finger moves | a translated track
|
|
200
|
-
| letting go too early | the track comes back
|
|
201
|
-
| what says the order | the layout map
|
|
202
|
-
| what one wheel push is | `move(±1)`, as an arrow key
|
|
196
|
+
| | `SlideContainer` | `RouteTravel` |
|
|
197
|
+
| ----------------------- | ---------------------------------- | ---------------------------------- |
|
|
198
|
+
| what the screens are | `<Slide>`s in one box, all mounted | routes — one mounted, ever |
|
|
199
|
+
| what says which is here | a `signal`, `current` / a command | the URL |
|
|
200
|
+
| what the finger moves | a translated track | the pictures of a view transition |
|
|
201
|
+
| letting go too early | the track comes back | the transition is played backwards |
|
|
202
|
+
| what says the order | the layout map | the `<Route>` children, in order |
|
|
203
|
+
| what one wheel push is | `move(±1)`, as an arrow key | one travel, as a tab pressed |
|
|
203
204
|
|
|
204
205
|
Both expose how far the travel has come, and the way to read it differs because
|
|
205
206
|
what draws an indicator differs. `SlideContainer` writes
|