@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.
@@ -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` only
29856
- * ever affects the `--anchor-width`/`--anchor-height` CSS vars (sizing the
29857
- * dialog relative to whatever opened it) Dialog's own positioning is never
29858
- * relative to it, unlike Popover.
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] - Only ever sizes
30344
- * the dialog via the `--anchor-width`/`--anchor-height` CSS vars never
30345
- * used for positioning (see this file's top comment). Defaults to whatever
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 does here: sizing (`--anchor-width`/`--anchor-height`).
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
- // Only ever affects --anchor-width/--anchor-height (see this file's top
30613
- // comment) — Dialog's own positioning is never relative to it.
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
- // does here: sizing. "ignore" is how a dialog that must not inherit its
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 two silent misconfigurations show. Both are about 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) pass
54388
- * through untouched via `...rest` to whichever of Popover/Dialog actually
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
- * sizing-only for `Dialog`, positioning for `Popover` (see each
54428
- * component's own doc for what it actually does there).
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 triggering event
54432
- * carried" has to mean the same thing in either mode, or the same
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
- /* Dialog itself already sizes min-width off --anchor-width only
54641
- the cursor reset below is picker-specific here. */
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. Inherits down to the popover. */
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, and in both
73980
- * modes: without it Popover docks next to whatever triggered the open instead
73981
- * of flush against the edge, and Dialog takes that trigger's width as its own
73982
- * `min-width` floor (`--anchor-width`), overriding the `width` prop.
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 {