@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/jsenv_navi.js
CHANGED
|
@@ -29331,9 +29331,13 @@ installImportMetaCssBuild(import.meta);
|
|
|
29331
29331
|
* - a bar only one state has never meets a counterpart. It belongs to the page
|
|
29332
29332
|
* that has it, so it travels with that page — leaving by the keyframes the
|
|
29333
29333
|
* page being left leaves by, arriving by the ones the page arriving arrives
|
|
29334
|
-
* by — instead of going out with the render.
|
|
29335
|
-
*
|
|
29336
|
-
*
|
|
29334
|
+
* by — instead of going out with the render. Over that page, as it is at
|
|
29335
|
+
* rest: the page runs under it, and what it paints outside its box (a button
|
|
29336
|
+
* standing up out of a tab bar) is not cut by its own page. Under the pages
|
|
29337
|
+
* only when its page is covered by the other one — a cover-* movement — so
|
|
29338
|
+
* the sheet comes over it; a popup over everything, standing where it
|
|
29339
|
+
* stands in the document (see the z-order in route_transition.jsx). Which
|
|
29340
|
+
* side a bar is on is said by a class on its group, written here.
|
|
29337
29341
|
*
|
|
29338
29342
|
* A popup shown in the top layer is furniture of the same kind, and its case
|
|
29339
29343
|
* is the sharper one: it is a DOM descendant of the area, yet painted outside
|
|
@@ -29411,11 +29415,17 @@ const FURNITURE_NAME_PREFIX = "navi-transition-furniture-";
|
|
|
29411
29415
|
const TOP_LAYER_WALL_SELECTOR =
|
|
29412
29416
|
".navi_dialog:modal, .navi_popover_backdrop:popover-open";
|
|
29413
29417
|
const WALL_ATTRIBUTE = "data-navi-transition-wall";
|
|
29414
|
-
//
|
|
29415
|
-
//
|
|
29416
|
-
//
|
|
29417
|
-
//
|
|
29418
|
-
|
|
29418
|
+
// Which side of the movement a bar is on, worn by the bar and read by the
|
|
29419
|
+
// browser as the class of its group (the CSS below): "leaving" from the first
|
|
29420
|
+
// picture, "arriving" for a bar the state arriving brought, "shared" for one
|
|
29421
|
+
// that stands in both states, written over "leaving" at the hold. The group's
|
|
29422
|
+
// class is the one captured with the LAST state the element stands in, so a
|
|
29423
|
+
// bar only the state being left has keeps "leaving" from the first capture,
|
|
29424
|
+
// and a shared one takes "shared" from the second. The z-order in
|
|
29425
|
+
// route_transition.jsx is written on these three. Only a bar — a popup's
|
|
29426
|
+
// class is written by layout/popup_css.js, and a second rule on the same
|
|
29427
|
+
// property would replace it.
|
|
29428
|
+
const FURNITURE_ATTRIBUTE = "data-navi-transition-furniture";
|
|
29419
29429
|
// What the wall paints, resolved on the matched element in both cases (the
|
|
29420
29430
|
// dialog for its ::backdrop, the popover's wall for itself): the same two
|
|
29421
29431
|
// properties, copied onto the stand-in.
|
|
@@ -29424,7 +29434,15 @@ const WALL_PROPERTIES = ["--backdrop-background", "--backdrop-filter"];
|
|
|
29424
29434
|
// The pictures the wall is painted into: the pages', and every bar's own.
|
|
29425
29435
|
const FIXED_BAR_SELECTOR$1 = ".navi_fixed_bar";
|
|
29426
29436
|
|
|
29427
|
-
const TRANSITION_FURNITURE_CSS = /* css */ `.navi_fixed_bar[data-navi-transition-furniture
|
|
29437
|
+
const TRANSITION_FURNITURE_CSS = /* css */ `.navi_fixed_bar[data-navi-transition-furniture="leaving"] {
|
|
29438
|
+
view-transition-class: navi_furniture_leaving;
|
|
29439
|
+
}
|
|
29440
|
+
|
|
29441
|
+
.navi_fixed_bar[data-navi-transition-furniture="arriving"] {
|
|
29442
|
+
view-transition-class: navi_furniture_arriving;
|
|
29443
|
+
}
|
|
29444
|
+
|
|
29445
|
+
.navi_fixed_bar[data-navi-transition-furniture="shared"] {
|
|
29428
29446
|
view-transition-class: navi_furniture_shared;
|
|
29429
29447
|
}
|
|
29430
29448
|
|
|
@@ -29497,7 +29515,7 @@ const nameTransitionFurniture = (owner, areaElement) => {
|
|
|
29497
29515
|
furnitureOwner = owner;
|
|
29498
29516
|
namedElements = new Set();
|
|
29499
29517
|
}
|
|
29500
|
-
nameFurnitureAround(areaElement);
|
|
29518
|
+
nameFurnitureAround(areaElement, "leaving");
|
|
29501
29519
|
const sources = paintTransitionWalls(areaElement);
|
|
29502
29520
|
// The state being left has walls: what no picture covers starts dimmed.
|
|
29503
29521
|
// The frame the first picture is taken on shows the live document, so the
|
|
@@ -29524,10 +29542,10 @@ const holdTransitionFurniture = (owner, areaElement) => {
|
|
|
29524
29542
|
if (!element.isConnected) {
|
|
29525
29543
|
namesLeaving.push(nameByElement.get(element));
|
|
29526
29544
|
} else if (element.matches(FIXED_BAR_SELECTOR$1)) {
|
|
29527
|
-
element.setAttribute(
|
|
29545
|
+
element.setAttribute(FURNITURE_ATTRIBUTE, "shared");
|
|
29528
29546
|
}
|
|
29529
29547
|
}
|
|
29530
|
-
const namesArriving = nameFurnitureAround(areaElement);
|
|
29548
|
+
const namesArriving = nameFurnitureAround(areaElement, "arriving");
|
|
29531
29549
|
const sources = paintTransitionWalls(areaElement);
|
|
29532
29550
|
// The state arriving has walls: what no picture covers ends dimmed. Painted
|
|
29533
29551
|
// from the state being left when that one had walls (they stay up if both
|
|
@@ -29577,7 +29595,8 @@ const holdTransitionFurniture = (owner, areaElement) => {
|
|
|
29577
29595
|
|
|
29578
29596
|
// Returns the elements it had to name, which are the ones the state arriving
|
|
29579
29597
|
// brought: everything else was already wearing its name from the first pass.
|
|
29580
|
-
|
|
29598
|
+
// `side` is what a bar named here is told it is on (see FURNITURE_ATTRIBUTE).
|
|
29599
|
+
const nameFurnitureAround = (areaElement, side) => {
|
|
29581
29600
|
const namesAdded = [];
|
|
29582
29601
|
for (const element of document.querySelectorAll(FURNITURE_SELECTOR)) {
|
|
29583
29602
|
if (namedElements.has(element)) {
|
|
@@ -29603,6 +29622,9 @@ const nameFurnitureAround = (areaElement) => {
|
|
|
29603
29622
|
nameByElement.set(element, name);
|
|
29604
29623
|
}
|
|
29605
29624
|
element.style.setProperty(NAME_PROPERTY$1, name);
|
|
29625
|
+
if (element.matches(FIXED_BAR_SELECTOR$1)) {
|
|
29626
|
+
element.setAttribute(FURNITURE_ATTRIBUTE, side);
|
|
29627
|
+
}
|
|
29606
29628
|
namedElements.add(element);
|
|
29607
29629
|
namesAdded.push(name);
|
|
29608
29630
|
}
|
|
@@ -29652,7 +29674,7 @@ const releaseTransitionFurniture = (owner) => {
|
|
|
29652
29674
|
furnitureOwner = null;
|
|
29653
29675
|
for (const element of namedElements) {
|
|
29654
29676
|
element.style.removeProperty(NAME_PROPERTY$1);
|
|
29655
|
-
element.removeAttribute(
|
|
29677
|
+
element.removeAttribute(FURNITURE_ATTRIBUTE);
|
|
29656
29678
|
}
|
|
29657
29679
|
namedElements = new Set();
|
|
29658
29680
|
if (travelStyleElement) {
|
|
@@ -29975,7 +29997,20 @@ const measureTransitionWindowState = (element) => {
|
|
|
29975
29997
|
};
|
|
29976
29998
|
};
|
|
29977
29999
|
|
|
29978
|
-
|
|
30000
|
+
/**
|
|
30001
|
+
* @param {object} options
|
|
30002
|
+
* @param {boolean} options.furnitureLive - Whether the bars stay live under
|
|
30003
|
+
* the pictures for the movement (a travel), or are pictures of their own
|
|
30004
|
+
* ordered over the page they belong to (a route transition, see
|
|
30005
|
+
* transition_furniture.js). Decides how far the cut may be opened for the
|
|
30006
|
+
* picture being left — see bandTheCutMayBeRelaxedTo.
|
|
30007
|
+
*/
|
|
30008
|
+
const holdTransitionWindow = (
|
|
30009
|
+
owner,
|
|
30010
|
+
element,
|
|
30011
|
+
stateBefore,
|
|
30012
|
+
{ furnitureLive },
|
|
30013
|
+
) => {
|
|
29979
30014
|
const bandBefore = stateBefore.band;
|
|
29980
30015
|
const rectAfter = element.getBoundingClientRect();
|
|
29981
30016
|
const bandAfter = readBand();
|
|
@@ -30009,7 +30044,9 @@ const holdTransitionWindow = (owner, element, stateBefore) => {
|
|
|
30009
30044
|
style.setProperty(WINDOW_OLD_LEFT_PROPERTY, `${rectBefore.left}px`);
|
|
30010
30045
|
style.setProperty(WINDOW_NEW_TOP_PROPERTY, `${rectAfter.top}px`);
|
|
30011
30046
|
style.setProperty(WINDOW_NEW_LEFT_PROPERTY, `${rectAfter.left}px`);
|
|
30012
|
-
const oldBand =
|
|
30047
|
+
const oldBand = furnitureLive
|
|
30048
|
+
? bandTheCutMayBeRelaxedTo(bandBefore, bandAfter, rectAfter)
|
|
30049
|
+
: bandBefore;
|
|
30013
30050
|
style.setProperty(OLD_BAND_TOP_PROPERTY, `${oldBand.top}px`);
|
|
30014
30051
|
style.setProperty(OLD_BAND_RIGHT_PROPERTY, `${oldBand.right}px`);
|
|
30015
30052
|
style.setProperty(OLD_BAND_BOTTOM_PROPERTY, `${oldBand.bottom}px`);
|
|
@@ -30172,18 +30209,25 @@ const readBand = () => {
|
|
|
30172
30209
|
};
|
|
30173
30210
|
};
|
|
30174
30211
|
|
|
30175
|
-
// How far the cut may be opened for the picture being left
|
|
30176
|
-
// state kept free, which is the
|
|
30177
|
-
// present in only one of the two
|
|
30178
|
-
//
|
|
30179
|
-
// header being sliced instead of
|
|
30212
|
+
// How far the cut may be opened for the picture being left when the furniture
|
|
30213
|
+
// is LIVE under the pictures — the band its own state kept free, which is the
|
|
30214
|
+
// whole point of photographing it: furniture present in only one of the two
|
|
30215
|
+
// states is not the frame, it is part of what changes, and cutting the page
|
|
30216
|
+
// being left at a bar it never had shows its header being sliced instead of
|
|
30217
|
+
// leaving.
|
|
30180
30218
|
//
|
|
30181
30219
|
// Never past what the picture ARRIVING needs, though: the cut is one line for
|
|
30182
30220
|
// both pictures, so opening it for one opens it for the other. A box that runs
|
|
30183
|
-
// under the furniture it arrives beside — a page scrolled below a top bar
|
|
30184
|
-
// would then be watched painting over that bar for the length of the
|
|
30185
|
-
// which is what the cut exists to prevent. On such an edge the
|
|
30186
|
-
// stands, and the page being left is cut as it always was.
|
|
30221
|
+
// under the live furniture it arrives beside — a page scrolled below a top bar
|
|
30222
|
+
// — would then be watched painting over that bar for the length of the
|
|
30223
|
+
// movement, which is what the cut exists to prevent. On such an edge the
|
|
30224
|
+
// arriving band stands, and the page being left is cut as it always was.
|
|
30225
|
+
//
|
|
30226
|
+
// With the furniture photographed (a route transition) none of this holds: a
|
|
30227
|
+
// bar only the arriving state has is a picture ordered over the page it
|
|
30228
|
+
// belongs to, and a page arriving under it paints nothing over it. The band
|
|
30229
|
+
// of the state being left is then published as it was, so the page being
|
|
30230
|
+
// left is never cut at a bar it never had.
|
|
30187
30231
|
const bandTheCutMayBeRelaxedTo = (bandBefore, bandAfter, rectAfter) => {
|
|
30188
30232
|
return {
|
|
30189
30233
|
top: rectAfter.top < bandAfter.top ? bandAfter.top : bandBefore.top,
|
|
@@ -30376,6 +30420,16 @@ const startViewTransition$1 = ensureDocumentStartViewTransition();
|
|
|
30376
30420
|
const TRANSITION_ATTRIBUTE = "data-navi-route-transition";
|
|
30377
30421
|
const TRANSITION_TYPE_ATTRIBUTE = "data-navi-route-transition-type";
|
|
30378
30422
|
const TRANSITION_DURATION_PROPERTY = "--navi-route-transition-duration";
|
|
30423
|
+
// Which page the other one COVERS, when the movement is one page over the
|
|
30424
|
+
// other: "old" (the page arriving comes over the page being left) or "new"
|
|
30425
|
+
// (the page being left slides off the page arriving). Published by the type
|
|
30426
|
+
// as a value on the root, like its keyframes (see the css), and mirrored as an
|
|
30427
|
+
// attribute for the length of the transition so the rules that depend on it
|
|
30428
|
+
// — which page is on top, what is cut, where the furniture goes — can be
|
|
30429
|
+
// written statically. Absent for a movement where neither page covers the
|
|
30430
|
+
// other.
|
|
30431
|
+
const TRANSITION_COVERED_PROPERTY = "--navi-route-transition-covered";
|
|
30432
|
+
const TRANSITION_COVERED_ATTRIBUTE = "data-navi-route-transition-covered";
|
|
30379
30433
|
// What the movement is played on. The root snapshot spans the viewport, and
|
|
30380
30434
|
// the regions of elements captured on their own (a named bar) are BLANK in it
|
|
30381
30435
|
// — a page sliding vertically then drags a blank band across the screen where
|
|
@@ -30458,7 +30512,7 @@ const css$12 = /* css */`:root[data-navi-route-transition] [data-navi-route-tran
|
|
|
30458
30512
|
z-index: 1;
|
|
30459
30513
|
}
|
|
30460
30514
|
|
|
30461
|
-
&::view-transition-group(.navi_furniture_shared) {
|
|
30515
|
+
&::view-transition-group(.navi_furniture_leaving), &::view-transition-group(.navi_furniture_arriving), &::view-transition-group(.navi_furniture_shared) {
|
|
30462
30516
|
z-index: 2;
|
|
30463
30517
|
}
|
|
30464
30518
|
|
|
@@ -30466,6 +30520,18 @@ const css$12 = /* css */`:root[data-navi-route-transition] [data-navi-route-tran
|
|
|
30466
30520
|
z-index: 3;
|
|
30467
30521
|
}
|
|
30468
30522
|
|
|
30523
|
+
&[data-navi-route-transition-covered="old"] {
|
|
30524
|
+
&::view-transition-group(.navi_furniture_leaving) {
|
|
30525
|
+
z-index: 0;
|
|
30526
|
+
}
|
|
30527
|
+
}
|
|
30528
|
+
|
|
30529
|
+
&[data-navi-route-transition-covered="new"] {
|
|
30530
|
+
&::view-transition-group(.navi_furniture_arriving) {
|
|
30531
|
+
z-index: 0;
|
|
30532
|
+
}
|
|
30533
|
+
}
|
|
30534
|
+
|
|
30469
30535
|
&::view-transition-group(*), &::view-transition-old(*), &::view-transition-new(*) {
|
|
30470
30536
|
animation-duration: var(--navi-route-transition-duration, .3s);
|
|
30471
30537
|
}
|
|
@@ -30505,6 +30571,38 @@ const css$12 = /* css */`:root[data-navi-route-transition] [data-navi-route-tran
|
|
|
30505
30571
|
left: calc(var(--navi-transition-window-new-left) - var(--navi-transition-window-left));
|
|
30506
30572
|
}
|
|
30507
30573
|
|
|
30574
|
+
&[data-navi-route-transition-target="area"] {
|
|
30575
|
+
&[data-navi-route-transition-covered="old"] {
|
|
30576
|
+
&::view-transition-old(navi-route-transition) {
|
|
30577
|
+
clip-path: polygon(calc(var(--navi-transition-old-band-left) - var(--navi-transition-window-old-left))
|
|
30578
|
+
calc(var(--navi-transition-old-band-top) - var(--navi-transition-window-old-top)),
|
|
30579
|
+
calc(100dvw - var(--navi-transition-old-band-right) - var(--navi-transition-window-old-left))
|
|
30580
|
+
calc(var(--navi-transition-old-band-top) - var(--navi-transition-window-old-top)),
|
|
30581
|
+
calc(100dvw - var(--navi-transition-old-band-right) - var(--navi-transition-window-old-left))
|
|
30582
|
+
calc(100dvh - var(--navi-transition-old-band-bottom) - var(--navi-transition-window-old-top)),
|
|
30583
|
+
calc(var(--navi-transition-old-band-left) - var(--navi-transition-window-old-left))
|
|
30584
|
+
calc(100dvh - var(--navi-transition-old-band-bottom) - var(--navi-transition-window-old-top)));
|
|
30585
|
+
}
|
|
30586
|
+
}
|
|
30587
|
+
|
|
30588
|
+
&[data-navi-route-transition-covered="new"] {
|
|
30589
|
+
&::view-transition-new(navi-route-transition) {
|
|
30590
|
+
clip-path: polygon(calc(var(--navi-safe-area-inset-left) +
|
|
30591
|
+
var(--navi-transition-cover-left) - var(--navi-transition-window-new-left))
|
|
30592
|
+
calc(var(--navi-safe-area-inset-top) +
|
|
30593
|
+
var(--navi-transition-cover-top) - var(--navi-transition-window-new-top)),
|
|
30594
|
+
calc(100dvw - var(--navi-safe-area-inset-right) - var(--navi-transition-cover-right) - var(--navi-transition-window-new-left))
|
|
30595
|
+
calc(var(--navi-safe-area-inset-top) +
|
|
30596
|
+
var(--navi-transition-cover-top) - var(--navi-transition-window-new-top)),
|
|
30597
|
+
calc(100dvw - var(--navi-safe-area-inset-right) - var(--navi-transition-cover-right) - var(--navi-transition-window-new-left))
|
|
30598
|
+
calc(100dvh - var(--navi-safe-area-inset-bottom) - var(--navi-transition-cover-bottom) - var(--navi-transition-window-new-top)),
|
|
30599
|
+
calc(var(--navi-safe-area-inset-left) +
|
|
30600
|
+
var(--navi-transition-cover-left) - var(--navi-transition-window-new-left))
|
|
30601
|
+
calc(100dvh - var(--navi-safe-area-inset-bottom) - var(--navi-transition-cover-bottom) - var(--navi-transition-window-new-top)));
|
|
30602
|
+
}
|
|
30603
|
+
}
|
|
30604
|
+
}
|
|
30605
|
+
|
|
30508
30606
|
&[data-navi-route-transition-type] {
|
|
30509
30607
|
&::view-transition-old(root), &::view-transition-new(root), &::view-transition-old(navi-route-transition), &::view-transition-new(navi-route-transition) {
|
|
30510
30608
|
object-fit: none;
|
|
@@ -30589,10 +30687,18 @@ const css$12 = /* css */`:root[data-navi-route-transition] [data-navi-route-tran
|
|
|
30589
30687
|
}
|
|
30590
30688
|
|
|
30591
30689
|
&[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"] {
|
|
30690
|
+
&[data-navi-route-transition="forward"] {
|
|
30691
|
+
--navi-route-transition-covered: old;
|
|
30692
|
+
}
|
|
30693
|
+
|
|
30592
30694
|
&[data-navi-route-transition="back"] {
|
|
30593
|
-
|
|
30594
|
-
|
|
30595
|
-
|
|
30695
|
+
--navi-route-transition-covered: new;
|
|
30696
|
+
}
|
|
30697
|
+
}
|
|
30698
|
+
|
|
30699
|
+
&[data-navi-route-transition-covered="new"] {
|
|
30700
|
+
&::view-transition-old(root), &::view-transition-old(navi-route-transition) {
|
|
30701
|
+
z-index: 1;
|
|
30596
30702
|
}
|
|
30597
30703
|
}
|
|
30598
30704
|
|
|
@@ -30795,6 +30901,11 @@ const RouteTransitionArea = ({
|
|
|
30795
30901
|
* }
|
|
30796
30902
|
* }
|
|
30797
30903
|
*
|
|
30904
|
+
* A type of the application's own that plays one page OVER the other says
|
|
30905
|
+
* which one is covered, next to its keyframes:
|
|
30906
|
+
* `--navi-route-transition-covered: old` (the page arriving comes over the
|
|
30907
|
+
* page being left) or `new` (the page being left slides off the page
|
|
30908
|
+
* arriving) — see docs/route_transitions.md, "Custom movements".
|
|
30798
30909
|
* Whatever is written here is what EVERY crossing of the pair plays. One
|
|
30799
30910
|
* crossing can ask for something else — `<Link routeTransition>`, or
|
|
30800
30911
|
* navTo(url, { routeTransition }) — which overrides this field by field, for
|
|
@@ -31438,6 +31549,12 @@ const beginTransition = ({
|
|
|
31438
31549
|
documentElement.setAttribute(TRANSITION_ATTRIBUTE, direction);
|
|
31439
31550
|
if (type) {
|
|
31440
31551
|
documentElement.setAttribute(TRANSITION_TYPE_ATTRIBUTE, type);
|
|
31552
|
+
// Read once the type is worn, which is what makes the type's value
|
|
31553
|
+
// resolve; a value a type does not publish leaves the attribute off.
|
|
31554
|
+
const covered = getComputedStyle(documentElement).getPropertyValue(TRANSITION_COVERED_PROPERTY).trim();
|
|
31555
|
+
if (covered === "old" || covered === "new") {
|
|
31556
|
+
documentElement.setAttribute(TRANSITION_COVERED_ATTRIBUTE, covered);
|
|
31557
|
+
}
|
|
31441
31558
|
}
|
|
31442
31559
|
// Looked up per transition, not once: the area is the application's own
|
|
31443
31560
|
// element and follows its lifecycle — a page layout without bars has none,
|
|
@@ -31540,7 +31657,9 @@ const beginTransition = ({
|
|
|
31540
31657
|
// replaced holds nothing: what it wore was taken off at the takeover.
|
|
31541
31658
|
if (areaElement && currentTransition === transition) {
|
|
31542
31659
|
holdTransitionFurniture(transition, areaElement);
|
|
31543
|
-
holdTransitionWindow(transition, areaElement, areaStateBefore
|
|
31660
|
+
holdTransitionWindow(transition, areaElement, areaStateBefore, {
|
|
31661
|
+
furnitureLive: false
|
|
31662
|
+
});
|
|
31544
31663
|
}
|
|
31545
31664
|
});
|
|
31546
31665
|
const end = () => {
|
|
@@ -31575,6 +31694,7 @@ const releaseTransitionRoot = transition => {
|
|
|
31575
31694
|
const documentElement = document.documentElement;
|
|
31576
31695
|
documentElement.removeAttribute(TRANSITION_ATTRIBUTE);
|
|
31577
31696
|
documentElement.removeAttribute(TRANSITION_TYPE_ATTRIBUTE);
|
|
31697
|
+
documentElement.removeAttribute(TRANSITION_COVERED_ATTRIBUTE);
|
|
31578
31698
|
documentElement.removeAttribute(TRANSITION_TARGET_ATTRIBUTE);
|
|
31579
31699
|
releaseTransitionWindow(transition);
|
|
31580
31700
|
releaseTransitionDestination(transition);
|
|
@@ -32329,7 +32449,11 @@ const RouteTravel = ({
|
|
|
32329
32449
|
// which is what the box is measured through: the two states are at the
|
|
32330
32450
|
// same place in the layout without being at the same place in the window
|
|
32331
32451
|
// (see transition_window.js).
|
|
32332
|
-
|
|
32452
|
+
// The bars stay live under the pictures for a travel: only the box is
|
|
32453
|
+
// photographed (see the TRAVEL_ATTRIBUTE css).
|
|
32454
|
+
holdTransitionWindow(travel, elementRef.current, stateBefore, {
|
|
32455
|
+
furnitureLive: true
|
|
32456
|
+
});
|
|
32333
32457
|
});
|
|
32334
32458
|
travel.viewTransition = viewTransition;
|
|
32335
32459
|
if (scrub) {
|
|
@@ -49208,10 +49332,10 @@ const css$R = /* css */`.navi_expandable {
|
|
|
49208
49332
|
}
|
|
49209
49333
|
|
|
49210
49334
|
& > .navi_expandable_content_container {
|
|
49211
|
-
clip-path: inset(-9999px -9999px 0);
|
|
49212
49335
|
grid-template-rows: 0fr;
|
|
49213
49336
|
display: grid;
|
|
49214
49337
|
position: relative;
|
|
49338
|
+
overflow-y: clip;
|
|
49215
49339
|
|
|
49216
49340
|
& > .navi_expandable_content_sizer {
|
|
49217
49341
|
min-height: 0;
|
|
@@ -49224,7 +49348,6 @@ const css$R = /* css */`.navi_expandable {
|
|
|
49224
49348
|
}
|
|
49225
49349
|
|
|
49226
49350
|
&[data-open-direction="up"] > .navi_expandable_content_container {
|
|
49227
|
-
clip-path: inset(0 -9999px -9999px);
|
|
49228
49351
|
align-content: end;
|
|
49229
49352
|
|
|
49230
49353
|
& > .navi_expandable_content_sizer {
|
|
@@ -49246,9 +49369,9 @@ const css$R = /* css */`.navi_expandable {
|
|
|
49246
49369
|
}
|
|
49247
49370
|
|
|
49248
49371
|
& > .navi_expandable_content_container {
|
|
49249
|
-
clip-path: inset(-9999px 0 0 -9999px);
|
|
49250
49372
|
grid-template-rows: 0fr;
|
|
49251
49373
|
grid-template-columns: 0fr;
|
|
49374
|
+
overflow: clip;
|
|
49252
49375
|
|
|
49253
49376
|
& > .navi_expandable_content_sizer {
|
|
49254
49377
|
min-width: 0;
|
|
@@ -49266,7 +49389,6 @@ const css$R = /* css */`.navi_expandable {
|
|
|
49266
49389
|
}
|
|
49267
49390
|
|
|
49268
49391
|
&[data-open-direction="left"] > .navi_expandable_content_container {
|
|
49269
|
-
clip-path: inset(-9999px -9999px 0 0);
|
|
49270
49392
|
justify-content: end;
|
|
49271
49393
|
|
|
49272
49394
|
& > .navi_expandable_content_sizer {
|
|
@@ -49288,11 +49410,10 @@ const css$R = /* css */`.navi_expandable {
|
|
|
49288
49410
|
}
|
|
49289
49411
|
|
|
49290
49412
|
&[aria-expanded="true"][data-settled] > .navi_expandable_content_container {
|
|
49291
|
-
|
|
49413
|
+
overflow: visible;
|
|
49292
49414
|
}
|
|
49293
49415
|
|
|
49294
49416
|
&:not([aria-expanded="true"])[data-settled] > .navi_expandable_content_container {
|
|
49295
|
-
clip-path: none;
|
|
49296
49417
|
overflow: clip;
|
|
49297
49418
|
}
|
|
49298
49419
|
|
|
@@ -49389,11 +49510,12 @@ const useExpandableContext = partName => {
|
|
|
49389
49510
|
* that can scroll so the content revealed past its edge is on screen: an
|
|
49390
49511
|
* expandable opening at the bottom of a list otherwise grows below the
|
|
49391
49512
|
* fold, and the user sees the row grow but not what it grew with. Measured
|
|
49392
|
-
* on the open layout
|
|
49393
|
-
*
|
|
49394
|
-
*
|
|
49395
|
-
*
|
|
49396
|
-
*
|
|
49513
|
+
* on the open layout, once per opening; when `animation` plays the
|
|
49514
|
+
* scroller rides along with the reveal, at the track's own progress, and
|
|
49515
|
+
* otherwise it goes there at once. A `scroll-margin` on the expandable is
|
|
49516
|
+
* honored. An expandable taller than the scroller keeps its UI part on
|
|
49517
|
+
* screen and the content follows as far as it fits. Only the nearest
|
|
49518
|
+
* scroller moves — a popup or a page around it stays where it is.
|
|
49397
49519
|
* @param maxContentHeight - Caps the content height; taller content scrolls
|
|
49398
49520
|
* inside the expandable instead of growing it.
|
|
49399
49521
|
* @param mount - When the content is built and thrown away, a popup's own
|
|
@@ -49516,15 +49638,27 @@ const Expandable = props => {
|
|
|
49516
49638
|
cancelSettleWatchRef.current?.();
|
|
49517
49639
|
cancelSettleWatchRef.current = null;
|
|
49518
49640
|
};
|
|
49519
|
-
|
|
49641
|
+
// `stopRide`, when the scroller rides along with the reveal (keepInView):
|
|
49642
|
+
// the ride is part of the movement, so it ends with it — settled or
|
|
49643
|
+
// cancelled — and never on its own clock.
|
|
49644
|
+
const watchSettle = stopRide => {
|
|
49520
49645
|
const contentContainer = contentContainerRef.current;
|
|
49521
49646
|
const contentElement = contentContainer.firstElementChild.firstElementChild;
|
|
49522
|
-
|
|
49647
|
+
const cancelWatch = whenTransitionSettles(contentContainer, () => {
|
|
49523
49648
|
cancelSettleWatchRef.current = null;
|
|
49649
|
+
if (stopRide) {
|
|
49650
|
+
stopRide();
|
|
49651
|
+
}
|
|
49524
49652
|
contentElement.style.width = "";
|
|
49525
49653
|
contentElement.style.height = "";
|
|
49526
49654
|
setSettled(true);
|
|
49527
49655
|
});
|
|
49656
|
+
cancelSettleWatchRef.current = () => {
|
|
49657
|
+
if (stopRide) {
|
|
49658
|
+
stopRide();
|
|
49659
|
+
}
|
|
49660
|
+
cancelWatch();
|
|
49661
|
+
};
|
|
49528
49662
|
};
|
|
49529
49663
|
|
|
49530
49664
|
// The reveal needs the content at its final size before the track starts
|
|
@@ -49543,17 +49677,22 @@ const Expandable = props => {
|
|
|
49543
49677
|
} else {
|
|
49544
49678
|
contentElement.style.height = `${finalRect.height}px`;
|
|
49545
49679
|
}
|
|
49680
|
+
let stopRide = null;
|
|
49546
49681
|
if (keepInView) {
|
|
49547
|
-
//
|
|
49548
|
-
// this point, so where the content ends is known before the
|
|
49549
|
-
// starts
|
|
49550
|
-
//
|
|
49551
|
-
|
|
49552
|
-
|
|
49553
|
-
|
|
49554
|
-
|
|
49555
|
-
|
|
49556
|
-
|
|
49682
|
+
// Measured here and not once the reveal settles: the layout is the open
|
|
49683
|
+
// one at this point, so where the content ends is known before the
|
|
49684
|
+
// movement starts. The scroll then rides the movement rather than
|
|
49685
|
+
// running ahead of it (see rideScrollerAlongReveal).
|
|
49686
|
+
const revealScroll = measureRevealScroll(rootRef.current, revealDirection);
|
|
49687
|
+
if (revealScroll) {
|
|
49688
|
+
const finalContainerRect = contentContainer.getBoundingClientRect();
|
|
49689
|
+
stopRide = rideScrollerAlongReveal(revealScroll, {
|
|
49690
|
+
contentContainer,
|
|
49691
|
+
axis: isColumn ? "x" : "y",
|
|
49692
|
+
startSize: isColumn ? startRect.width : startRect.height,
|
|
49693
|
+
finalSize: isColumn ? finalContainerRect.width : finalContainerRect.height
|
|
49694
|
+
});
|
|
49695
|
+
}
|
|
49557
49696
|
}
|
|
49558
49697
|
// Put the tracks back where the last paint left them and let the
|
|
49559
49698
|
// transition play from there. In fr — px does not interpolate with fr.
|
|
@@ -49576,6 +49715,7 @@ const Expandable = props => {
|
|
|
49576
49715
|
contentContainer.style.transitionProperty = "";
|
|
49577
49716
|
contentContainer.style.gridTemplateColumns = "";
|
|
49578
49717
|
contentContainer.style.gridTemplateRows = "";
|
|
49718
|
+
return stopRide;
|
|
49579
49719
|
};
|
|
49580
49720
|
|
|
49581
49721
|
// What opening LOOKS like here, and how to undo it — the one thing an
|
|
@@ -49607,12 +49747,17 @@ const Expandable = props => {
|
|
|
49607
49747
|
// transfer there is nothing to restore on close either.
|
|
49608
49748
|
const restoreFocus = autoFocus && !silent && contentContainer ? openController.transferFocusOnOpen(contentContainer) : null;
|
|
49609
49749
|
if (revealing) {
|
|
49610
|
-
armReveal(startRect);
|
|
49611
|
-
watchSettle();
|
|
49750
|
+
const stopRide = armReveal(startRect);
|
|
49751
|
+
watchSettle(stopRide);
|
|
49612
49752
|
} else if (keepInView && !silent && contentContainer) {
|
|
49613
|
-
|
|
49614
|
-
|
|
49615
|
-
|
|
49753
|
+
const revealScroll = measureRevealScroll(rootRef.current, revealDirection);
|
|
49754
|
+
if (revealScroll) {
|
|
49755
|
+
// No behavior: the scroller's own scroll-behavior decides.
|
|
49756
|
+
revealScroll.scrollerEl.scrollTo({
|
|
49757
|
+
left: revealScroll.left,
|
|
49758
|
+
top: revealScroll.top
|
|
49759
|
+
});
|
|
49760
|
+
}
|
|
49616
49761
|
}
|
|
49617
49762
|
if (!silent) {
|
|
49618
49763
|
rootRef.current.dispatchEvent(createToggleEvent(true));
|
|
@@ -49654,7 +49799,7 @@ const Expandable = props => {
|
|
|
49654
49799
|
}
|
|
49655
49800
|
}
|
|
49656
49801
|
if (collapsing) {
|
|
49657
|
-
watchSettle();
|
|
49802
|
+
watchSettle(null);
|
|
49658
49803
|
}
|
|
49659
49804
|
rootRef.current.dispatchEvent(createToggleEvent(false));
|
|
49660
49805
|
};
|
|
@@ -49994,16 +50139,14 @@ Expandable.Content = ExpandableContent;
|
|
|
49994
50139
|
// the one exception, excluded at the call site.
|
|
49995
50140
|
const UI_INTERACTIVE_SELECTOR = ["a[href]", "button", "input", "select", "textarea", "label", "[role='button']", "[contenteditable='']", "[contenteditable='true']", "audio[controls]", "video[controls]"].join(", ");
|
|
49996
50141
|
|
|
49997
|
-
//
|
|
49998
|
-
// part and revealed content —
|
|
49999
|
-
// so the caller
|
|
50000
|
-
// openEffect). A root taller than the view is aligned on
|
|
50001
|
-
// what the user pressed stays on screen, and the content
|
|
50002
|
-
// fits. One scroller only — a popup or a page around it
|
|
50003
|
-
|
|
50004
|
-
|
|
50005
|
-
behavior
|
|
50006
|
-
}) => {
|
|
50142
|
+
// Where the nearest scroller that can scroll would have to be for the whole
|
|
50143
|
+
// expandable — UI part and revealed content — to be in view. Measured on the
|
|
50144
|
+
// layout as it stands, so the caller measures while the open layout is the
|
|
50145
|
+
// one laid out (see openEffect). A root taller than the view is aligned on
|
|
50146
|
+
// its UI side instead: what the user pressed stays on screen, and the content
|
|
50147
|
+
// follows as far as it fits. One scroller only — a popup or a page around it
|
|
50148
|
+
// is left where it is. Null when there is no scroller, or nothing to scroll.
|
|
50149
|
+
const measureRevealScroll = (rootEl, revealDirection) => {
|
|
50007
50150
|
let scrollerEl = null;
|
|
50008
50151
|
for (const scrollContainer of getScrollContainerSet(rootEl)) {
|
|
50009
50152
|
if (isScrollable(scrollContainer)) {
|
|
@@ -50012,7 +50155,7 @@ const scrollExpandableIntoView = (rootEl, {
|
|
|
50012
50155
|
}
|
|
50013
50156
|
}
|
|
50014
50157
|
if (!scrollerEl) {
|
|
50015
|
-
return;
|
|
50158
|
+
return null;
|
|
50016
50159
|
}
|
|
50017
50160
|
const rootRect = rootEl.getBoundingClientRect();
|
|
50018
50161
|
let block = "nearest";
|
|
@@ -50024,12 +50167,74 @@ const scrollExpandableIntoView = (rootEl, {
|
|
|
50024
50167
|
} else if (rootRect.width > scrollerEl.clientWidth) {
|
|
50025
50168
|
inline = revealDirection === "right" ? "start" : "end";
|
|
50026
50169
|
}
|
|
50027
|
-
|
|
50170
|
+
const {
|
|
50171
|
+
left,
|
|
50172
|
+
top
|
|
50173
|
+
} = getScrollIntoViewScopedOffsets(rootEl, {
|
|
50028
50174
|
container: scrollerEl,
|
|
50029
50175
|
block,
|
|
50030
|
-
inline
|
|
50031
|
-
behavior
|
|
50176
|
+
inline
|
|
50032
50177
|
});
|
|
50178
|
+
if (left === scrollerEl.scrollLeft && top === scrollerEl.scrollTop) {
|
|
50179
|
+
return null;
|
|
50180
|
+
}
|
|
50181
|
+
return {
|
|
50182
|
+
scrollerEl,
|
|
50183
|
+
left,
|
|
50184
|
+
top
|
|
50185
|
+
};
|
|
50186
|
+
};
|
|
50187
|
+
|
|
50188
|
+
// Moves the scroller toward where the reveal ends at the pace of the reveal
|
|
50189
|
+
// itself: every frame the track's progress is read from the container's size
|
|
50190
|
+
// and the scroll stands the same fraction of its own way. The scroll cannot
|
|
50191
|
+
// run ahead of the track: only the box's own growth extends the scroller's
|
|
50192
|
+
// range, and what the target adds around the box (a parent's padding, a
|
|
50193
|
+
// scroll-margin) becomes reachable as the track grows — a scroll started at
|
|
50194
|
+
// once would be clamped short of it. One clock, the transition's, so the
|
|
50195
|
+
// content never waits below the fold either. Returns what stops the ride.
|
|
50196
|
+
const rideScrollerAlongReveal = ({
|
|
50197
|
+
scrollerEl,
|
|
50198
|
+
left,
|
|
50199
|
+
top
|
|
50200
|
+
}, {
|
|
50201
|
+
contentContainer,
|
|
50202
|
+
axis,
|
|
50203
|
+
startSize,
|
|
50204
|
+
finalSize
|
|
50205
|
+
}) => {
|
|
50206
|
+
const startLeft = scrollerEl.scrollLeft;
|
|
50207
|
+
const startTop = scrollerEl.scrollTop;
|
|
50208
|
+
const leftDelta = left - startLeft;
|
|
50209
|
+
const topDelta = top - startTop;
|
|
50210
|
+
let frameId;
|
|
50211
|
+
const tick = () => {
|
|
50212
|
+
const rect = contentContainer.getBoundingClientRect();
|
|
50213
|
+
const size = axis === "x" ? rect.width : rect.height;
|
|
50214
|
+
let progress = 1;
|
|
50215
|
+
if (finalSize !== startSize) {
|
|
50216
|
+
progress = (size - startSize) / (finalSize - startSize);
|
|
50217
|
+
if (progress < 0) {
|
|
50218
|
+
progress = 0;
|
|
50219
|
+
} else if (progress > 1) {
|
|
50220
|
+
progress = 1;
|
|
50221
|
+
}
|
|
50222
|
+
}
|
|
50223
|
+
scrollerEl.scrollTo({
|
|
50224
|
+
left: startLeft + leftDelta * progress,
|
|
50225
|
+
top: startTop + topDelta * progress,
|
|
50226
|
+
// Driven frame by frame: a smooth scroll-behavior on the scroller is
|
|
50227
|
+
// for a scroll that lands, not for one that is held.
|
|
50228
|
+
behavior: "instant"
|
|
50229
|
+
});
|
|
50230
|
+
if (progress < 1) {
|
|
50231
|
+
frameId = requestAnimationFrame(tick);
|
|
50232
|
+
}
|
|
50233
|
+
};
|
|
50234
|
+
frameId = requestAnimationFrame(tick);
|
|
50235
|
+
return () => {
|
|
50236
|
+
cancelAnimationFrame(frameId);
|
|
50237
|
+
};
|
|
50033
50238
|
};
|
|
50034
50239
|
const createToggleEvent = open => {
|
|
50035
50240
|
const newState = open ? "open" : "closed";
|