@jsenv/navi 0.29.133 → 0.29.135
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/jsenv_navi.js +814 -222
- package/dist/jsenv_navi.js.map +71 -69
- package/dist/jsenv_navi_side_effects.js +32 -0
- package/dist/jsenv_navi_side_effects.js.map +3 -3
- package/docs/control_group.md +17 -7
- package/docs/css_architecture.md +34 -3
- package/docs/route_transitions.md +57 -6
- package/package.json +2 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -373,6 +373,9 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
373
373
|
const URL_TARGET_ATTRIBUTE = "data-url-target";
|
|
374
374
|
const css$14 = /* css */`
|
|
375
375
|
@layer navi {
|
|
376
|
+
/* Layered whole: the mark is navi's suggestion for "here is what the URL
|
|
377
|
+
pointed at", not something it needs. An app replaces it, or removes it
|
|
378
|
+
with animation: none, from an unlayered rule of any weight. */
|
|
376
379
|
[${URL_TARGET_ATTRIBUTE}] {
|
|
377
380
|
animation: navi_url_target var(--navi-url-target-duration, 2000ms)
|
|
378
381
|
ease-out;
|
|
@@ -2229,6 +2232,17 @@ naviI18n.addAll({
|
|
|
2229
2232
|
pt: "meia-noite",
|
|
2230
2233
|
nl: "middernacht",
|
|
2231
2234
|
},
|
|
2235
|
+
// What <TimeRange> writes between the two bounds of a span — "8h–10h",
|
|
2236
|
+
// "11 mai – 14 mai". An en dash, the mark for a span, not a hyphen.
|
|
2237
|
+
"time.range_separator": {
|
|
2238
|
+
en: "–",
|
|
2239
|
+
fr: "–",
|
|
2240
|
+
de: "–",
|
|
2241
|
+
es: "–",
|
|
2242
|
+
it: "–",
|
|
2243
|
+
pt: "–",
|
|
2244
|
+
nl: "–",
|
|
2245
|
+
},
|
|
2232
2246
|
// Compact duration unit symbols used in "1h30", "45min", "2d", etc.
|
|
2233
2247
|
"time.duration.year_symbol": {
|
|
2234
2248
|
en: "y",
|
|
@@ -5968,25 +5982,32 @@ const css$12 = /* css */`
|
|
|
5968
5982
|
border-radius: 50%;
|
|
5969
5983
|
}
|
|
5970
5984
|
|
|
5985
|
+
/* The svg takes the whole square and the glyph keeps its share of it
|
|
5986
|
+
inside the viewBox (see CALLOUT_STATUS_GLYPH_VIEWBOX). Sized as a
|
|
5987
|
+
fraction of the square instead, the svg box lands on a fractional
|
|
5988
|
+
device pixel and the rasteriser snaps the glyph a pixel off centre —
|
|
5989
|
+
visible on a small badge, where the glyph is only a few pixels wide. */
|
|
5971
5990
|
svg {
|
|
5972
|
-
width:
|
|
5973
|
-
height:
|
|
5991
|
+
width: 100%;
|
|
5992
|
+
height: 100%;
|
|
5974
5993
|
}
|
|
5975
5994
|
}
|
|
5976
|
-
/* Inside an <Icon>, the icon box is the size: fill it.
|
|
5977
|
-
own share of it — the Icon's rule sizing any svg it holds to the whole
|
|
5978
|
-
box is for an svg that IS the icon, and this one sits in a square. */
|
|
5995
|
+
/* Inside an <Icon>, the icon box is the size: fill it. */
|
|
5979
5996
|
.navi_icon > .navi_callout_status_icon {
|
|
5980
5997
|
width: 100%;
|
|
5981
5998
|
height: 100%;
|
|
5982
5999
|
}
|
|
5983
|
-
.navi_icon[data-icon-char] .navi_callout_status_icon svg {
|
|
5984
|
-
width: auto;
|
|
5985
|
-
height: 55%;
|
|
5986
|
-
}
|
|
5987
6000
|
`;
|
|
5988
|
-
|
|
5989
|
-
|
|
6001
|
+
|
|
6002
|
+
/**
|
|
6003
|
+
* The "!" on a square, viewBox and path both. The box is square and holds the
|
|
6004
|
+
* glyph's margin: the ink is 298 of 540 units tall (55%), centered. Drawn this
|
|
6005
|
+
* way rather than tight around the ink so whoever shows it can give the svg the
|
|
6006
|
+
* whole square — the glyph is then placed by the vector rasteriser, which has
|
|
6007
|
+
* no device pixel grid to miss, at any square size down to a fractional one.
|
|
6008
|
+
*/
|
|
6009
|
+
const CALLOUT_STATUS_GLYPH_VIEWBOX = "0 0 540 540";
|
|
6010
|
+
const CALLOUT_STATUS_GLYPH_PATH = "m232.5,121 8,196h59l8-196zm36.5,224a37,37 0 1,0 2,0z";
|
|
5990
6011
|
|
|
5991
6012
|
/**
|
|
5992
6013
|
* @type {import("ignore:preact").FunctionComponent<{
|
|
@@ -6037,7 +6058,8 @@ const css$11 = /* css */`
|
|
|
6037
6058
|
/* A callout is parented to what it explains, so it inherits from it — and
|
|
6038
6059
|
an element that suppressed text selection (a list row, a drag source)
|
|
6039
6060
|
would make its own explanation unselectable. The message is text one
|
|
6040
|
-
copies.
|
|
6061
|
+
copies. Layered: an app that has a reason to lock its own callouts down
|
|
6062
|
+
says so and wins. */
|
|
6041
6063
|
user-select: text;
|
|
6042
6064
|
|
|
6043
6065
|
--callout-success-color: var(--navi-callout-success-color);
|
|
@@ -6197,9 +6219,11 @@ const css$11 = /* css */`
|
|
|
6197
6219
|
display: none;
|
|
6198
6220
|
}
|
|
6199
6221
|
|
|
6222
|
+
/* The glyph keeps its share of the square inside the viewBox
|
|
6223
|
+
(see CALLOUT_STATUS_GLYPH_VIEWBOX), so the svg takes all of it. */
|
|
6200
6224
|
svg {
|
|
6201
|
-
width:
|
|
6202
|
-
height:
|
|
6225
|
+
width: 100%;
|
|
6226
|
+
height: 100%;
|
|
6203
6227
|
color: white;
|
|
6204
6228
|
}
|
|
6205
6229
|
}
|
|
@@ -6946,6 +6970,7 @@ const calloutTemplate = /* html */`
|
|
|
6946
6970
|
<div
|
|
6947
6971
|
class="navi_callout"
|
|
6948
6972
|
popover="manual"
|
|
6973
|
+
navi-out-of-flow=""
|
|
6949
6974
|
aria-expanded="true"
|
|
6950
6975
|
>
|
|
6951
6976
|
<div class="navi_callout_box">
|
|
@@ -8082,27 +8107,35 @@ const formatTime = (date, lang) => {
|
|
|
8082
8107
|
* "compact" uses our own notation that omits the minute symbol when hours are present.
|
|
8083
8108
|
*
|
|
8084
8109
|
* @param {number} minutes
|
|
8085
|
-
* @param {{ lang?: string, format?: "long"|"short"|"narrow"|"compact", clockStyle?: boolean, forceUnit?: boolean }} [options]
|
|
8110
|
+
* @param {{ lang?: string, format?: "long"|"short"|"narrow"|"compact", clockStyle?: boolean, pad?: boolean, precision?: "hour"|"minute", forceUnit?: boolean }} [options]
|
|
8086
8111
|
* @param {boolean} [options.forceUnit=false] - Keep the value in minutes
|
|
8087
8112
|
* however big it gets ("2160 minutes" instead of "1 jour et 12 heures").
|
|
8088
8113
|
* Past 24 hours the default promotes to days, which reads better but hides
|
|
8089
8114
|
* the unit the caller works in.
|
|
8090
8115
|
* @param {boolean} [options.clockStyle=false] - Set this when `minutes`
|
|
8091
8116
|
* represents a time-of-day rather than a real duration (used by
|
|
8092
|
-
* `<Time type="time">`, see time.jsx's own TimeTime)
|
|
8093
|
-
*
|
|
8094
|
-
*
|
|
8095
|
-
*
|
|
8096
|
-
*
|
|
8097
|
-
*
|
|
8098
|
-
* doesn't collapse to something indistinguishable from an actual
|
|
8099
|
-
* 5-minute duration.
|
|
8100
|
-
* - `format: "compact"` also zero-pads a single-digit hour to 2 digits
|
|
8101
|
-
* (e.g. "5h30" → "05h30") and keeps a zero-valued minute (e.g. "10h" →
|
|
8102
|
-
* "10h00"), so it reads closer to a "05:30"/"10:00" clock. The other
|
|
8103
|
-
* formats spell out their units, so "10 heures"/"10h" reads fine there
|
|
8104
|
-
* and only "compact" needs the clock shape.
|
|
8117
|
+
* `<Time type="time">`, see time.jsx's own TimeTime). A clock's "0" is a
|
|
8118
|
+
* meaningful hour rather than "no hours": a zero-hours component is
|
|
8119
|
+
* normally dropped entirely (a real 5-minute duration should print as
|
|
8120
|
+
* "5 minutes", not "0 hours 5 minutes"); this keeps it instead (e.g.
|
|
8121
|
+
* "0 h et 5 min"/"0h 5min"/"00h05") so midnight doesn't collapse to
|
|
8122
|
+
* something indistinguishable from an actual 5-minute duration.
|
|
8105
8123
|
* Must not be set for plain duration formatting.
|
|
8124
|
+
* @param {boolean} [options.pad=true] - Zero-pad the hour to 2 digits
|
|
8125
|
+
* ("08h30" rather than "8h30"). `clockStyle` + `format: "compact"` only.
|
|
8126
|
+
* @param {"hour"|"minute"} [options.precision="minute"] - Whether a zero
|
|
8127
|
+
* minute is written: `"minute"` keeps it ("10h00"), `"hour"` drops it
|
|
8128
|
+
* ("10h"). `clockStyle` + `format: "compact"` only.
|
|
8129
|
+
*
|
|
8130
|
+
* These last two are the clock's two independent shape choices, and only
|
|
8131
|
+
* `format: "compact"` has to make them — the spelled-out formats put their
|
|
8132
|
+
* units in words, so "10 heures"/"10 h"/"10h" already reads as a time of
|
|
8133
|
+
* day whatever the padding, and they always write the hour bare and drop a
|
|
8134
|
+
* zero minute. Padded + minute ("08h00") is the column shape, where every
|
|
8135
|
+
* row occupies the same width; bare + hour ("8h", "8h30") is the shape a
|
|
8136
|
+
* person speaks. Bare + minute ("8h00") only ever makes sense next to a
|
|
8137
|
+
* partner that has minutes of its own — see `<TimeRange>`, which is the
|
|
8138
|
+
* only thing that asks for it.
|
|
8106
8139
|
*
|
|
8107
8140
|
* @example
|
|
8108
8141
|
* formatMinuteDuration(90, { lang: "fr" }) // "1 heure 30 minutes" (long, default)
|
|
@@ -8113,6 +8146,9 @@ const formatTime = (date, lang) => {
|
|
|
8113
8146
|
* formatMinuteDuration(5, { lang: "fr", format: "narrow", clockStyle: true }) // "0h 5min"
|
|
8114
8147
|
* formatMinuteDuration(330, { lang: "fr", format: "compact", clockStyle: true }) // "05h30"
|
|
8115
8148
|
* formatMinuteDuration(600, { lang: "fr", format: "compact", clockStyle: true }) // "10h00"
|
|
8149
|
+
* formatMinuteDuration(600, { lang: "fr", format: "compact", clockStyle: true, pad: false }) // "10h00"
|
|
8150
|
+
* formatMinuteDuration(600, { lang: "fr", format: "compact", clockStyle: true, pad: false, precision: "hour" }) // "10h"
|
|
8151
|
+
* formatMinuteDuration(510, { lang: "fr", format: "compact", clockStyle: true, pad: false, precision: "hour" }) // "8h30"
|
|
8116
8152
|
* formatMinuteDuration(2160, { lang: "fr" }) // "1 jour et 12 heures"
|
|
8117
8153
|
* formatMinuteDuration(2160, { lang: "fr", forceUnit: true }) // "2 160 minutes"
|
|
8118
8154
|
*/
|
|
@@ -8122,13 +8158,15 @@ const formatMinuteDuration = (
|
|
|
8122
8158
|
lang = languagesSignal.value,
|
|
8123
8159
|
format = "long",
|
|
8124
8160
|
clockStyle = false,
|
|
8161
|
+
pad = true,
|
|
8162
|
+
precision = "minute",
|
|
8125
8163
|
forceUnit = false,
|
|
8126
8164
|
} = {},
|
|
8127
8165
|
) => {
|
|
8128
8166
|
if (minutes < 0) {
|
|
8129
8167
|
// the d/h/m split below only holds for a positive value; formatting the
|
|
8130
8168
|
// magnitude and putting the sign back is the only reading that works
|
|
8131
|
-
return `-${formatMinuteDuration(-minutes, { lang, format, clockStyle, forceUnit })}`;
|
|
8169
|
+
return `-${formatMinuteDuration(-minutes, { lang, format, clockStyle, pad, precision, forceUnit })}`;
|
|
8132
8170
|
}
|
|
8133
8171
|
if (forceUnit || (minutes === 0 && !clockStyle)) {
|
|
8134
8172
|
// a zero has nothing to promote to, and rendering it as an empty string
|
|
@@ -8162,16 +8200,19 @@ const formatMinuteDuration = (
|
|
|
8162
8200
|
const hSym = naviI18n("time.duration.hour_symbol", undefined, { lang });
|
|
8163
8201
|
const mSym = naviI18n("time.duration.minute_symbol", undefined, { lang });
|
|
8164
8202
|
const dStr = d > 0 ? `${formatCompactNumber(d, lang)}${dSym}` : "";
|
|
8165
|
-
const hStr =
|
|
8166
|
-
|
|
8167
|
-
|
|
8203
|
+
const hStr =
|
|
8204
|
+
clockStyle && pad
|
|
8205
|
+
? String(h).padStart(2, "0")
|
|
8206
|
+
: formatCompactNumber(h, lang);
|
|
8168
8207
|
if (d === 0 && h === 0 && !clockStyle) {
|
|
8169
8208
|
return `${m}${mSym}`;
|
|
8170
8209
|
}
|
|
8171
8210
|
if (m === 0) {
|
|
8172
8211
|
if (clockStyle) {
|
|
8173
|
-
// "10h00" on a clock, "2h" for a real 2 hours duration
|
|
8174
|
-
|
|
8212
|
+
// "10h00" on a clock, "2h" for a real 2 hours duration — except at
|
|
8213
|
+
// precision "hour", where a clock drops the zero minute too ("10h"),
|
|
8214
|
+
// the way one says it out loud
|
|
8215
|
+
return precision === "minute" ? `${hStr}${hSym}00` : `${hStr}${hSym}`;
|
|
8175
8216
|
}
|
|
8176
8217
|
return h === 0 ? dStr : `${dStr}${hStr}${hSym}`;
|
|
8177
8218
|
}
|
|
@@ -27028,12 +27069,115 @@ const releaseTransitionDestination = (owner) => {
|
|
|
27028
27069
|
publishDestination(null);
|
|
27029
27070
|
};
|
|
27030
27071
|
|
|
27072
|
+
/**
|
|
27073
|
+
* The furniture around the pages — the fixed bars — photographed with them for
|
|
27074
|
+
* the length of a route transition, so that a piece of it belonging to ONE of
|
|
27075
|
+
* the two states takes part in the movement instead of appearing or vanishing
|
|
27076
|
+
* in a frame.
|
|
27077
|
+
*
|
|
27078
|
+
* Whether a bar is the frame or part of what changes is a fact about the PAIR
|
|
27079
|
+
* of states, never about the bar: the top bar of a list is the frame while one
|
|
27080
|
+
* goes into a row of that list, and part of what changes when the next page
|
|
27081
|
+
* takes the whole screen. So nothing is declared — a name is written on every
|
|
27082
|
+
* bar for the length of the movement, and the browser derives the rest:
|
|
27083
|
+
*
|
|
27084
|
+
* - a bar the two states SHARE is one element wearing one name on both sides.
|
|
27085
|
+
* The browser pairs the two pictures into one group and holds it where it
|
|
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.
|
|
27091
|
+
*
|
|
27092
|
+
* The name is per ELEMENT and kept for the element's whole life, which is what
|
|
27093
|
+
* makes "shared" mean shared: several bars can live on one edge
|
|
27094
|
+
* (layout/fixed_bar/fixed_bar_space.js), so a bar leaving and another one
|
|
27095
|
+
* arriving on that same edge are two names and two movements, not one bar
|
|
27096
|
+
* changing its mind.
|
|
27097
|
+
*
|
|
27098
|
+
* Worn only while a transition of navi's plays: named the rest of the time, a
|
|
27099
|
+
* bar would be captured during every view transition the APPLICATION starts —
|
|
27100
|
+
* dead to the pointer and drawn in the top layer for the length of a movement
|
|
27101
|
+
* that has nothing to do with it. Being unable to answer a press is the price
|
|
27102
|
+
* of being photographed, and a route transition is where it costs nothing:
|
|
27103
|
+
* both pages are pictures for those few hundred milliseconds anyway.
|
|
27104
|
+
*/
|
|
27105
|
+
|
|
27106
|
+
// What counts as furniture: what is pinned to an edge of the window and gives
|
|
27107
|
+
// its room back to the content (layout/fixed_bar/fixed_bar.jsx). A sticky row
|
|
27108
|
+
// inside the pages needs none of this — it lives in the area, so it is already
|
|
27109
|
+
// part of the pages' own picture.
|
|
27110
|
+
const FURNITURE_SELECTOR = ".navi_fixed_bar";
|
|
27111
|
+
const NAME_PROPERTY = "view-transition-name";
|
|
27112
|
+
const FURNITURE_NAME_PREFIX = "navi-transition-furniture-";
|
|
27113
|
+
|
|
27114
|
+
const nameByElement = new WeakMap();
|
|
27115
|
+
let nameCount = 0;
|
|
27116
|
+
|
|
27117
|
+
// Whose movement the names belong to, for the same reason the window has an
|
|
27118
|
+
// owner (transition_window.js): a movement ending after another has replaced
|
|
27119
|
+
// it must not strip what the new one is wearing.
|
|
27120
|
+
let furnitureOwner = null;
|
|
27121
|
+
let namedElements = new Set();
|
|
27122
|
+
|
|
27123
|
+
/**
|
|
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.
|
|
27129
|
+
*/
|
|
27130
|
+
const nameTransitionFurniture = (owner, areaElement) => {
|
|
27131
|
+
if (owner !== furnitureOwner) {
|
|
27132
|
+
furnitureOwner = owner;
|
|
27133
|
+
namedElements = new Set();
|
|
27134
|
+
}
|
|
27135
|
+
for (const element of document.querySelectorAll(FURNITURE_SELECTOR)) {
|
|
27136
|
+
if (namedElements.has(element)) {
|
|
27137
|
+
continue;
|
|
27138
|
+
}
|
|
27139
|
+
// Inside the area it is not furniture, it is the page: naming it would
|
|
27140
|
+
// punch a hole in the picture the movement is played on.
|
|
27141
|
+
if (areaElement.contains(element)) {
|
|
27142
|
+
continue;
|
|
27143
|
+
}
|
|
27144
|
+
let name = nameByElement.get(element);
|
|
27145
|
+
if (!name) {
|
|
27146
|
+
// A name the application wrote itself answers for that element, and it
|
|
27147
|
+
// is saying something navi is not: it wants that bar moved on the pages'
|
|
27148
|
+
// clock, by its own CSS. Asked only of a bar navi has never named — a
|
|
27149
|
+
// bar wearing one of ITS names is one this movement inherited from the
|
|
27150
|
+
// one it interrupted, and taking it for the application's would leave it
|
|
27151
|
+
// named for the rest of the document's life.
|
|
27152
|
+
if (getComputedStyle(element).viewTransitionName !== "none") {
|
|
27153
|
+
continue;
|
|
27154
|
+
}
|
|
27155
|
+
nameCount++;
|
|
27156
|
+
name = `${FURNITURE_NAME_PREFIX}${nameCount}`;
|
|
27157
|
+
nameByElement.set(element, name);
|
|
27158
|
+
}
|
|
27159
|
+
element.style.setProperty(NAME_PROPERTY, name);
|
|
27160
|
+
namedElements.add(element);
|
|
27161
|
+
}
|
|
27162
|
+
};
|
|
27163
|
+
|
|
27164
|
+
const releaseTransitionFurniture = (owner) => {
|
|
27165
|
+
if (owner !== furnitureOwner) {
|
|
27166
|
+
return;
|
|
27167
|
+
}
|
|
27168
|
+
furnitureOwner = null;
|
|
27169
|
+
for (const element of namedElements) {
|
|
27170
|
+
element.style.removeProperty(NAME_PROPERTY);
|
|
27171
|
+
}
|
|
27172
|
+
namedElements = new Set();
|
|
27173
|
+
};
|
|
27174
|
+
|
|
27031
27175
|
/**
|
|
27032
27176
|
* The window two pages are seen through while one replaces the other, measured
|
|
27033
27177
|
* once and published for the length of the movement.
|
|
27034
27178
|
*
|
|
27035
|
-
* Both ways of moving from one route to another need the same
|
|
27036
|
-
*
|
|
27179
|
+
* Both ways of moving from one route to another need the same numbers, so they
|
|
27180
|
+
* are written under the same names and read by the same CSS formulas —
|
|
27037
27181
|
* `route_travel.jsx` for a row a finger pushes, `route_transition.jsx` for a
|
|
27038
27182
|
* relation between two pages. Only one of them ever plays at a time (there is
|
|
27039
27183
|
* one view transition per document), which is what lets them share the names.
|
|
@@ -27044,16 +27188,25 @@ const releaseTransitionDestination = (owner) => {
|
|
|
27044
27188
|
* pictures of a transition are drawn in the top layer, above everything, so
|
|
27045
27189
|
* no overflow of the document reaches them: where to cut them can only be
|
|
27046
27190
|
* said from outside the document, and this is where that outside is known.
|
|
27047
|
-
* - **the
|
|
27048
|
-
* browser the
|
|
27049
|
-
*
|
|
27050
|
-
*
|
|
27051
|
-
*
|
|
27052
|
-
*
|
|
27053
|
-
*
|
|
27054
|
-
* same place in the
|
|
27055
|
-
*
|
|
27056
|
-
*
|
|
27191
|
+
* - **the box is the two states TOGETHER**, not either one of them. The
|
|
27192
|
+
* browser puts the group where the arriving state stands and animates it
|
|
27193
|
+
* from where the state being left stood; both are wrong for the same reason
|
|
27194
|
+
* — a window that is one of the two states cuts the other. Held at the
|
|
27195
|
+
* rectangle that contains both, nothing either picture holds is ever cut by
|
|
27196
|
+
* a box it never had, and the user never watches the window get anywhere.
|
|
27197
|
+
* - **where each state WAS**, which is not where the window stands: the two
|
|
27198
|
+
* states are at the same place in the layout without being at the same place
|
|
27199
|
+
* in the window — one page is scrolled and the other is not, one has a top
|
|
27200
|
+
* bar over it and the other has the screen. Each picture is placed at its
|
|
27201
|
+
* own corner inside the window.
|
|
27202
|
+
* - **the band the state being left kept free**, next to the one the arriving
|
|
27203
|
+
* state keeps free. A band is furniture — a fixed bar, a sticky row — and
|
|
27204
|
+
* the pictures are cut at it so they are not watched painting over it. Read
|
|
27205
|
+
* live it describes the arriving state alone, and a piece of furniture that
|
|
27206
|
+
* belongs to only ONE of the two states is then treated as the frame of
|
|
27207
|
+
* both: the page being left is cut at a bar it never had. Photographed here
|
|
27208
|
+
* at the one moment the state being left still exists, the cut can be taken
|
|
27209
|
+
* at what is furniture on BOTH sides (see the clip formulas).
|
|
27057
27210
|
*
|
|
27058
27211
|
* Only the measuring needs JS, and only for the one moment both states exist:
|
|
27059
27212
|
* the page arriving is in the DOM and the transition has not started playing.
|
|
@@ -27080,8 +27233,32 @@ const releaseTransitionDestination = (owner) => {
|
|
|
27080
27233
|
* Each one is a distance inward from the band the safe area already leaves
|
|
27081
27234
|
* free, so a row states its own height and nothing else: what the bars above
|
|
27082
27235
|
* it take is already counted.
|
|
27236
|
+
*
|
|
27237
|
+
* Registered as lengths for the same reason the safe area is (safe_area.js):
|
|
27238
|
+
* the band has to be readable in pixels at the moment a page leaves.
|
|
27083
27239
|
*/
|
|
27084
27240
|
const TRANSITION_WINDOW_CSS = /* css */ `
|
|
27241
|
+
@property --navi-transition-cover-top {
|
|
27242
|
+
syntax: "<length>";
|
|
27243
|
+
inherits: true;
|
|
27244
|
+
initial-value: 0px;
|
|
27245
|
+
}
|
|
27246
|
+
@property --navi-transition-cover-right {
|
|
27247
|
+
syntax: "<length>";
|
|
27248
|
+
inherits: true;
|
|
27249
|
+
initial-value: 0px;
|
|
27250
|
+
}
|
|
27251
|
+
@property --navi-transition-cover-bottom {
|
|
27252
|
+
syntax: "<length>";
|
|
27253
|
+
inherits: true;
|
|
27254
|
+
initial-value: 0px;
|
|
27255
|
+
}
|
|
27256
|
+
@property --navi-transition-cover-left {
|
|
27257
|
+
syntax: "<length>";
|
|
27258
|
+
inherits: true;
|
|
27259
|
+
initial-value: 0px;
|
|
27260
|
+
}
|
|
27261
|
+
|
|
27085
27262
|
@layer navi {
|
|
27086
27263
|
:root {
|
|
27087
27264
|
--navi-transition-cover-top: 0px;
|
|
@@ -27098,6 +27275,12 @@ const WINDOW_WIDTH_PROPERTY = "--navi-transition-window-width";
|
|
|
27098
27275
|
const WINDOW_HEIGHT_PROPERTY = "--navi-transition-window-height";
|
|
27099
27276
|
const WINDOW_OLD_TOP_PROPERTY = "--navi-transition-window-old-top";
|
|
27100
27277
|
const WINDOW_OLD_LEFT_PROPERTY = "--navi-transition-window-old-left";
|
|
27278
|
+
const WINDOW_NEW_TOP_PROPERTY = "--navi-transition-window-new-top";
|
|
27279
|
+
const WINDOW_NEW_LEFT_PROPERTY = "--navi-transition-window-new-left";
|
|
27280
|
+
const OLD_BAND_TOP_PROPERTY = "--navi-transition-old-band-top";
|
|
27281
|
+
const OLD_BAND_RIGHT_PROPERTY = "--navi-transition-old-band-right";
|
|
27282
|
+
const OLD_BAND_BOTTOM_PROPERTY = "--navi-transition-old-band-bottom";
|
|
27283
|
+
const OLD_BAND_LEFT_PROPERTY = "--navi-transition-old-band-left";
|
|
27101
27284
|
const WINDOW_PROPERTIES = [
|
|
27102
27285
|
WINDOW_TOP_PROPERTY,
|
|
27103
27286
|
WINDOW_LEFT_PROPERTY,
|
|
@@ -27105,6 +27288,12 @@ const WINDOW_PROPERTIES = [
|
|
|
27105
27288
|
WINDOW_HEIGHT_PROPERTY,
|
|
27106
27289
|
WINDOW_OLD_TOP_PROPERTY,
|
|
27107
27290
|
WINDOW_OLD_LEFT_PROPERTY,
|
|
27291
|
+
WINDOW_NEW_TOP_PROPERTY,
|
|
27292
|
+
WINDOW_NEW_LEFT_PROPERTY,
|
|
27293
|
+
OLD_BAND_TOP_PROPERTY,
|
|
27294
|
+
OLD_BAND_RIGHT_PROPERTY,
|
|
27295
|
+
OLD_BAND_BOTTOM_PROPERTY,
|
|
27296
|
+
OLD_BAND_LEFT_PROPERTY,
|
|
27108
27297
|
];
|
|
27109
27298
|
|
|
27110
27299
|
// Whose numbers are currently published. The window belongs to the movement
|
|
@@ -27113,21 +27302,50 @@ const WINDOW_PROPERTIES = [
|
|
|
27113
27302
|
// on.
|
|
27114
27303
|
let windowOwner = null;
|
|
27115
27304
|
|
|
27116
|
-
|
|
27305
|
+
/**
|
|
27306
|
+
* The state being left, taken while rendering is held — the page arriving is
|
|
27307
|
+
* not in the DOM yet, so this is still the one going away. Where its box
|
|
27308
|
+
* stands and what its furniture left free, which the arriving state answers
|
|
27309
|
+
* for differently and which nothing can be read back from once it is gone.
|
|
27310
|
+
*/
|
|
27311
|
+
const measureTransitionWindowState = (element) => {
|
|
27312
|
+
return {
|
|
27313
|
+
rect: element.getBoundingClientRect(),
|
|
27314
|
+
band: readBand(),
|
|
27315
|
+
};
|
|
27316
|
+
};
|
|
27317
|
+
|
|
27318
|
+
const holdTransitionWindow = (owner, element, stateBefore) => {
|
|
27319
|
+
const rectBefore = stateBefore.rect;
|
|
27320
|
+
const bandBefore = stateBefore.band;
|
|
27117
27321
|
const rectAfter = element.getBoundingClientRect();
|
|
27118
|
-
|
|
27119
|
-
//
|
|
27120
|
-
// would
|
|
27121
|
-
|
|
27122
|
-
|
|
27322
|
+
const bandAfter = readBand();
|
|
27323
|
+
// The rectangle that contains both states. It cannot be measured from one
|
|
27324
|
+
// side alone: a page arriving shorter than the one it replaces would cut the
|
|
27325
|
+
// one leaving, a page arriving taller would be cut itself, and either one
|
|
27326
|
+
// standing higher up than the other would be cut across.
|
|
27327
|
+
const top = rectBefore.top < rectAfter.top ? rectBefore.top : rectAfter.top;
|
|
27328
|
+
const left =
|
|
27329
|
+
rectBefore.left < rectAfter.left ? rectBefore.left : rectAfter.left;
|
|
27330
|
+
const bottom =
|
|
27331
|
+
rectBefore.bottom > rectAfter.bottom ? rectBefore.bottom : rectAfter.bottom;
|
|
27332
|
+
const right =
|
|
27333
|
+
rectBefore.right > rectAfter.right ? rectBefore.right : rectAfter.right;
|
|
27123
27334
|
windowOwner = owner;
|
|
27124
27335
|
const { style } = document.documentElement;
|
|
27125
|
-
style.setProperty(WINDOW_TOP_PROPERTY, `${
|
|
27126
|
-
style.setProperty(WINDOW_LEFT_PROPERTY, `${
|
|
27127
|
-
style.setProperty(WINDOW_WIDTH_PROPERTY, `${
|
|
27128
|
-
style.setProperty(WINDOW_HEIGHT_PROPERTY, `${
|
|
27336
|
+
style.setProperty(WINDOW_TOP_PROPERTY, `${top}px`);
|
|
27337
|
+
style.setProperty(WINDOW_LEFT_PROPERTY, `${left}px`);
|
|
27338
|
+
style.setProperty(WINDOW_WIDTH_PROPERTY, `${right - left}px`);
|
|
27339
|
+
style.setProperty(WINDOW_HEIGHT_PROPERTY, `${bottom - top}px`);
|
|
27129
27340
|
style.setProperty(WINDOW_OLD_TOP_PROPERTY, `${rectBefore.top}px`);
|
|
27130
27341
|
style.setProperty(WINDOW_OLD_LEFT_PROPERTY, `${rectBefore.left}px`);
|
|
27342
|
+
style.setProperty(WINDOW_NEW_TOP_PROPERTY, `${rectAfter.top}px`);
|
|
27343
|
+
style.setProperty(WINDOW_NEW_LEFT_PROPERTY, `${rectAfter.left}px`);
|
|
27344
|
+
const oldBand = bandTheCutMayBeRelaxedTo(bandBefore, bandAfter, rectAfter);
|
|
27345
|
+
style.setProperty(OLD_BAND_TOP_PROPERTY, `${oldBand.top}px`);
|
|
27346
|
+
style.setProperty(OLD_BAND_RIGHT_PROPERTY, `${oldBand.right}px`);
|
|
27347
|
+
style.setProperty(OLD_BAND_BOTTOM_PROPERTY, `${oldBand.bottom}px`);
|
|
27348
|
+
style.setProperty(OLD_BAND_LEFT_PROPERTY, `${oldBand.left}px`);
|
|
27131
27349
|
};
|
|
27132
27350
|
|
|
27133
27351
|
// The live layout takes the box back. A discontinuity by construction — the
|
|
@@ -27145,6 +27363,65 @@ const releaseTransitionWindow = (owner) => {
|
|
|
27145
27363
|
}
|
|
27146
27364
|
};
|
|
27147
27365
|
|
|
27366
|
+
// A band nothing can be wider than, published for an edge nothing is known
|
|
27367
|
+
// about: taken as the smaller of the two, it leaves the live band standing on
|
|
27368
|
+
// its own, which is the movement navi played before it knew any of this.
|
|
27369
|
+
const BAND_UNKNOWN = 1e6;
|
|
27370
|
+
|
|
27371
|
+
// What the furniture leaves free on each edge, as a distance inward from that
|
|
27372
|
+
// edge of the window: the app's safe area (everything pinned to the window's
|
|
27373
|
+
// edges) plus what covers the box from inside the document.
|
|
27374
|
+
const readBand = () => {
|
|
27375
|
+
const computedStyle = getComputedStyle(document.documentElement);
|
|
27376
|
+
const readEdge = (edge) => {
|
|
27377
|
+
const safeArea = parseFloat(
|
|
27378
|
+
computedStyle.getPropertyValue(`--navi-safe-area-inset-${edge}`),
|
|
27379
|
+
);
|
|
27380
|
+
const cover = parseFloat(
|
|
27381
|
+
computedStyle.getPropertyValue(`--navi-transition-cover-${edge}`),
|
|
27382
|
+
);
|
|
27383
|
+
// A browser that cannot register a custom property hands back the calc()
|
|
27384
|
+
// it was written as rather than what it computes to (see safe_area.js).
|
|
27385
|
+
if (!Number.isFinite(safeArea) || !Number.isFinite(cover)) {
|
|
27386
|
+
return BAND_UNKNOWN;
|
|
27387
|
+
}
|
|
27388
|
+
return safeArea + cover;
|
|
27389
|
+
};
|
|
27390
|
+
return {
|
|
27391
|
+
top: readEdge("top"),
|
|
27392
|
+
right: readEdge("right"),
|
|
27393
|
+
bottom: readEdge("bottom"),
|
|
27394
|
+
left: readEdge("left"),
|
|
27395
|
+
};
|
|
27396
|
+
};
|
|
27397
|
+
|
|
27398
|
+
// How far the cut may be opened for the picture being left — the band its own
|
|
27399
|
+
// state kept free, which is the whole point of photographing it: furniture
|
|
27400
|
+
// present in only one of the two states is not the frame, it is part of what
|
|
27401
|
+
// changes, and cutting the page being left at a bar it never had shows its
|
|
27402
|
+
// header being sliced instead of leaving.
|
|
27403
|
+
//
|
|
27404
|
+
// Never past what the picture ARRIVING needs, though: the cut is one line for
|
|
27405
|
+
// both pictures, so opening it for one opens it for the other. A box that runs
|
|
27406
|
+
// under the furniture it arrives beside — a page scrolled below a top bar —
|
|
27407
|
+
// would then be watched painting over that bar for the length of the movement,
|
|
27408
|
+
// which is what the cut exists to prevent. On such an edge the arriving band
|
|
27409
|
+
// stands, and the page being left is cut as it always was.
|
|
27410
|
+
const bandTheCutMayBeRelaxedTo = (bandBefore, bandAfter, rectAfter) => {
|
|
27411
|
+
return {
|
|
27412
|
+
top: rectAfter.top < bandAfter.top ? bandAfter.top : bandBefore.top,
|
|
27413
|
+
right:
|
|
27414
|
+
rectAfter.right > window.innerWidth - bandAfter.right
|
|
27415
|
+
? bandAfter.right
|
|
27416
|
+
: bandBefore.right,
|
|
27417
|
+
bottom:
|
|
27418
|
+
rectAfter.bottom > window.innerHeight - bandAfter.bottom
|
|
27419
|
+
? bandAfter.bottom
|
|
27420
|
+
: bandBefore.bottom,
|
|
27421
|
+
left: rectAfter.left < bandAfter.left ? bandAfter.left : bandBefore.left,
|
|
27422
|
+
};
|
|
27423
|
+
};
|
|
27424
|
+
|
|
27148
27425
|
installImportMetaCssBuild(import.meta);/**
|
|
27149
27426
|
* How two routes move against each other, said one relation at a time —
|
|
27150
27427
|
* without putting them in a row, and without a box in the tree.
|
|
@@ -27275,18 +27552,37 @@ const css$10 = /* css */`
|
|
|
27275
27552
|
the document animates, and the document belongs to the application the
|
|
27276
27553
|
rest of the time. */
|
|
27277
27554
|
:root[data-navi-route-transition] {
|
|
27278
|
-
/* With an area marked, the page AROUND it is not taken as
|
|
27279
|
-
exactly one of the two names below exists at a time, and the
|
|
27280
|
-
can be written once for both. It is also
|
|
27281
|
-
|
|
27282
|
-
|
|
27283
|
-
|
|
27284
|
-
|
|
27285
|
-
|
|
27286
|
-
|
|
27287
|
-
|
|
27555
|
+
/* With an area marked, the page AROUND it is not taken as one picture —
|
|
27556
|
+
so exactly one of the two names below exists at a time, and the
|
|
27557
|
+
movements can be written once for both. It is also the only way the
|
|
27558
|
+
furniture can take part in the movement: photographed with the whole
|
|
27559
|
+
document it is one picture the size of the screen, and a bar can be
|
|
27560
|
+
neither held where it stands nor moved with the page it belongs to
|
|
27561
|
+
inside it. Each bar is photographed on its own instead (see
|
|
27562
|
+
transition_furniture.js), and nothing shows through where the pages are
|
|
27563
|
+
— their two pictures cover the area's rectangle between them at every
|
|
27564
|
+
moment. */
|
|
27288
27565
|
&[data-navi-route-transition-target="area"] {
|
|
27289
27566
|
view-transition-name: none;
|
|
27567
|
+
|
|
27568
|
+
/* The pages travel OVER the furniture. Everything else captured while an
|
|
27569
|
+
area is marked is a fixed bar wearing a name of navi's own for the
|
|
27570
|
+
length of the movement (transition_furniture.js): a bar the two states
|
|
27571
|
+
share is one group the browser holds where it stands, and a bar only
|
|
27572
|
+
one of them has stands there too, with no counterpart to move to. Both
|
|
27573
|
+
belong under the pages — that is what lets a page come over a bar that
|
|
27574
|
+
is going away, and a page leaving uncover the bar arriving behind it.
|
|
27575
|
+
|
|
27576
|
+
Ordered here rather than left to the DOM, which decides it otherwise:
|
|
27577
|
+
where an application puts its bars relative to the area is its own
|
|
27578
|
+
business. A name and \`*\` weigh the same, so the two rules are read in
|
|
27579
|
+
the order they are written. */
|
|
27580
|
+
&::view-transition-group(*) {
|
|
27581
|
+
z-index: 0;
|
|
27582
|
+
}
|
|
27583
|
+
&::view-transition-group(navi-route-transition) {
|
|
27584
|
+
z-index: 1;
|
|
27585
|
+
}
|
|
27290
27586
|
}
|
|
27291
27587
|
|
|
27292
27588
|
&::view-transition-old(root),
|
|
@@ -27315,11 +27611,22 @@ const css$10 = /* css */`
|
|
|
27315
27611
|
overflow: clip;
|
|
27316
27612
|
}
|
|
27317
27613
|
&::view-transition-group(navi-route-transition) {
|
|
27318
|
-
/* Held still for the whole transition, at the
|
|
27319
|
-
|
|
27320
|
-
|
|
27321
|
-
|
|
27322
|
-
|
|
27614
|
+
/* Held still for the whole transition, at the rectangle that contains
|
|
27615
|
+
both states (see transition_window.js). Held by dropping the group's
|
|
27616
|
+
animation rather than by winning against it with !important. The
|
|
27617
|
+
browser puts the group where the ARRIVING area stands, so it is moved
|
|
27618
|
+
from there back to the window's own corner. */
|
|
27619
|
+
top: calc(
|
|
27620
|
+
var(--navi-transition-window-top) - var(
|
|
27621
|
+
--navi-transition-window-new-top
|
|
27622
|
+
)
|
|
27623
|
+
);
|
|
27624
|
+
left: calc(
|
|
27625
|
+
var(--navi-transition-window-left) - var(
|
|
27626
|
+
--navi-transition-window-new-left
|
|
27627
|
+
)
|
|
27628
|
+
);
|
|
27629
|
+
width: var(--navi-transition-window-width);
|
|
27323
27630
|
height: var(--navi-transition-window-height);
|
|
27324
27631
|
animation-name: none;
|
|
27325
27632
|
|
|
@@ -27338,31 +27645,51 @@ const css$10 = /* css */`
|
|
|
27338
27645
|
the pages covers the top of the area exactly as a fixed bar covers the
|
|
27339
27646
|
top of the screen. Both are read rather than asked for, so one that
|
|
27340
27647
|
grows, shrinks or unmounts mid-transition is followed without anything
|
|
27341
|
-
being told.
|
|
27342
|
-
|
|
27648
|
+
being told.
|
|
27649
|
+
|
|
27650
|
+
Read live, though, they describe the state ARRIVING and nothing else,
|
|
27651
|
+
so the cut is taken at the smaller of that and the band the state
|
|
27652
|
+
being left kept free (--navi-transition-old-band-*, photographed while
|
|
27653
|
+
both still existed). Furniture standing in BOTH states is the frame:
|
|
27654
|
+
the pages move behind it and are cut at it. Furniture standing in one
|
|
27655
|
+
of them is part of what changes, and cutting the page being left at a
|
|
27656
|
+
bar it never had shows its own header being sliced instead of
|
|
27657
|
+
leaving. */
|
|
27343
27658
|
--navi-route-transition-clip-top: max(
|
|
27344
27659
|
0px,
|
|
27345
|
-
|
|
27346
|
-
|
|
27660
|
+
min(
|
|
27661
|
+
var(--navi-safe-area-inset-top) + var(--navi-transition-cover-top),
|
|
27662
|
+
var(--navi-transition-old-band-top)
|
|
27663
|
+
) - var(--navi-transition-window-top)
|
|
27347
27664
|
);
|
|
27348
27665
|
--navi-route-transition-clip-left: max(
|
|
27349
27666
|
0px,
|
|
27350
|
-
|
|
27351
|
-
|
|
27667
|
+
min(
|
|
27668
|
+
var(--navi-safe-area-inset-left) + var(--navi-transition-cover-left),
|
|
27669
|
+
var(--navi-transition-old-band-left)
|
|
27670
|
+
) - var(--navi-transition-window-left)
|
|
27352
27671
|
);
|
|
27353
27672
|
--navi-route-transition-clip-bottom: max(
|
|
27354
27673
|
0px,
|
|
27355
27674
|
var(--navi-transition-window-top) +
|
|
27356
27675
|
var(--navi-transition-window-height) +
|
|
27357
|
-
|
|
27358
|
-
|
|
27676
|
+
min(
|
|
27677
|
+
var(--navi-safe-area-inset-bottom) +
|
|
27678
|
+
var(--navi-transition-cover-bottom),
|
|
27679
|
+
var(--navi-transition-old-band-bottom)
|
|
27680
|
+
) -
|
|
27681
|
+
100dvh
|
|
27359
27682
|
);
|
|
27360
27683
|
--navi-route-transition-clip-right: max(
|
|
27361
27684
|
0px,
|
|
27362
27685
|
var(--navi-transition-window-left) +
|
|
27363
27686
|
var(--navi-transition-window-width) +
|
|
27364
|
-
|
|
27365
|
-
|
|
27687
|
+
min(
|
|
27688
|
+
var(--navi-safe-area-inset-right) +
|
|
27689
|
+
var(--navi-transition-cover-right),
|
|
27690
|
+
var(--navi-transition-old-band-right)
|
|
27691
|
+
) -
|
|
27692
|
+
100dvw
|
|
27366
27693
|
);
|
|
27367
27694
|
clip-path: inset(
|
|
27368
27695
|
var(--navi-route-transition-clip-top)
|
|
@@ -27389,10 +27716,12 @@ const css$10 = /* css */`
|
|
|
27389
27716
|
) - var(--navi-route-transition-clip-bottom)
|
|
27390
27717
|
);
|
|
27391
27718
|
}
|
|
27719
|
+
/* Each picture at the corner its own state stood at, which is not the
|
|
27720
|
+
window's: the window contains both states, and a state that is scrolled
|
|
27721
|
+
— or that stands under a bar the other one does not have — is somewhere
|
|
27722
|
+
inside it (see transition_window.js). Offset here rather than by
|
|
27723
|
+
\`translate\`, which the movement itself uses. */
|
|
27392
27724
|
&::view-transition-old(navi-route-transition) {
|
|
27393
|
-
/* Where the area WAS on screen, which is not where the window stands
|
|
27394
|
-
(see transition_window.js). Offset here rather than by \`translate\`,
|
|
27395
|
-
which the movement itself uses. */
|
|
27396
27725
|
top: calc(
|
|
27397
27726
|
var(--navi-transition-window-old-top) - var(
|
|
27398
27727
|
--navi-transition-window-top
|
|
@@ -27404,6 +27733,18 @@ const css$10 = /* css */`
|
|
|
27404
27733
|
)
|
|
27405
27734
|
);
|
|
27406
27735
|
}
|
|
27736
|
+
&::view-transition-new(navi-route-transition) {
|
|
27737
|
+
top: calc(
|
|
27738
|
+
var(--navi-transition-window-new-top) - var(
|
|
27739
|
+
--navi-transition-window-top
|
|
27740
|
+
)
|
|
27741
|
+
);
|
|
27742
|
+
left: calc(
|
|
27743
|
+
var(--navi-transition-window-new-left) - var(
|
|
27744
|
+
--navi-transition-window-left
|
|
27745
|
+
)
|
|
27746
|
+
);
|
|
27747
|
+
}
|
|
27407
27748
|
|
|
27408
27749
|
/* ------------------------------------------------------------------
|
|
27409
27750
|
The movements. One of \`root\` and \`navi-route-transition\` exists at a
|
|
@@ -28086,12 +28427,17 @@ const beginTransition = ({
|
|
|
28086
28427
|
warnOnce("several-areas", `${areaElements.length} elements carry ${TRANSITION_AREA_ATTRIBUTE}. They all take the same view-transition-name, and a name belongs to one element at a time: the browser refuses EVERY view transition of the document while this holds. Mark the one element the pages live in.`);
|
|
28087
28428
|
}
|
|
28088
28429
|
const areaElement = areaElements.length > 0 ? areaElements[0] : null;
|
|
28089
|
-
// The area as it stands before anything moves
|
|
28090
|
-
// still the page being
|
|
28091
|
-
|
|
28430
|
+
// The area as it stands before anything moves, and the band the furniture
|
|
28431
|
+
// around it leaves free: rendering is held, so both are still the page being
|
|
28432
|
+
// left (see transition_window.js).
|
|
28433
|
+
let areaStateBefore = null;
|
|
28092
28434
|
if (areaElement) {
|
|
28093
28435
|
documentElement.setAttribute(TRANSITION_TARGET_ATTRIBUTE, "area");
|
|
28094
|
-
|
|
28436
|
+
// Said before the picture is taken, like every name (see
|
|
28437
|
+
// transition_furniture.js): what the bars are wearing when the transition
|
|
28438
|
+
// starts is what the browser photographs.
|
|
28439
|
+
nameTransitionFurniture(transition, areaElement);
|
|
28440
|
+
areaStateBefore = measureTransitionWindowState(areaElement);
|
|
28095
28441
|
}
|
|
28096
28442
|
// A duration of this relation's own, worn for the length of the transition —
|
|
28097
28443
|
// and whatever the application had written inline put back afterwards, not
|
|
@@ -28161,7 +28507,11 @@ const beginTransition = ({
|
|
|
28161
28507
|
// The page arriving is in the DOM and the transition has not started
|
|
28162
28508
|
// playing: the one moment both states of the area can be known.
|
|
28163
28509
|
if (areaElement) {
|
|
28164
|
-
|
|
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);
|
|
28514
|
+
holdTransitionWindow(transition, areaElement, areaStateBefore);
|
|
28165
28515
|
}
|
|
28166
28516
|
});
|
|
28167
28517
|
const end = () => {
|
|
@@ -28179,6 +28529,7 @@ const beginTransition = ({
|
|
|
28179
28529
|
documentElement.removeAttribute(TRANSITION_TARGET_ATTRIBUTE);
|
|
28180
28530
|
releaseTransitionWindow(transition);
|
|
28181
28531
|
releaseTransitionDestination(transition);
|
|
28532
|
+
releaseTransitionFurniture(transition);
|
|
28182
28533
|
if (restoreDuration) {
|
|
28183
28534
|
restoreDuration();
|
|
28184
28535
|
}
|
|
@@ -28221,7 +28572,7 @@ const warnAboutNamesEscapingArea = (areaElement, capturedNames) => {
|
|
|
28221
28572
|
}
|
|
28222
28573
|
let escapedName = null;
|
|
28223
28574
|
for (const name of capturedNames) {
|
|
28224
|
-
if (name === "root" || name === AREA_NAME) {
|
|
28575
|
+
if (name === "root" || name === AREA_NAME || name.startsWith(FURNITURE_NAME_PREFIX)) {
|
|
28225
28576
|
continue;
|
|
28226
28577
|
}
|
|
28227
28578
|
escapedName = name;
|
|
@@ -28306,16 +28657,37 @@ const pageIsCurrent$1 = ({
|
|
|
28306
28657
|
};
|
|
28307
28658
|
// The FIRST page that answers, and every page read all the same: a page that
|
|
28308
28659
|
// is not the current one today is the one that must wake the reader tomorrow.
|
|
28660
|
+
//
|
|
28661
|
+
// Two of them answering at once is the one thing this reading cannot get right.
|
|
28662
|
+
// Relations are declared one pair at a time, so the row read here is the order
|
|
28663
|
+
// they happened to be written in — an order nothing in the application shows —
|
|
28664
|
+
// and the movement then played is the one written for whichever page was
|
|
28665
|
+
// mentioned first. A movement is a movement: it looks deliberate, which is why
|
|
28666
|
+
// the overlap is said out loud here, where both pages are known.
|
|
28309
28667
|
const currentPageIndex$1 = pages => {
|
|
28310
28668
|
let currentIndex = -1;
|
|
28311
28669
|
for (let i = 0; i < pages.length; i++) {
|
|
28312
28670
|
const isCurrent = pageIsCurrent$1(pages[i]);
|
|
28313
|
-
if (isCurrent
|
|
28671
|
+
if (!isCurrent) {
|
|
28672
|
+
continue;
|
|
28673
|
+
}
|
|
28674
|
+
if (currentIndex === -1) {
|
|
28314
28675
|
currentIndex = i;
|
|
28676
|
+
continue;
|
|
28315
28677
|
}
|
|
28678
|
+
warnPagesBothCurrent(pages[currentIndex], pages[i]);
|
|
28316
28679
|
}
|
|
28317
28680
|
return currentIndex;
|
|
28318
28681
|
};
|
|
28682
|
+
const warnPagesBothCurrent = (pageKept, pageIgnored) => {
|
|
28683
|
+
const kept = describePage(pageKept);
|
|
28684
|
+
const ignored = describePage(pageIgnored);
|
|
28685
|
+
warnOnce(`both-current:${kept}|${ignored}`, `${kept} and ${ignored} are both current on "${window.location.pathname}": two relations claim this url. A relation is resolved through which page is current, so the one mentioned first in a defineRouteTransition call wins — ${kept} — and its movement plays whichever of the two the application is really showing. Make one of them decline this url with a param constraint (see navigation.md, "Which values a param accepts").`);
|
|
28686
|
+
};
|
|
28687
|
+
const describePage = ({
|
|
28688
|
+
route,
|
|
28689
|
+
params
|
|
28690
|
+
}) => params ? `${route} with ${JSON.stringify(params)}` : `${route}`;
|
|
28319
28691
|
|
|
28320
28692
|
installImportMetaCssBuild(import.meta);/**
|
|
28321
28693
|
* Dragging from one route to the next, when the tabs of a page are URLs.
|
|
@@ -28453,17 +28825,16 @@ const css$$ = /* css */`
|
|
|
28453
28825
|
same page changing its mind. */
|
|
28454
28826
|
mix-blend-mode: normal;
|
|
28455
28827
|
}
|
|
28828
|
+
/* Each picture at the corner its own box stood at, which is not the
|
|
28829
|
+
window's: the window contains both boxes, and the two are at the same
|
|
28830
|
+
place in the layout without being at the same place in the window — one
|
|
28831
|
+
page is scrolled and the other is not, so the box being left starts
|
|
28832
|
+
higher up. Left at the window's own corner the page being left would be
|
|
28833
|
+
seen jumping back to its top before it even begins to leave. Offset here
|
|
28834
|
+
rather than by \`translate\`, which the movement itself uses, and at its
|
|
28835
|
+
own size rather than the group's so that nothing is cut off the far side
|
|
28836
|
+
of the shift (see transition_window.js). */
|
|
28456
28837
|
&::view-transition-old(navi-route-travel) {
|
|
28457
|
-
/* Where the page being left WAS on screen, which is not where the group
|
|
28458
|
-
stands: the group is at the arriving box (its position animation is
|
|
28459
|
-
dropped along with its height one, below), and the two boxes are at the
|
|
28460
|
-
same place in the layout without being at the same place in the window
|
|
28461
|
-
— one page is scrolled and the other is not, so the box being left
|
|
28462
|
-
starts higher up. Left at the group's own corner the page being left
|
|
28463
|
-
would be seen jumping back to its top before it even begins to leave.
|
|
28464
|
-
Offset here rather than by \`translate\`, which the movement itself uses,
|
|
28465
|
-
and at its own size rather than the group's so that nothing is cut off
|
|
28466
|
-
the far side of the shift (see transition_window.js). */
|
|
28467
28838
|
top: calc(
|
|
28468
28839
|
var(--navi-transition-window-old-top) - var(
|
|
28469
28840
|
--navi-transition-window-top
|
|
@@ -28476,6 +28847,19 @@ const css$$ = /* css */`
|
|
|
28476
28847
|
);
|
|
28477
28848
|
width: auto;
|
|
28478
28849
|
}
|
|
28850
|
+
&::view-transition-new(navi-route-travel) {
|
|
28851
|
+
top: calc(
|
|
28852
|
+
var(--navi-transition-window-new-top) - var(
|
|
28853
|
+
--navi-transition-window-top
|
|
28854
|
+
)
|
|
28855
|
+
);
|
|
28856
|
+
left: calc(
|
|
28857
|
+
var(--navi-transition-window-new-left) - var(
|
|
28858
|
+
--navi-transition-window-left
|
|
28859
|
+
)
|
|
28860
|
+
);
|
|
28861
|
+
width: auto;
|
|
28862
|
+
}
|
|
28479
28863
|
/* The pages are cut at the edge of the box they travel in. Said HERE and
|
|
28480
28864
|
nowhere else: these pictures are drawn in the top layer, so no overflow
|
|
28481
28865
|
on any element of the document — not the box's own, not a frame around
|
|
@@ -28487,17 +28871,28 @@ const css$$ = /* css */`
|
|
|
28487
28871
|
}
|
|
28488
28872
|
&::view-transition-group(navi-route-travel) {
|
|
28489
28873
|
/* The window the two pictures are seen through, held still for the whole
|
|
28490
|
-
travel at the
|
|
28491
|
-
is what CLIPS, and the browser
|
|
28492
|
-
left to the box arriving — so the
|
|
28493
|
-
|
|
28494
|
-
|
|
28495
|
-
|
|
28496
|
-
|
|
28497
|
-
|
|
28498
|
-
|
|
28499
|
-
|
|
28500
|
-
|
|
28874
|
+
travel at the rectangle that contains both boxes (see
|
|
28875
|
+
transition_window.js): the group is what CLIPS, and the browser
|
|
28876
|
+
animates it from the box being left to the box arriving — so the
|
|
28877
|
+
window moves and shrinks under the pictures, cutting the page leaving
|
|
28878
|
+
from the bottom, progressively. The box does end up at the arriving
|
|
28879
|
+
page's height, and that is right; what must not happen is the user
|
|
28880
|
+
watching it get there.
|
|
28881
|
+
|
|
28882
|
+
Held by dropping the group's animation rather than by winning against
|
|
28883
|
+
it with !important. The browser puts the group where the ARRIVING box
|
|
28884
|
+
stands, so it is moved from there back to the window's own corner. */
|
|
28885
|
+
top: calc(
|
|
28886
|
+
var(--navi-transition-window-top) - var(
|
|
28887
|
+
--navi-transition-window-new-top
|
|
28888
|
+
)
|
|
28889
|
+
);
|
|
28890
|
+
left: calc(
|
|
28891
|
+
var(--navi-transition-window-left) - var(
|
|
28892
|
+
--navi-transition-window-new-left
|
|
28893
|
+
)
|
|
28894
|
+
);
|
|
28895
|
+
width: var(--navi-transition-window-width);
|
|
28501
28896
|
height: var(--navi-transition-window-height);
|
|
28502
28897
|
|
|
28503
28898
|
/* Cut at what covers the box, on top of being cut at the box. The
|
|
@@ -28515,31 +28910,51 @@ const css$$ = /* css */`
|
|
|
28515
28910
|
above the pages covers the top of the box exactly as a fixed bar covers
|
|
28516
28911
|
the top of the screen. Both are read rather than asked for, so one that
|
|
28517
28912
|
grows, shrinks or unmounts mid-travel is followed without anything
|
|
28518
|
-
being told.
|
|
28519
|
-
|
|
28913
|
+
being told.
|
|
28914
|
+
|
|
28915
|
+
Read live, though, they describe the state ARRIVING and nothing else,
|
|
28916
|
+
so the cut is taken at the smaller of that and the band the state
|
|
28917
|
+
being left kept free (--navi-transition-old-band-*, photographed while
|
|
28918
|
+
both still existed). Furniture standing in BOTH states is the frame:
|
|
28919
|
+
the pages move behind it and are cut at it. Furniture standing in one
|
|
28920
|
+
of them is part of what changes, and cutting the page being left at a
|
|
28921
|
+
bar it never had shows its own header being sliced instead of
|
|
28922
|
+
leaving. */
|
|
28520
28923
|
--navi-route-travel-clip-top: max(
|
|
28521
28924
|
0px,
|
|
28522
|
-
|
|
28523
|
-
|
|
28925
|
+
min(
|
|
28926
|
+
var(--navi-safe-area-inset-top) + var(--navi-transition-cover-top),
|
|
28927
|
+
var(--navi-transition-old-band-top)
|
|
28928
|
+
) - var(--navi-transition-window-top)
|
|
28524
28929
|
);
|
|
28525
28930
|
--navi-route-travel-clip-left: max(
|
|
28526
28931
|
0px,
|
|
28527
|
-
|
|
28528
|
-
|
|
28932
|
+
min(
|
|
28933
|
+
var(--navi-safe-area-inset-left) + var(--navi-transition-cover-left),
|
|
28934
|
+
var(--navi-transition-old-band-left)
|
|
28935
|
+
) - var(--navi-transition-window-left)
|
|
28529
28936
|
);
|
|
28530
28937
|
--navi-route-travel-clip-bottom: max(
|
|
28531
28938
|
0px,
|
|
28532
28939
|
var(--navi-transition-window-top) +
|
|
28533
28940
|
var(--navi-transition-window-height) +
|
|
28534
|
-
|
|
28535
|
-
|
|
28941
|
+
min(
|
|
28942
|
+
var(--navi-safe-area-inset-bottom) +
|
|
28943
|
+
var(--navi-transition-cover-bottom),
|
|
28944
|
+
var(--navi-transition-old-band-bottom)
|
|
28945
|
+
) -
|
|
28946
|
+
100dvh
|
|
28536
28947
|
);
|
|
28537
28948
|
--navi-route-travel-clip-right: max(
|
|
28538
28949
|
0px,
|
|
28539
28950
|
var(--navi-transition-window-left) +
|
|
28540
28951
|
var(--navi-transition-window-width) +
|
|
28541
|
-
|
|
28542
|
-
|
|
28952
|
+
min(
|
|
28953
|
+
var(--navi-safe-area-inset-right) +
|
|
28954
|
+
var(--navi-transition-cover-right),
|
|
28955
|
+
var(--navi-transition-old-band-right)
|
|
28956
|
+
) -
|
|
28957
|
+
100dvw
|
|
28543
28958
|
);
|
|
28544
28959
|
clip-path: inset(
|
|
28545
28960
|
var(--navi-route-travel-clip-top) var(--navi-route-travel-clip-right)
|
|
@@ -28876,9 +29291,10 @@ const RouteTravel = ({
|
|
|
28876
29291
|
document.documentElement.setAttribute(DRAGGED_ATTRIBUTE, "");
|
|
28877
29292
|
}
|
|
28878
29293
|
pageAskedForRef.current = page;
|
|
28879
|
-
// The box as it stands before anything moves
|
|
28880
|
-
//
|
|
28881
|
-
|
|
29294
|
+
// The box as it stands before anything moves, and the band the furniture
|
|
29295
|
+
// around it leaves free: rendering is held, so both are still the page
|
|
29296
|
+
// being left (see transition_window.js).
|
|
29297
|
+
const stateBefore = measureTransitionWindowState(elementRef.current);
|
|
28882
29298
|
// The hold a navigation already took, if this travel is the answer to one:
|
|
28883
29299
|
// taking another would be taking a hold on a page that is holding still.
|
|
28884
29300
|
const releaseRendering = takeoverRoutingRenderingHold();
|
|
@@ -28921,7 +29337,7 @@ const RouteTravel = ({
|
|
|
28921
29337
|
// which is what the box is measured through: the two states are at the
|
|
28922
29338
|
// same place in the layout without being at the same place in the window
|
|
28923
29339
|
// (see transition_window.js).
|
|
28924
|
-
holdTransitionWindow(travel, elementRef.current,
|
|
29340
|
+
holdTransitionWindow(travel, elementRef.current, stateBefore);
|
|
28925
29341
|
});
|
|
28926
29342
|
travel.viewTransition = viewTransition;
|
|
28927
29343
|
if (scrub) {
|
|
@@ -29786,16 +30202,22 @@ const whilePageRenders = async (page, change, wait = armRouteRenderWait()) => {
|
|
|
29786
30202
|
};
|
|
29787
30203
|
|
|
29788
30204
|
// Whether the document's offset belongs to the tabs. The pages of a row scroll
|
|
29789
|
-
// the document when nothing between the box and the viewport
|
|
29790
|
-
// the tab on screen is then what makes the document tall, and the
|
|
29791
|
-
// is that tab's — it has to be given back with the tab, and the
|
|
29792
|
-
// clamping of it while pages are swapped has to be ignored.
|
|
30205
|
+
// the document when nothing between the box and the viewport is a scroll
|
|
30206
|
+
// container: the tab on screen is then what makes the document tall, and the
|
|
30207
|
+
// offset on it is that tab's — it has to be given back with the tab, and the
|
|
30208
|
+
// browser's clamping of it while pages are swapped has to be ignored.
|
|
29793
30209
|
//
|
|
29794
30210
|
// A box that lives inside a scroller of its own — a frame in an article, a
|
|
29795
30211
|
// panel beside other content — shares nothing with the document: the offset
|
|
29796
30212
|
// there is the surrounding page's, the reader never left it, and a travel has
|
|
29797
30213
|
// no business moving it. Each of its pages brings its own scrollport, which
|
|
29798
30214
|
// goes away with the page and has nothing to restore.
|
|
30215
|
+
//
|
|
30216
|
+
// includeHidden, because an `overflow: hidden` ancestor is one of those
|
|
30217
|
+
// scrollers: it shows no scrollbar and still holds an offset of its own, and
|
|
30218
|
+
// what is under it never reaches the document. A wrapper that merely clips
|
|
30219
|
+
// (`overflow: clip`) holds nothing and is walked straight through — see
|
|
30220
|
+
// is_scrollable.js.
|
|
29799
30221
|
const pagesScrollTheDocument = element => {
|
|
29800
30222
|
const scrollContainer = getScrollContainer(element, {
|
|
29801
30223
|
includeHidden: true
|
|
@@ -38342,6 +38764,9 @@ const selectByTextStrings = (element, range, startText, endText) => {
|
|
|
38342
38764
|
installImportMetaCssBuild(import.meta);// https://jsfiddle.net/v5xzJ/4/
|
|
38343
38765
|
const css$X = /* css */`
|
|
38344
38766
|
@layer navi {
|
|
38767
|
+
/* Same reason as .navi_icon below: the display here is a starting point,
|
|
38768
|
+
and box.jsx's unlayered [navi-box-flow] attributes have to win over it.
|
|
38769
|
+
The rest is appearance a caller may want back. */
|
|
38345
38770
|
.navi_text {
|
|
38346
38771
|
&[data-skeleton] {
|
|
38347
38772
|
border-radius: 0.2em;
|
|
@@ -44613,6 +45038,11 @@ const CheckboxPseudoElements = ["::-navi-loader", "::-navi-checkmark"];
|
|
|
44613
45038
|
|
|
44614
45039
|
installImportMetaCssBuild(import.meta);const css$M = /* css */`
|
|
44615
45040
|
@layer navi {
|
|
45041
|
+
/* Layered on purpose, rules included: a Field and its Label are chrome an
|
|
45042
|
+
app restyles wholesale (its own label color, its own spacing), and
|
|
45043
|
+
nothing declared here is structural — a cursor, a dimmed color, and
|
|
45044
|
+
spacing that already has --spacing-with-control as its knob. So an app
|
|
45045
|
+
rule of any weight takes them back, no specificity games. */
|
|
44616
45046
|
.navi_label {
|
|
44617
45047
|
--label-required-indicator-color: var(--navi-color-danger, #b42318);
|
|
44618
45048
|
|
|
@@ -46263,7 +46693,11 @@ installImportMetaCssBuild(import.meta);const css$J = /* css */`
|
|
|
46263
46693
|
--button-color-disabled: var(--button-color-readonly);
|
|
46264
46694
|
|
|
46265
46695
|
/* Here to be easy to override */
|
|
46266
|
-
|
|
46696
|
+
/* Layered, this one and the three below: display so box.jsx's unlayered
|
|
46697
|
+
[navi-box-flow] can put the button inline-flex, the font and the line
|
|
46698
|
+
so an app's own button typography wins without having to go through
|
|
46699
|
+
the --button-* variables. */
|
|
46700
|
+
display: inline-block;
|
|
46267
46701
|
font-size: var(--button-font-size);
|
|
46268
46702
|
font-family: var(--button-font-family);
|
|
46269
46703
|
/* A form control comes with a line of its own from the browser, and that
|
|
@@ -49817,70 +50251,95 @@ const css$G = /* css */`
|
|
|
49817
50251
|
controls answer it, an app never writes it. Whoever answers it also
|
|
49818
50252
|
stops it (see .navi_button_content in button_ui.jsx), so a button
|
|
49819
50253
|
deeper in — the clear cross in a picker's slot, the Save of a form in
|
|
49820
|
-
a popup the member opens — never mistakes itself for the seam.
|
|
49821
|
-
|
|
49822
|
-
|
|
49823
|
-
|
|
49824
|
-
|
|
49825
|
-
|
|
49826
|
-
|
|
49827
|
-
|
|
49828
|
-
|
|
49829
|
-
|
|
49830
|
-
|
|
49831
|
-
|
|
49832
|
-
|
|
49833
|
-
|
|
49834
|
-
|
|
49835
|
-
|
|
49836
|
-
|
|
49837
|
-
|
|
49838
|
-
|
|
49839
|
-
|
|
49840
|
-
|
|
49841
|
-
|
|
49842
|
-
|
|
49843
|
-
|
|
49844
|
-
|
|
49845
|
-
|
|
49846
|
-
|
|
49847
|
-
|
|
49848
|
-
|
|
49849
|
-
|
|
49850
|
-
|
|
49851
|
-
|
|
49852
|
-
|
|
49853
|
-
|
|
49854
|
-
|
|
49855
|
-
|
|
49856
|
-
|
|
49857
|
-
|
|
49858
|
-
|
|
49859
|
-
|
|
49860
|
-
|
|
49861
|
-
|
|
49862
|
-
|
|
49863
|
-
|
|
49864
|
-
|
|
49865
|
-
|
|
49866
|
-
|
|
49867
|
-
|
|
50254
|
+
a popup the member opens — never mistakes itself for the seam.
|
|
50255
|
+
Both are asked of members only (see just below for what one is): the
|
|
50256
|
+
second one alone being reset by a popup would leave the first one
|
|
50257
|
+
reaching it. */
|
|
50258
|
+
|
|
50259
|
+
/* What the group counts as a member — a child on its line, spelled
|
|
50260
|
+
*:not([navi-out-of-flow]) here and at every seam below. Not every child
|
|
50261
|
+
is one. A popup renders inside its opener's own subtree — a Dialog
|
|
50262
|
+
written next to the Button that opens it lands as a child of the group
|
|
50263
|
+
itself, and brings its backdrop (and, for layer="local", its clip
|
|
50264
|
+
wrapper) along; a callout anchored on a <button> is mounted in that
|
|
50265
|
+
button's parent, which is the group too. All of them are out of flow:
|
|
50266
|
+
none is ever at a seam, and none is between two members either. Counted
|
|
50267
|
+
as members they take a corner meant for a real one — a dialog in the
|
|
50268
|
+
middle of a row comes out square — and, worse, they move the real ones:
|
|
50269
|
+
a row of one button plus the dialog it opens has no :only-child left, so
|
|
50270
|
+
the lone button squares the side it joins nothing on. Read off a marker
|
|
50271
|
+
the elements set themselves (see popover.jsx, dialog.jsx, callout.js)
|
|
50272
|
+
rather than named class by class here: a layout component knowing the
|
|
50273
|
+
private classes of every component that can open something is exactly
|
|
50274
|
+
what the corner claims above exist to avoid. */
|
|
50275
|
+
> *:not([navi-out-of-flow]) {
|
|
50276
|
+
/* Members overlap by the width of one border, so along each seam one of
|
|
50277
|
+
the two borders covers the other. Whichever member the user is on has
|
|
50278
|
+
to be the one on top: it is the one whose border changes color, and
|
|
50279
|
+
the one whose focus ring goes all the way around — half a ring, cut by
|
|
50280
|
+
the neighbour painted after it, is what this avoids. z-index needs a
|
|
50281
|
+
positioned element to mean anything, hence position: relative.
|
|
50282
|
+
Deliberately not paired with isolation: isolate — a stacking context
|
|
50283
|
+
here would also trap the popup of a picker held in the group, which
|
|
50284
|
+
counts on its own band reaching the whole page. What keeps these
|
|
50285
|
+
values from escaping is instead that everything they could reach is a
|
|
50286
|
+
band above them (see navi_z_indexes.js). */
|
|
50287
|
+
&:hover,
|
|
50288
|
+
&[data-hover] {
|
|
50289
|
+
position: relative;
|
|
50290
|
+
z-index: var(--navi-z-index-control-hovered);
|
|
50291
|
+
}
|
|
50292
|
+
|
|
50293
|
+
/* Three spellings for one thing — the member showing a focus ring. Some
|
|
50294
|
+
controls take the focus on their own root (a button); others wrap a
|
|
50295
|
+
real input and draw the ring on their frame while the keyboard is held
|
|
50296
|
+
somewhere inside (a picker, a spin). The ring is what must not be
|
|
50297
|
+
sliced, so the member holding it is raised whether it wears the state
|
|
50298
|
+
itself or merely contains it. */
|
|
50299
|
+
&:focus-visible,
|
|
50300
|
+
&[data-focus-visible],
|
|
50301
|
+
&:has([data-focus-visible]) {
|
|
50302
|
+
position: relative;
|
|
50303
|
+
z-index: var(--navi-z-index-control-focused);
|
|
50304
|
+
}
|
|
50305
|
+
|
|
50306
|
+
/* The member holding something open. Neither of the two above covers it:
|
|
50307
|
+
the click that opened the popup gives no focus ring, the focus itself
|
|
50308
|
+
left for the popup's content, and the pointer is free to travel to a
|
|
50309
|
+
neighbour — yet the member keeps the border color its open state gives
|
|
50310
|
+
it, and that border is exactly what the neighbour painted after it
|
|
50311
|
+
slices. Read as a state, not as a pseudo-class: :active only lasts as
|
|
50312
|
+
long as the button is held down, and while it is held :hover is true
|
|
50313
|
+
anyway, so it would add nothing here.
|
|
50314
|
+
|
|
50315
|
+
:has, for the same reason as focus-visible above — the group member
|
|
50316
|
+
can be an enrobage around the control that expands — and reaching a
|
|
50317
|
+
popup held inline (a Popover with layer="local" renders inside its
|
|
50318
|
+
member) costs nothing: that popup only reads expanded while its own
|
|
50319
|
+
member is, which is the member this raises. A popup that is a child of
|
|
50320
|
+
the group itself wears aria-expanded too, and is not a member:
|
|
50321
|
+
position/z-index here would fight the placement it does its own way. */
|
|
50322
|
+
&[aria-expanded="true"],
|
|
50323
|
+
&:has([aria-expanded="true"]) {
|
|
50324
|
+
position: relative;
|
|
50325
|
+
z-index: var(--navi-z-index-control-expanded);
|
|
50326
|
+
}
|
|
49868
50327
|
}
|
|
49869
50328
|
|
|
49870
|
-
/*
|
|
50329
|
+
/* Where two members meet, stated as the relationship itself rather than as
|
|
50330
|
+
positions in the child list: the corner a member loses is the one facing
|
|
50331
|
+
a member, and the child list holds more than members (see above).
|
|
50332
|
+
A group of one — or of one member and the popup it opens — matches
|
|
50333
|
+
neither rule and keeps the radius it has on its own. */
|
|
50334
|
+
|
|
50335
|
+
/* Horizontal (default) */
|
|
49871
50336
|
&:not([data-vertical]) {
|
|
49872
|
-
|
|
50337
|
+
/* A member with a member before it: its left corners are on that seam,
|
|
50338
|
+
and it is the one pulled back so the two borders there become one
|
|
50339
|
+
line — same relationship, so the same rule. */
|
|
50340
|
+
> *:not([navi-out-of-flow]) ~ *:not([navi-out-of-flow]) {
|
|
49873
50341
|
margin-left: calc(var(--border-width, var(--group-border-width)) * -1);
|
|
49874
|
-
}
|
|
49875
|
-
> *:first-child:not(:only-child) {
|
|
49876
|
-
--x-corner-top-right-radius: 0;
|
|
49877
|
-
--x-corner-bottom-right-radius: 0;
|
|
49878
|
-
|
|
49879
|
-
border-top-right-radius: 0 !important;
|
|
49880
|
-
border-bottom-right-radius: 0 !important;
|
|
49881
|
-
}
|
|
49882
50342
|
|
|
49883
|
-
> *:last-child:not(:only-child) {
|
|
49884
50343
|
--x-corner-top-left-radius: 0;
|
|
49885
50344
|
--x-corner-bottom-left-radius: 0;
|
|
49886
50345
|
|
|
@@ -49888,30 +50347,23 @@ const css$G = /* css */`
|
|
|
49888
50347
|
border-bottom-left-radius: 0 !important;
|
|
49889
50348
|
}
|
|
49890
50349
|
|
|
49891
|
-
|
|
49892
|
-
|
|
50350
|
+
/* A member with a member after it: its right corners are on that seam. */
|
|
50351
|
+
> *:not([navi-out-of-flow]):has(~ *:not([navi-out-of-flow])) {
|
|
49893
50352
|
--x-corner-top-right-radius: 0;
|
|
49894
50353
|
--x-corner-bottom-right-radius: 0;
|
|
49895
|
-
--x-corner-bottom-left-radius: 0;
|
|
49896
50354
|
|
|
49897
|
-
border-radius: 0 !important;
|
|
50355
|
+
border-top-right-radius: 0 !important;
|
|
50356
|
+
border-bottom-right-radius: 0 !important;
|
|
49898
50357
|
}
|
|
49899
50358
|
}
|
|
49900
50359
|
|
|
49901
|
-
/* Vertical
|
|
50360
|
+
/* Vertical */
|
|
49902
50361
|
&[data-vertical] {
|
|
49903
|
-
|
|
50362
|
+
/* A member with a member above it — see the horizontal block's own
|
|
50363
|
+
comments, this is the same thing turned a quarter. */
|
|
50364
|
+
> *:not([navi-out-of-flow]) ~ *:not([navi-out-of-flow]) {
|
|
49904
50365
|
margin-top: calc(var(--border-width, var(--group-border-width)) * -1);
|
|
49905
|
-
}
|
|
49906
|
-
> *:first-child:not(:only-child) {
|
|
49907
|
-
--x-corner-bottom-right-radius: 0;
|
|
49908
|
-
--x-corner-bottom-left-radius: 0;
|
|
49909
|
-
|
|
49910
|
-
border-bottom-right-radius: 0 !important;
|
|
49911
|
-
border-bottom-left-radius: 0 !important;
|
|
49912
|
-
}
|
|
49913
50366
|
|
|
49914
|
-
> *:last-child:not(:only-child) {
|
|
49915
50367
|
--x-corner-top-left-radius: 0;
|
|
49916
50368
|
--x-corner-top-right-radius: 0;
|
|
49917
50369
|
|
|
@@ -49919,13 +50371,13 @@ const css$G = /* css */`
|
|
|
49919
50371
|
border-top-right-radius: 0 !important;
|
|
49920
50372
|
}
|
|
49921
50373
|
|
|
49922
|
-
|
|
49923
|
-
|
|
49924
|
-
--x-corner-top-right-radius: 0;
|
|
50374
|
+
/* A member with a member below it. */
|
|
50375
|
+
> *:not([navi-out-of-flow]):has(~ *:not([navi-out-of-flow])) {
|
|
49925
50376
|
--x-corner-bottom-right-radius: 0;
|
|
49926
50377
|
--x-corner-bottom-left-radius: 0;
|
|
49927
50378
|
|
|
49928
|
-
border-radius: 0 !important;
|
|
50379
|
+
border-bottom-right-radius: 0 !important;
|
|
50380
|
+
border-bottom-left-radius: 0 !important;
|
|
49929
50381
|
}
|
|
49930
50382
|
}
|
|
49931
50383
|
}
|
|
@@ -53120,6 +53572,8 @@ const TimeTime = ({
|
|
|
53120
53572
|
children,
|
|
53121
53573
|
lang = languagesSignal.value,
|
|
53122
53574
|
format = "long",
|
|
53575
|
+
pad = true,
|
|
53576
|
+
precision = pad ? "minute" : "hour",
|
|
53123
53577
|
...props
|
|
53124
53578
|
}) => {
|
|
53125
53579
|
if (children === undefined) {
|
|
@@ -53128,13 +53582,7 @@ const TimeTime = ({
|
|
|
53128
53582
|
children: "--:--"
|
|
53129
53583
|
});
|
|
53130
53584
|
}
|
|
53131
|
-
const date =
|
|
53132
|
-
if (/^\d{2}:\d{2}(?::\d{2})?$/.test(value)) {
|
|
53133
|
-
const d = new Date(`1970-01-01T${value}`);
|
|
53134
|
-
return isNaN(d.getTime()) ? null : d;
|
|
53135
|
-
}
|
|
53136
|
-
return null;
|
|
53137
|
-
});
|
|
53585
|
+
const date = toTimeOfDay(children);
|
|
53138
53586
|
// toDate turns a non-finite number into an Invalid Date, which is an object
|
|
53139
53587
|
if (!date || isNaN(date.getTime())) {
|
|
53140
53588
|
return jsx(TimeText, {
|
|
@@ -53171,7 +53619,9 @@ const TimeTime = ({
|
|
|
53171
53619
|
text = formatMinuteDuration(totalMinutes, {
|
|
53172
53620
|
lang,
|
|
53173
53621
|
format,
|
|
53174
|
-
clockStyle: true
|
|
53622
|
+
clockStyle: true,
|
|
53623
|
+
pad,
|
|
53624
|
+
precision
|
|
53175
53625
|
});
|
|
53176
53626
|
} else if (format !== "long") {
|
|
53177
53627
|
// short/narrow/compact: keep the "0 h"/"0h" hour part instead of
|
|
@@ -53181,7 +53631,9 @@ const TimeTime = ({
|
|
|
53181
53631
|
text = formatMinuteDuration(totalMinutes, {
|
|
53182
53632
|
lang,
|
|
53183
53633
|
format,
|
|
53184
|
-
clockStyle: true
|
|
53634
|
+
clockStyle: true,
|
|
53635
|
+
pad,
|
|
53636
|
+
precision
|
|
53185
53637
|
});
|
|
53186
53638
|
} else {
|
|
53187
53639
|
const midnightWord = naviI18n("time.midnight", undefined, {
|
|
@@ -53472,6 +53924,111 @@ const TimeText = props => {
|
|
|
53472
53924
|
...props
|
|
53473
53925
|
});
|
|
53474
53926
|
};
|
|
53927
|
+
|
|
53928
|
+
/**
|
|
53929
|
+
* Displays a span between two instants — an opening slot, an availability
|
|
53930
|
+
* window — as the two `<time>` elements `<Time>` would render, around a
|
|
53931
|
+
* separator.
|
|
53932
|
+
*
|
|
53933
|
+
* On top of writing the separator, it makes the two bounds agree on how
|
|
53934
|
+
* precisely they are written, which is a property of the pair and of nothing
|
|
53935
|
+
* else: with `type="time" format="compact" pad={false}`, "08:00"–"10:00" reads
|
|
53936
|
+
* "8h–10h", but "11:30"–"14:00" reads "11h30–14h00" and not "11h30–14h", where
|
|
53937
|
+
* the eye stops on the difference of shape before it reads the hours. Any bound
|
|
53938
|
+
* with minutes gives minutes to both, zero included. The padded clock
|
|
53939
|
+
* (`pad` left at its default) already writes every bound at the same width, and
|
|
53940
|
+
* the spelled-out formats say their units in words, so neither needs the rule
|
|
53941
|
+
* and neither is touched by it.
|
|
53942
|
+
*
|
|
53943
|
+
* @param {Date|number|string} from
|
|
53944
|
+
* The start of the span, in whatever `<Time>` accepts for this `type`.
|
|
53945
|
+
* @param {Date|number|string} to
|
|
53946
|
+
* The end of the span. An undefined bound renders `<Time>`'s own placeholder.
|
|
53947
|
+
* @param {"date"|"month"|"datetime"|"time"|"hour"|"minute"|"second"} [type="time"]
|
|
53948
|
+
* Passed to both bounds. Only `"time"` gets the shared-precision rule; the
|
|
53949
|
+
* other types are written one after the other, with nothing factored out (a
|
|
53950
|
+
* date span reads "11 mai – 14 mai", never "du 11 au 14 mai").
|
|
53951
|
+
* @param {"hour"|"minute"} [precision]
|
|
53952
|
+
* Writes both bounds at this precision instead of the one the pair calls for
|
|
53953
|
+
* — `"minute"` to keep a zero minute on both ("8h00–10h00"), `"hour"` to drop
|
|
53954
|
+
* it on both ("8h–11h30", which is the shape the rule exists to avoid: set it
|
|
53955
|
+
* only when you mean it).
|
|
53956
|
+
* @param {string} [separator]
|
|
53957
|
+
* What goes between the two bounds. Defaults to the `"time.range_separator"`
|
|
53958
|
+
* navi text (an en dash), tightened against both bounds in `format="compact"`
|
|
53959
|
+
* — where the span is one short token — and spaced out otherwise.
|
|
53960
|
+
*
|
|
53961
|
+
* Every other prop is forwarded to both bounds; see `<Time>`.
|
|
53962
|
+
*/
|
|
53963
|
+
const TimeRange = ({
|
|
53964
|
+
from,
|
|
53965
|
+
to,
|
|
53966
|
+
type = "time",
|
|
53967
|
+
format = "long",
|
|
53968
|
+
lang = languagesSignal.value,
|
|
53969
|
+
pad = true,
|
|
53970
|
+
precision,
|
|
53971
|
+
separator = naviI18n("time.range_separator", undefined, {
|
|
53972
|
+
lang
|
|
53973
|
+
}),
|
|
53974
|
+
...props
|
|
53975
|
+
}) => {
|
|
53976
|
+
const boundProps = {
|
|
53977
|
+
type,
|
|
53978
|
+
format,
|
|
53979
|
+
lang
|
|
53980
|
+
};
|
|
53981
|
+
if (type === "time") {
|
|
53982
|
+
boundProps.pad = pad;
|
|
53983
|
+
boundProps.precision = precision ?? resolvePairPrecision(from, to, {
|
|
53984
|
+
format,
|
|
53985
|
+
pad
|
|
53986
|
+
});
|
|
53987
|
+
}
|
|
53988
|
+
// compact writes the whole span as one short token ("8h–10h"): nothing
|
|
53989
|
+
// around the separator, and no break inside it. The other formats are
|
|
53990
|
+
// phrases — they get room around the separator, and may wrap there.
|
|
53991
|
+
const tight = format === "compact";
|
|
53992
|
+
return jsxs(Text, {
|
|
53993
|
+
noWrap: tight,
|
|
53994
|
+
...props,
|
|
53995
|
+
children: [jsx(Time, {
|
|
53996
|
+
...boundProps,
|
|
53997
|
+
children: from
|
|
53998
|
+
}), tight ? separator : ` ${separator} `, jsx(Time, {
|
|
53999
|
+
...boundProps,
|
|
54000
|
+
children: to
|
|
54001
|
+
})]
|
|
54002
|
+
});
|
|
54003
|
+
};
|
|
54004
|
+
|
|
54005
|
+
// The two bounds of a span are written to the same precision, decided by the
|
|
54006
|
+
// pair: "8h–10h" as long as neither has minutes, "11h30–14h00" as soon as one
|
|
54007
|
+
// of them does. Only ever a question for the unpadded compact clock — the
|
|
54008
|
+
// padded one always writes "08h00", and the spelled-out formats name their
|
|
54009
|
+
// units, leaving no shape for the eye to trip on.
|
|
54010
|
+
const resolvePairPrecision = (from, to, {
|
|
54011
|
+
format,
|
|
54012
|
+
pad
|
|
54013
|
+
}) => {
|
|
54014
|
+
if (pad || format !== "compact") {
|
|
54015
|
+
return "minute";
|
|
54016
|
+
}
|
|
54017
|
+
const hasMinutes = value => {
|
|
54018
|
+
const date = toTimeOfDay(value);
|
|
54019
|
+
return Boolean(date) && !isNaN(date.getTime()) && date.getMinutes() !== 0;
|
|
54020
|
+
};
|
|
54021
|
+
return hasMinutes(from) || hasMinutes(to) ? "minute" : "hour";
|
|
54022
|
+
};
|
|
54023
|
+
const toTimeOfDay = value => {
|
|
54024
|
+
return toDate(value, string => {
|
|
54025
|
+
if (/^\d{2}:\d{2}(?::\d{2})?$/.test(string)) {
|
|
54026
|
+
const d = new Date(`1970-01-01T${string}`);
|
|
54027
|
+
return isNaN(d.getTime()) ? null : d;
|
|
54028
|
+
}
|
|
54029
|
+
return null;
|
|
54030
|
+
});
|
|
54031
|
+
};
|
|
53475
54032
|
const toDate = (value, parseString) => {
|
|
53476
54033
|
if (value instanceof Date) {
|
|
53477
54034
|
return value;
|
|
@@ -55836,7 +56393,13 @@ const DialogLocal = props => {
|
|
|
55836
56393
|
children: [backdropProps && jsx(Box, {
|
|
55837
56394
|
...backdropProps
|
|
55838
56395
|
}), jsx("div", {
|
|
55839
|
-
className: "navi_dialog_clip_wrapper"
|
|
56396
|
+
className: "navi_dialog_clip_wrapper"
|
|
56397
|
+
// Out of flow like the dialog it holds — see the dialog's own
|
|
56398
|
+
// contentProps for what reads the marker.
|
|
56399
|
+
// eslint-disable-next-line react/no-unknown-property
|
|
56400
|
+
,
|
|
56401
|
+
|
|
56402
|
+
"navi-out-of-flow": "",
|
|
55840
56403
|
children: jsx(Box, {
|
|
55841
56404
|
...contentProps
|
|
55842
56405
|
})
|
|
@@ -56515,6 +57078,9 @@ const useDialogProps = props => {
|
|
|
56515
57078
|
// real element we render ourselves.
|
|
56516
57079
|
Object.assign(backdropProps, {
|
|
56517
57080
|
"ref": backdropRef,
|
|
57081
|
+
// Out of flow like the popup it belongs to — see the content element's own
|
|
57082
|
+
// note for what the marker is read by.
|
|
57083
|
+
"navi-out-of-flow": "",
|
|
56518
57084
|
"baseClassName": "navi_dialog_backdrop",
|
|
56519
57085
|
"aria-hidden": "true",
|
|
56520
57086
|
// Recomputed fresh on every render from openController.opened (not
|
|
@@ -56588,6 +57154,13 @@ const useDialogProps = props => {
|
|
|
56588
57154
|
onNaviCommand(e);
|
|
56589
57155
|
rest.onnavi_command?.(e);
|
|
56590
57156
|
},
|
|
57157
|
+
// Not a child on the line of whatever holds it: a popup renders inside its
|
|
57158
|
+
// opener's own subtree, so a Dialog written next to the control that opens it
|
|
57159
|
+
// is a child of that control's own parent. A Group frames the children on
|
|
57160
|
+
// its line and this is not one of them — it is in the top layer, or
|
|
57161
|
+
// absolutely placed by its own code — so it says so once, here (group.jsx
|
|
57162
|
+
// reads this attribute to tell a member from anything else on its line).
|
|
57163
|
+
"navi-out-of-flow": "",
|
|
56591
57164
|
"baseClassName": "navi_dialog",
|
|
56592
57165
|
"pseudoClasses": DIALOG_PSEUDO_CLASSES,
|
|
56593
57166
|
// Distinguishes the two renderers for the CSS above (position: fixed
|
|
@@ -57298,7 +57871,13 @@ const PopoverCustom = props => {
|
|
|
57298
57871
|
children: [backdropProps && jsx(Box, {
|
|
57299
57872
|
...backdropProps
|
|
57300
57873
|
}), jsx("div", {
|
|
57301
|
-
className: "navi_popover_clip_wrapper"
|
|
57874
|
+
className: "navi_popover_clip_wrapper"
|
|
57875
|
+
// Out of flow like the popover it holds — see the popover's own
|
|
57876
|
+
// contentProps for what reads the marker.
|
|
57877
|
+
// eslint-disable-next-line react/no-unknown-property
|
|
57878
|
+
,
|
|
57879
|
+
|
|
57880
|
+
"navi-out-of-flow": "",
|
|
57302
57881
|
children: jsx(Box, {
|
|
57303
57882
|
...contentProps
|
|
57304
57883
|
})
|
|
@@ -58034,6 +58613,9 @@ const usePopoverProps = props => {
|
|
|
58034
58613
|
Object.assign(backdropProps, {
|
|
58035
58614
|
"ref": backdropRef,
|
|
58036
58615
|
"id": backdropId,
|
|
58616
|
+
// Out of flow like the popup it belongs to — see the content element's own
|
|
58617
|
+
// note for what the marker is read by.
|
|
58618
|
+
"navi-out-of-flow": "",
|
|
58037
58619
|
"baseClassName": "navi_popover_backdrop",
|
|
58038
58620
|
"aria-hidden": "true",
|
|
58039
58621
|
// Recomputed fresh on every render from openController.opened (not a
|
|
@@ -58129,6 +58711,13 @@ const usePopoverProps = props => {
|
|
|
58129
58711
|
// it contains claim header/footer/body (see box.jsx) — a popup is always a
|
|
58130
58712
|
// scrolling area, so it says so once, here.
|
|
58131
58713
|
"overflow": "auto",
|
|
58714
|
+
// Not a child on the line of whatever holds it: a popup renders inside its
|
|
58715
|
+
// opener's own subtree, so a Popover written next to the control that opens it
|
|
58716
|
+
// is a child of that control's own parent. A Group frames the children on
|
|
58717
|
+
// its line and this is not one of them — it is in the top layer, or
|
|
58718
|
+
// absolutely placed by its own code — so it says so once, here (group.jsx
|
|
58719
|
+
// reads this attribute to tell a member from anything else on its line).
|
|
58720
|
+
"navi-out-of-flow": "",
|
|
58132
58721
|
"baseClassName": "navi_popover",
|
|
58133
58722
|
"pseudoClasses": POPOVER_PSEUDO_CLASSES,
|
|
58134
58723
|
"onKeyDown": e => {
|
|
@@ -58239,7 +58828,10 @@ const css$C = /* css */`
|
|
|
58239
58828
|
opens it (a Picker holds its popup children inside its root), and
|
|
58240
58829
|
line-height inherits as computed: the control's line is a length
|
|
58241
58830
|
(--navi-control-line-height), and inherited it would arrive as that
|
|
58242
|
-
control's pixels — a 12px caption on an 18px picker's 23px rows.
|
|
58831
|
+
control's pixels — a 12px caption on an 18px picker's 23px rows.
|
|
58832
|
+
Layered, like the dialog padding below: both are what navi puts there
|
|
58833
|
+
in the absence of anything else, and an app writing its own line or
|
|
58834
|
+
its own popup padding is meant to win. */
|
|
58243
58835
|
line-height: var(--navi-line-height);
|
|
58244
58836
|
|
|
58245
58837
|
&.navi_popover {
|
|
@@ -80875,5 +81467,5 @@ const UserSvg = () => jsx("svg", {
|
|
|
80875
81467
|
})
|
|
80876
81468
|
});
|
|
80877
81469
|
|
|
80878
|
-
export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, BadgeList, Binder, Box, Button, ButtonCopyToClipboard, CalloutStatusIcon, Caption, CardLayout, CheckSvg, CheckboxGroup, CloseSvg, Code, Col, Colgroup, Color, ConstructionSvg, ControlGroup, DaySpin, Details, Dialog, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, Expandable, EyeClosedSvg, EyeSvg, Field, FixedBar, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, InfoSvg, Input, InputDuration, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemGroup, ListItems, Loading, LoadingDotsSvg, LoadingIndicator, LoadingIndicatorFluid, LoadingOutline, MessageBox, Meter, Nav, NaviDebug, NumberSpin, OfflineError, Paragraph, Picker, Popover, Popup, Quantity, RadioGroup, Route, RouteTransitionArea, RouteTravel, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectableInput, SelectionContext, Separator, SettingsSvg, SidePanel, Slide, SlideContainer, Spin, SpinGroup, SplitButton, StarSvg, Step, StepList, SummaryMarker, Svg, Table, TableCell, Tbody, Text, TextBox, Textarea, TextareaCharCount, Thead, Time, TimeRangeSpin, TimeRangeWheel, TimeSpin, TimeWheel, Title, Tr, UITransition, Unit, UserSvg, ViewportLayout, Wheel, WheelGroup, WheelItem, actionRunEffect, anyMatchingRouteSignal, applySearch, arraySignalMembership, canNavBackSignal, canNavForwardSignal, coarsePointerSignal, compareTwoJsValues, constraintFromValidityRule, createAction, createAvailableConstraint, createI18n, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, createSlot, defineInteractionDetector, defineRouteDefaultTransition, defineRouteTransition, detectHorizontalOverflow, enableDebugActions, enableDebugOnDocumentLoading, ensureDocumentStartViewTransition, errorIsDisplayed, filterTableSelection, formatDatetime, formatDay, formatDayRelative, formatMonth, formatNumber, formatTime, formatTimeRelative, getNowHours, getNowHoursRoundedToStep, interpolateText, isCellSelected, isColumnSelected, isOfflineError, isRowSelected, isScrolling, isToday, languagesSignal, localStorageSignal, markErrorAsDisplayedBy, moveArrayItemByIndex, navBack, navForward, navIntegratedVia, navTo, naviI18n, openCallout, rawUrlPart, registerGlobalConstraint, reload, rerunActions, resource, route, routeAction, scrollActivitySignal, setBaseUrl, setNetworkPolicy, setPreferredLanguage, setSupportedLanguages, setUrlTargetOptions, setupRoutes, smallTouchScreenSignal, stateSignal, stopLoad, stringifyTableSelectionValue, swapArrayItemByIndex, syncOwnedResourceToSignals, syncResourceToSignals, triggerNaviCommand, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutElement, useCalloutRequestClose, useCanNavBack, useCanNavForward, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useInputGroup, useKeyboardShortcuts, useNavState, useNetworkPolicyReason, useOrderedColumns, usePopupMode, useRouteStatus, useRunOnMount, useSearchText, useSelectableElement, useSelectionController, useSignalSync, useSlideContainer, useSlideValue, useStateArray, useTitleLevel, useUrlSearchParam, useUrlTargetId, valueInLocalStorage, windowWidthSignal };
|
|
81470
|
+
export { ActionRenderer, ActiveKeyboardShortcuts, Address, Badge, BadgeCount, BadgeList, Binder, Box, Button, ButtonCopyToClipboard, CalloutStatusIcon, Caption, CardLayout, CheckSvg, CheckboxGroup, CloseSvg, Code, Col, Colgroup, Color, ConstructionSvg, ControlGroup, DaySpin, Details, Dialog, Editable, ErrorBoundary, ErrorBoundaryContext, ExclamationSvg, Expandable, EyeClosedSvg, EyeSvg, Field, FixedBar, Form, Group, Head, HeartSvg, HomeSvg, Icon, Image, InfoSvg, Input, InputDuration, Interpolate, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, LinkCurrentSvg, List, ListItem, ListItemGroup, ListItems, Loading, LoadingDotsSvg, LoadingIndicator, LoadingIndicatorFluid, LoadingOutline, MessageBox, Meter, Nav, NaviDebug, NumberSpin, OfflineError, Paragraph, Picker, Popover, Popup, Quantity, RadioGroup, Route, RouteTransitionArea, RouteTravel, RowNumberCol, RowNumberTableCell, SVGMaskOverlay, SearchSvg, Select, SelectableInput, SelectionContext, Separator, SettingsSvg, SidePanel, Slide, SlideContainer, Spin, SpinGroup, SplitButton, StarSvg, Step, StepList, SummaryMarker, Svg, Table, TableCell, Tbody, Text, TextBox, Textarea, TextareaCharCount, Thead, Time, TimeRange, TimeRangeSpin, TimeRangeWheel, TimeSpin, TimeWheel, Title, Tr, UITransition, Unit, UserSvg, ViewportLayout, Wheel, WheelGroup, WheelItem, actionRunEffect, anyMatchingRouteSignal, applySearch, arraySignalMembership, canNavBackSignal, canNavForwardSignal, coarsePointerSignal, compareTwoJsValues, constraintFromValidityRule, createAction, createAvailableConstraint, createI18n, createRequestCanceller, createSearch, createSelectionKeyboardShortcuts, createSlot, defineInteractionDetector, defineRouteDefaultTransition, defineRouteTransition, detectHorizontalOverflow, enableDebugActions, enableDebugOnDocumentLoading, ensureDocumentStartViewTransition, errorIsDisplayed, filterTableSelection, formatDatetime, formatDay, formatDayRelative, formatMonth, formatNumber, formatTime, formatTimeRelative, getNowHours, getNowHoursRoundedToStep, interpolateText, isCellSelected, isColumnSelected, isOfflineError, isRowSelected, isScrolling, isToday, languagesSignal, localStorageSignal, markErrorAsDisplayedBy, moveArrayItemByIndex, navBack, navForward, navIntegratedVia, navTo, naviI18n, openCallout, rawUrlPart, registerGlobalConstraint, reload, rerunActions, resource, route, routeAction, scrollActivitySignal, setBaseUrl, setNetworkPolicy, setPreferredLanguage, setSupportedLanguages, setUrlTargetOptions, setupRoutes, smallTouchScreenSignal, stateSignal, stopLoad, stringifyTableSelectionValue, swapArrayItemByIndex, syncOwnedResourceToSignals, syncResourceToSignals, triggerNaviCommand, updateActions, useActionStatus, useArraySignalMembership, useAsyncData, useCalloutElement, useCalloutRequestClose, useCanNavBack, useCanNavForward, useCancelPrevious, useCellGridFromRows, useConstraintValidityState, useDependenciesDiff, useDisplayedLayoutEffect, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useInputGroup, useKeyboardShortcuts, useNavState, useNetworkPolicyReason, useOrderedColumns, usePopupMode, useRouteStatus, useRunOnMount, useSearchText, useSelectableElement, useSelectionController, useSignalSync, useSlideContainer, useSlideValue, useStateArray, useTitleLevel, useUrlSearchParam, useUrlTargetId, valueInLocalStorage, windowWidthSignal };
|
|
80879
81471
|
//# sourceMappingURL=jsenv_navi.js.map
|