@jsenv/navi 0.29.135 → 0.29.137

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.
@@ -27084,10 +27084,17 @@ const releaseTransitionDestination = (owner) => {
27084
27084
  * - a bar the two states SHARE is one element wearing one name on both sides.
27085
27085
  * The browser pairs the two pictures into one group and holds it where it
27086
27086
  * stands: the frame, and the pages move behind it exactly as before.
27087
- * - a bar only one state has never meets a counterpart. It stands where it was
27088
- * photographed while the pages move OVER it (see the z-order in
27089
- * route_transition.jsx) — covered progressively as a page comes over it,
27090
- * uncovered as one leaves — rather than going out with the render.
27087
+ * - a bar only one state has never meets a counterpart. It belongs to the page
27088
+ * that has it, so it travels with that page — leaving by the keyframes the
27089
+ * page being left leaves by, arriving by the ones the page arriving arrives
27090
+ * by — instead of going out with the render. Under the pages, so a page
27091
+ * coming over it covers it (see the z-order in route_transition.jsx).
27092
+ *
27093
+ * Which keyframes those are is published by the movement itself
27094
+ * (--navi-route-transition-leave / -enter, see route_transition.jsx): a
27095
+ * selector cannot say "the bars that have no counterpart" — the names are per
27096
+ * element, so there is nothing static to write — so the rule is written for
27097
+ * the length of the movement, over the names this one turned out to have.
27091
27098
  *
27092
27099
  * The name is per ELEMENT and kept for the element's whole life, which is what
27093
27100
  * makes "shared" mean shared: several bars can live on one edge
@@ -27108,6 +27115,10 @@ const releaseTransitionDestination = (owner) => {
27108
27115
  // inside the pages needs none of this — it lives in the area, so it is already
27109
27116
  // part of the pages' own picture.
27110
27117
  const FURNITURE_SELECTOR = ".navi_fixed_bar";
27118
+ // Worn by the root for the length of a route transition (route_transition.jsx
27119
+ // owns it). Written out rather than imported: importing the module that owns
27120
+ // it back into this one would close a cycle.
27121
+ const TRANSITION_ATTRIBUTE$1 = "data-navi-route-transition";
27111
27122
  const NAME_PROPERTY = "view-transition-name";
27112
27123
  const FURNITURE_NAME_PREFIX = "navi-transition-furniture-";
27113
27124
 
@@ -27119,19 +27130,54 @@ let nameCount = 0;
27119
27130
  // it must not strip what the new one is wearing.
27120
27131
  let furnitureOwner = null;
27121
27132
  let namedElements = new Set();
27133
+ // The rule giving the one-sided bars their movement, written for one movement
27134
+ // and taken down with it.
27135
+ let travelStyleElement = null;
27122
27136
 
27123
27137
  /**
27124
- * Name what stands around the area. Called twice for one movement: before the
27125
- * picture of the state being left is taken, and again once the state arriving
27126
- * has rendered — a bar that just mounted has to wear its name before the
27127
- * second picture, and one that survived the render is left with the name it
27128
- * already has.
27138
+ * Name what stands around the area, before the picture of the state being left
27139
+ * is taken: the browser reads the names off the DOM as it stands when the
27140
+ * transition starts.
27129
27141
  */
27130
27142
  const nameTransitionFurniture = (owner, areaElement) => {
27131
27143
  if (owner !== furnitureOwner) {
27132
27144
  furnitureOwner = owner;
27133
27145
  namedElements = new Set();
27134
27146
  }
27147
+ nameFurnitureAround(areaElement);
27148
+ };
27149
+
27150
+ /**
27151
+ * The state arriving has rendered and the second picture has not been taken:
27152
+ * the one moment both states of the furniture are known. A bar that just
27153
+ * mounted is named — one that survived the render keeps the name it has, which
27154
+ * is what pairs its two pictures — and the bars only one of the two states has
27155
+ * are given the movement of the page they belong to.
27156
+ */
27157
+ const holdTransitionFurniture = (owner, areaElement) => {
27158
+ if (owner !== furnitureOwner) {
27159
+ return;
27160
+ }
27161
+ const namesLeaving = [];
27162
+ for (const element of namedElements) {
27163
+ if (!element.isConnected) {
27164
+ namesLeaving.push(nameByElement.get(element));
27165
+ }
27166
+ }
27167
+ const namesArriving = nameFurnitureAround(areaElement);
27168
+ const cssText = `${travelRule("old", namesLeaving, "--navi-route-transition-leave")}${travelRule("new", namesArriving, "--navi-route-transition-enter")}`;
27169
+ if (!cssText) {
27170
+ return;
27171
+ }
27172
+ travelStyleElement = document.createElement("style");
27173
+ travelStyleElement.textContent = cssText;
27174
+ document.head.appendChild(travelStyleElement);
27175
+ };
27176
+
27177
+ // Returns the elements it had to name, which are the ones the state arriving
27178
+ // brought: everything else was already wearing its name from the first pass.
27179
+ const nameFurnitureAround = (areaElement) => {
27180
+ const namesAdded = [];
27135
27181
  for (const element of document.querySelectorAll(FURNITURE_SELECTOR)) {
27136
27182
  if (namedElements.has(element)) {
27137
27183
  continue;
@@ -27158,7 +27204,32 @@ const nameTransitionFurniture = (owner, areaElement) => {
27158
27204
  }
27159
27205
  element.style.setProperty(NAME_PROPERTY, name);
27160
27206
  namedElements.add(element);
27207
+ namesAdded.push(name);
27161
27208
  }
27209
+ return namesAdded;
27210
+ };
27211
+
27212
+ // The movement, played on pictures no static rule can name. The keyframes are
27213
+ // read rather than guessed: a type navi ships publishes them, and so may one
27214
+ // an application writes — a type that publishes nothing leaves its furniture
27215
+ // to the browser's own fade, which is what the rule not being written means.
27216
+ const travelRule = (side, names, movementProperty) => {
27217
+ if (names.length === 0) {
27218
+ return "";
27219
+ }
27220
+ const animationName = getComputedStyle(document.documentElement)
27221
+ .getPropertyValue(movementProperty)
27222
+ .trim();
27223
+ if (!animationName) {
27224
+ return "";
27225
+ }
27226
+ const selector = names
27227
+ .map(
27228
+ (name) =>
27229
+ `:root[${TRANSITION_ATTRIBUTE$1}]::view-transition-${side}(${name})`,
27230
+ )
27231
+ .join(",");
27232
+ return `${selector}{animation-name:${animationName};animation-timing-function:ease;animation-fill-mode:both}`;
27162
27233
  };
27163
27234
 
27164
27235
  const releaseTransitionFurniture = (owner) => {
@@ -27170,6 +27241,10 @@ const releaseTransitionFurniture = (owner) => {
27170
27241
  element.style.removeProperty(NAME_PROPERTY);
27171
27242
  }
27172
27243
  namedElements = new Set();
27244
+ if (travelStyleElement) {
27245
+ travelStyleElement.remove();
27246
+ travelStyleElement = null;
27247
+ }
27173
27248
  };
27174
27249
 
27175
27250
  /**
@@ -27583,6 +27658,16 @@ const css$10 = /* css */`
27583
27658
  &::view-transition-group(navi-route-transition) {
27584
27659
  z-index: 1;
27585
27660
  }
27661
+
27662
+ /* And on the transition's own clock, whatever was captured. How long the
27663
+ movement lasts is a fact about the movement, not about the pages: a bar
27664
+ left on the browser's own 250ms would be gone a third of the way into a
27665
+ longer one, instead of being covered by the page coming over it. */
27666
+ &::view-transition-group(*),
27667
+ &::view-transition-old(*),
27668
+ &::view-transition-new(*) {
27669
+ animation-duration: var(--navi-route-transition-duration, 300ms);
27670
+ }
27586
27671
  }
27587
27672
 
27588
27673
  &::view-transition-old(root),
@@ -27773,47 +27858,29 @@ const css$10 = /* css */`
27773
27858
  object-position: top left;
27774
27859
  /* Two pages crossing are two solid things, and seeing through one to
27775
27860
  the other says they are the same page changing its mind. A movement
27776
- that keeps the browser's fade on one of its two sides wants the
27777
- opposite, and says so — see zoom below. */
27861
+ that fades on one of its two sides wants the opposite, and says so —
27862
+ see zoom below. */
27778
27863
  mix-blend-mode: normal;
27779
27864
  animation-fill-mode: both;
27780
27865
  }
27781
27866
  }
27782
27867
 
27783
- /* Eased, which is a taste about THESE four: a custom type says its own
27784
- curve. */
27785
- &[data-navi-route-transition-type="slide-x"],
27786
- &[data-navi-route-transition-type="slide-y"],
27787
- &[data-navi-route-transition-type="cover-x"],
27788
- &[data-navi-route-transition-type="cover-y"] {
27789
- &::view-transition-old(root),
27790
- &::view-transition-new(root),
27791
- &::view-transition-old(navi-route-transition),
27792
- &::view-transition-new(navi-route-transition) {
27793
- animation-timing-function: ease;
27794
- }
27795
- }
27796
-
27868
+ /* Which keyframes a page leaves and arrives by, said as a VALUE on the
27869
+ root rather than only as a rule on the pictures. That pair IS the
27870
+ movement, and the pages are not the only thing playing it: a fixed bar
27871
+ the two states do not share travels with the page it belongs to, and its
27872
+ picture wears a name nobody can write a selector for (it is per element
27873
+ — see transition_furniture.js). Read from here, it is given the same
27874
+ two. A type an application defines its own way is free to publish them
27875
+ and have its furniture travel too. */
27797
27876
  &[data-navi-route-transition-type="slide-x"] {
27798
27877
  &[data-navi-route-transition="forward"] {
27799
- &::view-transition-old(root),
27800
- &::view-transition-old(navi-route-transition) {
27801
- animation-name: navi-route-transition-leave-towards-start;
27802
- }
27803
- &::view-transition-new(root),
27804
- &::view-transition-new(navi-route-transition) {
27805
- animation-name: navi-route-transition-enter-from-end;
27806
- }
27878
+ --navi-route-transition-leave: navi-route-transition-leave-towards-start;
27879
+ --navi-route-transition-enter: navi-route-transition-enter-from-end;
27807
27880
  }
27808
27881
  &[data-navi-route-transition="back"] {
27809
- &::view-transition-old(root),
27810
- &::view-transition-old(navi-route-transition) {
27811
- animation-name: navi-route-transition-leave-towards-end;
27812
- }
27813
- &::view-transition-new(root),
27814
- &::view-transition-new(navi-route-transition) {
27815
- animation-name: navi-route-transition-enter-from-start;
27816
- }
27882
+ --navi-route-transition-leave: navi-route-transition-leave-towards-end;
27883
+ --navi-route-transition-enter: navi-route-transition-enter-from-start;
27817
27884
  }
27818
27885
  }
27819
27886
 
@@ -27822,24 +27889,12 @@ const css$10 = /* css */`
27822
27889
  coming up from below. */
27823
27890
  &[data-navi-route-transition-type="slide-y"] {
27824
27891
  &[data-navi-route-transition="forward"] {
27825
- &::view-transition-old(root),
27826
- &::view-transition-old(navi-route-transition) {
27827
- animation-name: navi-route-transition-leave-towards-top;
27828
- }
27829
- &::view-transition-new(root),
27830
- &::view-transition-new(navi-route-transition) {
27831
- animation-name: navi-route-transition-enter-from-bottom;
27832
- }
27892
+ --navi-route-transition-leave: navi-route-transition-leave-towards-top;
27893
+ --navi-route-transition-enter: navi-route-transition-enter-from-bottom;
27833
27894
  }
27834
27895
  &[data-navi-route-transition="back"] {
27835
- &::view-transition-old(root),
27836
- &::view-transition-old(navi-route-transition) {
27837
- animation-name: navi-route-transition-leave-towards-bottom;
27838
- }
27839
- &::view-transition-new(root),
27840
- &::view-transition-new(navi-route-transition) {
27841
- animation-name: navi-route-transition-enter-from-top;
27842
- }
27896
+ --navi-route-transition-leave: navi-route-transition-leave-towards-bottom;
27897
+ --navi-route-transition-enter: navi-route-transition-enter-from-top;
27843
27898
  }
27844
27899
  }
27845
27900
 
@@ -27850,79 +27905,90 @@ const css$10 = /* css */`
27850
27905
  fade. */
27851
27906
  &[data-navi-route-transition-type="cover-x"] {
27852
27907
  &[data-navi-route-transition="forward"] {
27853
- &::view-transition-old(root),
27854
- &::view-transition-old(navi-route-transition) {
27855
- animation-name: navi-route-transition-still;
27856
- }
27857
- &::view-transition-new(root),
27858
- &::view-transition-new(navi-route-transition) {
27859
- animation-name: navi-route-transition-enter-from-end;
27860
- }
27908
+ --navi-route-transition-leave: navi-route-transition-still;
27909
+ --navi-route-transition-enter: navi-route-transition-enter-from-end;
27861
27910
  }
27862
27911
  &[data-navi-route-transition="back"] {
27912
+ --navi-route-transition-leave: navi-route-transition-leave-towards-end;
27913
+ --navi-route-transition-enter: navi-route-transition-still;
27863
27914
  &::view-transition-old(root),
27864
27915
  &::view-transition-old(navi-route-transition) {
27865
27916
  /* The page leaving is the cover: it must slide off ABOVE the one it
27866
27917
  uncovers, against the browser's default of drawing the new page on
27867
27918
  top. */
27868
27919
  z-index: 1;
27869
- animation-name: navi-route-transition-leave-towards-end;
27870
- }
27871
- &::view-transition-new(root),
27872
- &::view-transition-new(navi-route-transition) {
27873
- animation-name: navi-route-transition-still;
27874
27920
  }
27875
27921
  }
27876
27922
  }
27877
27923
  &[data-navi-route-transition-type="cover-y"] {
27878
27924
  &[data-navi-route-transition="forward"] {
27879
- &::view-transition-old(root),
27880
- &::view-transition-old(navi-route-transition) {
27881
- animation-name: navi-route-transition-still;
27882
- }
27883
- &::view-transition-new(root),
27884
- &::view-transition-new(navi-route-transition) {
27885
- animation-name: navi-route-transition-enter-from-bottom;
27886
- }
27925
+ --navi-route-transition-leave: navi-route-transition-still;
27926
+ --navi-route-transition-enter: navi-route-transition-enter-from-bottom;
27887
27927
  }
27888
27928
  &[data-navi-route-transition="back"] {
27929
+ --navi-route-transition-leave: navi-route-transition-leave-towards-bottom;
27930
+ --navi-route-transition-enter: navi-route-transition-still;
27889
27931
  &::view-transition-old(root),
27890
27932
  &::view-transition-old(navi-route-transition) {
27891
27933
  z-index: 1;
27892
- animation-name: navi-route-transition-leave-towards-bottom;
27893
- }
27894
- &::view-transition-new(root),
27895
- &::view-transition-new(navi-route-transition) {
27896
- animation-name: navi-route-transition-still;
27897
27934
  }
27898
27935
  }
27899
27936
  }
27900
27937
 
27901
27938
  /* Going deeper is coming closer: the page arriving lands from slightly too
27902
27939
  big, and going back it is the page leaving that grows away. The other
27903
- side keeps the browser's own fade under it. */
27940
+ side fades, which is what the browser would have done there anyway —
27941
+ written out so that this type says both of its halves like every
27942
+ other. */
27904
27943
  &[data-navi-route-transition-type="zoom"] {
27944
+ &[data-navi-route-transition="forward"] {
27945
+ --navi-route-transition-leave: navi-route-transition-fade-out;
27946
+ --navi-route-transition-enter: navi-route-transition-zoom-in;
27947
+ }
27948
+ &[data-navi-route-transition="back"] {
27949
+ --navi-route-transition-leave: navi-route-transition-zoom-out;
27950
+ --navi-route-transition-enter: navi-route-transition-fade-in;
27951
+ }
27905
27952
  &::view-transition-old(root),
27906
27953
  &::view-transition-new(root),
27907
27954
  &::view-transition-old(navi-route-transition),
27908
27955
  &::view-transition-new(navi-route-transition) {
27909
- /* One side of this one is the browser's fade, and a fade is two
27910
- half-transparent pictures: they must ADD up rather than cover each
27911
- other, or the page behind shows through the middle of the
27912
- movement. */
27956
+ /* One side of this one is a fade, and a fade is two half-transparent
27957
+ pictures: they must ADD up rather than cover each other, or the page
27958
+ behind shows through the middle of the movement. */
27913
27959
  mix-blend-mode: plus-lighter;
27914
27960
  }
27915
- &[data-navi-route-transition="forward"] {
27916
- &::view-transition-new(root),
27917
- &::view-transition-new(navi-route-transition) {
27918
- animation-name: navi-route-transition-zoom-in;
27919
- }
27961
+ }
27962
+
27963
+ /* The pages play what the type published. Written once for the types navi
27964
+ ships and for those only: a type an application defines writes its own
27965
+ rule, and one of navi's here would race it on cascade order. */
27966
+ &[data-navi-route-transition-type="slide-x"],
27967
+ &[data-navi-route-transition-type="slide-y"],
27968
+ &[data-navi-route-transition-type="cover-x"],
27969
+ &[data-navi-route-transition-type="cover-y"],
27970
+ &[data-navi-route-transition-type="zoom"] {
27971
+ &::view-transition-old(root),
27972
+ &::view-transition-old(navi-route-transition) {
27973
+ animation-name: var(--navi-route-transition-leave);
27920
27974
  }
27921
- &[data-navi-route-transition="back"] {
27922
- &::view-transition-old(root),
27923
- &::view-transition-old(navi-route-transition) {
27924
- animation-name: navi-route-transition-zoom-out;
27925
- }
27975
+ &::view-transition-new(root),
27976
+ &::view-transition-new(navi-route-transition) {
27977
+ animation-name: var(--navi-route-transition-enter);
27978
+ }
27979
+ }
27980
+
27981
+ /* Eased, which is a taste about THESE four: a custom type says its own
27982
+ curve, and zoom keeps the browser's. */
27983
+ &[data-navi-route-transition-type="slide-x"],
27984
+ &[data-navi-route-transition-type="slide-y"],
27985
+ &[data-navi-route-transition-type="cover-x"],
27986
+ &[data-navi-route-transition-type="cover-y"] {
27987
+ &::view-transition-old(root),
27988
+ &::view-transition-new(root),
27989
+ &::view-transition-old(navi-route-transition),
27990
+ &::view-transition-new(navi-route-transition) {
27991
+ animation-timing-function: ease;
27926
27992
  }
27927
27993
  }
27928
27994
  }
@@ -27989,6 +28055,19 @@ const css$10 = /* css */`
27989
28055
  translate: 0 0;
27990
28056
  }
27991
28057
  }
28058
+ /* The browser's own fade, written out: a movement says both of its halves,
28059
+ so that whoever else plays it (transition_furniture.js) can be given the
28060
+ same one. */
28061
+ @keyframes navi-route-transition-fade-out {
28062
+ to {
28063
+ opacity: 0;
28064
+ }
28065
+ }
28066
+ @keyframes navi-route-transition-fade-in {
28067
+ from {
28068
+ opacity: 0;
28069
+ }
28070
+ }
27992
28071
  `;
27993
28072
 
27994
28073
  /**
@@ -28507,10 +28586,7 @@ const beginTransition = ({
28507
28586
  // The page arriving is in the DOM and the transition has not started
28508
28587
  // playing: the one moment both states of the area can be known.
28509
28588
  if (areaElement) {
28510
- // A bar the arriving state mounted has to wear its name before the
28511
- // second picture is taken; one that survived the render keeps the name
28512
- // it already has, which is what pairs its two pictures.
28513
- nameTransitionFurniture(transition, areaElement);
28589
+ holdTransitionFurniture(transition, areaElement);
28514
28590
  holdTransitionWindow(transition, areaElement, areaStateBefore);
28515
28591
  }
28516
28592
  });
@@ -53987,10 +54063,15 @@ const TimeRange = ({
53987
54063
  }
53988
54064
  // compact writes the whole span as one short token ("8h–10h"): nothing
53989
54065
  // around the separator, and no break inside it. The other formats are
53990
- // phrases — they get room around the separator, and may wrap there.
54066
+ // phrases — they get room around the separator, and may wrap there (their
54067
+ // separator carries its own spaces, which is enough to keep Text from adding
54068
+ // more). Text spaces its children out by default, so the tight span has to
54069
+ // say it wants none — before {...props}, so a caller can still ask for its
54070
+ // own spacing.
53991
54071
  const tight = format === "compact";
53992
54072
  return jsxs(Text, {
53993
54073
  noWrap: tight,
54074
+ spacing: tight ? 0 : undefined,
53994
54075
  ...props,
53995
54076
  children: [jsx(Time, {
53996
54077
  ...boundProps,