@jsenv/navi 0.29.72 → 0.29.74
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 +109 -45
- package/dist/jsenv_navi.js.map +15 -9
- package/docs/popup_open.md +6 -4
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -29852,10 +29852,13 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
29852
29852
|
* `positionArea` accepts the same grammar Popover does (see
|
|
29853
29853
|
* popup_shared.js), even though several combinations land identically here
|
|
29854
29854
|
* since Dialog is never really anchored — kept distinct anyway because
|
|
29855
|
-
* `positionArea` still picks which animation direction plays. `anchor`
|
|
29856
|
-
*
|
|
29857
|
-
*
|
|
29858
|
-
*
|
|
29855
|
+
* `positionArea` still picks which animation direction plays. `anchor` is
|
|
29856
|
+
* inert here unless `sizeFromAnchor` asks for it: a dialog is a surface of
|
|
29857
|
+
* its own, sized by its content, not a panel grown out of the control that
|
|
29858
|
+
* opened it — that is Popover's job. With `sizeFromAnchor`, the anchor's box
|
|
29859
|
+
* reaches the `--anchor-width`/`--anchor-height` CSS vars and becomes a
|
|
29860
|
+
* min-width/min-height floor. Either way Dialog's own positioning is never
|
|
29861
|
+
* relative to the anchor, unlike Popover.
|
|
29859
29862
|
*
|
|
29860
29863
|
* Two rendering strategies, picked via `layer`: `DialogAsModal` (a real
|
|
29861
29864
|
* `<dialog>`, `showModal()`, top layer — native focus trap,
|
|
@@ -30340,17 +30343,24 @@ const css$X = /* css */`
|
|
|
30340
30343
|
* value is used as-is.
|
|
30341
30344
|
* @param {string} [props.animationDuration] - Maps to
|
|
30342
30345
|
* `--popup-animation-duration`.
|
|
30343
|
-
* @param {Element|{current: Element}|string} [props.anchor] -
|
|
30344
|
-
*
|
|
30345
|
-
*
|
|
30346
|
+
* @param {Element|{current: Element}|string} [props.anchor] - Never used for
|
|
30347
|
+
* positioning (see this file's top comment), and ignored entirely unless
|
|
30348
|
+
* `sizeFromAnchor` is set — then it sizes the dialog via the
|
|
30349
|
+
* `--anchor-width`/`--anchor-height` CSS vars. Defaults to whatever
|
|
30346
30350
|
* triggered the open (`e.detail.anchor`), if any. A string is resolved via
|
|
30347
30351
|
* `document.getElementById` when the dialog opens — see popover.jsx's own
|
|
30348
30352
|
* `anchor` doc for why (mainly `defaultOpen`).
|
|
30353
|
+
* @param {boolean} [props.sizeFromAnchor=false] - Whether the dialog takes the
|
|
30354
|
+
* anchor's width/height as a min-width/min-height floor
|
|
30355
|
+
* (`--anchor-width`/`--anchor-height`). Off by default: unlike a popover,
|
|
30356
|
+
* a dialog is not attached to what opened it, so following that element's
|
|
30357
|
+
* box is a deliberate choice (a picker-style surface meant to read as the
|
|
30358
|
+
* trigger's own continuation), not the norm.
|
|
30349
30359
|
* @param {"override"|"ignore"} [props.anchorCustomEventDetail="override"] -
|
|
30350
30360
|
* Whether an explicit `anchor` prop takes precedence over (`"override"`,
|
|
30351
30361
|
* default) or is ignored in favor of (`"ignore"`) whatever anchor the
|
|
30352
30362
|
* triggering event carried. Same prop as Popover's, applied to the only
|
|
30353
|
-
* thing an anchor
|
|
30363
|
+
* thing an anchor can do here: sizing, and only under `sizeFromAnchor`.
|
|
30354
30364
|
* @param {string} [props.minWidth] - Maps to `--dialog-min-width`; clamped
|
|
30355
30365
|
* so it can never push the dialog past `--dialog-maxmax-width` (the
|
|
30356
30366
|
* viewport/container-spacing ceiling) regardless of how large a value is
|
|
@@ -30609,12 +30619,15 @@ const useDialogProps = props => {
|
|
|
30609
30619
|
// once, held at that size while open. See this prop's own JSDoc above.
|
|
30610
30620
|
sizing = "auto",
|
|
30611
30621
|
animation,
|
|
30612
|
-
//
|
|
30613
|
-
//
|
|
30622
|
+
// Inert unless sizeFromAnchor below (see this file's top comment) —
|
|
30623
|
+
// Dialog's own positioning is never relative to it.
|
|
30614
30624
|
anchor,
|
|
30625
|
+
// Opt-in: --anchor-width/--anchor-height are only set when this is true.
|
|
30626
|
+
// See this prop's own JSDoc above for why a dialog does not follow its
|
|
30627
|
+
// trigger's box by default.
|
|
30628
|
+
sizeFromAnchor = false,
|
|
30615
30629
|
// Same meaning as Popover's own prop, applied to the only thing an anchor
|
|
30616
|
-
//
|
|
30617
|
-
// trigger's width says so (SidePanel does exactly that).
|
|
30630
|
+
// can do here: sizing under sizeFromAnchor.
|
|
30618
30631
|
anchorCustomEventDetail = "override",
|
|
30619
30632
|
// Makes the dialog itself a valid focus target so
|
|
30620
30633
|
// autoFocus="last-resort" below has somewhere to land when it contains
|
|
@@ -30809,7 +30822,7 @@ const useDialogProps = props => {
|
|
|
30809
30822
|
// see openLocalDialogCount's own comment
|
|
30810
30823
|
dialogEl.style.setProperty("--dialog-stack-order", openLocalDialogCount++);
|
|
30811
30824
|
}
|
|
30812
|
-
if (anchorElement) {
|
|
30825
|
+
if (sizeFromAnchor && anchorElement) {
|
|
30813
30826
|
const {
|
|
30814
30827
|
width,
|
|
30815
30828
|
height
|
|
@@ -38824,6 +38837,21 @@ const css$T = /* css */`
|
|
|
38824
38837
|
view-transition-name: navi-route-transition;
|
|
38825
38838
|
}
|
|
38826
38839
|
|
|
38840
|
+
/* A named descendant — a row named for a reorder gesture, a thumbnail named
|
|
38841
|
+
for a morph — is a hole in the area's picture and a group of its own at the
|
|
38842
|
+
top of the tree: it stands still and cross-fades on its own clock while the
|
|
38843
|
+
pages move. Nested groups put it back INSIDE the area's picture, so it
|
|
38844
|
+
travels with the pages and is cut at their edge. Said here rather than
|
|
38845
|
+
erasing the name: a name inside the area is legitimate, and "contain" says
|
|
38846
|
+
"these move with the page" where "none" would say "these do not exist". A
|
|
38847
|
+
browser without nested groups is warned instead (see
|
|
38848
|
+
warnAboutNamesEscapingArea). */
|
|
38849
|
+
@supports (view-transition-group: contain) {
|
|
38850
|
+
[data-navi-route-transition-area] {
|
|
38851
|
+
view-transition-group: contain;
|
|
38852
|
+
}
|
|
38853
|
+
}
|
|
38854
|
+
|
|
38827
38855
|
/* Only while a transition of OURS is playing: everything below changes how
|
|
38828
38856
|
the document animates, and the document belongs to the application the
|
|
38829
38857
|
rest of the time. */
|
|
@@ -38861,6 +38889,12 @@ const css$T = /* css */`
|
|
|
38861
38889
|
overflow on any element of the document can reach them. */
|
|
38862
38890
|
overflow: clip;
|
|
38863
38891
|
}
|
|
38892
|
+
/* The nested groups of named descendants, cut at that same edge. On its own
|
|
38893
|
+
rule: a selector a browser cannot parse takes the whole list it is
|
|
38894
|
+
written in down with it, and the pages must be cut everywhere. */
|
|
38895
|
+
&::view-transition-group-children(navi-route-transition) {
|
|
38896
|
+
overflow: clip;
|
|
38897
|
+
}
|
|
38864
38898
|
&::view-transition-group(navi-route-transition) {
|
|
38865
38899
|
/* Held still for the whole transition, at the taller of the two states,
|
|
38866
38900
|
and standing where the area stands (see transition_window.js). Held by
|
|
@@ -39645,7 +39679,7 @@ const beginTransition = ({
|
|
|
39645
39679
|
// something that has already happened.
|
|
39646
39680
|
const renderWait = armRouteRenderWait$1();
|
|
39647
39681
|
// What the browser ACTUALLY captured, read once the pictures exist: it is
|
|
39648
|
-
// the only place the
|
|
39682
|
+
// the only place the silent misconfigurations show. They are all about the
|
|
39649
39683
|
// same thing — a movement playing on pictures that are not the pages.
|
|
39650
39684
|
const viewTransitionReady = () => {
|
|
39651
39685
|
const capturedNames = capturedViewTransitionNames();
|
|
@@ -39653,6 +39687,7 @@ const beginTransition = ({
|
|
|
39653
39687
|
if (!capturedNames.has(AREA_NAME)) {
|
|
39654
39688
|
warnOnce("area-not-captured", `The element marked ${TRANSITION_AREA_ATTRIBUTE} was not captured, so the movement plays on nothing. An element is captured only if it generates a box: \`display: contents\` (or an element not rendered) cannot be the area — its rectangle is what gets photographed and clipped.`);
|
|
39655
39689
|
}
|
|
39690
|
+
warnAboutNamesEscapingArea(areaElement, capturedNames);
|
|
39656
39691
|
return;
|
|
39657
39692
|
}
|
|
39658
39693
|
for (const name of capturedNames) {
|
|
@@ -39738,6 +39773,42 @@ const capturedViewTransitionNames = () => {
|
|
|
39738
39773
|
return names;
|
|
39739
39774
|
};
|
|
39740
39775
|
|
|
39776
|
+
// Nested groups keep a name written inside the area inside its picture (see
|
|
39777
|
+
// the @supports block in the CSS above). Without them the name escapes to the
|
|
39778
|
+
// top of the ::view-transition tree and the element it belongs to stands still,
|
|
39779
|
+
// fading on its own, while the pages move under it.
|
|
39780
|
+
const NESTED_GROUPS_SUPPORTED = window.CSS.supports("view-transition-group", "contain");
|
|
39781
|
+
const warnAboutNamesEscapingArea = (areaElement, capturedNames) => {
|
|
39782
|
+
if (NESTED_GROUPS_SUPPORTED) {
|
|
39783
|
+
return;
|
|
39784
|
+
}
|
|
39785
|
+
let escapedName = null;
|
|
39786
|
+
for (const name of capturedNames) {
|
|
39787
|
+
if (name === "root" || name === AREA_NAME) {
|
|
39788
|
+
continue;
|
|
39789
|
+
}
|
|
39790
|
+
escapedName = name;
|
|
39791
|
+
break;
|
|
39792
|
+
}
|
|
39793
|
+
// A name captured next to the area is not necessarily inside it — a bar the
|
|
39794
|
+
// application animates on the same clock is named on purpose. The subtree is
|
|
39795
|
+
// walked only once something is there to find, so the common case reads
|
|
39796
|
+
// nothing.
|
|
39797
|
+
if (!escapedName) {
|
|
39798
|
+
return;
|
|
39799
|
+
}
|
|
39800
|
+
for (const descendant of areaElement.querySelectorAll("*")) {
|
|
39801
|
+
const {
|
|
39802
|
+
viewTransitionName
|
|
39803
|
+
} = getComputedStyle(descendant);
|
|
39804
|
+
if (!viewTransitionName || viewTransitionName === "none") {
|
|
39805
|
+
continue;
|
|
39806
|
+
}
|
|
39807
|
+
warnOnce("names-escaping-area", `"${viewTransitionName}" is a view-transition-name written inside the element marked ${TRANSITION_AREA_ATTRIBUTE}, and this browser has no nested groups (view-transition-group: contain): the element it names is lifted out of the area's picture, so it stands still and fades on its own while the pages move. Give that name only for the length of the gesture it serves, or drop it while a route transition plays (:root[${TRANSITION_ATTRIBUTE}] { view-transition-name: none }).`);
|
|
39808
|
+
return;
|
|
39809
|
+
}
|
|
39810
|
+
};
|
|
39811
|
+
|
|
39741
39812
|
// Said once per kind, whatever the number of navigations: a misconfiguration
|
|
39742
39813
|
// is one fact about the application, and repeating it every time the user
|
|
39743
39814
|
// moves would bury it.
|
|
@@ -54384,9 +54455,9 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
54384
54455
|
*
|
|
54385
54456
|
* `layer` (shared by both — picks the top-layer vs. local-container rendering
|
|
54386
54457
|
* strategy either way) and `anchorCustomEventDetail` (shared too: Popover
|
|
54387
|
-
* resolves an anchor to position against, Dialog to size itself from
|
|
54388
|
-
*
|
|
54389
|
-
* renders.
|
|
54458
|
+
* resolves an anchor to position against, Dialog only to size itself from,
|
|
54459
|
+
* and only under its own `sizeFromAnchor`) pass through untouched via
|
|
54460
|
+
* `...rest` to whichever of Popover/Dialog actually renders.
|
|
54390
54461
|
*/
|
|
54391
54462
|
const css$A = /* css */`
|
|
54392
54463
|
@layer navi {
|
|
@@ -54424,13 +54495,12 @@ const css$A = /* css */`
|
|
|
54424
54495
|
* @param {"top"|"local"} [props.layer] - Forwarded as-is to whichever of
|
|
54425
54496
|
* `Dialog`/`Popover` renders — see either component's own doc.
|
|
54426
54497
|
* @param {Element|{current: Element}} [props.anchor] - Forwarded as-is —
|
|
54427
|
-
*
|
|
54428
|
-
*
|
|
54498
|
+
* positioning for `Popover`, and for `Dialog` sizing only, and only when
|
|
54499
|
+
* `sizeFromAnchor` is also passed (see each component's own doc).
|
|
54429
54500
|
* @param {"override"|"ignore"} [props.anchorCustomEventDetail] - Forwarded
|
|
54430
54501
|
* as-is to both — what it governs differs (positioning for `Popover`,
|
|
54431
|
-
* sizing for `Dialog`), but "ignore whatever anchor the
|
|
54432
|
-
* carried" has to mean the same thing in either mode
|
|
54433
|
-
* `<Popup>` usage silently picks up its trigger's width on small screens.
|
|
54502
|
+
* `sizeFromAnchor` sizing for `Dialog`), but "ignore whatever anchor the
|
|
54503
|
+
* triggering event carried" has to mean the same thing in either mode.
|
|
54434
54504
|
* @param {string} [props.marginWithAnchor] - **Popover-only**, destructured
|
|
54435
54505
|
* out so it can't leak onto the real `<dialog>` element as a stray DOM
|
|
54436
54506
|
* attribute when `mode="dialog"` is picked.
|
|
@@ -54633,12 +54703,17 @@ installImportMetaCssBuild(import.meta);const css$z = /* css */`
|
|
|
54633
54703
|
|
|
54634
54704
|
/* No fallback on purpose (same as --popover-max-height above): unset
|
|
54635
54705
|
picker props leave these declarations invalid at computed-value
|
|
54636
|
-
time, so the dialog keeps its own ceilings. */
|
|
54706
|
+
time, so the dialog keeps its own floors/ceilings. */
|
|
54707
|
+
--dialog-min-width: var(--picker-dialog-min-width);
|
|
54708
|
+
--dialog-min-height: var(--picker-dialog-min-height);
|
|
54637
54709
|
--dialog-max-width: var(--picker-dialog-max-width);
|
|
54638
54710
|
--dialog-max-height: var(--picker-dialog-max-height);
|
|
54639
54711
|
|
|
54640
|
-
/*
|
|
54641
|
-
|
|
54712
|
+
/* Nothing bridges the trigger's width in here: a dialog does not
|
|
54713
|
+
follow its anchor's box (dialog.jsx, sizeFromAnchor) — it is not
|
|
54714
|
+
visually attached to the trigger, so it is sized by its content,
|
|
54715
|
+
and dialogMinWidth/dialogMinHeight are how a caller says otherwise.
|
|
54716
|
+
Only the cursor reset below is picker-specific here. */
|
|
54642
54717
|
cursor: default; /* Reset pointer cursor within the select */
|
|
54643
54718
|
|
|
54644
54719
|
/* Dialog already applies display: flex to [open] itself, but
|
|
@@ -54660,24 +54735,10 @@ installImportMetaCssBuild(import.meta);const css$z = /* css */`
|
|
|
54660
54735
|
}
|
|
54661
54736
|
|
|
54662
54737
|
/* popupWidthFitContent (picker.jsx): drop the trigger-width floor so the
|
|
54663
|
-
popup shrinks to its content.
|
|
54738
|
+
popup shrinks to its content. Popover-only — the dialog has no such
|
|
54739
|
+
floor to drop (see the dialog block above). */
|
|
54664
54740
|
&[data-popup-width-fit-content] {
|
|
54665
54741
|
--picker-popover-min-width: 0px;
|
|
54666
|
-
|
|
54667
|
-
/* The popover var above only reaches the popover — the dialog reads
|
|
54668
|
-
--anchor-width directly for its own min-width floor (dialog.jsx). A
|
|
54669
|
-
modal dialog isn't visually attached to the trigger, so with
|
|
54670
|
-
fit-content we drop that floor here too, letting the content size the
|
|
54671
|
-
dialog like the popover. (More specific than dialog.jsx's own
|
|
54672
|
-
.navi_dialog rule; both are unlayered, so this wins.) */
|
|
54673
|
-
&[aria-haspopup="dialog"] {
|
|
54674
|
-
.navi_dialog {
|
|
54675
|
-
min-width: min(
|
|
54676
|
-
var(--dialog-min-width, 0px),
|
|
54677
|
-
var(--x-dialog-max-width)
|
|
54678
|
-
);
|
|
54679
|
-
}
|
|
54680
|
-
}
|
|
54681
54742
|
}
|
|
54682
54743
|
}
|
|
54683
54744
|
`;
|
|
@@ -62633,6 +62694,8 @@ const PickerStyleCSSVars = {
|
|
|
62633
62694
|
"borderWidth": "--picker-border-width",
|
|
62634
62695
|
"borderRadius": "--picker-border-radius",
|
|
62635
62696
|
"popoverMaxHeight": "--picker-popover-max-height",
|
|
62697
|
+
"dialogMinWidth": "--picker-dialog-min-width",
|
|
62698
|
+
"dialogMinHeight": "--picker-dialog-min-height",
|
|
62636
62699
|
"dialogMaxWidth": "--picker-dialog-max-width",
|
|
62637
62700
|
"dialogMaxHeight": "--picker-dialog-max-height",
|
|
62638
62701
|
"popupBackgroundColor": "--picker-popup-background-color",
|
|
@@ -73976,10 +74039,11 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
73976
74039
|
* `navi-side`/`data-layer` attributes) rather than computed in JS — read
|
|
73977
74040
|
* the CSS block below instead of expecting a JS equivalent of it here.
|
|
73978
74041
|
*
|
|
73979
|
-
* `anchorCustomEventDetail="ignore"` is required, not cosmetic
|
|
73980
|
-
*
|
|
73981
|
-
*
|
|
73982
|
-
*
|
|
74042
|
+
* `anchorCustomEventDetail="ignore"` is required, not cosmetic: without it
|
|
74043
|
+
* Popover docks next to whatever triggered the open instead of flush against
|
|
74044
|
+
* the edge. Dialog needs nothing here — it never sizes itself from an anchor
|
|
74045
|
+
* unless asked to (`sizeFromAnchor`, see dialog.jsx), which a side panel
|
|
74046
|
+
* never does: its `width`/`height` props are what size it.
|
|
73983
74047
|
*/
|
|
73984
74048
|
const css = /* css */`
|
|
73985
74049
|
.navi_side_panel {
|