@jsenv/navi 0.29.368 → 0.29.369

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.
@@ -89,6 +89,7 @@ const css$17 = /* css */ `@layer navi {
89
89
  --navi-z-index-bar: 100;
90
90
  --navi-z-index-popup: 1000;
91
91
  --navi-z-index-callout: var(--navi-z-index-popup);
92
+ --navi-z-index-top-layer: 10000;
92
93
  }
93
94
  }
94
95
  `;
@@ -29928,6 +29929,8 @@ const warnOnce$1 = (id, message) => {
29928
29929
  console.warn(message);
29929
29930
  };
29930
29931
 
29932
+ installImportMetaCssBuild(import.meta);
29933
+
29931
29934
  /**
29932
29935
  * The furniture around the pages — the fixed bars, and the popups standing
29933
29936
  * over them in the top layer — photographed with them for the length of a
@@ -29975,6 +29978,23 @@ const warnOnce$1 = (id, message) => {
29975
29978
  * that has nothing to do with it. Being unable to answer a press is the price
29976
29979
  * of being photographed, and a route transition is where it costs nothing:
29977
29980
  * both pages are pictures for those few hundred milliseconds anyway.
29981
+ *
29982
+ * The WALL of a modal dialog goes the other way round: it cannot be
29983
+ * photographed at all. It is the browser's own ::backdrop — a pseudo-element,
29984
+ * which wears no name — and the top layer it is painted in is drawn during a
29985
+ * transition only as part of the root's picture, which is opted out while an
29986
+ * area is marked (route_transition.jsx). Captured on its own, the dialog's
29987
+ * box travels; its wall is painted nowhere for the length of the movement,
29988
+ * and the page under it leaves undimmed. So the wall is painted INTO the
29989
+ * page's picture instead: a stand-in laid over the area before each of the
29990
+ * two pictures is taken, painting what the ::backdrop paints, and removed
29991
+ * with the movement. Carried by the page's picture, it leaves with the page
29992
+ * being left and arrives with the page arriving, cut at the page's edge — and
29993
+ * under the dialog's own picture, which stands over the pages (the z-order in
29994
+ * route_transition.jsx). A bar the two states share is outside both pictures
29995
+ * and goes undimmed for those few hundred milliseconds: it is the frame, not
29996
+ * part of the page. A dialog with layer="local" paints a real element for its
29997
+ * wall, inside the page, and needs none of this.
29978
29998
  */
29979
29999
 
29980
30000
  // The browser's top layer: painted above everything the document paints, so
