@jsenv/navi 0.29.73 → 0.29.75
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 +375 -97
- package/dist/jsenv_navi.js.map +19 -14
- package/docs/popup_open.md +6 -4
- package/package.json +2 -2
package/dist/jsenv_navi.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { installImportMetaCssBuild, windowHeightSignal, windowWidthSignal, visualViewportHeightSignal, visualViewportWidthSignal, getAppHeight, getAppWidth, smallTouchScreenSignal } from "./jsenv_navi_side_effects.js";
|
|
6
6
|
export { coarsePointerSignal, disableVirtualKeyboardOverlay } from "./jsenv_navi_side_effects.js";
|
|
7
|
-
import { elementIsFocusable, createPubSub, dispatchInternalCustomEvent, dispatchCustomEvent, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, getElementSignature, findEvent, createValueEffect, findFocusDelegateTarget, findFocusable, allowWheelThrough, dispatchPublicCustomEvent, resolveCSSColor, ELEMENT_SIZE_CHANGE, findSelfOrAncestorFixedPosition, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, applyNewPosition, measureLongestVisualLineWidth, chainEvent, waitForPressHeld, suppressClickAfterGesture, startDragToTravel, markDragSource, startDragTo, createIterableWeakSet, createEventGroupLogger, getKeyboardEventDefaultAction, activeElementSignal, normalizeStyle, mergeOneStyle, getPositionedParent, mergeTwoStyles, normalizeStyles, resolveCSSSize, hasCSSSizeUnit, resolveOklchLightness, contrastColor, closestOpenableAncestor, isAncestorOpen, observeAncestorOpenState, getAncestorOpenType, clickIsSuppressed, scrollRoomTowards, parsePositionArea, snapToPixel, trapFocusInside, trapScrollInside, onAncestorReopen, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, watchWheelTravel, findBefore, findAfter, initFocusGroup,
|
|
7
|
+
import { elementIsFocusable, createPubSub, dispatchInternalCustomEvent, dispatchCustomEvent, getVisuallyVisibleInfo, getFirstVisuallyVisibleAncestor, getElementSignature, findEvent, createValueEffect, findFocusDelegateTarget, findFocusable, allowWheelThrough, dispatchPublicCustomEvent, resolveCSSColor, ELEMENT_SIZE_CHANGE, findSelfOrAncestorFixedPosition, visibleRectEffect, pickPositionRelativeTo, getBorderSizes, getPaddingSizes, applyNewPosition, measureLongestVisualLineWidth, chainEvent, waitForPressHeld, suppressClickAfterGesture, startDragToTravel, markDragSource, startDragTo, createIterableWeakSet, createEventGroupLogger, getKeyboardEventDefaultAction, activeElementSignal, normalizeStyle, mergeOneStyle, getPositionedParent, mergeTwoStyles, normalizeStyles, resolveCSSSize, hasCSSSizeUnit, resolveOklchLightness, contrastColor, closestOpenableAncestor, isAncestorOpen, observeAncestorOpenState, getAncestorOpenType, clickIsSuppressed, isTouchDrivenEvent, scrollIntoViewScoped, scrollRoomTowards, parsePositionArea, snapToPixel, trapFocusInside, trapScrollInside, onAncestorReopen, createGroupTransitionController, getBorderRadius, preventIntermediateScrollbar, createOpacityTransition, watchWheelTravel, findBefore, findAfter, initFocusGroup, getScrollContainer, canScroll, measureWidestChildRow, performTabNavigation, wheelGestureIsTakenFrom, releaseWheelGesture, claimWheelGesture, dragAfterIntent, stickyAsRelativeCoords, createDragToMoveGestureController, getDropTargetInfo, setStyles, useActiveElement, stringifyStyle as stringifyStyle$1 } from "@jsenv/dom";
|
|
8
8
|
export { clickIsSuppressed, contrastColor, findEvent, startDragTo } from "@jsenv/dom";
|
|
9
9
|
import { signal, computed, effect, batch, untracked, useSignal } from "@preact/signals";
|
|
10
10
|
import { createContext, isValidElement, h, Fragment, render, toChildArray, options, cloneElement } from "preact";
|
|
@@ -19345,10 +19345,48 @@ import.meta.css = [/* css */`
|
|
|
19345
19345
|
outline-offset: calc(-1 * var(--navi-focus-outline-width));
|
|
19346
19346
|
overflow: auto;
|
|
19347
19347
|
|
|
19348
|
+
/* The same reading as the header's corners above, on all four: a body
|
|
19349
|
+
follows the corners of the box it is drawn in — which is also what
|
|
19350
|
+
it clips its content to, the overflow just above. */
|
|
19351
|
+
border-top-left-radius: inherit;
|
|
19352
|
+
border-top-right-radius: inherit;
|
|
19353
|
+
border-bottom-right-radius: inherit;
|
|
19354
|
+
border-bottom-left-radius: inherit;
|
|
19355
|
+
|
|
19348
19356
|
&:focus-visible {
|
|
19349
19357
|
outline-style: solid;
|
|
19350
19358
|
}
|
|
19351
19359
|
}
|
|
19360
|
+
|
|
19361
|
+
/* A corner a header or a footer covers is not the body's to follow:
|
|
19362
|
+
what the body meets there is their flat separator line, not a curve,
|
|
19363
|
+
and a radius against it shows the box through the gap it opens. */
|
|
19364
|
+
> [data-header] ~ [data-body] {
|
|
19365
|
+
border-top-left-radius: 0;
|
|
19366
|
+
border-top-right-radius: 0;
|
|
19367
|
+
}
|
|
19368
|
+
> [data-body]:has(~ [data-footer]) {
|
|
19369
|
+
border-bottom-right-radius: 0;
|
|
19370
|
+
border-bottom-left-radius: 0;
|
|
19371
|
+
}
|
|
19372
|
+
|
|
19373
|
+
/* A body with no padding of its own holds content running edge to edge:
|
|
19374
|
+
whatever sits at one of its ends is drawn ON the corner the body just
|
|
19375
|
+
resolved, so a radius of its own there carves a notch out of it. The
|
|
19376
|
+
body already clips to that corner, which makes "none" the right radius
|
|
19377
|
+
for what lands on it — square, and the body draws the curve. The ask
|
|
19378
|
+
travels down as a corner claim (see group.jsx) so a navi control
|
|
19379
|
+
answers it wherever it sits inside. */
|
|
19380
|
+
> [data-body][data-body-flush] {
|
|
19381
|
+
> :first-child {
|
|
19382
|
+
--x-corner-top-left-radius: 0;
|
|
19383
|
+
--x-corner-top-right-radius: 0;
|
|
19384
|
+
}
|
|
19385
|
+
> :last-child {
|
|
19386
|
+
--x-corner-bottom-right-radius: 0;
|
|
19387
|
+
--x-corner-bottom-left-radius: 0;
|
|
19388
|
+
}
|
|
19389
|
+
}
|
|
19352
19390
|
}
|
|
19353
19391
|
}
|
|
19354
19392
|
|
|
@@ -19551,6 +19589,11 @@ const Box = props => {
|
|
|
19551
19589
|
}
|
|
19552
19590
|
if (body) {
|
|
19553
19591
|
rest["data-body"] = "";
|
|
19592
|
+
// Padding is what decides whether the content reaches the body's own
|
|
19593
|
+
// corners — see the corner claims in this file's CSS.
|
|
19594
|
+
if (!PADDING_PROP_NAMES.some(name => isNonZeroSpacing(rest[name]))) {
|
|
19595
|
+
rest["data-body-flush"] = "";
|
|
19596
|
+
}
|
|
19554
19597
|
}
|
|
19555
19598
|
const defaultDisplay = getDefaultDisplay(TagName);
|
|
19556
19599
|
// Read the parent flow early so we can use it when display="inherit" is requested.
|
|
@@ -20015,6 +20058,16 @@ const shouldInjectSeparatorBetween = (left, right) => {
|
|
|
20015
20058
|
}
|
|
20016
20059
|
return true;
|
|
20017
20060
|
};
|
|
20061
|
+
const PADDING_PROP_NAMES = ["padding", "paddingX", "paddingY", "paddingTop", "paddingRight", "paddingBottom", "paddingLeft"];
|
|
20062
|
+
const isNonZeroSpacing = value => {
|
|
20063
|
+
if (value === undefined || value === null || value === false) {
|
|
20064
|
+
return false;
|
|
20065
|
+
}
|
|
20066
|
+
if (value === 0 || value === "0" || value === "none") {
|
|
20067
|
+
return false;
|
|
20068
|
+
}
|
|
20069
|
+
return true;
|
|
20070
|
+
};
|
|
20018
20071
|
|
|
20019
20072
|
const useDebounceTrue = (value, delay = 300) => {
|
|
20020
20073
|
const [debouncedTrue, setDebouncedTrue] = useState(false);
|
|
@@ -28546,7 +28599,21 @@ const prepareFocusTransfer = (prepareEvent, debugFocus) => {
|
|
|
28546
28599
|
focusedElement,
|
|
28547
28600
|
focusVisible,
|
|
28548
28601
|
|
|
28549
|
-
|
|
28602
|
+
/**
|
|
28603
|
+
* Moves the focus into `containerEl`, on the element the ladder above
|
|
28604
|
+
* picks.
|
|
28605
|
+
*
|
|
28606
|
+
* `getDelay(target)` — asked once the target is known, answers how many
|
|
28607
|
+
* milliseconds to wait before actually focusing it. The ladder is what
|
|
28608
|
+
* decides WHO gets the focus and it may only run once (it consumes the
|
|
28609
|
+
* autofocus-restore mark), so a caller with a policy about WHEN cannot
|
|
28610
|
+
* resolve the target itself to make up its mind: it is handed the answer
|
|
28611
|
+
* instead. Returns a cancel function when it did delay, so a container
|
|
28612
|
+
* closing before the delay is up takes back a focus it never gave;
|
|
28613
|
+
* undefined when it focused straight away and there is nothing to take
|
|
28614
|
+
* back.
|
|
28615
|
+
*/
|
|
28616
|
+
transferFocus: (transferEvent, containerEl, { getDelay } = {}) => {
|
|
28550
28617
|
let target;
|
|
28551
28618
|
let reason;
|
|
28552
28619
|
const lastFocused = clearAutofocusRestore(containerEl);
|
|
@@ -28574,24 +28641,39 @@ const prepareFocusTransfer = (prepareEvent, debugFocus) => {
|
|
|
28574
28641
|
}
|
|
28575
28642
|
}
|
|
28576
28643
|
if (!target) {
|
|
28577
|
-
return;
|
|
28644
|
+
return undefined;
|
|
28578
28645
|
}
|
|
28579
28646
|
// The modality speaks for the transfer, but an editable target outranks
|
|
28580
28647
|
// it: it draws its ring on any focus (see isMatchingFocusVisible), so
|
|
28581
28648
|
// the native :focus-visible is told the same.
|
|
28582
28649
|
const targetFocusVisible = focusVisible || isEditableTarget(target);
|
|
28650
|
+
const giveFocus = () => {
|
|
28651
|
+
debugFocus(
|
|
28652
|
+
transferEvent,
|
|
28653
|
+
`Moving focus to ${getElementSignature(target)}.focus({ preventScroll: true, focusVisible: ${targetFocusVisible} }) (reason: ${reason})`,
|
|
28654
|
+
);
|
|
28655
|
+
target.focus({
|
|
28656
|
+
preventScroll: true,
|
|
28657
|
+
focusVisible: targetFocusVisible,
|
|
28658
|
+
});
|
|
28659
|
+
if (target.hasAttribute("navi-autofocus-select")) {
|
|
28660
|
+
target.select();
|
|
28661
|
+
target.scrollLeft = 0;
|
|
28662
|
+
}
|
|
28663
|
+
};
|
|
28664
|
+
const delay = getDelay?.(target) || 0;
|
|
28665
|
+
if (!delay) {
|
|
28666
|
+
giveFocus();
|
|
28667
|
+
return undefined;
|
|
28668
|
+
}
|
|
28583
28669
|
debugFocus(
|
|
28584
28670
|
transferEvent,
|
|
28585
|
-
`
|
|
28671
|
+
`Delaying focus to ${getElementSignature(target)} by ${delay}ms`,
|
|
28586
28672
|
);
|
|
28587
|
-
|
|
28588
|
-
|
|
28589
|
-
|
|
28590
|
-
}
|
|
28591
|
-
if (target.hasAttribute("navi-autofocus-select")) {
|
|
28592
|
-
target.select();
|
|
28593
|
-
target.scrollLeft = 0;
|
|
28594
|
-
}
|
|
28673
|
+
const timeout = setTimeout(giveFocus, delay);
|
|
28674
|
+
return () => {
|
|
28675
|
+
clearTimeout(timeout);
|
|
28676
|
+
};
|
|
28595
28677
|
},
|
|
28596
28678
|
|
|
28597
28679
|
restoreFocus: (restoreEvent) => {
|
|
@@ -28633,6 +28715,21 @@ const getFocusedBeforeTransfer = (e) => {
|
|
|
28633
28715
|
return document.activeElement;
|
|
28634
28716
|
};
|
|
28635
28717
|
|
|
28718
|
+
// How long a popup waits before handing the focus to a field, when giving it
|
|
28719
|
+
// is what raises the on-screen keyboard.
|
|
28720
|
+
//
|
|
28721
|
+
// The focus is normally given as early as possible. But a popup places itself
|
|
28722
|
+
// against the viewport, and on a phone the keyboard takes a third of that
|
|
28723
|
+
// viewport away the moment a field receives focus — so the two landing in the
|
|
28724
|
+
// same tick means the popup is still arriving when the room under it changes,
|
|
28725
|
+
// and it re-places itself mid-entrance. Waiting lets it settle first, and the
|
|
28726
|
+
// keyboard then shrinks a box that has stopped moving.
|
|
28727
|
+
//
|
|
28728
|
+
// Long enough to outlast an entrance transition rather than merely reaching
|
|
28729
|
+
// the next frame: what has to be over is the popup MOVING, not one paint of
|
|
28730
|
+
// it.
|
|
28731
|
+
const FOCUS_DELAY_ON_KEYBOARD_MS = 250;
|
|
28732
|
+
|
|
28636
28733
|
/**
|
|
28637
28734
|
* Owns open/close decision-making for a popup (Dialog or Popover): guards
|
|
28638
28735
|
* against duplicate requests and notifies the popup owner's own reactions.
|
|
@@ -28871,8 +28968,32 @@ const createOpenController = (
|
|
|
28871
28968
|
// once mousedown.preventDefault() has kept focus from landing
|
|
28872
28969
|
// anywhere yet.
|
|
28873
28970
|
|
|
28874
|
-
|
|
28971
|
+
// Two conditions, and both are about THIS opening rather than about
|
|
28972
|
+
// the device:
|
|
28973
|
+
// - the interaction: only a finger raises a virtual keyboard, and a
|
|
28974
|
+
// hybrid tablet answers "coarse" to every device-level signal
|
|
28975
|
+
// whichever of its two inputs was just used — the open event still
|
|
28976
|
+
// remembers which one it was. An opening with no pointer in it at
|
|
28977
|
+
// all (a keyboard shortcut, defaultOpen, an app calling open()) is
|
|
28978
|
+
// not one either.
|
|
28979
|
+
// - the target: focusing a button raises nothing, so there is nothing
|
|
28980
|
+
// to wait for and the focus stays immediate. Only a field the
|
|
28981
|
+
// keyboard comes up for is worth delaying — which is why the
|
|
28982
|
+
// decision is taken on the resolved target, inside transferFocus.
|
|
28983
|
+
const openedByTouch = Boolean(
|
|
28984
|
+
findEvent(requestOpenEvent, isTouchDrivenEvent),
|
|
28985
|
+
);
|
|
28986
|
+
const cancelPendingFocus = focusTransfer.transferFocus(e, el, {
|
|
28987
|
+
getDelay: (target) =>
|
|
28988
|
+
openedByTouch && isEditableTarget(target)
|
|
28989
|
+
? FOCUS_DELAY_ON_KEYBOARD_MS
|
|
28990
|
+
: 0,
|
|
28991
|
+
});
|
|
28875
28992
|
return (closeEvent) => {
|
|
28993
|
+
// Closed before the delay was up: the focus was never given, so it
|
|
28994
|
+
// must not be given now — to a field inside a popup on its way out,
|
|
28995
|
+
// raising the keyboard as it goes.
|
|
28996
|
+
cancelPendingFocus?.();
|
|
28876
28997
|
markAutofocusRestoreOnClose(el, closeEvent, focusedAtClose);
|
|
28877
28998
|
const focusoutEvent = findEvent(closeEvent, "focusout");
|
|
28878
28999
|
if (focusoutEvent) {
|
|
@@ -29141,6 +29262,60 @@ const flushSyncRendering = (fn) => {
|
|
|
29141
29262
|
*/
|
|
29142
29263
|
|
|
29143
29264
|
|
|
29265
|
+
/**
|
|
29266
|
+
* Whether a visibleRectEffect delivery is one that can have taken height away
|
|
29267
|
+
* from a popup, and so pushed whatever holds focus out of sight:
|
|
29268
|
+
* - "resize": the window/visual viewport settled — which is also how the
|
|
29269
|
+
* on-screen keyboard arrives, overlay or not (window_size.js);
|
|
29270
|
+
* - ELEMENT_SIZE_CHANGE: the popup's own box measured different;
|
|
29271
|
+
* - "focusin": the focus-settled re-measure, for the room that changes with
|
|
29272
|
+
* nothing announcing it (subscribeFocusSettled in window_size.js).
|
|
29273
|
+
*
|
|
29274
|
+
* Everything else is a scroll of one kind or another, where nothing got
|
|
29275
|
+
* smaller and scrolling the focused element back would fight the very gesture
|
|
29276
|
+
* that fired it.
|
|
29277
|
+
*/
|
|
29278
|
+
const mayHaveHiddenFocus = (event) => {
|
|
29279
|
+
const type = event?.type;
|
|
29280
|
+
return (
|
|
29281
|
+
type === "resize" || type === ELEMENT_SIZE_CHANGE || type === "focusin"
|
|
29282
|
+
);
|
|
29283
|
+
};
|
|
29284
|
+
|
|
29285
|
+
/**
|
|
29286
|
+
* Scrolls whatever holds focus inside `popupEl` back into view, if the popup
|
|
29287
|
+
* getting shorter has pushed it out.
|
|
29288
|
+
*
|
|
29289
|
+
* The case this exists for: a field low in the scrolling body of a popup that
|
|
29290
|
+
* also has a footer (box.jsx — with a body, the body is the only thing that
|
|
29291
|
+
* scrolls and the footer is a sibling sitting right under it). Focusing the
|
|
29292
|
+
* field makes the browser scroll it into view, which it does against the
|
|
29293
|
+
* popup's height AT THAT MOMENT; the on-screen keyboard then opens and takes
|
|
29294
|
+
* that height away. The body shrinks, its scrollTop does not move, so the
|
|
29295
|
+
* content slides down relative to the shorter scrollport and the field ends up
|
|
29296
|
+
* past its bottom edge — visually, swallowed by the footer. The browser does
|
|
29297
|
+
* not redo a scroll-into-view it already answered, so this does.
|
|
29298
|
+
*
|
|
29299
|
+
* Scoped to the field's own scroll container (never the page): a popup traps
|
|
29300
|
+
* scrolling precisely so the document underneath cannot move, and a plain
|
|
29301
|
+
* scrollIntoView walks past a container whose scrollbar isn't visible — see
|
|
29302
|
+
* scrollIntoViewScoped's own doc.
|
|
29303
|
+
*
|
|
29304
|
+
* "nearest": the smallest scroll that makes it visible, and none at all when
|
|
29305
|
+
* it already is — so this is free to call on every resize, and never fights
|
|
29306
|
+
* where the user had scrolled to.
|
|
29307
|
+
*/
|
|
29308
|
+
const keepFocusedElementVisible = (popupEl) => {
|
|
29309
|
+
const { activeElement } = document;
|
|
29310
|
+
if (!activeElement || activeElement === popupEl) {
|
|
29311
|
+
return;
|
|
29312
|
+
}
|
|
29313
|
+
if (!popupEl.contains(activeElement)) {
|
|
29314
|
+
return;
|
|
29315
|
+
}
|
|
29316
|
+
scrollIntoViewScoped(activeElement, { block: "nearest" });
|
|
29317
|
+
};
|
|
29318
|
+
|
|
29144
29319
|
/**
|
|
29145
29320
|
* Calls `onSettled` once `el`'s current CSS transition is over — via
|
|
29146
29321
|
* `transitionend`, with a safety `setTimeout` fallback matching the longest
|
|
@@ -29852,10 +30027,13 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
29852
30027
|
* `positionArea` accepts the same grammar Popover does (see
|
|
29853
30028
|
* popup_shared.js), even though several combinations land identically here
|
|
29854
30029
|
* since Dialog is never really anchored — kept distinct anyway because
|
|
29855
|
-
* `positionArea` still picks which animation direction plays. `anchor`
|
|
29856
|
-
*
|
|
29857
|
-
*
|
|
29858
|
-
*
|
|
30030
|
+
* `positionArea` still picks which animation direction plays. `anchor` is
|
|
30031
|
+
* inert here unless `sizeFromAnchor` asks for it: a dialog is a surface of
|
|
30032
|
+
* its own, sized by its content, not a panel grown out of the control that
|
|
30033
|
+
* opened it — that is Popover's job. With `sizeFromAnchor`, the anchor's box
|
|
30034
|
+
* reaches the `--anchor-width`/`--anchor-height` CSS vars and becomes a
|
|
30035
|
+
* min-width/min-height floor. Either way Dialog's own positioning is never
|
|
30036
|
+
* relative to the anchor, unlike Popover.
|
|
29859
30037
|
*
|
|
29860
30038
|
* Two rendering strategies, picked via `layer`: `DialogAsModal` (a real
|
|
29861
30039
|
* `<dialog>`, `showModal()`, top layer — native focus trap,
|
|
@@ -30340,17 +30518,24 @@ const css$X = /* css */`
|
|
|
30340
30518
|
* value is used as-is.
|
|
30341
30519
|
* @param {string} [props.animationDuration] - Maps to
|
|
30342
30520
|
* `--popup-animation-duration`.
|
|
30343
|
-
* @param {Element|{current: Element}|string} [props.anchor] -
|
|
30344
|
-
*
|
|
30345
|
-
*
|
|
30521
|
+
* @param {Element|{current: Element}|string} [props.anchor] - Never used for
|
|
30522
|
+
* positioning (see this file's top comment), and ignored entirely unless
|
|
30523
|
+
* `sizeFromAnchor` is set — then it sizes the dialog via the
|
|
30524
|
+
* `--anchor-width`/`--anchor-height` CSS vars. Defaults to whatever
|
|
30346
30525
|
* triggered the open (`e.detail.anchor`), if any. A string is resolved via
|
|
30347
30526
|
* `document.getElementById` when the dialog opens — see popover.jsx's own
|
|
30348
30527
|
* `anchor` doc for why (mainly `defaultOpen`).
|
|
30528
|
+
* @param {boolean} [props.sizeFromAnchor=false] - Whether the dialog takes the
|
|
30529
|
+
* anchor's width/height as a min-width/min-height floor
|
|
30530
|
+
* (`--anchor-width`/`--anchor-height`). Off by default: unlike a popover,
|
|
30531
|
+
* a dialog is not attached to what opened it, so following that element's
|
|
30532
|
+
* box is a deliberate choice (a picker-style surface meant to read as the
|
|
30533
|
+
* trigger's own continuation), not the norm.
|
|
30349
30534
|
* @param {"override"|"ignore"} [props.anchorCustomEventDetail="override"] -
|
|
30350
30535
|
* Whether an explicit `anchor` prop takes precedence over (`"override"`,
|
|
30351
30536
|
* default) or is ignored in favor of (`"ignore"`) whatever anchor the
|
|
30352
30537
|
* triggering event carried. Same prop as Popover's, applied to the only
|
|
30353
|
-
* thing an anchor
|
|
30538
|
+
* thing an anchor can do here: sizing, and only under `sizeFromAnchor`.
|
|
30354
30539
|
* @param {string} [props.minWidth] - Maps to `--dialog-min-width`; clamped
|
|
30355
30540
|
* so it can never push the dialog past `--dialog-maxmax-width` (the
|
|
30356
30541
|
* viewport/container-spacing ceiling) regardless of how large a value is
|
|
@@ -30609,12 +30794,15 @@ const useDialogProps = props => {
|
|
|
30609
30794
|
// once, held at that size while open. See this prop's own JSDoc above.
|
|
30610
30795
|
sizing = "auto",
|
|
30611
30796
|
animation,
|
|
30612
|
-
//
|
|
30613
|
-
//
|
|
30797
|
+
// Inert unless sizeFromAnchor below (see this file's top comment) —
|
|
30798
|
+
// Dialog's own positioning is never relative to it.
|
|
30614
30799
|
anchor,
|
|
30800
|
+
// Opt-in: --anchor-width/--anchor-height are only set when this is true.
|
|
30801
|
+
// See this prop's own JSDoc above for why a dialog does not follow its
|
|
30802
|
+
// trigger's box by default.
|
|
30803
|
+
sizeFromAnchor = false,
|
|
30615
30804
|
// 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).
|
|
30805
|
+
// can do here: sizing under sizeFromAnchor.
|
|
30618
30806
|
anchorCustomEventDetail = "override",
|
|
30619
30807
|
// Makes the dialog itself a valid focus target so
|
|
30620
30808
|
// autoFocus="last-resort" below has somewhere to land when it contains
|
|
@@ -30809,7 +30997,7 @@ const useDialogProps = props => {
|
|
|
30809
30997
|
// see openLocalDialogCount's own comment
|
|
30810
30998
|
dialogEl.style.setProperty("--dialog-stack-order", openLocalDialogCount++);
|
|
30811
30999
|
}
|
|
30812
|
-
if (anchorElement) {
|
|
31000
|
+
if (sizeFromAnchor && anchorElement) {
|
|
30813
31001
|
const {
|
|
30814
31002
|
width,
|
|
30815
31003
|
height
|
|
@@ -30977,6 +31165,11 @@ const useDialogProps = props => {
|
|
|
30977
31165
|
// handled generically by applyNewPosition itself (dispatches
|
|
30978
31166
|
// navi_position_change on every call) — nothing to do here.
|
|
30979
31167
|
};
|
|
31168
|
+
// Cleared here rather than on close, where the box is deliberately left
|
|
31169
|
+
// frozen at the size it was closing at (see the closing function's own
|
|
31170
|
+
// comment): this opening has its own content to be measured against, and
|
|
31171
|
+
// measuring it inside last time's box would answer with last time's size.
|
|
31172
|
+
unfreezeSize(dialogEl);
|
|
30980
31173
|
positionDialog();
|
|
30981
31174
|
if (sizing === "frozen") {
|
|
30982
31175
|
// After positionDialog: the caps it writes
|
|
@@ -30999,6 +31192,12 @@ const useDialogProps = props => {
|
|
|
30999
31192
|
event
|
|
31000
31193
|
}) => {
|
|
31001
31194
|
positionDialog(event);
|
|
31195
|
+
// Only for what can have taken height away from the dialog — a
|
|
31196
|
+
// scroll never does, and re-scrolling on one would fight the finger
|
|
31197
|
+
// that caused it. See keepFocusedElementVisible's own doc.
|
|
31198
|
+
if (mayHaveHiddenFocus(event)) {
|
|
31199
|
+
keepFocusedElementVisible(dialogEl);
|
|
31200
|
+
}
|
|
31002
31201
|
}, {
|
|
31003
31202
|
event: e,
|
|
31004
31203
|
skipElementResize: true
|
|
@@ -31051,6 +31250,12 @@ const useDialogProps = props => {
|
|
|
31051
31250
|
}
|
|
31052
31251
|
const hasCssTransitionAnimation = Boolean(resolvedAnimation);
|
|
31053
31252
|
const cancelOpenInteractionSuppression = !silent && hasCssTransitionAnimation ? suppressPointerEventsDuringTransition(dialogEl) : null;
|
|
31253
|
+
// Handing the focus to a field is what raises the on-screen keyboard, and
|
|
31254
|
+
// the keyboard takes away the very room this dialog was just placed
|
|
31255
|
+
// against — so on a touch-driven opening the transfer waits for the
|
|
31256
|
+
// entrance to be over. Decided by transferFocusOnOpen, the only place that
|
|
31257
|
+
// knows WHICH element is about to be focused (open_controller.js and its
|
|
31258
|
+
// FOCUS_DELAY_ON_KEYBOARD_MS).
|
|
31054
31259
|
const restoreFocus = openController.transferFocusOnOpen(dialogEl);
|
|
31055
31260
|
|
|
31056
31261
|
// isModal outside-click detection (see this file's top comment for why
|
|
@@ -31116,9 +31321,16 @@ const useDialogProps = props => {
|
|
|
31116
31321
|
// property is actually present — harmless the rest of the time.
|
|
31117
31322
|
dialogEl.setAttribute("navi-hidden", "");
|
|
31118
31323
|
dialogEl.close();
|
|
31119
|
-
//
|
|
31120
|
-
//
|
|
31121
|
-
|
|
31324
|
+
// Held at the size it has right now, for the whole way out. cleanup()
|
|
31325
|
+
// below already stops the JS repositioning, but the size is CSS-driven
|
|
31326
|
+
// (--x-dialog-max-height, and `height` outright under expandY) and
|
|
31327
|
+
// keeps following the visual viewport on its own — so a dialog closed
|
|
31328
|
+
// while the keyboard is up grows back to fill the room the keyboard is
|
|
31329
|
+
// giving back, WHILE fading out. Coherent, and still wrong to watch: a
|
|
31330
|
+
// box being dismissed has nothing left to adapt to, and the growth
|
|
31331
|
+
// reads as something happening at the exact moment nothing should. The
|
|
31332
|
+
// next opening clears it (see openEffect's own unfreezeSize).
|
|
31333
|
+
freezeSize(dialogEl);
|
|
31122
31334
|
cancelOpenInteractionSuppression?.();
|
|
31123
31335
|
if (hasCssTransitionAnimation) {
|
|
31124
31336
|
suppressPointerEventsDuringTransition(dialogEl);
|
|
@@ -32430,6 +32642,12 @@ const usePopoverProps = props => {
|
|
|
32430
32642
|
}
|
|
32431
32643
|
popoverEl.removeAttribute("data-anchor-out-of-view");
|
|
32432
32644
|
positionPopover(event);
|
|
32645
|
+
// Same as Dialog's own — a popup with a scrolling body and a footer
|
|
32646
|
+
// swallows the field it just got shorter around. See
|
|
32647
|
+
// keepFocusedElementVisible's own doc in popup_shared.js.
|
|
32648
|
+
if (mayHaveHiddenFocus(event)) {
|
|
32649
|
+
keepFocusedElementVisible(popoverEl);
|
|
32650
|
+
}
|
|
32433
32651
|
}, {
|
|
32434
32652
|
event: e,
|
|
32435
32653
|
// it's ok for the popover to become unsync with the anchor size
|
|
@@ -38817,24 +39035,34 @@ const ROUTE_TRAVEL_ATTRIBUTE = "data-navi-route-travel";
|
|
|
38817
39035
|
// included).
|
|
38818
39036
|
|
|
38819
39037
|
const css$T = /* css */`
|
|
38820
|
-
/* The marked region is a picture of its own
|
|
38821
|
-
|
|
38822
|
-
|
|
38823
|
-
|
|
39038
|
+
/* The marked region is a picture of its own for the length of a transition of
|
|
39039
|
+
OURS, and only then — the name is what makes the pages a picture the
|
|
39040
|
+
movement below can carry.
|
|
39041
|
+
|
|
39042
|
+
Named outside that, it would be a picture during every view transition the
|
|
39043
|
+
APPLICATION starts — two rows swapping, a list changing — and a page is
|
|
39044
|
+
several screens tall: its picture is the whole element, drawn in the top
|
|
39045
|
+
layer from wherever the element starts, so it paints over the fixed bars
|
|
39046
|
+
and past the bottom of the screen for the length of a movement that has
|
|
39047
|
+
nothing to do with the pages. Unnamed, it stays part of the document's own
|
|
39048
|
+
picture, where the browser cuts it at the viewport like everything else. */
|
|
39049
|
+
:root[data-navi-route-transition] [data-navi-route-transition-area] {
|
|
38824
39050
|
view-transition-name: navi-route-transition;
|
|
38825
39051
|
}
|
|
38826
39052
|
|
|
38827
|
-
/* A named descendant — a
|
|
38828
|
-
|
|
38829
|
-
|
|
38830
|
-
pages
|
|
38831
|
-
|
|
38832
|
-
|
|
38833
|
-
|
|
38834
|
-
|
|
39053
|
+
/* A named descendant — a thumbnail named for a morph, a row named for a
|
|
39054
|
+
reorder gesture — is a hole in the area's picture and a group of its own.
|
|
39055
|
+
Nested groups keep that group inside the area's, which is what cuts it at
|
|
39056
|
+
the pages' edge instead of letting it paint across the screen. What it does
|
|
39057
|
+
NOT do is make it travel: the movement is carried by the area's two
|
|
39058
|
+
pictures, and a group is not one of them, so a named descendant stands
|
|
39059
|
+
where it was captured while the pages slide under it. A morph wants exactly
|
|
39060
|
+
that; a component that names its parts for changes of its own does not, and
|
|
39061
|
+
drops its names for the length of the movement (see list.jsx). A browser
|
|
39062
|
+
without nested groups is warned instead (see
|
|
38835
39063
|
warnAboutNamesEscapingArea). */
|
|
38836
39064
|
@supports (view-transition-group: contain) {
|
|
38837
|
-
[data-navi-route-transition-area] {
|
|
39065
|
+
:root[data-navi-route-transition] [data-navi-route-transition-area] {
|
|
38838
39066
|
view-transition-group: contain;
|
|
38839
39067
|
}
|
|
38840
39068
|
}
|
|
@@ -45723,9 +45951,12 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
45723
45951
|
* along the bar it adds to the padding asked for. Note that every
|
|
45724
45952
|
* `env(safe-area-inset-*)` is 0 unless the page asks for it:
|
|
45725
45953
|
* `<meta name="viewport" content="…, viewport-fit=cover">`.
|
|
45726
|
-
* 4. **Its hairline is
|
|
45727
|
-
*
|
|
45728
|
-
*
|
|
45954
|
+
* 4. **Its hairline is part of its box.** The line covers the content just as
|
|
45955
|
+
* the bar does, so the room given back has to include it — a line drawn
|
|
45956
|
+
* outside the box (a box-shadow, an outline) is a line the content scrolls
|
|
45957
|
+
* under, and a line a page transition paints over. It is a real border,
|
|
45958
|
+
* added to the size asked for exactly like the notch inset is, so the
|
|
45959
|
+
* content still gets the size the prop names.
|
|
45729
45960
|
*/
|
|
45730
45961
|
const css$M = /* css */`
|
|
45731
45962
|
@layer navi {
|
|
@@ -45785,39 +46016,50 @@ const css$M = /* css */`
|
|
|
45785
46016
|
}
|
|
45786
46017
|
|
|
45787
46018
|
/* Across the bar, the inset of the edge it is pinned to is padding AND is
|
|
45788
|
-
added to the size
|
|
45789
|
-
|
|
46019
|
+
added to the size, and the hairline on the content side is added the
|
|
46020
|
+
same way: the background then runs under the notch, the line stands
|
|
46021
|
+
clear of the content, and the content keeps the whole width/height asked
|
|
46022
|
+
for. */
|
|
45790
46023
|
&[data-area="top"] {
|
|
45791
46024
|
top: var(--navi-app-inset-top);
|
|
45792
|
-
height: calc(
|
|
46025
|
+
height: calc(
|
|
46026
|
+
var(--navi-fixed-bar-height) + env(safe-area-inset-top) +
|
|
46027
|
+
var(--navi-fixed-bar-border-width)
|
|
46028
|
+
);
|
|
45793
46029
|
padding-top: env(safe-area-inset-top);
|
|
45794
|
-
|
|
46030
|
+
border-bottom: var(--navi-fixed-bar-border-width) solid
|
|
45795
46031
|
var(--navi-fixed-bar-border-color);
|
|
45796
46032
|
}
|
|
45797
46033
|
&[data-area="bottom"] {
|
|
45798
46034
|
bottom: var(--navi-app-inset-bottom);
|
|
45799
|
-
height: calc(
|
|
46035
|
+
height: calc(
|
|
46036
|
+
var(--navi-fixed-bar-height) + env(safe-area-inset-bottom) +
|
|
46037
|
+
var(--navi-fixed-bar-border-width)
|
|
46038
|
+
);
|
|
45800
46039
|
padding-bottom: env(safe-area-inset-bottom);
|
|
45801
|
-
|
|
46040
|
+
border-top: var(--navi-fixed-bar-border-width) solid
|
|
45802
46041
|
var(--navi-fixed-bar-border-color);
|
|
45803
46042
|
}
|
|
45804
46043
|
&[data-area="left"] {
|
|
45805
46044
|
left: var(--navi-app-inset-left);
|
|
45806
|
-
width: calc(
|
|
46045
|
+
width: calc(
|
|
46046
|
+
var(--navi-fixed-bar-width) + env(safe-area-inset-left) +
|
|
46047
|
+
var(--navi-fixed-bar-border-width)
|
|
46048
|
+
);
|
|
45807
46049
|
padding-left: env(safe-area-inset-left);
|
|
45808
|
-
|
|
46050
|
+
border-right: var(--navi-fixed-bar-border-width) solid
|
|
45809
46051
|
var(--navi-fixed-bar-border-color);
|
|
45810
46052
|
}
|
|
45811
46053
|
&[data-area="right"] {
|
|
45812
46054
|
right: var(--navi-app-inset-right);
|
|
45813
|
-
width: calc(
|
|
46055
|
+
width: calc(
|
|
46056
|
+
var(--navi-fixed-bar-width) + env(safe-area-inset-right) +
|
|
46057
|
+
var(--navi-fixed-bar-border-width)
|
|
46058
|
+
);
|
|
45814
46059
|
padding-right: env(safe-area-inset-right);
|
|
45815
|
-
|
|
46060
|
+
border-left: var(--navi-fixed-bar-border-width) solid
|
|
45816
46061
|
var(--navi-fixed-bar-border-color);
|
|
45817
46062
|
}
|
|
45818
|
-
&[data-border="none"] {
|
|
45819
|
-
box-shadow: none;
|
|
45820
|
-
}
|
|
45821
46063
|
}
|
|
45822
46064
|
`;
|
|
45823
46065
|
const FixedBarStyleCSSVars = {
|
|
@@ -45851,9 +46093,10 @@ const FixedBarStyleCSSVars = {
|
|
|
45851
46093
|
* @param {string|number} [props.width] - …and for one on a side. The safe-area
|
|
45852
46094
|
* inset is NOT part of it: it is added on top, so the content keeps the size
|
|
45853
46095
|
* asked for.
|
|
45854
|
-
* @param {boolean} [props.border=true] - The hairline on the content side.
|
|
45855
|
-
*
|
|
45856
|
-
* `borderWidth`/`borderColor`, or
|
|
46096
|
+
* @param {boolean} [props.border=true] - The hairline on the content side. It
|
|
46097
|
+
* is added to the size rather than taken out of it, and counts in the room
|
|
46098
|
+
* the bar gives back; give it a `borderWidth`/`borderColor`, or
|
|
46099
|
+
* `border={false}` for none.
|
|
45857
46100
|
* @param {string|number} [props.maxWidth] - Keeps the bar lined up with a
|
|
45858
46101
|
* content column narrower than the window (it stays centered).
|
|
45859
46102
|
*/
|
|
@@ -45866,9 +46109,16 @@ const FixedBar = ({
|
|
|
45866
46109
|
import.meta.css = [css$M, "@jsenv/navi/src/layout/fixed_bar/fixed_bar.jsx"];
|
|
45867
46110
|
const defaultRef = useRef();
|
|
45868
46111
|
props.ref = props.ref || defaultRef;
|
|
46112
|
+
// Said with the width the border rule reads rather than with an attribute of
|
|
46113
|
+
// its own: the width is what the size calc adds, so a line asked away here
|
|
46114
|
+
// is a line that takes no room either.
|
|
46115
|
+
if (!border) {
|
|
46116
|
+
props.borderWidth = "0px";
|
|
46117
|
+
}
|
|
45869
46118
|
// Whichever of width/height crosses the edge the bar sits on is what the
|
|
45870
46119
|
// content has to be given back — and the bar's border box already IS that:
|
|
45871
|
-
// the size it was given
|
|
46120
|
+
// the size it was given, the inset of that edge, and the hairline standing
|
|
46121
|
+
// between it and the content. Measured rather than
|
|
45872
46122
|
// rebuilt as a calc() expression, so a size coming from anywhere — a prop, a
|
|
45873
46123
|
// theme variable, the content itself — is reserved just the same, and each
|
|
45874
46124
|
// `env()` inset stays the browser's business alone.
|
|
@@ -45915,7 +46165,6 @@ const FixedBar = ({
|
|
|
45915
46165
|
return jsx(Box, {
|
|
45916
46166
|
baseClassName: "navi_fixed_bar",
|
|
45917
46167
|
"data-area": area,
|
|
45918
|
-
"data-border": border ? undefined : "none",
|
|
45919
46168
|
...props,
|
|
45920
46169
|
styleCSSVars: FixedBarStyleCSSVars,
|
|
45921
46170
|
children: children
|
|
@@ -54442,9 +54691,9 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
54442
54691
|
*
|
|
54443
54692
|
* `layer` (shared by both — picks the top-layer vs. local-container rendering
|
|
54444
54693
|
* strategy either way) and `anchorCustomEventDetail` (shared too: Popover
|
|
54445
|
-
* resolves an anchor to position against, Dialog to size itself from
|
|
54446
|
-
*
|
|
54447
|
-
* renders.
|
|
54694
|
+
* resolves an anchor to position against, Dialog only to size itself from,
|
|
54695
|
+
* and only under its own `sizeFromAnchor`) pass through untouched via
|
|
54696
|
+
* `...rest` to whichever of Popover/Dialog actually renders.
|
|
54448
54697
|
*/
|
|
54449
54698
|
const css$A = /* css */`
|
|
54450
54699
|
@layer navi {
|
|
@@ -54482,13 +54731,12 @@ const css$A = /* css */`
|
|
|
54482
54731
|
* @param {"top"|"local"} [props.layer] - Forwarded as-is to whichever of
|
|
54483
54732
|
* `Dialog`/`Popover` renders — see either component's own doc.
|
|
54484
54733
|
* @param {Element|{current: Element}} [props.anchor] - Forwarded as-is —
|
|
54485
|
-
*
|
|
54486
|
-
*
|
|
54734
|
+
* positioning for `Popover`, and for `Dialog` sizing only, and only when
|
|
54735
|
+
* `sizeFromAnchor` is also passed (see each component's own doc).
|
|
54487
54736
|
* @param {"override"|"ignore"} [props.anchorCustomEventDetail] - Forwarded
|
|
54488
54737
|
* as-is to both — what it governs differs (positioning for `Popover`,
|
|
54489
|
-
* sizing for `Dialog`), but "ignore whatever anchor the
|
|
54490
|
-
* carried" has to mean the same thing in either mode
|
|
54491
|
-
* `<Popup>` usage silently picks up its trigger's width on small screens.
|
|
54738
|
+
* `sizeFromAnchor` sizing for `Dialog`), but "ignore whatever anchor the
|
|
54739
|
+
* triggering event carried" has to mean the same thing in either mode.
|
|
54492
54740
|
* @param {string} [props.marginWithAnchor] - **Popover-only**, destructured
|
|
54493
54741
|
* out so it can't leak onto the real `<dialog>` element as a stray DOM
|
|
54494
54742
|
* attribute when `mode="dialog"` is picked.
|
|
@@ -54691,12 +54939,17 @@ installImportMetaCssBuild(import.meta);const css$z = /* css */`
|
|
|
54691
54939
|
|
|
54692
54940
|
/* No fallback on purpose (same as --popover-max-height above): unset
|
|
54693
54941
|
picker props leave these declarations invalid at computed-value
|
|
54694
|
-
time, so the dialog keeps its own ceilings. */
|
|
54942
|
+
time, so the dialog keeps its own floors/ceilings. */
|
|
54943
|
+
--dialog-min-width: var(--picker-dialog-min-width);
|
|
54944
|
+
--dialog-min-height: var(--picker-dialog-min-height);
|
|
54695
54945
|
--dialog-max-width: var(--picker-dialog-max-width);
|
|
54696
54946
|
--dialog-max-height: var(--picker-dialog-max-height);
|
|
54697
54947
|
|
|
54698
|
-
/*
|
|
54699
|
-
|
|
54948
|
+
/* Nothing bridges the trigger's width in here: a dialog does not
|
|
54949
|
+
follow its anchor's box (dialog.jsx, sizeFromAnchor) — it is not
|
|
54950
|
+
visually attached to the trigger, so it is sized by its content,
|
|
54951
|
+
and dialogMinWidth/dialogMinHeight are how a caller says otherwise.
|
|
54952
|
+
Only the cursor reset below is picker-specific here. */
|
|
54700
54953
|
cursor: default; /* Reset pointer cursor within the select */
|
|
54701
54954
|
|
|
54702
54955
|
/* Dialog already applies display: flex to [open] itself, but
|
|
@@ -54718,24 +54971,10 @@ installImportMetaCssBuild(import.meta);const css$z = /* css */`
|
|
|
54718
54971
|
}
|
|
54719
54972
|
|
|
54720
54973
|
/* popupWidthFitContent (picker.jsx): drop the trigger-width floor so the
|
|
54721
|
-
popup shrinks to its content.
|
|
54974
|
+
popup shrinks to its content. Popover-only — the dialog has no such
|
|
54975
|
+
floor to drop (see the dialog block above). */
|
|
54722
54976
|
&[data-popup-width-fit-content] {
|
|
54723
54977
|
--picker-popover-min-width: 0px;
|
|
54724
|
-
|
|
54725
|
-
/* The popover var above only reaches the popover — the dialog reads
|
|
54726
|
-
--anchor-width directly for its own min-width floor (dialog.jsx). A
|
|
54727
|
-
modal dialog isn't visually attached to the trigger, so with
|
|
54728
|
-
fit-content we drop that floor here too, letting the content size the
|
|
54729
|
-
dialog like the popover. (More specific than dialog.jsx's own
|
|
54730
|
-
.navi_dialog rule; both are unlayered, so this wins.) */
|
|
54731
|
-
&[aria-haspopup="dialog"] {
|
|
54732
|
-
.navi_dialog {
|
|
54733
|
-
min-width: min(
|
|
54734
|
-
var(--dialog-min-width, 0px),
|
|
54735
|
-
var(--x-dialog-max-width)
|
|
54736
|
-
);
|
|
54737
|
-
}
|
|
54738
|
-
}
|
|
54739
54978
|
}
|
|
54740
54979
|
}
|
|
54741
54980
|
`;
|
|
@@ -57048,7 +57287,26 @@ const css$w = /* css */`
|
|
|
57048
57287
|
flex-direction: column;
|
|
57049
57288
|
background-color: var(--x-list-background-color);
|
|
57050
57289
|
border: var(--x-list-border-width) solid var(--x-list-border-color);
|
|
57051
|
-
|
|
57290
|
+
/* Squared from the outside, corner by corner: whoever draws the surface
|
|
57291
|
+
the list is laid on says which corners are the list's to draw (a popup's
|
|
57292
|
+
body does, see box.jsx), and each corner falls back to the list's own
|
|
57293
|
+
radius when nothing asks for anything. */
|
|
57294
|
+
border-top-left-radius: var(
|
|
57295
|
+
--x-corner-top-left-radius,
|
|
57296
|
+
var(--x-list-border-radius)
|
|
57297
|
+
);
|
|
57298
|
+
border-top-right-radius: var(
|
|
57299
|
+
--x-corner-top-right-radius,
|
|
57300
|
+
var(--x-list-border-radius)
|
|
57301
|
+
);
|
|
57302
|
+
border-bottom-right-radius: var(
|
|
57303
|
+
--x-corner-bottom-right-radius,
|
|
57304
|
+
var(--x-list-border-radius)
|
|
57305
|
+
);
|
|
57306
|
+
border-bottom-left-radius: var(
|
|
57307
|
+
--x-corner-bottom-left-radius,
|
|
57308
|
+
var(--x-list-border-radius)
|
|
57309
|
+
);
|
|
57052
57310
|
|
|
57053
57311
|
transition: opacity 0.2s ease;
|
|
57054
57312
|
/* overflow:hidden is required on the container (not the inner scroll element)
|
|
@@ -57057,6 +57315,13 @@ const css$w = /* css */`
|
|
|
57057
57315
|
overflow: hidden;
|
|
57058
57316
|
|
|
57059
57317
|
.navi_list_scroll_container {
|
|
57318
|
+
/* The ask stops here: this element is inside the list's frame, so a row
|
|
57319
|
+
or a control it holds is not at the surface's corner. */
|
|
57320
|
+
--x-corner-top-left-radius: initial;
|
|
57321
|
+
--x-corner-top-right-radius: initial;
|
|
57322
|
+
--x-corner-bottom-right-radius: initial;
|
|
57323
|
+
--x-corner-bottom-left-radius: initial;
|
|
57324
|
+
|
|
57060
57325
|
width: inherit;
|
|
57061
57326
|
min-width: inherit;
|
|
57062
57327
|
max-width: var(--list-max-width, inherit);
|
|
@@ -57530,9 +57795,19 @@ const css$w = /* css */`
|
|
|
57530
57795
|
without being contained animate across the page (the pictures live in the
|
|
57531
57796
|
top layer, where no overflow of the document reaches them), which is worse
|
|
57532
57797
|
than not animating at all. So a browser with no nested groups gets no name
|
|
57533
|
-
either, and the change simply happens.
|
|
57798
|
+
either, and the change simply happens.
|
|
57799
|
+
|
|
57800
|
+
Named for a change of the list's own, and for that alone: while the PAGES
|
|
57801
|
+
are the ones moving — a route transition, a route travel — the list is part
|
|
57802
|
+
of what travels, and a picture of its own is precisely what does not
|
|
57803
|
+
travel. A page is carried by its own picture; anything named inside it is
|
|
57804
|
+
lifted out of that picture into a group of its own, which stays where it
|
|
57805
|
+
was captured while the page slides away under it. So the names are dropped
|
|
57806
|
+
for the length of such a movement and the list crosses the screen with the
|
|
57807
|
+
page, as a block. */
|
|
57534
57808
|
@supports (view-transition-group: contain) {
|
|
57535
|
-
|
|
57809
|
+
:root:not([data-navi-route-transition], [data-navi-route-travel])
|
|
57810
|
+
.navi_list_container[data-item-transition] {
|
|
57536
57811
|
/* The list needs a name to be a group at all; which name does not matter,
|
|
57537
57812
|
only that no other element in the document carries it. */
|
|
57538
57813
|
view-transition-name: match-element;
|
|
@@ -62691,6 +62966,8 @@ const PickerStyleCSSVars = {
|
|
|
62691
62966
|
"borderWidth": "--picker-border-width",
|
|
62692
62967
|
"borderRadius": "--picker-border-radius",
|
|
62693
62968
|
"popoverMaxHeight": "--picker-popover-max-height",
|
|
62969
|
+
"dialogMinWidth": "--picker-dialog-min-width",
|
|
62970
|
+
"dialogMinHeight": "--picker-dialog-min-height",
|
|
62694
62971
|
"dialogMaxWidth": "--picker-dialog-max-width",
|
|
62695
62972
|
"dialogMaxHeight": "--picker-dialog-max-height",
|
|
62696
62973
|
"popupBackgroundColor": "--picker-popup-background-color",
|
|
@@ -74034,10 +74311,11 @@ installImportMetaCssBuild(import.meta);/**
|
|
|
74034
74311
|
* `navi-side`/`data-layer` attributes) rather than computed in JS — read
|
|
74035
74312
|
* the CSS block below instead of expecting a JS equivalent of it here.
|
|
74036
74313
|
*
|
|
74037
|
-
* `anchorCustomEventDetail="ignore"` is required, not cosmetic
|
|
74038
|
-
*
|
|
74039
|
-
*
|
|
74040
|
-
*
|
|
74314
|
+
* `anchorCustomEventDetail="ignore"` is required, not cosmetic: without it
|
|
74315
|
+
* Popover docks next to whatever triggered the open instead of flush against
|
|
74316
|
+
* the edge. Dialog needs nothing here — it never sizes itself from an anchor
|
|
74317
|
+
* unless asked to (`sizeFromAnchor`, see dialog.jsx), which a side panel
|
|
74318
|
+
* never does: its `width`/`height` props are what size it.
|
|
74041
74319
|
*/
|
|
74042
74320
|
const css = /* css */`
|
|
74043
74321
|
.navi_side_panel {
|