@jsenv/navi 0.29.372 → 0.29.374
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 +127 -9
- package/dist/dev/jsenv_navi.js.map +3 -3
- package/dist/jsenv_navi.js +127 -9
- package/dist/jsenv_navi.js.map +3 -3
- package/docs/route_transitions.md +20 -1
- package/docs/view_transitions.md +43 -0
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -29123,6 +29123,11 @@ const FURNITURE_NAME_PREFIX = "navi-transition-furniture-";
|
|
|
29123
29123
|
const TOP_LAYER_WALL_SELECTOR =
|
|
29124
29124
|
".navi_dialog:modal, .navi_popover_backdrop:popover-open";
|
|
29125
29125
|
const WALL_ATTRIBUTE = "data-navi-transition-wall";
|
|
29126
|
+
// Worn by a bar both states have, from the hold on: its two pictures are one
|
|
29127
|
+
// group, and the group is ordered over the pages (route_transition.jsx). Only
|
|
29128
|
+
// a bar — a popup's class is written by layout/popup_css.js, and a second rule
|
|
29129
|
+
// on the same property would replace it.
|
|
29130
|
+
const SHARED_ATTRIBUTE = "data-navi-transition-furniture-shared";
|
|
29126
29131
|
// What the wall paints, resolved on the matched element in both cases (the
|
|
29127
29132
|
// dialog for its ::backdrop, the popover's wall for itself): the same two
|
|
29128
29133
|
// properties, copied onto the stand-in.
|
|
@@ -29131,7 +29136,11 @@ const WALL_PROPERTIES = ["--backdrop-background", "--backdrop-filter"];
|
|
|
29131
29136
|
// The pictures the wall is painted into: the pages', and every bar's own.
|
|
29132
29137
|
const FIXED_BAR_SELECTOR$1 = ".navi_fixed_bar";
|
|
29133
29138
|
|
|
29134
|
-
const
|
|
29139
|
+
const TRANSITION_FURNITURE_CSS = /* css */ `.navi_fixed_bar[data-navi-transition-furniture-shared] {
|
|
29140
|
+
view-transition-class: navi_furniture_shared;
|
|
29141
|
+
}
|
|
29142
|
+
|
|
29143
|
+
[data-navi-transition-wall] {
|
|
29135
29144
|
z-index: var(--navi-z-index-top-layer);
|
|
29136
29145
|
background: var(--backdrop-background);
|
|
29137
29146
|
backdrop-filter: var(--backdrop-filter);
|
|
@@ -29164,7 +29173,7 @@ const TRANSITION_WALL_CSS = /* css */ `[data-navi-transition-wall] {
|
|
|
29164
29173
|
// a page that never travels between routes must not carry this sheet, and a
|
|
29165
29174
|
// build that sees no caller drops the css with the function.
|
|
29166
29175
|
const installTransitionFurnitureCss = () => {
|
|
29167
|
-
import.meta.css = [
|
|
29176
|
+
import.meta.css = [TRANSITION_FURNITURE_CSS, "@jsenv/navi/src/nav/transition_furniture.js"];
|
|
29168
29177
|
};
|
|
29169
29178
|
|
|
29170
29179
|
const nameByElement = new WeakMap();
|
|
@@ -29226,6 +29235,8 @@ const holdTransitionFurniture = (owner, areaElement) => {
|
|
|
29226
29235
|
for (const element of namedElements) {
|
|
29227
29236
|
if (!element.isConnected) {
|
|
29228
29237
|
namesLeaving.push(nameByElement.get(element));
|
|
29238
|
+
} else if (element.matches(FIXED_BAR_SELECTOR$1)) {
|
|
29239
|
+
element.setAttribute(SHARED_ATTRIBUTE, "");
|
|
29229
29240
|
}
|
|
29230
29241
|
}
|
|
29231
29242
|
const namesArriving = nameFurnitureAround(areaElement);
|
|
@@ -29356,6 +29367,7 @@ const releaseTransitionFurniture = (owner) => {
|
|
|
29356
29367
|
furnitureOwner = null;
|
|
29357
29368
|
for (const element of namedElements) {
|
|
29358
29369
|
element.style.removeProperty(NAME_PROPERTY$1);
|
|
29370
|
+
element.removeAttribute(SHARED_ATTRIBUTE);
|
|
29359
29371
|
}
|
|
29360
29372
|
namedElements = new Set();
|
|
29361
29373
|
if (travelStyleElement) {
|
|
@@ -29387,12 +29399,12 @@ const paintTransitionWalls = (areaElement) => {
|
|
|
29387
29399
|
// positioned against an ancestor of it: the wall is placed from
|
|
29388
29400
|
// wherever its containing block turns out to be, by the offset between
|
|
29389
29401
|
// that box and the target's.
|
|
29390
|
-
const targetRect = target
|
|
29402
|
+
const targetRect = pictureRect(target);
|
|
29391
29403
|
const wallRect = wall.getBoundingClientRect();
|
|
29392
29404
|
wall.style.left = `${targetRect.left - wallRect.left}px`;
|
|
29393
29405
|
wall.style.top = `${targetRect.top - wallRect.top}px`;
|
|
29394
|
-
wall.style.width = `${targetRect.
|
|
29395
|
-
wall.style.height = `${targetRect.
|
|
29406
|
+
wall.style.width = `${targetRect.right - targetRect.left}px`;
|
|
29407
|
+
wall.style.height = `${targetRect.bottom - targetRect.top}px`;
|
|
29396
29408
|
wallElements.push(wall);
|
|
29397
29409
|
}
|
|
29398
29410
|
}
|
|
@@ -29446,11 +29458,45 @@ const paintRestWalls = (sources, opacity) => {
|
|
|
29446
29458
|
const measurePictureRects = (areaElement) => {
|
|
29447
29459
|
const rects = new Map();
|
|
29448
29460
|
for (const target of pictureTargets(areaElement)) {
|
|
29449
|
-
rects.set(target, target
|
|
29461
|
+
rects.set(target, pictureRect(target));
|
|
29450
29462
|
}
|
|
29451
29463
|
return rects;
|
|
29452
29464
|
};
|
|
29453
29465
|
|
|
29466
|
+
// What the picture holds, which is what the wall covers at rest: a bar's
|
|
29467
|
+
// picture carries what its content paints outside its box (a button standing
|
|
29468
|
+
// up out of a tab bar), so its rectangle is taken with its descendants'. The
|
|
29469
|
+
// pages' is their own box — the movement cuts them at it anyway.
|
|
29470
|
+
const pictureRect = (target) => {
|
|
29471
|
+
const rect = target.getBoundingClientRect();
|
|
29472
|
+
let { left, top, right, bottom } = rect;
|
|
29473
|
+
if (!target.matches(FIXED_BAR_SELECTOR$1)) {
|
|
29474
|
+
return { left, top, right, bottom };
|
|
29475
|
+
}
|
|
29476
|
+
for (const descendant of target.querySelectorAll("*")) {
|
|
29477
|
+
if (descendant.hasAttribute(WALL_ATTRIBUTE)) {
|
|
29478
|
+
continue;
|
|
29479
|
+
}
|
|
29480
|
+
const descendantRect = descendant.getBoundingClientRect();
|
|
29481
|
+
if (descendantRect.width === 0 || descendantRect.height === 0) {
|
|
29482
|
+
continue;
|
|
29483
|
+
}
|
|
29484
|
+
if (descendantRect.left < left) {
|
|
29485
|
+
left = descendantRect.left;
|
|
29486
|
+
}
|
|
29487
|
+
if (descendantRect.top < top) {
|
|
29488
|
+
top = descendantRect.top;
|
|
29489
|
+
}
|
|
29490
|
+
if (descendantRect.right > right) {
|
|
29491
|
+
right = descendantRect.right;
|
|
29492
|
+
}
|
|
29493
|
+
if (descendantRect.bottom > bottom) {
|
|
29494
|
+
bottom = descendantRect.bottom;
|
|
29495
|
+
}
|
|
29496
|
+
}
|
|
29497
|
+
return { left, top, right, bottom };
|
|
29498
|
+
};
|
|
29499
|
+
|
|
29454
29500
|
// The holes for the movement, and the ones for its last frame (see the CSS).
|
|
29455
29501
|
const cutRestWalls = (holes, holesArriving = null) => {
|
|
29456
29502
|
for (const restWall of restWallElements) {
|
|
@@ -29465,15 +29511,83 @@ const cutRestWalls = (holes, holesArriving = null) => {
|
|
|
29465
29511
|
};
|
|
29466
29512
|
|
|
29467
29513
|
// One evenodd polygon: the window, then each hole entered from and left by
|
|
29468
|
-
// the window's origin, so the bridges between them have no area.
|
|
29514
|
+
// the window's origin, so the bridges between them have no area. The holes
|
|
29515
|
+
// must not overlap — evenodd fills where two of them do — and they do
|
|
29516
|
+
// overlap as measured: the pages run under the bars by design, so a bar's
|
|
29517
|
+
// rectangle lies inside the area's. Each is cut down to what the ones before
|
|
29518
|
+
// it left.
|
|
29469
29519
|
const holesPolygon = (holes) => {
|
|
29470
29520
|
let polygon = "0 0, 100% 0, 100% 100%, 0 100%, 0 0";
|
|
29471
|
-
for (const { left, top, right, bottom } of holes) {
|
|
29521
|
+
for (const { left, top, right, bottom } of disjointRects(holes)) {
|
|
29472
29522
|
polygon += `, ${left}px ${top}px, ${right}px ${top}px, ${right}px ${bottom}px, ${left}px ${bottom}px, ${left}px ${top}px, 0 0`;
|
|
29473
29523
|
}
|
|
29474
29524
|
return `polygon(evenodd, ${polygon})`;
|
|
29475
29525
|
};
|
|
29476
29526
|
|
|
29527
|
+
const disjointRects = (rects) => {
|
|
29528
|
+
const result = [];
|
|
29529
|
+
for (const rect of rects) {
|
|
29530
|
+
let pieces = [rect];
|
|
29531
|
+
for (const placed of result) {
|
|
29532
|
+
const remaining = [];
|
|
29533
|
+
for (const piece of pieces) {
|
|
29534
|
+
remaining.push(...subtractRect(piece, placed));
|
|
29535
|
+
}
|
|
29536
|
+
pieces = remaining;
|
|
29537
|
+
}
|
|
29538
|
+
result.push(...pieces);
|
|
29539
|
+
}
|
|
29540
|
+
return result;
|
|
29541
|
+
};
|
|
29542
|
+
|
|
29543
|
+
// What is left of `rect` outside `hole`: up to four rectangles around it.
|
|
29544
|
+
const subtractRect = (rect, hole) => {
|
|
29545
|
+
if (
|
|
29546
|
+
hole.left >= rect.right ||
|
|
29547
|
+
hole.right <= rect.left ||
|
|
29548
|
+
hole.top >= rect.bottom ||
|
|
29549
|
+
hole.bottom <= rect.top
|
|
29550
|
+
) {
|
|
29551
|
+
return [rect];
|
|
29552
|
+
}
|
|
29553
|
+
const pieces = [];
|
|
29554
|
+
const innerTop = hole.top > rect.top ? hole.top : rect.top;
|
|
29555
|
+
const innerBottom = hole.bottom < rect.bottom ? hole.bottom : rect.bottom;
|
|
29556
|
+
if (hole.top > rect.top) {
|
|
29557
|
+
pieces.push({
|
|
29558
|
+
left: rect.left,
|
|
29559
|
+
top: rect.top,
|
|
29560
|
+
right: rect.right,
|
|
29561
|
+
bottom: hole.top,
|
|
29562
|
+
});
|
|
29563
|
+
}
|
|
29564
|
+
if (hole.bottom < rect.bottom) {
|
|
29565
|
+
pieces.push({
|
|
29566
|
+
left: rect.left,
|
|
29567
|
+
top: hole.bottom,
|
|
29568
|
+
right: rect.right,
|
|
29569
|
+
bottom: rect.bottom,
|
|
29570
|
+
});
|
|
29571
|
+
}
|
|
29572
|
+
if (hole.left > rect.left) {
|
|
29573
|
+
pieces.push({
|
|
29574
|
+
left: rect.left,
|
|
29575
|
+
top: innerTop,
|
|
29576
|
+
right: hole.left,
|
|
29577
|
+
bottom: innerBottom,
|
|
29578
|
+
});
|
|
29579
|
+
}
|
|
29580
|
+
if (hole.right < rect.right) {
|
|
29581
|
+
pieces.push({
|
|
29582
|
+
left: hole.right,
|
|
29583
|
+
top: innerTop,
|
|
29584
|
+
right: rect.right,
|
|
29585
|
+
bottom: innerBottom,
|
|
29586
|
+
});
|
|
29587
|
+
}
|
|
29588
|
+
return pieces;
|
|
29589
|
+
};
|
|
29590
|
+
|
|
29477
29591
|
const removeRestWalls = () => {
|
|
29478
29592
|
for (const restWall of restWallElements) {
|
|
29479
29593
|
restWall.remove();
|
|
@@ -30058,10 +30172,14 @@ const css$12 = /* css */`:root[data-navi-route-transition] [data-navi-route-tran
|
|
|
30058
30172
|
z-index: 1;
|
|
30059
30173
|
}
|
|
30060
30174
|
|
|
30061
|
-
&::view-transition-group(.
|
|
30175
|
+
&::view-transition-group(.navi_furniture_shared) {
|
|
30062
30176
|
z-index: 2;
|
|
30063
30177
|
}
|
|
30064
30178
|
|
|
30179
|
+
&::view-transition-group(.navi_popup) {
|
|
30180
|
+
z-index: 3;
|
|
30181
|
+
}
|
|
30182
|
+
|
|
30065
30183
|
&::view-transition-group(*), &::view-transition-old(*), &::view-transition-new(*) {
|
|
30066
30184
|
animation-duration: var(--navi-route-transition-duration, .3s);
|
|
30067
30185
|
}
|