@@ -29992,6 +30012,32 @@ const FURNITURE_SELECTOR = `.navi_fixed_bar, .navi_popover:is(${TOP_LAYER_SELECT
29992
30012
  const TRANSITION_ATTRIBUTE$1 = "data-navi-route-transition";
29993
30013
  const NAME_PROPERTY$1 = "view-transition-name";
29994
30014
  const FURNITURE_NAME_PREFIX = "navi-transition-furniture-";
30015
+ // The dialogs whose wall is the browser's ::backdrop: shown with showModal().
30016
+ // A top-layer dialog without a wall is shown as a popover and has nothing to
30017
+ // stand in for.
30018
+ const MODAL_DIALOG_SELECTOR = ".navi_dialog:modal";
30019
+ const WALL_ATTRIBUTE = "data-navi-transition-wall";
30020
+ // What the ::backdrop paints, resolved on the dialog (layout/dialog.jsx): the
30021
+ // same two properties, copied onto the wall.
30022
+ const WALL_PROPERTIES = ["--backdrop-background", "--backdrop-filter"];
30023
+
30024
+ const TRANSITION_WALL_CSS = /* css */ `[data-navi-transition-wall] {
30025
+ z-index: var(--navi-z-index-top-layer);
30026
+ background: var(--backdrop-background);
30027
+ backdrop-filter: var(--backdrop-filter);
30028
+ pointer-events: none;
30029
+ position: absolute;
30030
+ top: 0;
30031
+ left: 0;
30032
+ }
30033
+ `;
30034
+
30035
+ // Called from the render of whatever holds the pages, never at module scope:
30036
+ // a page that never travels between routes must not carry this sheet, and a
30037
+ // build that sees no caller drops the css with the function.
30038
+ const installTransitionFurnitureCss = () => {
30039
+ import.meta.css = [TRANSITION_WALL_CSS, "@jsenv/navi/src/nav/transition_furniture.js"];
30040
+ };
29995
30041
 
29996
30042
  const nameByElement = new WeakMap();
29997
30043
  let nameCount = 0;
@@ -30004,6 +30050,9 @@ let namedElements = new Set();
30004
30050
  // The rule giving the one-sided bars their movement, written for one movement
30005
30051
  // and taken down with it.
30006
30052
  let travelStyleElement = null;
30053
+ // The walls standing in for the ::backdrop of the modal dialogs open in the
30054
+ // area, painted for one picture and taken down before the next.
30055
+ let wallElements = [];
30007
30056
 
30008
30057
  /**
30009
30058
  * Name what stands around the area, before the picture of the state being left
@@ -30016,6 +30065,7 @@ const nameTransitionFurniture = (owner, areaElement) => {
30016
30065
  namedElements = new Set();
30017
30066
  }
30018
30067
  nameFurnitureAround(areaElement);
30068
+ paintTransitionWalls(areaElement);
30019
30069
  };
30020
30070
 
30021
30071
  /**
@@ -30036,6 +30086,7 @@ const holdTransitionFurniture = (owner, areaElement) => {
30036
30086
  }
30037
30087
  }
30038
30088
  const namesArriving = nameFurnitureAround(areaElement);
30089
+ paintTransitionWalls(areaElement);
30039
30090
  const cssText = `${travelRule("old", namesLeaving, "--navi-route-transition-leave")}${travelRule("new", namesArriving, "--navi-route-transition-enter")}`;
30040
30091
  if (!cssText) {
30041
30092
  return;
@@ -30118,6 +30169,40 @@ const releaseTransitionFurniture = (owner) => {
30118
30169
  travelStyleElement.remove();
30119
30170
  travelStyleElement = null;
30120
30171
  }
30172
+ removeTransitionWalls();
30173
+ };
30174
+
30175
+ // One wall per modal dialog open in the area, in document order: the
30176
+ // ::backdrops stack in the top layer, and what dims the page is all of them.
30177
+ const paintTransitionWalls = (areaElement) => {
30178
+ removeTransitionWalls();
30179
+ for (const dialog of areaElement.querySelectorAll(MODAL_DIALOG_SELECTOR)) {
30180
+ const dialogStyle = getComputedStyle(dialog);
30181
+ const wall = document.createElement("div");
30182
+ wall.setAttribute(WALL_ATTRIBUTE, "");
30183
+ for (const property of WALL_PROPERTIES) {
30184
+ wall.style.setProperty(property, dialogStyle.getPropertyValue(property));
30185
+ }
30186
+ areaElement.appendChild(wall);
30187
+ // The area is not necessarily a containing block, and made one for the
30188
+ // movement it would move whatever the page positioned against an ancestor
30189
+ // of the area: the wall is placed from wherever its containing block
30190
+ // turns out to be, by the offset between that box and the area's.
30191
+ const areaRect = areaElement.getBoundingClientRect();
30192
+ const wallRect = wall.getBoundingClientRect();
30193
+ wall.style.left = `${areaRect.left - wallRect.left}px`;
30194
+ wall.style.top = `${areaRect.top - wallRect.top}px`;
30195
+ wall.style.width = `${areaRect.width}px`;
30196
+ wall.style.height = `${areaRect.height}px`;
30197
+ wallElements.push(wall);
30198
+ }
30199
+ };
30200
+
30201
+ const removeTransitionWalls = () => {
30202
+ for (const wall of wallElements) {
30203
+ wall.remove();
30204
+ }
30205
+ wallElements = [];
30121
30206
  };
30122
30207
 
30123
30208
  installImportMetaCssBuild(import.meta);
@@ -30969,6 +31054,7 @@ const RouteTransitionArea = ({
30969
31054
  }) => {
30970
31055
  import.meta.css = [css$12, "@jsenv/navi/src/nav/route_transition.jsx"];
30971
31056
  installTransitionWindowCss();
31057
+ installTransitionFurnitureCss();
30972
31058
  const props = {
30973
31059
  ...rest,
30974
31060
  [TRANSITION_AREA_ATTRIBUTE]: ""