@jsenv/navi 0.29.355 → 0.29.357
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/dev/jsenv_navi.js +131 -114
- package/dist/dev/jsenv_navi.js.map +14 -14
- package/dist/jsenv_navi.js +106 -110
- package/dist/jsenv_navi.js.map +14 -14
- package/docs/AI_INSTRUCTIONS.md +2 -1
- package/docs/form_changed.md +27 -0
- package/docs/popup_backdrop.md +15 -15
- package/docs/popup_lift.md +3 -0
- package/docs/popup_open.md +7 -7
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -6730,7 +6730,7 @@ const css$13 = /* css */ `
|
|
|
6730
6730
|
* for free (`status`/`alert`); reach for this when the role is not enough to tell two
|
|
6731
6731
|
* callouts apart.
|
|
6732
6732
|
* @param {Function} [options.onClose] - Callback when callout is closed
|
|
6733
|
-
* @param {boolean} [options.
|
|
6733
|
+
* @param {boolean} [options.closeByPressOutside] - Whether a press outside closes the callout (defaults to true for "info" status)
|
|
6734
6734
|
* @param {boolean|number} [options.closeByScroll=false] - Dismiss the callout once the page has
|
|
6735
6735
|
* scrolled under it. `true` uses a short distance, a number sets it in pixels
|
|
6736
6736
|
* (`closeByScroll: 100` waits for 100px). Measured from where the scroll containers stood when
|
|
@@ -6798,15 +6798,15 @@ const openCallout = (
|
|
|
6798
6798
|
status = "",
|
|
6799
6799
|
testId,
|
|
6800
6800
|
onClose,
|
|
6801
|
-
|
|
6802
|
-
closeOnFocusLeave =
|
|
6801
|
+
closeByPressOutside = status === "info",
|
|
6802
|
+
closeOnFocusLeave = closeByPressOutside,
|
|
6803
6803
|
closeByScroll = false,
|
|
6804
|
+
closeButton = true,
|
|
6804
6805
|
openingEvent,
|
|
6805
6806
|
reopen = "toggle",
|
|
6806
6807
|
showErrorStack,
|
|
6807
6808
|
skipFocus = false,
|
|
6808
6809
|
icon = true,
|
|
6809
|
-
closeButton = true,
|
|
6810
6810
|
debug = () => {},
|
|
6811
6811
|
} = {},
|
|
6812
6812
|
) => {
|
|
@@ -6893,7 +6893,7 @@ const openCallout = (
|
|
|
6893
6893
|
const clickOrSpaceOutside =
|
|
6894
6894
|
reason === "click_outside" || reason === "space_outside";
|
|
6895
6895
|
if (clickOrSpaceOutside) {
|
|
6896
|
-
if (!
|
|
6896
|
+
if (!closeByPressOutside) {
|
|
6897
6897
|
return;
|
|
6898
6898
|
}
|
|
6899
6899
|
if (callout.status === "error") {
|
|
@@ -7024,9 +7024,9 @@ const openCallout = (
|
|
|
7024
7024
|
updateStatus(options.status);
|
|
7025
7025
|
}
|
|
7026
7026
|
|
|
7027
|
-
if (Object.hasOwn(options, "
|
|
7028
|
-
|
|
7029
|
-
if (
|
|
7027
|
+
if (Object.hasOwn(options, "closeByPressOutside")) {
|
|
7028
|
+
closeByPressOutside = options.closeByPressOutside;
|
|
7029
|
+
if (closeByPressOutside) {
|
|
7030
7030
|
closeOnFocusLeave = true;
|
|
7031
7031
|
}
|
|
7032
7032
|
}
|
|
@@ -7230,7 +7230,7 @@ const openCallout = (
|
|
|
7230
7230
|
const openingDownEvent =
|
|
7231
7231
|
findEvent(openingEvent, "mousedown") ||
|
|
7232
7232
|
findEvent(openingEvent, "pointerdown");
|
|
7233
|
-
if (
|
|
7233
|
+
if (closeByPressOutside && openingEvent && openingDownEvent) {
|
|
7234
7234
|
const upType =
|
|
7235
7235
|
openingDownEvent.type === "pointerdown" ? "pointerup" : "mouseup";
|
|
7236
7236
|
debug(
|
|
@@ -8384,7 +8384,7 @@ const createCalloutManager = (
|
|
|
8384
8384
|
testId: tokenData.testId,
|
|
8385
8385
|
icon: tokenData.icon,
|
|
8386
8386
|
closeButton: tokenData.closeButton,
|
|
8387
|
-
|
|
8387
|
+
closeByPressOutside: tokenData.status !== "error",
|
|
8388
8388
|
closeByScroll: tokenData.closeByScroll,
|
|
8389
8389
|
anchorElement,
|
|
8390
8390
|
openingEvent: event,
|
|
@@ -12140,7 +12140,7 @@ defineInteractionDetector({
|
|
|
12140
12140
|
// button to press, and what closes it is the hand going quiet.
|
|
12141
12141
|
skipFocus: true,
|
|
12142
12142
|
closeButton: false,
|
|
12143
|
-
|
|
12143
|
+
closeByPressOutside: false,
|
|
12144
12144
|
closeOnFocusLeave: false,
|
|
12145
12145
|
onClose: () => {
|
|
12146
12146
|
hint = null;
|
|
@@ -35386,7 +35386,7 @@ const INSIDE_ATTRIBUTE = "data-navi-popup-inside";
|
|
|
35386
35386
|
*/
|
|
35387
35387
|
const handlePressOnOutsideRegion = (
|
|
35388
35388
|
mouseDownEvent,
|
|
35389
|
-
{ popupEl, openController,
|
|
35389
|
+
{ popupEl, openController, pressOutside },
|
|
35390
35390
|
) => {
|
|
35391
35391
|
if (mouseDownEvent.button !== 0) {
|
|
35392
35392
|
return;
|
|
@@ -35409,16 +35409,13 @@ const handlePressOnOutsideRegion = (
|
|
|
35409
35409
|
) {
|
|
35410
35410
|
return;
|
|
35411
35411
|
}
|
|
35412
|
-
if (
|
|
35412
|
+
if (pressOutside === "capture") {
|
|
35413
35413
|
mouseDownEvent.preventDefault();
|
|
35414
35414
|
return;
|
|
35415
35415
|
}
|
|
35416
|
-
if (
|
|
35417
|
-
pointerInteractionOutsideEffect === "close" ||
|
|
35418
|
-
pointerInteractionOutsideEffect === "cancel"
|
|
35419
|
-
) {
|
|
35416
|
+
if (pressOutside === "close" || pressOutside === "cancel") {
|
|
35420
35417
|
openController.requestClose(mouseDownEvent, {
|
|
35421
|
-
isCancel:
|
|
35418
|
+
isCancel: pressOutside === "cancel",
|
|
35422
35419
|
});
|
|
35423
35420
|
}
|
|
35424
35421
|
};
|
|
@@ -35466,11 +35463,7 @@ const handlePressOnOutsideRegion = (
|
|
|
35466
35463
|
*/
|
|
35467
35464
|
const armOutsidePressClose = (
|
|
35468
35465
|
popupEl,
|
|
35469
|
-
{
|
|
35470
|
-
openController,
|
|
35471
|
-
pointerInteractionOutsideEffect,
|
|
35472
|
-
pressEventType = "pointerdown",
|
|
35473
|
-
},
|
|
35466
|
+
{ openController, pressOutside, pressEventType = "pointerdown" },
|
|
35474
35467
|
) => {
|
|
35475
35468
|
const onDocumentPointerDown = (pointerDownEvent) => {
|
|
35476
35469
|
if (pointerDownEvent.button !== 0) {
|
|
@@ -35532,7 +35525,7 @@ const armOutsidePressClose = (
|
|
|
35532
35525
|
return;
|
|
35533
35526
|
}
|
|
35534
35527
|
openController.requestClose(pointerDownEvent, {
|
|
35535
|
-
isCancel:
|
|
35528
|
+
isCancel: pressOutside === "cancel",
|
|
35536
35529
|
});
|
|
35537
35530
|
};
|
|
35538
35531
|
document.addEventListener(pressEventType, onDocumentPointerDown, {
|
|
@@ -59814,7 +59807,7 @@ const css$E = /* css */`
|
|
|
59814
59807
|
--backdrop-background: var(--navi-backdrop-lift-background);
|
|
59815
59808
|
--backdrop-filter: var(--navi-backdrop-lift-backdrop-filter);
|
|
59816
59809
|
}
|
|
59817
|
-
&[data-
|
|
59810
|
+
&[data-press-outside="capture"] {
|
|
59818
59811
|
--backdrop-background: var(--navi-backdrop-capture-background);
|
|
59819
59812
|
--backdrop-filter: var(--navi-backdrop-capture-backdrop-filter);
|
|
59820
59813
|
}
|
|
@@ -59966,7 +59959,7 @@ const css$E = /* css */`
|
|
|
59966
59959
|
a real sibling element instead, same idea/CSS shape as Popover's own
|
|
59967
59960
|
.navi_popover_backdrop (see popover.jsx's top comment for the design this
|
|
59968
59961
|
mirrors). Rendered whenever backdrop={true}, whatever
|
|
59969
|
-
|
|
59962
|
+
pressOutside says: a wall that closes nothing still
|
|
59970
59963
|
absorbs the press, matching what showModal() gives a modal for free. */
|
|
59971
59964
|
.navi_dialog_backdrop {
|
|
59972
59965
|
--popup-animation-duration: 0.18s;
|
|
@@ -60006,9 +59999,9 @@ const css$E = /* css */`
|
|
|
60006
59999
|
display: none;
|
|
60007
60000
|
}
|
|
60008
60001
|
|
|
60009
|
-
/* Makes
|
|
60010
|
-
&[data-
|
|
60011
|
-
&[data-
|
|
60002
|
+
/* Makes pressOutside have a visible impact on backdrop */
|
|
60003
|
+
&[data-press-outside="close"],
|
|
60004
|
+
&[data-press-outside="cancel"] {
|
|
60012
60005
|
--backdrop-background: var(--navi-backdrop-close-background);
|
|
60013
60006
|
--backdrop-filter: var(--navi-backdrop-close-backdrop-filter);
|
|
60014
60007
|
}
|
|
@@ -60021,7 +60014,7 @@ const css$E = /* css */`
|
|
|
60021
60014
|
--backdrop-background: var(--navi-backdrop-lift-background);
|
|
60022
60015
|
--backdrop-filter: var(--navi-backdrop-lift-backdrop-filter);
|
|
60023
60016
|
}
|
|
60024
|
-
&[data-
|
|
60017
|
+
&[data-press-outside="capture"] {
|
|
60025
60018
|
--backdrop-background: var(--navi-backdrop-capture-background);
|
|
60026
60019
|
--backdrop-filter: var(--navi-backdrop-capture-backdrop-filter);
|
|
60027
60020
|
}
|
|
@@ -60276,24 +60269,24 @@ const css$E = /* css */`
|
|
|
60276
60269
|
* the dialog and the page at all — asked before any question of what an
|
|
60277
60270
|
* outside press does or how the backdrop is painted. `false` leaves the page
|
|
60278
60271
|
* reachable: a press outside closes the dialog (per
|
|
60279
|
-
* `
|
|
60272
|
+
* `pressOutside`) *and* is answered by whatever it landed
|
|
60280
60273
|
* on, in the same gesture; focus is free to leave too, the page behind being
|
|
60281
60274
|
* meant to be reached. Works in either layer — a top-layer dialog with no
|
|
60282
60275
|
* wall is shown through the Popover API rather than `showModal()`, which is
|
|
60283
60276
|
* what a sheet docked to the screen's bottom edge over a still-readable map
|
|
60284
60277
|
* needs. What it gives up is what only a modal gets natively: the hardware
|
|
60285
60278
|
* back button no longer dismisses it. See docs/popup_backdrop.md.
|
|
60286
|
-
* @param {"close"|"cancel"|"capture"|"
|
|
60287
|
-
* - `"close"` closes the dialog on an outside
|
|
60288
|
-
* both just absorb the
|
|
60279
|
+
* @param {"close"|"cancel"|"capture"|"ignore"} [props.pressOutside="close"]
|
|
60280
|
+
* - `"close"` closes the dialog on an outside press. `"capture"`/`"ignore"`
|
|
60281
|
+
* both just absorb the press without closing (visually dimmed backdrop vs.
|
|
60289
60282
|
* not) — a dialog with a backdrop is modal one way or another, so there's
|
|
60290
|
-
* always at least a
|
|
60283
|
+
* always at least a press-absorbing backdrop regardless of this prop.
|
|
60291
60284
|
* "Outside" is the dialog's own border box; a see-through dialog whose box is
|
|
60292
60285
|
* bigger than what it paints marks the difference with
|
|
60293
60286
|
* `data-navi-popup-outside` (see docs/popup_backdrop.md).
|
|
60294
60287
|
* @param {"auto"|"lift"|"discrete"|"invisible"} [props.backdropVariant="auto"]
|
|
60295
60288
|
* - How visible the backdrop is, independently of what it does. `"auto"`:
|
|
60296
|
-
* the paint `
|
|
60289
|
+
* the paint `pressOutside` implies (dimmed for
|
|
60297
60290
|
* `"close"`/`"cancel"`, blurred glass for `"capture"`), or the opaque wall
|
|
60298
60291
|
* `animation="lifting"` asks for. `"lift"`: that same opaque, blurred wall
|
|
60299
60292
|
* (`--navi-backdrop-lift-*`) asked for on its own, for a dialog whose
|
|
@@ -60671,20 +60664,20 @@ const useDialogProps = props => {
|
|
|
60671
60664
|
expand,
|
|
60672
60665
|
expandX: expandXProp,
|
|
60673
60666
|
expandY: expandYProp,
|
|
60674
|
-
// "close" (default) closes on an outside
|
|
60667
|
+
// "close" (default) closes on an outside press. "capture"/"ignore" both
|
|
60675
60668
|
// just absorb it without closing — for a modal, showModal() already makes
|
|
60676
60669
|
// the rest of the page inert, so there's nothing for a click to reach
|
|
60677
60670
|
// either way; otherwise there's no native inert-ing, so the real backdrop
|
|
60678
|
-
// below is what makes "capture"/"
|
|
60679
|
-
|
|
60671
|
+
// below is what makes "capture"/"ignore" behave the same way here too.
|
|
60672
|
+
pressOutside = "close",
|
|
60680
60673
|
// Whether there is a wall between the dialog and the page at all, asked
|
|
60681
|
-
// before what a press on it does (
|
|
60674
|
+
// before what a press on it does (pressOutside) and
|
|
60682
60675
|
// before how it is painted (backdropVariant below). It also picks the show
|
|
60683
60676
|
// call for layer="top": a wall is what showModal() is for, and without one
|
|
60684
60677
|
// the dialog goes to the same top layer through the Popover API instead.
|
|
60685
60678
|
backdrop = true,
|
|
60686
60679
|
// How loudly the backdrop says it is there — independent of what it
|
|
60687
|
-
// *does* (that's
|
|
60680
|
+
// *does* (that's pressOutside above). "lift" is the
|
|
60688
60681
|
// opaque wall at one end, "invisible" a wall that is not seen at the
|
|
60689
60682
|
// other — not the absence of one, it only stops the dim from being
|
|
60690
60683
|
// drawn.
|
|
@@ -60749,8 +60742,8 @@ const useDialogProps = props => {
|
|
|
60749
60742
|
const isTopLayer = layer === "top";
|
|
60750
60743
|
const isModal = isTopLayer && backdrop;
|
|
60751
60744
|
const isTopLayerPopover = isTopLayer && !backdrop;
|
|
60752
|
-
if (!backdrop &&
|
|
60753
|
-
console.warn(`Dialog:
|
|
60745
|
+
if (!backdrop && pressOutside === "capture") {
|
|
60746
|
+
console.warn(`Dialog: pressOutside="capture" needs a backdrop. Absorbing a press is what a wall does, and backdrop={false} takes it away.`);
|
|
60754
60747
|
}
|
|
60755
60748
|
const ref = props.ref;
|
|
60756
60749
|
const expandY = Boolean(expand) || Boolean(expandYProp);
|
|
@@ -61282,10 +61275,10 @@ const useDialogProps = props => {
|
|
|
61282
61275
|
// file's top comment), and a local one the caller asked to leave the page
|
|
61283
61276
|
// reachable. Active for the dialog's entire open lifetime, not just
|
|
61284
61277
|
// mid-transition.
|
|
61285
|
-
if ((isModal || !backdrop) && (
|
|
61278
|
+
if ((isModal || !backdrop) && (pressOutside === "close" || pressOutside === "cancel")) {
|
|
61286
61279
|
addCleanup(armOutsidePressClose(dialogEl, {
|
|
61287
61280
|
openController,
|
|
61288
|
-
|
|
61281
|
+
pressOutside,
|
|
61289
61282
|
// A modal wall spends the press the page acts on (mousedown); a
|
|
61290
61283
|
// local dialog with no wall lets that same press through
|
|
61291
61284
|
// (pointerdown). See armOutsidePressClose for why the two differ on
|
|
@@ -61385,7 +61378,7 @@ const useDialogProps = props => {
|
|
|
61385
61378
|
"navi-hidden": openController.openedInDom ? undefined : "",
|
|
61386
61379
|
"styleCSSVars": DIALOG_STYLE_CSS_VARS,
|
|
61387
61380
|
"animationDuration": rest.animationDuration,
|
|
61388
|
-
"data-
|
|
61381
|
+
"data-press-outside": pressOutside,
|
|
61389
61382
|
"data-backdrop-variant": backdropVariant,
|
|
61390
61383
|
"data-lifting": lifting ? "" : undefined,
|
|
61391
61384
|
backdropColor,
|
|
@@ -61417,7 +61410,7 @@ const useDialogProps = props => {
|
|
|
61417
61410
|
// navi-animation above. Harmless for a local dialog too (its own real
|
|
61418
61411
|
// backdrop element already gets the same attribute via backdropProps
|
|
61419
61412
|
// above, which is what its own CSS actually keys off).
|
|
61420
|
-
"data-
|
|
61413
|
+
"data-press-outside": pressOutside,
|
|
61421
61414
|
// Only load-bearing for a modal's own native ::backdrop, same "a
|
|
61422
61415
|
// pseudo-element can't carry attributes" reasoning as the prop just above
|
|
61423
61416
|
// (and harmless for a local dialog, whose real backdrop element gets it
|
|
@@ -61468,7 +61461,7 @@ const useDialogProps = props => {
|
|
|
61468
61461
|
// The top layer without a wall: showPopover() is what puts it there, and
|
|
61469
61462
|
// it only accepts an element that declares itself a popover. "manual" so
|
|
61470
61463
|
// the browser's own light dismiss stays out of it — what an outside press
|
|
61471
|
-
// does is
|
|
61464
|
+
// does is pressOutside's answer, given by the
|
|
61472
61465
|
// document-level listener in openEffect above.
|
|
61473
61466
|
"popover": isTopLayerPopover ? "manual" : undefined,
|
|
61474
61467
|
"baseClassName": "navi_dialog",
|
|
@@ -61511,7 +61504,7 @@ const useDialogProps = props => {
|
|
|
61511
61504
|
handlePressOnOutsideRegion(e, {
|
|
61512
61505
|
popupEl: ref.current,
|
|
61513
61506
|
openController,
|
|
61514
|
-
|
|
61507
|
+
pressOutside
|
|
61515
61508
|
});
|
|
61516
61509
|
},
|
|
61517
61510
|
"onKeyDown": e => {
|
|
@@ -61564,12 +61557,12 @@ const useDialogProps = props => {
|
|
|
61564
61557
|
if (popupUnderPointer && popupUnderPointer !== dialogEl && !dialogEl?.contains(popupUnderPointer)) {
|
|
61565
61558
|
return;
|
|
61566
61559
|
}
|
|
61567
|
-
if (
|
|
61560
|
+
if (pressOutside === "close" || pressOutside === "cancel") {
|
|
61568
61561
|
openController.requestClose(mouseDownEvent, {
|
|
61569
|
-
isCancel:
|
|
61562
|
+
isCancel: pressOutside === "cancel"
|
|
61570
61563
|
});
|
|
61571
61564
|
}
|
|
61572
|
-
// "capture"/"
|
|
61565
|
+
// "capture"/"ignore" both just absorb the press without closing — see
|
|
61573
61566
|
// this hook's own destructuring comment for why the two collapse to
|
|
61574
61567
|
// the same behavior for Dialog.
|
|
61575
61568
|
};
|
|
@@ -61880,13 +61873,13 @@ const css$D = /* css */`
|
|
|
61880
61873
|
display: none !important;
|
|
61881
61874
|
}
|
|
61882
61875
|
|
|
61883
|
-
/* Makes
|
|
61884
|
-
&[data-
|
|
61885
|
-
&[data-
|
|
61876
|
+
/* Makes pressOutside have a visible impact on backdrop */
|
|
61877
|
+
&[data-press-outside="close"],
|
|
61878
|
+
&[data-press-outside="cancel"] {
|
|
61886
61879
|
--backdrop-background: var(--navi-backdrop-close-background);
|
|
61887
61880
|
--backdrop-filter: var(--navi-backdrop-close-backdrop-filter);
|
|
61888
61881
|
}
|
|
61889
|
-
&[data-
|
|
61882
|
+
&[data-press-outside="capture"] {
|
|
61890
61883
|
--backdrop-background: var(--navi-backdrop-capture-background);
|
|
61891
61884
|
--backdrop-filter: var(--navi-backdrop-capture-backdrop-filter);
|
|
61892
61885
|
}
|
|
@@ -61895,7 +61888,7 @@ const css$D = /* css */`
|
|
|
61895
61888
|
specificity (class + one attribute), so these have to stay *after*
|
|
61896
61889
|
them to win. Only the paint changes: the element is still rendered
|
|
61897
61890
|
and still pointer-events: auto, so an outside click keeps doing
|
|
61898
|
-
exactly what
|
|
61891
|
+
exactly what pressOutside says. */
|
|
61899
61892
|
/* "lift": the wall a lifted popup brings (see navi_css_vars.js), asked
|
|
61900
61893
|
for on its own — a popover whose own content is what must be looked at
|
|
61901
61894
|
wants the page gone behind it, without moving out of anything. */
|
|
@@ -61980,15 +61973,15 @@ const css$D = /* css */`
|
|
|
61980
61973
|
* the popover and the page at all — asked before what an outside press does
|
|
61981
61974
|
* and before how the backdrop is painted. `false` leaves the page
|
|
61982
61975
|
* reachable: a press outside closes the popover (per
|
|
61983
|
-
* `
|
|
61976
|
+
* `pressOutside`) *and* is answered by whatever it landed
|
|
61984
61977
|
* on, in the same gesture — one press where a wall would have cost two. It
|
|
61985
61978
|
* is a `Popover`-level answer only for `"close"`/`"cancel"`; `"capture"` has
|
|
61986
|
-
* nothing left to absorb without a wall, and `"
|
|
61979
|
+
* nothing left to absorb without a wall, and `"ignore"` renders no wall anyway.
|
|
61987
61980
|
* See docs/popup_backdrop.md.
|
|
61988
|
-
* @param {"close"|"cancel"|"capture"|"
|
|
61989
|
-
* - `"
|
|
61990
|
-
* through. `"close"` closes the popover on an outside
|
|
61991
|
-
* absorbs the
|
|
61981
|
+
* @param {"close"|"cancel"|"capture"|"ignore"} [props.pressOutside="ignore"]
|
|
61982
|
+
* - `"ignore"` (default): no backdrop at all, outside presses pass straight
|
|
61983
|
+
* through. `"close"` closes the popover on an outside press. `"capture"`
|
|
61984
|
+
* absorbs the press (dims the backdrop) without closing. Note this
|
|
61992
61985
|
* default differs from `Dialog`'s own (`"close"`) — a popover is
|
|
61993
61986
|
* typically a lightweight, non-modal affordance. "Outside" is the popover's
|
|
61994
61987
|
* own border box; a see-through popover whose box is bigger than what it
|
|
@@ -61996,7 +61989,7 @@ const css$D = /* css */`
|
|
|
61996
61989
|
* docs/popup_backdrop.md).
|
|
61997
61990
|
* @param {"auto"|"lift"|"discrete"|"invisible"} [props.backdropVariant="auto"]
|
|
61998
61991
|
* - How visible the backdrop is, independently of what it does. `"auto"`:
|
|
61999
|
-
* the paint `
|
|
61992
|
+
* the paint `pressOutside` implies (dimmed for
|
|
62000
61993
|
* `"close"`/`"cancel"`, blurred glass for `"capture"`). `"lift"`: the
|
|
62001
61994
|
* opaque, blurred wall (`--navi-backdrop-lift-*`) a lifted popup brings,
|
|
62002
61995
|
* for content that is the thing to look at rather than a surface shown over
|
|
@@ -62005,7 +61998,7 @@ const css$D = /* css */`
|
|
|
62005
61998
|
* catching every outside click. This only
|
|
62006
61999
|
* changes how much the popover insists on being the thing you deal with;
|
|
62007
62000
|
* whether there is a wall to paint at all is `backdrop` above. Ignored when
|
|
62008
|
-
* there is none (`
|
|
62001
|
+
* there is none (`pressOutside="ignore"`, or
|
|
62009
62002
|
* `backdrop={false}`).
|
|
62010
62003
|
* @param {string} [props.backdropColor] - The wash painted over what is
|
|
62011
62004
|
* behind, for this popup alone: any CSS color (`"rgb(6 10 20 / 88%)"`).
|
|
@@ -62327,16 +62320,16 @@ const usePopoverProps = props => {
|
|
|
62327
62320
|
// "close" → pointer press outside closes (a plain close = commit)
|
|
62328
62321
|
// "cancel" → pointer press outside closes AS A CANCEL (revert)
|
|
62329
62322
|
// "capture"→ absorb the press, stay open
|
|
62330
|
-
// "
|
|
62331
|
-
|
|
62323
|
+
// "ignore" → no backdrop
|
|
62324
|
+
pressOutside = "ignore",
|
|
62332
62325
|
// Whether there is a wall between the popover and the page at all, asked
|
|
62333
|
-
// before what a press on it does (
|
|
62326
|
+
// before what a press on it does (pressOutside) and
|
|
62334
62327
|
// before how it is painted (backdropVariant below). false with a closing
|
|
62335
62328
|
// effect is a press that both dismisses the popover and reaches whatever
|
|
62336
62329
|
// it landed on.
|
|
62337
62330
|
backdrop = true,
|
|
62338
62331
|
// How loudly the backdrop says it is there — independent of what it
|
|
62339
|
-
// *does* (that's
|
|
62332
|
+
// *does* (that's pressOutside above). "auto" keeps
|
|
62340
62333
|
// the paint the effect implies; "lift" asks for the opaque wall, and
|
|
62341
62334
|
// "discrete"/"invisible" tone it down or stop drawing it — none of them
|
|
62342
62335
|
// gives up the outside click, a wall that is not seen is still a wall
|
|
@@ -62409,9 +62402,9 @@ const usePopoverProps = props => {
|
|
|
62409
62402
|
// animation={true} or "auto" always resolves to "sliding" or "scaling"
|
|
62410
62403
|
// (see resolveAutoAnimationKind).
|
|
62411
62404
|
const isAutoAnimation = animation === true || animation === "auto";
|
|
62412
|
-
const hasBackdrop =
|
|
62413
|
-
if (!backdrop &&
|
|
62414
|
-
console.warn(`Popover:
|
|
62405
|
+
const hasBackdrop = pressOutside !== "ignore" && backdrop;
|
|
62406
|
+
if (!backdrop && pressOutside === "capture") {
|
|
62407
|
+
console.warn(`Popover: pressOutside="capture" needs a backdrop. Absorbing a press is what a wall does, and backdrop={false} takes it away — every press outside reaches the page, exactly as with "ignore".`);
|
|
62415
62408
|
}
|
|
62416
62409
|
// positionPopover lives in openEffect's closure — created once, when the
|
|
62417
62410
|
// popover opens. Reading the placement props through a ref instead of that
|
|
@@ -62470,7 +62463,7 @@ const usePopoverProps = props => {
|
|
|
62470
62463
|
openController.getElement = () => ref.current;
|
|
62471
62464
|
openController.openEffect = e => {
|
|
62472
62465
|
const popoverEl = ref.current;
|
|
62473
|
-
// backdropEl is null when
|
|
62466
|
+
// backdropEl is null when pressOutside is "ignore" —
|
|
62474
62467
|
// the backdrop isn't rendered at all in that case.
|
|
62475
62468
|
const backdropEl = backdropRef.current;
|
|
62476
62469
|
if (!popoverEl) {
|
|
@@ -62765,10 +62758,10 @@ const usePopoverProps = props => {
|
|
|
62765
62758
|
// With no backdrop of its own to catch a press, the popover hears an
|
|
62766
62759
|
// outside one from the document and takes nothing from it: it closes, and
|
|
62767
62760
|
// the press goes on to whatever it landed on (armOutsidePressClose).
|
|
62768
|
-
if (!hasBackdrop && (
|
|
62761
|
+
if (!hasBackdrop && (pressOutside === "close" || pressOutside === "cancel")) {
|
|
62769
62762
|
addCleanup(armOutsidePressClose(popoverEl, {
|
|
62770
62763
|
openController,
|
|
62771
|
-
|
|
62764
|
+
pressOutside
|
|
62772
62765
|
}));
|
|
62773
62766
|
}
|
|
62774
62767
|
if (scrollCapture) {
|
|
@@ -63080,7 +63073,7 @@ const usePopoverProps = props => {
|
|
|
63080
63073
|
"navi-hidden": openController.openedInDom ? undefined : "",
|
|
63081
63074
|
"styleCSSVars": POPUP_STYLE_CSS_VARS,
|
|
63082
63075
|
"animationDuration": rest.animationDuration,
|
|
63083
|
-
"data-
|
|
63076
|
+
"data-press-outside": pressOutside,
|
|
63084
63077
|
"data-backdrop-variant": backdropVariant,
|
|
63085
63078
|
backdropColor,
|
|
63086
63079
|
backdropFilter,
|
|
@@ -63102,16 +63095,16 @@ const usePopoverProps = props => {
|
|
|
63102
63095
|
return;
|
|
63103
63096
|
}
|
|
63104
63097
|
// "capture" absorbs the click so it doesn't reach whatever's
|
|
63105
|
-
// behind the popover, without closing it. "
|
|
63098
|
+
// behind the popover, without closing it. "ignore" never reaches
|
|
63106
63099
|
// here at all — the backdrop isn't rendered in that case.
|
|
63107
|
-
if (
|
|
63100
|
+
if (pressOutside === "capture") {
|
|
63108
63101
|
mouseDownEvent.preventDefault();
|
|
63109
63102
|
return;
|
|
63110
63103
|
}
|
|
63111
63104
|
// "close" commits (plain close), "cancel" reverts. Both dismiss.
|
|
63112
|
-
if (
|
|
63105
|
+
if (pressOutside === "close" || pressOutside === "cancel") {
|
|
63113
63106
|
openController.requestClose(mouseDownEvent, {
|
|
63114
|
-
isCancel:
|
|
63107
|
+
isCancel: pressOutside === "cancel"
|
|
63115
63108
|
});
|
|
63116
63109
|
return;
|
|
63117
63110
|
}
|
|
@@ -63175,7 +63168,7 @@ const usePopoverProps = props => {
|
|
|
63175
63168
|
handlePressOnOutsideRegion(e, {
|
|
63176
63169
|
popupEl: ref.current,
|
|
63177
63170
|
openController,
|
|
63178
|
-
|
|
63171
|
+
pressOutside
|
|
63179
63172
|
});
|
|
63180
63173
|
},
|
|
63181
63174
|
"onKeyDown": e => {
|
|
@@ -63322,15 +63315,15 @@ const css$C = /* css */`@layer navi {
|
|
|
63322
63315
|
* `Popover` have different own defaults (`"center"` vs. `"bottom"`),
|
|
63323
63316
|
* deliberately not homogenized here (each reads best for its own typical
|
|
63324
63317
|
* use case).
|
|
63325
|
-
* @param {"close"|"cancel"|"capture"|"
|
|
63318
|
+
* @param {"close"|"cancel"|"capture"|"ignore"} [props.pressOutside="close"]
|
|
63326
63319
|
* - Forwarded to whichever component renders, defaulted here to `"close"`
|
|
63327
|
-
* specifically to override `Popover`'s own different default (`"
|
|
63320
|
+
* specifically to override `Popover`'s own different default (`"ignore"`)
|
|
63328
63321
|
* — without this, the exact same `<Popup>` usage would behave
|
|
63329
|
-
* differently (close
|
|
63322
|
+
* differently (close on an outside press or not) purely based on which mode
|
|
63330
63323
|
* the screen-size check happens to pick, which defeats the point of
|
|
63331
63324
|
* having one shared API in the first place. Note this only says what a
|
|
63332
63325
|
* press outside *does*; whether it reaches the page at all is `backdrop`
|
|
63333
|
-
* below, and `"
|
|
63326
|
+
* below, and `"ignore"`/`"capture"` describe a wall either way — the popup
|
|
63334
63327
|
* absorbs the press without closing, dimmed or not.
|
|
63335
63328
|
* @param {boolean} [props.backdrop] - Whether anything is laid between the
|
|
63336
63329
|
* popup and the page at all: `false` lets a press outside both dismiss the
|
|
@@ -63344,7 +63337,7 @@ const css$C = /* css */`@layer navi {
|
|
|
63344
63337
|
* as-is to whichever component renders (both understand it identically):
|
|
63345
63338
|
* how visible the backdrop is, independently of what an outside click
|
|
63346
63339
|
* does — a wall that is not seen is still a wall (that is `backdrop`
|
|
63347
|
-
* above). Unlike `
|
|
63340
|
+
* above). Unlike `pressOutside`, this one needs no
|
|
63348
63341
|
* default here — `"auto"` already means the same thing on both sides.
|
|
63349
63342
|
* @param {string} [props.backdropColor] - Forwarded as-is (both understand it
|
|
63350
63343
|
* identically): the wash the backdrop paints over what is behind.
|
|
@@ -63406,10 +63399,10 @@ const Popup = props => {
|
|
|
63406
63399
|
className,
|
|
63407
63400
|
children,
|
|
63408
63401
|
// Both default here (not left to each component's own, *different*
|
|
63409
|
-
// default — Dialog's own is "close", Popover's own is "
|
|
63402
|
+
// default — Dialog's own is "close", Popover's own is "ignore") so the
|
|
63410
63403
|
// exact same <Popup> usage behaves identically regardless of which
|
|
63411
63404
|
// mode the automatic screen-size resolution happens to pick.
|
|
63412
|
-
|
|
63405
|
+
pressOutside = "close",
|
|
63413
63406
|
backdrop,
|
|
63414
63407
|
// Popover-only (see this component's own doc) — destructured out so
|
|
63415
63408
|
// they're never part of ...rest, and therefore never forwarded to
|
|
@@ -63445,7 +63438,7 @@ const Popup = props => {
|
|
|
63445
63438
|
sizeFromAnchor: sizeFromAnchor,
|
|
63446
63439
|
lift: lift,
|
|
63447
63440
|
maxWidth: maxWidth,
|
|
63448
|
-
|
|
63441
|
+
pressOutside: pressOutside,
|
|
63449
63442
|
backdrop: backdrop,
|
|
63450
63443
|
className: withPropsClassName("navi_popup", className),
|
|
63451
63444
|
expand: expand,
|
|
@@ -63458,7 +63451,7 @@ const Popup = props => {
|
|
|
63458
63451
|
return jsx(Popover, {
|
|
63459
63452
|
...rest,
|
|
63460
63453
|
maxWidth: maxWidth,
|
|
63461
|
-
|
|
63454
|
+
pressOutside: pressOutside,
|
|
63462
63455
|
backdrop: backdrop,
|
|
63463
63456
|
marginWithAnchor: marginWithAnchor,
|
|
63464
63457
|
focusCapture: focusCapture,
|
|
@@ -64254,7 +64247,7 @@ const PickerContentInsidePopup = props => {
|
|
|
64254
64247
|
// Clicking outside the popup closes it and COMMITS by default (fires the
|
|
64255
64248
|
// action if the value changed) — Escape still cancels. Pass "cancel" to make
|
|
64256
64249
|
// clicking outside revert instead, or "capture" to keep it open.
|
|
64257
|
-
|
|
64250
|
+
pressOutside = "close",
|
|
64258
64251
|
// Named/forwarded rather than left in ...rest: rest goes to the picker
|
|
64259
64252
|
// element itself, not the popup, and these belong to the popup.
|
|
64260
64253
|
backdrop,
|
|
@@ -64375,7 +64368,7 @@ const PickerContentInsidePopup = props => {
|
|
|
64375
64368
|
marginWithAnchor: isPopover ? popoverSpacing : undefined,
|
|
64376
64369
|
marginWithContainer: marginWithContainer === undefined && isPopover ? popoverSpacing : marginWithContainer,
|
|
64377
64370
|
scrollCapture: scrollCapture,
|
|
64378
|
-
|
|
64371
|
+
pressOutside: pointerLock ? "capture" : pressOutside,
|
|
64379
64372
|
backdrop: backdrop,
|
|
64380
64373
|
backdropVariant: backdropVariant,
|
|
64381
64374
|
backdropColor: backdropColor,
|
|
@@ -76124,7 +76117,7 @@ const css$n = /* css */`.navi_split_button {
|
|
|
76124
76117
|
* backdropVariant?: "auto" | "lift" | "discrete" | "invisible",
|
|
76125
76118
|
* backdropColor?: string,
|
|
76126
76119
|
* backdropFilter?: string,
|
|
76127
|
-
*
|
|
76120
|
+
* pressOutside?: "close" | "cancel" | "capture",
|
|
76128
76121
|
* escapeEffect?: "cancel" | "close",
|
|
76129
76122
|
* popupLayer?: "top" | "local",
|
|
76130
76123
|
* popupTestId?: string,
|
|
@@ -76171,7 +76164,7 @@ const css$n = /* css */`.navi_split_button {
|
|
|
76171
76164
|
* `marginWithContainer`, `popoverMode`, `popoverSpacing`, `popupLayer`,
|
|
76172
76165
|
* `popupTestId`, `popupWidthFitContent`, `popoverMaxHeight`, `backdrop`,
|
|
76173
76166
|
* `backdropVariant`, `backdropColor`, `backdropFilter`,
|
|
76174
|
-
* `
|
|
76167
|
+
* `pressOutside`, `escapeEffect`, `closeOnFocusOut`,
|
|
76175
76168
|
* `scrollCapture`, `focusCapture`, `popupBackgroundColor`,
|
|
76176
76169
|
* `popupBorderRadius`, `animation`. See picker.jsx for what each one says.
|
|
76177
76170
|
* Anything else lands on the split button's own box.
|
|
@@ -76371,7 +76364,7 @@ const SplitButton = props => {
|
|
|
76371
76364
|
// What the Picker's popup answers to — Picker's own popup props, named here so
|
|
76372
76365
|
// a caller reaches all of them through the split button (see picker.jsx's JSDoc
|
|
76373
76366
|
// for what each one says).
|
|
76374
|
-
const POPUP_PROP_SET = new Set(["mode", "popupLayer", "popupTestId", "positionArea", "popoverMode", "popoverSpacing", "popupWidthFitContent", "popoverMaxHeight", "dialogMinWidth", "dialogMinHeight", "dialogMaxWidth", "dialogMaxHeight", "dialogExpand", "dialogExpandX", "dialogExpandY", "dockedOnSmallTouchScreen", "marginWithContainer", "backdrop", "backdropVariant", "backdropColor", "backdropFilter", "
|
|
76367
|
+
const POPUP_PROP_SET = new Set(["mode", "popupLayer", "popupTestId", "positionArea", "popoverMode", "popoverSpacing", "popupWidthFitContent", "popoverMaxHeight", "dialogMinWidth", "dialogMinHeight", "dialogMaxWidth", "dialogMaxHeight", "dialogExpand", "dialogExpandX", "dialogExpandY", "dockedOnSmallTouchScreen", "marginWithContainer", "backdrop", "backdropVariant", "backdropColor", "backdropFilter", "pressOutside", "escapeEffect", "closeOnFocusOut", "scrollCapture", "focusCapture", "popupBackgroundColor", "popupBorderRadius", "animation"]);
|
|
76375
76368
|
const splitPopupProps = props => {
|
|
76376
76369
|
const popupProps = {};
|
|
76377
76370
|
const boxProps = {};
|
|
@@ -85849,19 +85842,19 @@ const css = /* css */`.navi_side_panel {
|
|
|
85849
85842
|
* (`slide-from-<side>`); `"fading"` is the other common choice. Other
|
|
85850
85843
|
* values are forwarded as-is but not a documented/encouraged part of this
|
|
85851
85844
|
* component's own API.
|
|
85852
|
-
* @param {boolean} [props.
|
|
85853
|
-
* maps to `
|
|
85845
|
+
* @param {boolean} [props.closeByPressOutside=false] - `false` (default):
|
|
85846
|
+
* maps to `pressOutside="ignore"` — in popover mode, no
|
|
85854
85847
|
* backdrop at all, outside clicks pass straight through; in dialog mode,
|
|
85855
85848
|
* the outside click is absorbed by the panel's own wall but changes
|
|
85856
85849
|
* nothing. Pass `backdrop={false}` (forwarded to `Popup`) for a panel with
|
|
85857
85850
|
* no wall in either mode, whose outside presses reach the page. `true`:
|
|
85858
|
-
* closes the panel on an outside
|
|
85851
|
+
* closes the panel on an outside press instead, and also enables trapping
|
|
85859
85852
|
* Tab navigation inside the panel (`focusCapture`) — closing on outside
|
|
85860
85853
|
* interaction only makes sense paired with not letting focus silently
|
|
85861
85854
|
* leave the panel first. A box of the page whose press must not close the
|
|
85862
85855
|
* panel (a card that fills it) names the panel:
|
|
85863
85856
|
* `data-navi-popup-inside={id}` — see docs/popup_backdrop.md.
|
|
85864
|
-
* @param {boolean} [props.
|
|
85857
|
+
* @param {boolean} [props.closeByDrag=true] - Pushing the panel back
|
|
85865
85858
|
* towards the edge it is docked to closes it: the panel follows the
|
|
85866
85859
|
* pointer and finishes leaving (or comes back to rest) when it is
|
|
85867
85860
|
* released. Set to `false` for a panel that must only ever be dismissed
|
|
@@ -85870,13 +85863,16 @@ const css = /* css */`.navi_side_panel {
|
|
|
85870
85863
|
* one underlying renderer instead of its automatic screen-size
|
|
85871
85864
|
* resolution. Note that if `Popup` ends up in dialog mode (small screen, or
|
|
85872
85865
|
* forced here), the panel is modal unless it says `backdrop={false}`:
|
|
85873
|
-
* `
|
|
85866
|
+
* `closeByPressOutside`/`pressOutside` only say what a
|
|
85874
85867
|
* press on the wall does, not whether there is one (see `dialog.jsx`'s own
|
|
85875
85868
|
* doc).
|
|
85876
85869
|
* @param {import("ignore:preact").ComponentChildren} props.children - No built-in
|
|
85877
85870
|
* close button — add one wherever it makes sense for the layout (e.g. a
|
|
85878
85871
|
* plain `<Button command="--navi-close">`), use `SidePanel.Head`'s own
|
|
85879
|
-
* `closeButton` prop, or rely on `
|
|
85872
|
+
* `closeButton` prop, or rely on `closeByPressOutside`/Escape instead.
|
|
85873
|
+
* A form sent inside the panel closes it, as in any popup: a panel one
|
|
85874
|
+
* keeps editing in says `command="--navi-void"` on that form (see
|
|
85875
|
+
* docs/form_changed.md).
|
|
85880
85876
|
*/
|
|
85881
85877
|
const SidePanel = ({
|
|
85882
85878
|
open,
|
|
@@ -85891,15 +85887,15 @@ const SidePanel = ({
|
|
|
85891
85887
|
minWidth,
|
|
85892
85888
|
minHeight,
|
|
85893
85889
|
animation,
|
|
85894
|
-
|
|
85895
|
-
|
|
85890
|
+
closeByPressOutside = false,
|
|
85891
|
+
closeByDrag = true,
|
|
85896
85892
|
mode,
|
|
85897
85893
|
layer = "top",
|
|
85898
85894
|
className,
|
|
85899
85895
|
...rest
|
|
85900
85896
|
}) => {
|
|
85901
85897
|
import.meta.css = [css, "@jsenv/navi/src/layout/side_panel.jsx"];
|
|
85902
|
-
const onSwipePointerDown =
|
|
85898
|
+
const onSwipePointerDown = closeByDrag ? createSwipeToClose(side) : null;
|
|
85903
85899
|
return jsx(Popup, {
|
|
85904
85900
|
mode: mode
|
|
85905
85901
|
// Spread rather than written: the collision warning between `signal` and
|
|
@@ -85922,26 +85918,26 @@ const SidePanel = ({
|
|
|
85922
85918
|
,
|
|
85923
85919
|
marginWithContainer: 0,
|
|
85924
85920
|
animation: animation === true ? `slide-from-${side}` : animation,
|
|
85925
|
-
|
|
85926
|
-
focusCapture:
|
|
85921
|
+
pressOutside: closeByPressOutside ? "close" : "ignore",
|
|
85922
|
+
focusCapture: closeByPressOutside,
|
|
85927
85923
|
minWidth: toCssLength(minWidth),
|
|
85928
85924
|
minHeight: toCssLength(minHeight),
|
|
85929
85925
|
className: withPropsClassName("navi_side_panel", className),
|
|
85930
85926
|
"navi-side": side,
|
|
85931
|
-
"data-swipe-to-close":
|
|
85927
|
+
"data-swipe-to-close": closeByDrag ? "" : undefined
|
|
85932
85928
|
// The axis the panel travels on when it is pushed back, said to the
|
|
85933
85929
|
// shared gesture layer: it keeps the panel's scrolling from spilling onto
|
|
85934
85930
|
// the page, and it is what a box travelling inside the panel reads to
|
|
85935
85931
|
// know this axis is already walked (see @jsenv/dom's drag_to_travel).
|
|
85936
85932
|
,
|
|
85937
|
-
"data-drag-travel":
|
|
85938
|
-
"data-travel-by-drag":
|
|
85933
|
+
"data-drag-travel": closeByDrag ? SWIPE_AXIS_BY_SIDE[side] : undefined,
|
|
85934
|
+
"data-travel-by-drag": closeByDrag ? SWIPE_AXIS_BY_SIDE[side] : undefined
|
|
85939
85935
|
// A touch this panel may take has to be refusable before the finger
|
|
85940
85936
|
// lands, or the browser can cancel the close gesture mid-swipe by
|
|
85941
85937
|
// scrolling the panel's content — see keepTouchRefusable for why a JSX
|
|
85942
85938
|
// prop is enough (an element-level touchmove listener is non-passive).
|
|
85943
85939
|
,
|
|
85944
|
-
onTouchMove:
|
|
85940
|
+
onTouchMove: closeByDrag ? keepTouchRefusable : undefined,
|
|
85945
85941
|
...rest,
|
|
85946
85942
|
onPointerDown: pointerDownEvent => {
|
|
85947
85943
|
rest.onPointerDown?.(pointerDownEvent);
|