@jsenv/navi 0.29.213 → 0.29.215
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 +73 -30
- package/dist/dev/jsenv_navi.js.map +8 -8
- package/dist/jsenv_navi.js +73 -30
- package/dist/jsenv_navi.js.map +8 -8
- package/package.json +1 -1
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -44924,6 +44924,10 @@ const FOCUS_DELAY_ON_KEYBOARD_MS = 250;
|
|
|
44924
44924
|
* controller (not exposed as a property) and invoked when the popup actually
|
|
44925
44925
|
* closes, however that happens.
|
|
44926
44926
|
*
|
|
44927
|
+
* `controller.getElement` is assigned alongside it and answers with the
|
|
44928
|
+
* element that effect acts on, so a mount-time open can tell whether there is
|
|
44929
|
+
* anything in the document to open yet (see useOpenPropsEffectOnOpenController).
|
|
44930
|
+
*
|
|
44927
44931
|
* Dialog/Popover also call `openController.requestClose(e, { isCancel })` for
|
|
44928
44932
|
* their own internal triggers (backdrop click, Escape).
|
|
44929
44933
|
*
|
|
@@ -45192,6 +45196,10 @@ const createOpenController = (
|
|
|
45192
45196
|
// openedDuringThisPress). Never any press before there has been one.
|
|
45193
45197
|
pressCountAtOpen: null,
|
|
45194
45198
|
openEffect: null,
|
|
45199
|
+
// The element openEffect acts on, asked for before the mount-time open is
|
|
45200
|
+
// let through: it has to be in the document for showModal()/showPopover()
|
|
45201
|
+
// to be legal at all (see useOpenPropsEffectOnOpenController).
|
|
45202
|
+
getElement: null,
|
|
45195
45203
|
// Set by the controlled element (see popup_content_mount.js) when its
|
|
45196
45204
|
// content is still waiting for a first open to be built. Called below,
|
|
45197
45205
|
// before openEffect, so the popup measures and positions the real thing.
|
|
@@ -45454,32 +45462,27 @@ const useOpenController = (openHandler) => {
|
|
|
45454
45462
|
// relative to each other, but there's no meaningful "correct" order between
|
|
45455
45463
|
// those anyway.
|
|
45456
45464
|
//
|
|
45457
|
-
// The
|
|
45458
|
-
//
|
|
45459
|
-
//
|
|
45460
|
-
// children and moves their dom into a detached <div>
|
|
45461
|
-
// then be opening a popup whose element has left the document.
|
|
45462
|
-
let pendingMountOpens =
|
|
45465
|
+
// The cancel this returns answers whether the open was still pending: a
|
|
45466
|
+
// `<Loading>` above the popup can park the whole subtree between the effect
|
|
45467
|
+
// and the flush (preact/compat's Suspense runs every hook cleanup of the
|
|
45468
|
+
// suspended children and moves their dom into a detached <div>), and the flush
|
|
45469
|
+
// would then be opening a popup whose element has left the document.
|
|
45470
|
+
let pendingMountOpens = new Set();
|
|
45463
45471
|
let mountOpenFlushScheduled = false;
|
|
45464
45472
|
const scheduleMountOpen = (run) => {
|
|
45465
|
-
pendingMountOpens.
|
|
45473
|
+
pendingMountOpens.add(run);
|
|
45466
45474
|
if (!mountOpenFlushScheduled) {
|
|
45467
45475
|
mountOpenFlushScheduled = true;
|
|
45468
45476
|
queueMicrotask(() => {
|
|
45469
|
-
const entries = pendingMountOpens;
|
|
45470
|
-
pendingMountOpens =
|
|
45477
|
+
const entries = [...pendingMountOpens];
|
|
45478
|
+
pendingMountOpens = new Set();
|
|
45471
45479
|
mountOpenFlushScheduled = false;
|
|
45472
45480
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
45473
45481
|
entries[i]();
|
|
45474
45482
|
}
|
|
45475
45483
|
});
|
|
45476
45484
|
}
|
|
45477
|
-
return () =>
|
|
45478
|
-
const index = pendingMountOpens.indexOf(run);
|
|
45479
|
-
if (index > -1) {
|
|
45480
|
-
pendingMountOpens.splice(index, 1);
|
|
45481
|
-
}
|
|
45482
|
-
};
|
|
45485
|
+
return () => pendingMountOpens.delete(run);
|
|
45483
45486
|
};
|
|
45484
45487
|
|
|
45485
45488
|
// Where the popup's open state is kept, when it is kept anywhere: `navState`
|
|
@@ -45657,6 +45660,9 @@ const useOpenPropsEffectOnOpenController = (
|
|
|
45657
45660
|
// subsequent `open` change is a real, later toggle and should animate
|
|
45658
45661
|
// normally like any other interactive open/close.
|
|
45659
45662
|
const isFirstRunRef = useRef(true);
|
|
45663
|
+
// The mount-time open, from the first run below until the effect after it
|
|
45664
|
+
// could schedule it.
|
|
45665
|
+
const mountOpenOwedRef = useRef(null);
|
|
45660
45666
|
|
|
45661
45667
|
useLayoutEffect(() => {
|
|
45662
45668
|
const isFirstRun = isFirstRunRef.current;
|
|
@@ -45673,15 +45679,10 @@ const useOpenPropsEffectOnOpenController = (
|
|
|
45673
45679
|
// shown as "closed" for the user to see it transition away from, so the
|
|
45674
45680
|
// entrance is skipped (`silent`, see popover.jsx's own openEffect).
|
|
45675
45681
|
//
|
|
45676
|
-
|
|
45677
|
-
// directly, so nested popups that both mount already-open end up
|
|
45678
|
-
// stacked ancestor-first instead of Preact's own child-first effect
|
|
45679
|
-
// order.
|
|
45680
|
-
return scheduleMountOpen(() =>
|
|
45682
|
+
mountOpenOwedRef.current = () =>
|
|
45681
45683
|
openController.open(new CustomEvent("open_by_prop", { detail: {} }), {
|
|
45682
45684
|
silent: mountOpenReason !== "interaction",
|
|
45683
|
-
})
|
|
45684
|
-
);
|
|
45685
|
+
});
|
|
45685
45686
|
}
|
|
45686
45687
|
return undefined;
|
|
45687
45688
|
}
|
|
@@ -45716,6 +45717,38 @@ const useOpenPropsEffectOnOpenController = (
|
|
|
45716
45717
|
}
|
|
45717
45718
|
return undefined;
|
|
45718
45719
|
}, [open]);
|
|
45720
|
+
|
|
45721
|
+
// Schedules the owed mount-time open — on every render, until it can. It has
|
|
45722
|
+
// to wait for the element to be IN THE DOCUMENT, and a mount does not
|
|
45723
|
+
// guarantee that: a `<Loading>` above the popup parks a suspended subtree by
|
|
45724
|
+
// moving its dom into a detached <div> while keeping its components alive
|
|
45725
|
+
// (preact/compat), and a render there re-creates the hooks, so the first run
|
|
45726
|
+
// above happens against dom that is not in the page — where showModal() and
|
|
45727
|
+
// showPopover() throw. The boundary settling re-renders the subtree with its
|
|
45728
|
+
// dom back, and that render is the one that schedules.
|
|
45729
|
+
//
|
|
45730
|
+
// Deferred + batched (see scheduleMountOpen) rather than called directly,
|
|
45731
|
+
// so nested popups that both mount already-open end up stacked
|
|
45732
|
+
// ancestor-first instead of Preact's own child-first effect order. An open
|
|
45733
|
+
// still pending when this cleans up goes back to being owed: the parking
|
|
45734
|
+
// itself runs this cleanup, and the fresh run that follows re-asks.
|
|
45735
|
+
useLayoutEffect(() => {
|
|
45736
|
+
const mountOpen = mountOpenOwedRef.current;
|
|
45737
|
+
if (!mountOpen) {
|
|
45738
|
+
return undefined;
|
|
45739
|
+
}
|
|
45740
|
+
const element = openController.getElement?.();
|
|
45741
|
+
if (element && !element.isConnected) {
|
|
45742
|
+
return undefined;
|
|
45743
|
+
}
|
|
45744
|
+
mountOpenOwedRef.current = null;
|
|
45745
|
+
const cancelMountOpen = scheduleMountOpen(mountOpen);
|
|
45746
|
+
return () => {
|
|
45747
|
+
if (cancelMountOpen()) {
|
|
45748
|
+
mountOpenOwedRef.current = mountOpen;
|
|
45749
|
+
}
|
|
45750
|
+
};
|
|
45751
|
+
});
|
|
45719
45752
|
};
|
|
45720
45753
|
|
|
45721
45754
|
const useOpenControllerByProps = (props, name) => {
|
|
@@ -46807,6 +46840,7 @@ const Expandable = props => {
|
|
|
46807
46840
|
// What opening LOOKS like here, and how to undo it — the one thing an
|
|
46808
46841
|
// expandable owns that a popup does not (see open_controller.js). Reassigned
|
|
46809
46842
|
// on every render so it always closes over the latest props.
|
|
46843
|
+
openController.getElement = () => rootRef.current;
|
|
46810
46844
|
openController.openEffect = openEvent => {
|
|
46811
46845
|
const contentContainer = contentContainerRef.current;
|
|
46812
46846
|
// `silent`: the expandable was already open when the page appeared
|
|
@@ -57161,8 +57195,11 @@ const getAvailableWidth = (layer, element) => {
|
|
|
57161
57195
|
* (a top-docked SidePanel: title and tabs at its top). So here the cut alone
|
|
57162
57196
|
* does the reveal — the same curtain descending from the container's top
|
|
57163
57197
|
* edge a full slide draws — while the box travels only `--popup-cover-travel`
|
|
57164
|
-
* (default
|
|
57165
|
-
*
|
|
57198
|
+
* (default 24px): the head is on screen from the first frame, settling its
|
|
57199
|
+
* last few pixels into place. A length, not a share of the panel: the travel
|
|
57200
|
+
* is a settle, the curtain is what reveals, and a share would grow with a
|
|
57201
|
+
* full-screen panel while its head does not — at 15% of 800px the head spent
|
|
57202
|
+
* the first 40% of the entrance above the cut. The exit is the same
|
|
57166
57203
|
* movement backwards and still reads as a slide, the head leading. One
|
|
57167
57204
|
* direction only: a bottom sheet leads with its head by itself, and a
|
|
57168
57205
|
* left/right panel keeps its head on the axis it does not travel.
|
|
@@ -57192,7 +57229,7 @@ const popupCss = /* css */ `
|
|
|
57192
57229
|
.navi_dialog {
|
|
57193
57230
|
--popup-animation-duration: 0.18s;
|
|
57194
57231
|
--popup-scale-from: 0.9;
|
|
57195
|
-
--popup-cover-travel:
|
|
57232
|
+
--popup-cover-travel: 24px;
|
|
57196
57233
|
|
|
57197
57234
|
--popup-opacity-duration: var(--popup-animation-duration);
|
|
57198
57235
|
--popup-translate-duration: var(--popup-animation-duration);
|
|
@@ -57373,7 +57410,7 @@ const popupCss = /* css */ `
|
|
|
57373
57410
|
|
|
57374
57411
|
/* cover — a top-docked popup unrolling from the top edge of its area (see
|
|
57375
57412
|
this file's top comment): the cut does the reveal, the box travels
|
|
57376
|
-
--popup-cover-travel
|
|
57413
|
+
--popup-cover-travel, a length. The far cut sits where the
|
|
57377
57414
|
popup's shadow ends (--navi-popup-box-shadow reaches about 50px) or
|
|
57378
57415
|
where the room does, whichever is nearer, so the reveal finishes on
|
|
57379
57416
|
the box and its shadow at the pace of the box's own settle. On the
|
|
@@ -59076,6 +59113,7 @@ const useDialogProps = props => {
|
|
|
59076
59113
|
// *when* this runs. openEffect runs outside of render (triggered by
|
|
59077
59114
|
// openController.open()), so it cannot call hooks — cleanup is a plain
|
|
59078
59115
|
// pub/sub.
|
|
59116
|
+
openController.getElement = () => ref.current;
|
|
59079
59117
|
openController.openEffect = e => {
|
|
59080
59118
|
const dialogEl = ref.current;
|
|
59081
59119
|
const backdropEl = backdropRef.current;
|
|
@@ -60539,6 +60577,7 @@ const usePopoverProps = props => {
|
|
|
60539
60577
|
// slower, flash-prone `toggle` event instead of the fast, pre-paint
|
|
60540
60578
|
// MutationObserver path.
|
|
60541
60579
|
|
|
60580
|
+
openController.getElement = () => ref.current;
|
|
60542
60581
|
openController.openEffect = e => {
|
|
60543
60582
|
const popoverEl = ref.current;
|
|
60544
60583
|
// backdropEl is null when pointerInteractionOutsideEffect is "none" —
|
|
@@ -62467,6 +62506,7 @@ const PickerCalloutPopup = ({
|
|
|
62467
62506
|
}
|
|
62468
62507
|
// Reassigned on every render, like Popover's own, so it closes over the
|
|
62469
62508
|
// latest props.
|
|
62509
|
+
openController.getElement = () => pickerRef.current;
|
|
62470
62510
|
openController.openEffect = openEvent => {
|
|
62471
62511
|
const pickerEl = pickerRef.current;
|
|
62472
62512
|
const calloutManager = getPickerInput(pickerEl).__uiStateController__.rules.callout;
|
|
@@ -83131,6 +83171,7 @@ const ANIMATION_BY_SIDE = {
|
|
|
83131
83171
|
};
|
|
83132
83172
|
const css = /* css */`.navi_side_panel {
|
|
83133
83173
|
--popup-border-radius: 0px;
|
|
83174
|
+
--popup-animation-duration: .3s;
|
|
83134
83175
|
width: var(--navi-side-panel-width, auto);
|
|
83135
83176
|
height: var(--navi-side-panel-height, auto);
|
|
83136
83177
|
|
|
@@ -83295,10 +83336,12 @@ const css = /* css */`.navi_side_panel {
|
|
|
83295
83336
|
* @param {boolean|"fading"} [props.animation] - Off by default (unlike
|
|
83296
83337
|
* `Dialog`/`Popover` themselves) — SidePanel is commonly toggled instead
|
|
83297
83338
|
* of opened/closed as a one-off, where a slide transition is more often
|
|
83298
|
-
* undesired noise than not. `true`
|
|
83299
|
-
* unrolls from its edge
|
|
83300
|
-
* `
|
|
83301
|
-
*
|
|
83339
|
+
* undesired noise than not. `true` plays the entrance of `side`:
|
|
83340
|
+
* `cover-from-top` for a top panel (it unrolls from its edge, head first),
|
|
83341
|
+
* `slide-from-<side>` for the three others — see `ANIMATION_BY_SIDE` for
|
|
83342
|
+
* why the top differs. `"fading"` is the other common choice. Other values
|
|
83343
|
+
* are forwarded as-is but not a documented/encouraged part of this
|
|
83344
|
+
* component's own API.
|
|
83302
83345
|
* @param {boolean} [props.closeOnClickOutside=false] - `false` (default):
|
|
83303
83346
|
* maps to `pointerInteractionOutsideEffect="none"` — in popover mode, no
|
|
83304
83347
|
* backdrop at all, outside clicks pass straight through; in dialog mode,
|