@jsenv/navi 0.29.390 → 0.29.392
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/dist/dev/jsenv_navi.js +279 -74
- package/dist/dev/jsenv_navi.js.map +6 -6
- package/dist/jsenv_navi.js +279 -74
- package/dist/jsenv_navi.js.map +6 -6
- package/docs/route_transitions.md +37 -13
- package/package.json +1 -1
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -30237,9 +30237,13 @@ installImportMetaCssBuild(import.meta);
|
|
|
30237
30237
|
* - a bar only one state has never meets a counterpart. It belongs to the page
|
|
30238
30238
|
* that has it, so it travels with that page — leaving by the keyframes the
|
|
30239
30239
|
* page being left leaves by, arriving by the ones the page arriving arrives
|
|
30240
|
-
* by — instead of going out with the render.
|
|
30241
|
-
*
|
|
30242
|
-
*
|
|
30240
|
+
* by — instead of going out with the render. Over that page, as it is at
|
|
30241
|
+
* rest: the page runs under it, and what it paints outside its box (a button
|
|
30242
|
+
* standing up out of a tab bar) is not cut by its own page. Under the pages
|
|
30243
|
+
* only when its page is covered by the other one — a cover-* movement — so
|
|
30244
|
+
* the sheet comes over it; a popup over everything, standing where it
|
|
30245
|
+
* stands in the document (see the z-order in route_transition.jsx). Which
|
|
30246
|
+
* side a bar is on is said by a class on its group, written here.
|
|
30243
30247
|
*
|
|
30244
30248
|
* A popup shown in the top layer is furniture of the same kind, and its case
|
|
30245
30249
|
* is the sharper one: it is a DOM descendant of the area, yet painted outside
|
|
@@ -30317,11 +30321,17 @@ const FURNITURE_NAME_PREFIX = "navi-transition-furniture-";
|
|
|
30317
30321
|
const TOP_LAYER_WALL_SELECTOR =
|
|
30318
30322
|
".navi_dialog:modal, .navi_popover_backdrop:popover-open";
|
|
30319
30323
|
const WALL_ATTRIBUTE = "data-navi-transition-wall";
|
|
30320
|
-
//
|
|
30321
|
-
//
|
|
30322
|
-
//
|
|
30323
|
-
//
|
|
30324
|
-
|
|
30324
|
+
// Which side of the movement a bar is on, worn by the bar and read by the
|
|
30325
|
+
// browser as the class of its group (the CSS below): "leaving" from the first
|
|
30326
|
+
// picture, "arriving" for a bar the state arriving brought, "shared" for one
|
|
30327
|
+
// that stands in both states, written over "leaving" at the hold. The group's
|
|
30328
|
+
// class is the one captured with the LAST state the element stands in, so a
|
|
30329
|
+
// bar only the state being left has keeps "leaving" from the first capture,
|
|
30330
|
+
// and a shared one takes "shared" from the second. The z-order in
|
|
30331
|
+
// route_transition.jsx is written on these three. Only a bar — a popup's
|
|
30332
|
+
// class is written by layout/popup_css.js, and a second rule on the same
|
|
30333
|
+
// property would replace it.
|
|
30334
|
+
const FURNITURE_ATTRIBUTE = "data-navi-transition-furniture";
|
|
30325
30335
|
// What the wall paints, resolved on the matched element in both cases (the
|
|
30326
30336
|
// dialog for its ::backdrop, the popover's wall for itself): the same two
|
|
30327
30337
|
// properties, copied onto the stand-in.
|
|
@@ -30330,7 +30340,15 @@ const WALL_PROPERTIES = ["--backdrop-background", "--backdrop-filter"];
|
|
|
30330
30340
|
// The pictures the wall is painted into: the pages', and every bar's own.
|
|
30331
30341
|
const FIXED_BAR_SELECTOR$1 = ".navi_fixed_bar";
|
|
30332
30342
|
|
|
30333
|
-
const TRANSITION_FURNITURE_CSS = /* css */ `.navi_fixed_bar[data-navi-transition-furniture
|
|
30343
|
+
const TRANSITION_FURNITURE_CSS = /* css */ `.navi_fixed_bar[data-navi-transition-furniture="leaving"] {
|
|
30344
|
+
view-transition-class: navi_furniture_leaving;
|
|
30345
|
+
}
|
|
30346
|
+
|
|
30347
|
+
.navi_fixed_bar[data-navi-transition-furniture="arriving"] {
|
|
30348
|
+
view-transition-class: navi_furniture_arriving;
|
|
30349
|
+
}
|
|
30350
|
+
|
|
30351
|
+
.navi_fixed_bar[data-navi-transition-furniture="shared"] {
|
|
30334
30352
|
view-transition-class: navi_furniture_shared;
|
|
30335
30353
|
}
|
|
30336
30354
|
|
|
@@ -30403,7 +30421,7 @@ const nameTransitionFurniture = (owner, areaElement) => {
|
|
|
30403
30421
|
furnitureOwner = owner;
|
|
30404
30422
|
namedElements = new Set();
|
|
30405
30423
|
}
|
|
30406
|
-
nameFurnitureAround(areaElement);
|
|
30424
|
+
nameFurnitureAround(areaElement, "leaving");
|
|
30407
30425
|
const sources = paintTransitionWalls(areaElement);
|
|
30408
30426
|
// The state being left has walls: what no picture covers starts dimmed.
|
|
30409
30427
|
// The frame the first picture is taken on shows the live document, so the
|
|
@@ -30430,10 +30448,10 @@ const holdTransitionFurniture = (owner, areaElement) => {
|
|
|
30430
30448
|
if (!element.isConnected) {
|
|
30431
30449
|
namesLeaving.push(nameByElement.get(element));
|
|
30432
30450
|
} else if (element.matches(FIXED_BAR_SELECTOR$1)) {
|
|
30433
|
-
element.setAttribute(
|
|
30451
|
+
element.setAttribute(FURNITURE_ATTRIBUTE, "shared");
|
|
30434
30452
|
}
|
|
30435
30453
|
}
|
|
30436
|
-
const namesArriving = nameFurnitureAround(areaElement);
|
|
30454
|
+
const namesArriving = nameFurnitureAround(areaElement, "arriving");
|
|
30437
30455
|
const sources = paintTransitionWalls(areaElement);
|
|
30438
30456
|
// The state arriving has walls: what no picture covers ends dimmed. Painted
|
|
30439
30457
|
// from the state being left when that one had walls (they stay up if both
|
|
@@ -30483,7 +30501,8 @@ const holdTransitionFurniture = (owner, areaElement) => {
|
|
|
30483
30501
|
|
|
30484
30502
|
// Returns the elements it had to name, which are the ones the state arriving
|
|
30485
30503
|
// brought: everything else was already wearing its name from the first pass.
|
|
30486
|
-
|
|
30504
|
+
// `side` is what a bar named here is told it is on (see FURNITURE_ATTRIBUTE).
|
|
30505
|
+
const nameFurnitureAround = (areaElement, side) => {
|
|
30487
30506
|
const namesAdded = [];
|
|
30488
30507
|
for (const element of document.querySelectorAll(FURNITURE_SELECTOR)) {
|
|
30489
30508
|
if (namedElements.has(element)) {
|
|
@@ -30509,6 +30528,9 @@ const nameFurnitureAround = (areaElement) => {
|
|
|
30509
30528
|
nameByElement.set(element, name);
|
|
30510
30529
|
}
|
|
30511
30530
|
element.style.setProperty(NAME_PROPERTY$1, name);
|
|
30531
|
+
if (element.matches(FIXED_BAR_SELECTOR$1)) {
|
|
30532
|
+
element.setAttribute(FURNITURE_ATTRIBUTE, side);
|
|
30533
|
+
}
|
|
30512
30534
|
namedElements.add(element);
|
|
30513
30535
|
namesAdded.push(name);
|
|
30514
30536
|
}
|
|
@@ -30558,7 +30580,7 @@ const releaseTransitionFurniture = (owner) => {
|
|
|
30558
30580
|
furnitureOwner = null;
|
|
30559
30581
|
for (const element of namedElements) {
|
|
30560
30582
|
element.style.removeProperty(NAME_PROPERTY$1);
|
|
30561
|
-
element.removeAttribute(
|
|
30583
|
+
element.removeAttribute(FURNITURE_ATTRIBUTE);
|
|
30562
30584
|
}
|
|
30563
30585
|
namedElements = new Set();
|
|
30564
30586
|
if (travelStyleElement) {
|
|
@@ -30881,7 +30903,20 @@ const measureTransitionWindowState = (element) => {
|
|
|
30881
30903
|
};
|
|
30882
30904
|
};
|
|
30883
30905
|
|
|
30884
|
-
|
|
30906
|
+
/**
|
|
30907
|
+
* @param {object} options
|
|
30908
|
+
* @param {boolean} options.furnitureLive - Whether the bars stay live under
|
|
30909
|
+
* the pictures for the movement (a travel), or are pictures of their own
|
|
30910
|
+
* ordered over the page they belong to (a route transition, see
|
|
30911
|
+
* transition_furniture.js). Decides how far the cut may be opened for the
|
|
30912
|
+
* picture being left — see bandTheCutMayBeRelaxedTo.
|
|
30913
|
+
*/
|
|
30914
|
+
const holdTransitionWindow = (
|
|
30915
|
+
owner,
|
|
30916
|
+
element,
|
|
30917
|
+
stateBefore,
|
|
30918
|
+
{ furnitureLive },
|
|
30919
|
+
) => {
|
|
30885
30920
|
const bandBefore = stateBefore.band;
|
|
30886
30921
|
const rectAfter = element.getBoundingClientRect();
|
|
30887
30922
|
const bandAfter = readBand();
|
|
@@ -30915,7 +30950,9 @@ const holdTransitionWindow = (owner, element, stateBefore) => {
|
|
|
30915
30950
|
style.setProperty(WINDOW_OLD_LEFT_PROPERTY, `${rectBefore.left}px`);
|
|
30916
30951
|
style.setProperty(WINDOW_NEW_TOP_PROPERTY, `${rectAfter.top}px`);
|
|
30917
30952
|
style.setProperty(WINDOW_NEW_LEFT_PROPERTY, `${rectAfter.left}px`);
|
|
30918
|
-
const oldBand =
|
|
30953
|
+
const oldBand = furnitureLive
|
|
30954
|
+
? bandTheCutMayBeRelaxedTo(bandBefore, bandAfter, rectAfter)
|
|
30955
|
+
: bandBefore;
|
|
30919
30956
|
style.setProperty(OLD_BAND_TOP_PROPERTY, `${oldBand.top}px`);
|
|
30920
30957
|
style.setProperty(OLD_BAND_RIGHT_PROPERTY, `${oldBand.right}px`);
|
|
30921
30958
|
style.setProperty(OLD_BAND_BOTTOM_PROPERTY, `${oldBand.bottom}px`);
|
|
@@ -31078,18 +31115,25 @@ const readBand = () => {
|
|
|
31078
31115
|
};
|
|
31079
31116
|
};
|
|
31080
31117
|
|
|
31081
|
-
// How far the cut may be opened for the picture being left
|
|
31082
|
-
// state kept free, which is the
|
|
31083
|
-
// present in only one of the two
|
|
31084
|
-
//
|
|
31085
|
-
// header being sliced instead of
|
|
31118
|
+
// How far the cut may be opened for the picture being left when the furniture
|
|
31119
|
+
// is LIVE under the pictures — the band its own state kept free, which is the
|
|
31120
|
+
// whole point of photographing it: furniture present in only one of the two
|
|
31121
|
+
// states is not the frame, it is part of what changes, and cutting the page
|
|
31122
|
+
// being left at a bar it never had shows its header being sliced instead of
|
|
31123
|
+
// leaving.
|
|
31086
31124
|
//
|
|
31087
31125
|
// Never past what the picture ARRIVING needs, though: the cut is one line for
|
|
31088
31126
|
// both pictures, so opening it for one opens it for the other. A box that runs
|
|
31089
|
-
// under the furniture it arrives beside — a page scrolled below a top bar
|
|
31090
|
-
// would then be watched painting over that bar for the length of the
|
|
31091
|
-
// which is what the cut exists to prevent. On such an edge the
|
|
31092
|
-
// stands, and the page being left is cut as it always was.
|
|
31127
|
+
// under the live furniture it arrives beside — a page scrolled below a top bar
|
|
31128
|
+
// — would then be watched painting over that bar for the length of the
|
|
31129
|
+
// movement, which is what the cut exists to prevent. On such an edge the
|
|
31130
|
+
// arriving band stands, and the page being left is cut as it always was.
|
|
31131
|
+
//
|
|
31132
|
+
// With the furniture photographed (a route transition) none of this holds: a
|
|
31133
|
+
// bar only the arriving state has is a picture ordered over the page it
|
|
31134
|
+
// belongs to, and a page arriving under it paints nothing over it. The band
|
|
31135
|
+
// of the state being left is then published as it was, so the page being
|
|
31136
|
+
// left is never cut at a bar it never had.
|
|
31093
31137
|
const bandTheCutMayBeRelaxedTo = (bandBefore, bandAfter, rectAfter) => {
|
|
31094
31138
|
return {
|
|
31095
31139
|
top: rectAfter.top < bandAfter.top ? bandAfter.top : bandBefore.top,
|
|
@@ -31282,6 +31326,16 @@ const startViewTransition$1 = ensureDocumentStartViewTransition();
|
|
|
31282
31326
|
const TRANSITION_ATTRIBUTE = "data-navi-route-transition";
|
|
31283
31327
|
const TRANSITION_TYPE_ATTRIBUTE = "data-navi-route-transition-type";
|
|
31284
31328
|
const TRANSITION_DURATION_PROPERTY = "--navi-route-transition-duration";
|
|
31329
|
+
// Which page the other one COVERS, when the movement is one page over the
|
|
31330
|
+
// other: "old" (the page arriving comes over the page being left) or "new"
|
|
31331
|
+
// (the page being left slides off the page arriving). Published by the type
|
|
31332
|
+
// as a value on the root, like its keyframes (see the css), and mirrored as an
|
|
31333
|
+
// attribute for the length of the transition so the rules that depend on it
|
|
31334
|
+
// — which page is on top, what is cut, where the furniture goes — can be
|
|
31335
|
+
// written statically. Absent for a movement where neither page covers the
|
|
31336
|
+
// other.
|
|
31337
|
+
const TRANSITION_COVERED_PROPERTY = "--navi-route-transition-covered";
|
|
31338
|
+
const TRANSITION_COVERED_ATTRIBUTE = "data-navi-route-transition-covered";
|
|
31285
31339
|
// What the movement is played on. The root snapshot spans the viewport, and
|
|
31286
31340
|
// the regions of elements captured on their own (a named bar) are BLANK in it
|
|
31287
31341
|
// — a page sliding vertically then drags a blank band across the screen where
|
|
@@ -31364,7 +31418,7 @@ const css$12 = /* css */`:root[data-navi-route-transition] [data-navi-route-tran
|
|
|
31364
31418
|
z-index: 1;
|
|
31365
31419
|
}
|
|
31366
31420
|
|
|
31367
|
-
&::view-transition-group(.navi_furniture_shared) {
|
|
31421
|
+
&::view-transition-group(.navi_furniture_leaving), &::view-transition-group(.navi_furniture_arriving), &::view-transition-group(.navi_furniture_shared) {
|
|
31368
31422
|
z-index: 2;
|
|
31369
31423
|
}
|
|
31370
31424
|
|
|
@@ -31372,6 +31426,18 @@ const css$12 = /* css */`:root[data-navi-route-transition] [data-navi-route-tran
|
|
|
31372
31426
|
z-index: 3;
|
|
31373
31427
|
}
|
|
31374
31428
|
|
|
31429
|
+
&[data-navi-route-transition-covered="old"] {
|
|
31430
|
+
&::view-transition-group(.navi_furniture_leaving) {
|
|
31431
|
+
z-index: 0;
|
|
31432
|
+
}
|
|
31433
|
+
}
|
|
31434
|
+
|
|
31435
|
+
&[data-navi-route-transition-covered="new"] {
|
|
31436
|
+
&::view-transition-group(.navi_furniture_arriving) {
|
|
31437
|
+
z-index: 0;
|
|
31438
|
+
}
|
|
31439
|
+
}
|
|
31440
|
+
|
|
31375
31441
|
&::view-transition-group(*), &::view-transition-old(*), &::view-transition-new(*) {
|
|
31376
31442
|
animation-duration: var(--navi-route-transition-duration, .3s);
|
|
31377
31443
|
}
|
|
@@ -31411,6 +31477,38 @@ const css$12 = /* css */`:root[data-navi-route-transition] [data-navi-route-tran
|
|
|
31411
31477
|
left: calc(var(--navi-transition-window-new-left) - var(--navi-transition-window-left));
|
|
31412
31478
|
}
|
|
31413
31479
|
|
|
31480
|
+
&[data-navi-route-transition-target="area"] {
|
|
31481
|
+
&[data-navi-route-transition-covered="old"] {
|
|
31482
|
+
&::view-transition-old(navi-route-transition) {
|
|
31483
|
+
clip-path: polygon(calc(var(--navi-transition-old-band-left) - var(--navi-transition-window-old-left))
|
|
31484
|
+
calc(var(--navi-transition-old-band-top) - var(--navi-transition-window-old-top)),
|
|
31485
|
+
calc(100dvw - var(--navi-transition-old-band-right) - var(--navi-transition-window-old-left))
|
|
31486
|
+
calc(var(--navi-transition-old-band-top) - var(--navi-transition-window-old-top)),
|
|
31487
|
+
calc(100dvw - var(--navi-transition-old-band-right) - var(--navi-transition-window-old-left))
|
|
31488
|
+
calc(100dvh - var(--navi-transition-old-band-bottom) - var(--navi-transition-window-old-top)),
|
|
31489
|
+
calc(var(--navi-transition-old-band-left) - var(--navi-transition-window-old-left))
|
|
31490
|
+
calc(100dvh - var(--navi-transition-old-band-bottom) - var(--navi-transition-window-old-top)));
|
|
31491
|
+
}
|
|
31492
|
+
}
|
|
31493
|
+
|
|
31494
|
+
&[data-navi-route-transition-covered="new"] {
|
|
31495
|
+
&::view-transition-new(navi-route-transition) {
|
|
31496
|
+
clip-path: polygon(calc(var(--navi-safe-area-inset-left) +
|
|
31497
|
+
var(--navi-transition-cover-left) - var(--navi-transition-window-new-left))
|
|
31498
|
+
calc(var(--navi-safe-area-inset-top) +
|
|
31499
|
+
var(--navi-transition-cover-top) - var(--navi-transition-window-new-top)),
|
|
31500
|
+
calc(100dvw - var(--navi-safe-area-inset-right) - var(--navi-transition-cover-right) - var(--navi-transition-window-new-left))
|
|
31501
|
+
calc(var(--navi-safe-area-inset-top) +
|
|
31502
|
+
var(--navi-transition-cover-top) - var(--navi-transition-window-new-top)),
|
|
31503
|
+
calc(100dvw - var(--navi-safe-area-inset-right) - var(--navi-transition-cover-right) - var(--navi-transition-window-new-left))
|
|
31504
|
+
calc(100dvh - var(--navi-safe-area-inset-bottom) - var(--navi-transition-cover-bottom) - var(--navi-transition-window-new-top)),
|
|
31505
|
+
calc(var(--navi-safe-area-inset-left) +
|
|
31506
|
+
var(--navi-transition-cover-left) - var(--navi-transition-window-new-left))
|
|
31507
|
+
calc(100dvh - var(--navi-safe-area-inset-bottom) - var(--navi-transition-cover-bottom) - var(--navi-transition-window-new-top)));
|
|
31508
|
+
}
|
|
31509
|
+
}
|
|
31510
|
+
}
|
|
31511
|
+
|
|
31414
31512
|
&[data-navi-route-transition-type] {
|
|
31415
31513
|
&::view-transition-old(root), &::view-transition-new(root), &::view-transition-old(navi-route-transition), &::view-transition-new(navi-route-transition) {
|
|
31416
31514
|
object-fit: none;
|
|
@@ -31495,10 +31593,18 @@ const css$12 = /* css */`:root[data-navi-route-transition] [data-navi-route-tran
|
|
|
31495
31593
|
}
|
|
31496
31594
|
|
|
31497
31595
|
&[data-navi-route-transition-type="cover-right"], &[data-navi-route-transition-type="cover-left"], &[data-navi-route-transition-type="cover-bottom"], &[data-navi-route-transition-type="cover-top"] {
|
|
31596
|
+
&[data-navi-route-transition="forward"] {
|
|
31597
|
+
--navi-route-transition-covered: old;
|
|
31598
|
+
}
|
|
31599
|
+
|
|
31498
31600
|
&[data-navi-route-transition="back"] {
|
|
31499
|
-
|
|
31500
|
-
|
|
31501
|
-
|
|
31601
|
+
--navi-route-transition-covered: new;
|
|
31602
|
+
}
|
|
31603
|
+
}
|
|
31604
|
+
|
|
31605
|
+
&[data-navi-route-transition-covered="new"] {
|
|
31606
|
+
&::view-transition-old(root), &::view-transition-old(navi-route-transition) {
|
|
31607
|
+
z-index: 1;
|
|
31502
31608
|
}
|
|
31503
31609
|
}
|
|
31504
31610
|
|
|
@@ -31701,6 +31807,11 @@ const RouteTransitionArea = ({
|
|
|
31701
31807
|
* }
|
|
31702
31808
|
* }
|
|
31703
31809
|
*
|
|
31810
|
+
* A type of the application's own that plays one page OVER the other says
|
|
31811
|
+
* which one is covered, next to its keyframes:
|
|
31812
|
+
* `--navi-route-transition-covered: old` (the page arriving comes over the
|
|
31813
|
+
* page being left) or `new` (the page being left slides off the page
|
|
31814
|
+
* arriving) — see docs/route_transitions.md, "Custom movements".
|
|
31704
31815
|
* Whatever is written here is what EVERY crossing of the pair plays. One
|
|
31705
31816
|
* crossing can ask for something else — `<Link routeTransition>`, or
|
|
31706
31817
|
* navTo(url, { routeTransition }) — which overrides this field by field, for
|
|
@@ -32344,6 +32455,12 @@ const beginTransition = ({
|
|
|
32344
32455
|
documentElement.setAttribute(TRANSITION_ATTRIBUTE, direction);
|
|
32345
32456
|
if (type) {
|
|
32346
32457
|
documentElement.setAttribute(TRANSITION_TYPE_ATTRIBUTE, type);
|
|
32458
|
+
// Read once the type is worn, which is what makes the type's value
|
|
32459
|
+
// resolve; a value a type does not publish leaves the attribute off.
|
|
32460
|
+
const covered = getComputedStyle(documentElement).getPropertyValue(TRANSITION_COVERED_PROPERTY).trim();
|
|
32461
|
+
if (covered === "old" || covered === "new") {
|
|
32462
|
+
documentElement.setAttribute(TRANSITION_COVERED_ATTRIBUTE, covered);
|
|
32463
|
+
}
|
|
32347
32464
|
}
|
|
32348
32465
|
// Looked up per transition, not once: the area is the application's own
|
|
32349
32466
|
// element and follows its lifecycle — a page layout without bars has none,
|
|
@@ -32446,7 +32563,9 @@ const beginTransition = ({
|
|
|
32446
32563
|
// replaced holds nothing: what it wore was taken off at the takeover.
|
|
32447
32564
|
if (areaElement && currentTransition === transition) {
|
|
32448
32565
|
holdTransitionFurniture(transition, areaElement);
|
|
32449
|
-
holdTransitionWindow(transition, areaElement, areaStateBefore
|
|
32566
|
+
holdTransitionWindow(transition, areaElement, areaStateBefore, {
|
|
32567
|
+
furnitureLive: false
|
|
32568
|
+
});
|
|
32450
32569
|
}
|
|
32451
32570
|
});
|
|
32452
32571
|
const end = () => {
|
|
@@ -32481,6 +32600,7 @@ const releaseTransitionRoot = transition => {
|
|
|
32481
32600
|
const documentElement = document.documentElement;
|
|
32482
32601
|
documentElement.removeAttribute(TRANSITION_ATTRIBUTE);
|
|
32483
32602
|
documentElement.removeAttribute(TRANSITION_TYPE_ATTRIBUTE);
|
|
32603
|
+
documentElement.removeAttribute(TRANSITION_COVERED_ATTRIBUTE);
|
|
32484
32604
|
documentElement.removeAttribute(TRANSITION_TARGET_ATTRIBUTE);
|
|
32485
32605
|
releaseTransitionWindow(transition);
|
|
32486
32606
|
releaseTransitionDestination(transition);
|
|
@@ -33235,7 +33355,11 @@ const RouteTravel = ({
|
|
|
33235
33355
|
// which is what the box is measured through: the two states are at the
|
|
33236
33356
|
// same place in the layout without being at the same place in the window
|
|
33237
33357
|
// (see transition_window.js).
|
|
33238
|
-
|
|
33358
|
+
// The bars stay live under the pictures for a travel: only the box is
|
|
33359
|
+
// photographed (see the TRAVEL_ATTRIBUTE css).
|
|
33360
|
+
holdTransitionWindow(travel, elementRef.current, stateBefore, {
|
|
33361
|
+
furnitureLive: true
|
|
33362
|
+
});
|
|
33239
33363
|
});
|
|
33240
33364
|
travel.viewTransition = viewTransition;
|
|
33241
33365
|
if (scrub) {
|
|
@@ -50338,10 +50462,10 @@ const css$R = /* css */`.navi_expandable {
|
|
|
50338
50462
|
}
|
|
50339
50463
|
|
|
50340
50464
|
& > .navi_expandable_content_container {
|
|
50341
|
-
clip-path: inset(-9999px -9999px 0);
|
|
50342
50465
|
grid-template-rows: 0fr;
|
|
50343
50466
|
display: grid;
|
|
50344
50467
|
position: relative;
|
|
50468
|
+
overflow-y: clip;
|
|
50345
50469
|
|
|
50346
50470
|
& > .navi_expandable_content_sizer {
|
|
50347
50471
|
min-height: 0;
|
|
@@ -50354,7 +50478,6 @@ const css$R = /* css */`.navi_expandable {
|
|
|
50354
50478
|
}
|
|
50355
50479
|
|
|
50356
50480
|
&[data-open-direction="up"] > .navi_expandable_content_container {
|
|
50357
|
-
clip-path: inset(0 -9999px -9999px);
|
|
50358
50481
|
align-content: end;
|
|
50359
50482
|
|
|
50360
50483
|
& > .navi_expandable_content_sizer {
|
|
@@ -50376,9 +50499,9 @@ const css$R = /* css */`.navi_expandable {
|
|
|
50376
50499
|
}
|
|
50377
50500
|
|
|
50378
50501
|
& > .navi_expandable_content_container {
|
|
50379
|
-
clip-path: inset(-9999px 0 0 -9999px);
|
|
50380
50502
|
grid-template-rows: 0fr;
|
|
50381
50503
|
grid-template-columns: 0fr;
|
|
50504
|
+
overflow: clip;
|
|
50382
50505
|
|
|
50383
50506
|
& > .navi_expandable_content_sizer {
|
|
50384
50507
|
min-width: 0;
|
|
@@ -50396,7 +50519,6 @@ const css$R = /* css */`.navi_expandable {
|
|
|
50396
50519
|
}
|
|
50397
50520
|
|
|
50398
50521
|
&[data-open-direction="left"] > .navi_expandable_content_container {
|
|
50399
|
-
clip-path: inset(-9999px -9999px 0 0);
|
|
50400
50522
|
justify-content: end;
|
|
50401
50523
|
|
|
50402
50524
|
& > .navi_expandable_content_sizer {
|
|
@@ -50418,11 +50540,10 @@ const css$R = /* css */`.navi_expandable {
|
|
|
50418
50540
|
}
|
|
50419
50541
|
|
|
50420
50542
|
&[aria-expanded="true"][data-settled] > .navi_expandable_content_container {
|
|
50421
|
-
|
|
50543
|
+
overflow: visible;
|
|
50422
50544
|
}
|
|
50423
50545
|
|
|
50424
50546
|
&:not([aria-expanded="true"])[data-settled] > .navi_expandable_content_container {
|
|
50425
|
-
clip-path: none;
|
|
50426
50547
|
overflow: clip;
|
|
50427
50548
|
}
|
|
50428
50549
|
|
|
@@ -50519,11 +50640,12 @@ const useExpandableContext = partName => {
|
|
|
50519
50640
|
* that can scroll so the content revealed past its edge is on screen: an
|
|
50520
50641
|
* expandable opening at the bottom of a list otherwise grows below the
|
|
50521
50642
|
* fold, and the user sees the row grow but not what it grew with. Measured
|
|
50522
|
-
* on the open layout
|
|
50523
|
-
*
|
|
50524
|
-
*
|
|
50525
|
-
*
|
|
50526
|
-
*
|
|
50643
|
+
* on the open layout, once per opening; when `animation` plays the
|
|
50644
|
+
* scroller rides along with the reveal, at the track's own progress, and
|
|
50645
|
+
* otherwise it goes there at once. A `scroll-margin` on the expandable is
|
|
50646
|
+
* honored. An expandable taller than the scroller keeps its UI part on
|
|
50647
|
+
* screen and the content follows as far as it fits. Only the nearest
|
|
50648
|
+
* scroller moves — a popup or a page around it stays where it is.
|
|
50527
50649
|
* @param maxContentHeight - Caps the content height; taller content scrolls
|
|
50528
50650
|
* inside the expandable instead of growing it.
|
|
50529
50651
|
* @param mount - When the content is built and thrown away, a popup's own
|
|
@@ -50646,15 +50768,27 @@ const Expandable = props => {
|
|
|
50646
50768
|
cancelSettleWatchRef.current?.();
|
|
50647
50769
|
cancelSettleWatchRef.current = null;
|
|
50648
50770
|
};
|
|
50649
|
-
|
|
50771
|
+
// `stopRide`, when the scroller rides along with the reveal (keepInView):
|
|
50772
|
+
// the ride is part of the movement, so it ends with it — settled or
|
|
50773
|
+
// cancelled — and never on its own clock.
|
|
50774
|
+
const watchSettle = stopRide => {
|
|
50650
50775
|
const contentContainer = contentContainerRef.current;
|
|
50651
50776
|
const contentElement = contentContainer.firstElementChild.firstElementChild;
|
|
50652
|
-
|
|
50777
|
+
const cancelWatch = whenTransitionSettles(contentContainer, () => {
|
|
50653
50778
|
cancelSettleWatchRef.current = null;
|
|
50779
|
+
if (stopRide) {
|
|
50780
|
+
stopRide();
|
|
50781
|
+
}
|
|
50654
50782
|
contentElement.style.width = "";
|
|
50655
50783
|
contentElement.style.height = "";
|
|
50656
50784
|
setSettled(true);
|
|
50657
50785
|
});
|
|
50786
|
+
cancelSettleWatchRef.current = () => {
|
|
50787
|
+
if (stopRide) {
|
|
50788
|
+
stopRide();
|
|
50789
|
+
}
|
|
50790
|
+
cancelWatch();
|
|
50791
|
+
};
|
|
50658
50792
|
};
|
|
50659
50793
|
|
|
50660
50794
|
// The reveal needs the content at its final size before the track starts
|
|
@@ -50673,17 +50807,22 @@ const Expandable = props => {
|
|
|
50673
50807
|
} else {
|
|
50674
50808
|
contentElement.style.height = `${finalRect.height}px`;
|
|
50675
50809
|
}
|
|
50810
|
+
let stopRide = null;
|
|
50676
50811
|
if (keepInView) {
|
|
50677
|
-
//
|
|
50678
|
-
// this point, so where the content ends is known before the
|
|
50679
|
-
// starts
|
|
50680
|
-
//
|
|
50681
|
-
|
|
50682
|
-
|
|
50683
|
-
|
|
50684
|
-
|
|
50685
|
-
|
|
50686
|
-
|
|
50812
|
+
// Measured here and not once the reveal settles: the layout is the open
|
|
50813
|
+
// one at this point, so where the content ends is known before the
|
|
50814
|
+
// movement starts. The scroll then rides the movement rather than
|
|
50815
|
+
// running ahead of it (see rideScrollerAlongReveal).
|
|
50816
|
+
const revealScroll = measureRevealScroll(rootRef.current, revealDirection);
|
|
50817
|
+
if (revealScroll) {
|
|
50818
|
+
const finalContainerRect = contentContainer.getBoundingClientRect();
|
|
50819
|
+
stopRide = rideScrollerAlongReveal(revealScroll, {
|
|
50820
|
+
contentContainer,
|
|
50821
|
+
axis: isColumn ? "x" : "y",
|
|
50822
|
+
startSize: isColumn ? startRect.width : startRect.height,
|
|
50823
|
+
finalSize: isColumn ? finalContainerRect.width : finalContainerRect.height
|
|
50824
|
+
});
|
|
50825
|
+
}
|
|
50687
50826
|
}
|
|
50688
50827
|
// Put the tracks back where the last paint left them and let the
|
|
50689
50828
|
// transition play from there. In fr — px does not interpolate with fr.
|
|
@@ -50706,6 +50845,7 @@ const Expandable = props => {
|
|
|
50706
50845
|
contentContainer.style.transitionProperty = "";
|
|
50707
50846
|
contentContainer.style.gridTemplateColumns = "";
|
|
50708
50847
|
contentContainer.style.gridTemplateRows = "";
|
|
50848
|
+
return stopRide;
|
|
50709
50849
|
};
|
|
50710
50850
|
|
|
50711
50851
|
// What opening LOOKS like here, and how to undo it — the one thing an
|
|
@@ -50737,12 +50877,17 @@ const Expandable = props => {
|
|
|
50737
50877
|
// transfer there is nothing to restore on close either.
|
|
50738
50878
|
const restoreFocus = autoFocus && !silent && contentContainer ? openController.transferFocusOnOpen(contentContainer) : null;
|
|
50739
50879
|
if (revealing) {
|
|
50740
|
-
armReveal(startRect);
|
|
50741
|
-
watchSettle();
|
|
50880
|
+
const stopRide = armReveal(startRect);
|
|
50881
|
+
watchSettle(stopRide);
|
|
50742
50882
|
} else if (keepInView && !silent && contentContainer) {
|
|
50743
|
-
|
|
50744
|
-
|
|
50745
|
-
|
|
50883
|
+
const revealScroll = measureRevealScroll(rootRef.current, revealDirection);
|
|
50884
|
+
if (revealScroll) {
|
|
50885
|
+
// No behavior: the scroller's own scroll-behavior decides.
|
|
50886
|
+
revealScroll.scrollerEl.scrollTo({
|
|
50887
|
+
left: revealScroll.left,
|
|
50888
|
+
top: revealScroll.top
|
|
50889
|
+
});
|
|
50890
|
+
}
|
|
50746
50891
|
}
|
|
50747
50892
|
if (!silent) {
|
|
50748
50893
|
rootRef.current.dispatchEvent(createToggleEvent(true));
|
|
@@ -50784,7 +50929,7 @@ const Expandable = props => {
|
|
|
50784
50929
|
}
|
|
50785
50930
|
}
|
|
50786
50931
|
if (collapsing) {
|
|
50787
|
-
watchSettle();
|
|
50932
|
+
watchSettle(null);
|
|
50788
50933
|
}
|
|
50789
50934
|
rootRef.current.dispatchEvent(createToggleEvent(false));
|
|
50790
50935
|
};
|
|
@@ -51124,16 +51269,14 @@ Expandable.Content = ExpandableContent;
|
|
|
51124
51269
|
// the one exception, excluded at the call site.
|
|
51125
51270
|
const UI_INTERACTIVE_SELECTOR = ["a[href]", "button", "input", "select", "textarea", "label", "[role='button']", "[contenteditable='']", "[contenteditable='true']", "audio[controls]", "video[controls]"].join(", ");
|
|
51126
51271
|
|
|
51127
|
-
//
|
|
51128
|
-
// part and revealed content —
|
|
51129
|
-
// so the caller
|
|
51130
|
-
// openEffect). A root taller than the view is aligned on
|
|
51131
|
-
// what the user pressed stays on screen, and the content
|
|
51132
|
-
// fits. One scroller only — a popup or a page around it
|
|
51133
|
-
|
|
51134
|
-
|
|
51135
|
-
behavior
|
|
51136
|
-
}) => {
|
|
51272
|
+
// Where the nearest scroller that can scroll would have to be for the whole
|
|
51273
|
+
// expandable — UI part and revealed content — to be in view. Measured on the
|
|
51274
|
+
// layout as it stands, so the caller measures while the open layout is the
|
|
51275
|
+
// one laid out (see openEffect). A root taller than the view is aligned on
|
|
51276
|
+
// its UI side instead: what the user pressed stays on screen, and the content
|
|
51277
|
+
// follows as far as it fits. One scroller only — a popup or a page around it
|
|
51278
|
+
// is left where it is. Null when there is no scroller, or nothing to scroll.
|
|
51279
|
+
const measureRevealScroll = (rootEl, revealDirection) => {
|
|
51137
51280
|
let scrollerEl = null;
|
|
51138
51281
|
for (const scrollContainer of getScrollContainerSet(rootEl)) {
|
|
51139
51282
|
if (isScrollable(scrollContainer)) {
|
|
@@ -51142,7 +51285,7 @@ const scrollExpandableIntoView = (rootEl, {
|
|
|
51142
51285
|
}
|
|
51143
51286
|
}
|
|
51144
51287
|
if (!scrollerEl) {
|
|
51145
|
-
return;
|
|
51288
|
+
return null;
|
|
51146
51289
|
}
|
|
51147
51290
|
const rootRect = rootEl.getBoundingClientRect();
|
|
51148
51291
|
let block = "nearest";
|
|
@@ -51154,12 +51297,74 @@ const scrollExpandableIntoView = (rootEl, {
|
|
|
51154
51297
|
} else if (rootRect.width > scrollerEl.clientWidth) {
|
|
51155
51298
|
inline = revealDirection === "right" ? "start" : "end";
|
|
51156
51299
|
}
|
|
51157
|
-
|
|
51300
|
+
const {
|
|
51301
|
+
left,
|
|
51302
|
+
top
|
|
51303
|
+
} = getScrollIntoViewScopedOffsets(rootEl, {
|
|
51158
51304
|
container: scrollerEl,
|
|
51159
51305
|
block,
|
|
51160
|
-
inline
|
|
51161
|
-
behavior
|
|
51306
|
+
inline
|
|
51162
51307
|
});
|
|
51308
|
+
if (left === scrollerEl.scrollLeft && top === scrollerEl.scrollTop) {
|
|
51309
|
+
return null;
|
|
51310
|
+
}
|
|
51311
|
+
return {
|
|
51312
|
+
scrollerEl,
|
|
51313
|
+
left,
|
|
51314
|
+
top
|
|
51315
|
+
};
|
|
51316
|
+
};
|
|
51317
|
+
|
|
51318
|
+
// Moves the scroller toward where the reveal ends at the pace of the reveal
|
|
51319
|
+
// itself: every frame the track's progress is read from the container's size
|
|
51320
|
+
// and the scroll stands the same fraction of its own way. The scroll cannot
|
|
51321
|
+
// run ahead of the track: only the box's own growth extends the scroller's
|
|
51322
|
+
// range, and what the target adds around the box (a parent's padding, a
|
|
51323
|
+
// scroll-margin) becomes reachable as the track grows — a scroll started at
|
|
51324
|
+
// once would be clamped short of it. One clock, the transition's, so the
|
|
51325
|
+
// content never waits below the fold either. Returns what stops the ride.
|
|
51326
|
+
const rideScrollerAlongReveal = ({
|
|
51327
|
+
scrollerEl,
|
|
51328
|
+
left,
|
|
51329
|
+
top
|
|
51330
|
+
}, {
|
|
51331
|
+
contentContainer,
|
|
51332
|
+
axis,
|
|
51333
|
+
startSize,
|
|
51334
|
+
finalSize
|
|
51335
|
+
}) => {
|
|
51336
|
+
const startLeft = scrollerEl.scrollLeft;
|
|
51337
|
+
const startTop = scrollerEl.scrollTop;
|
|
51338
|
+
const leftDelta = left - startLeft;
|
|
51339
|
+
const topDelta = top - startTop;
|
|
51340
|
+
let frameId;
|
|
51341
|
+
const tick = () => {
|
|
51342
|
+
const rect = contentContainer.getBoundingClientRect();
|
|
51343
|
+
const size = axis === "x" ? rect.width : rect.height;
|
|
51344
|
+
let progress = 1;
|
|
51345
|
+
if (finalSize !== startSize) {
|
|
51346
|
+
progress = (size - startSize) / (finalSize - startSize);
|
|
51347
|
+
if (progress < 0) {
|
|
51348
|
+
progress = 0;
|
|
51349
|
+
} else if (progress > 1) {
|
|
51350
|
+
progress = 1;
|
|
51351
|
+
}
|
|
51352
|
+
}
|
|
51353
|
+
scrollerEl.scrollTo({
|
|
51354
|
+
left: startLeft + leftDelta * progress,
|
|
51355
|
+
top: startTop + topDelta * progress,
|
|
51356
|
+
// Driven frame by frame: a smooth scroll-behavior on the scroller is
|
|
51357
|
+
// for a scroll that lands, not for one that is held.
|
|
51358
|
+
behavior: "instant"
|
|
51359
|
+
});
|
|
51360
|
+
if (progress < 1) {
|
|
51361
|
+
frameId = requestAnimationFrame(tick);
|
|
51362
|
+
}
|
|
51363
|
+
};
|
|
51364
|
+
frameId = requestAnimationFrame(tick);
|
|
51365
|
+
return () => {
|
|
51366
|
+
cancelAnimationFrame(frameId);
|
|
51367
|
+
};
|
|
51163
51368
|
};
|
|
51164
51369
|
const createToggleEvent = open => {
|
|
51165
51370
|
const newState = open ? "open" : "closed";
|