@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/jsenv_navi.js
CHANGED
|
@@ -44357,6 +44357,10 @@ const FOCUS_DELAY_ON_KEYBOARD_MS = 250;
|
|
|
44357
44357
|
* controller (not exposed as a property) and invoked when the popup actually
|
|
44358
44358
|
* closes, however that happens.
|
|
44359
44359
|
*
|
|
44360
|
+
* `controller.getElement` is assigned alongside it and answers with the
|
|
44361
|
+
* element that effect acts on, so a mount-time open can tell whether there is
|
|
44362
|
+
* anything in the document to open yet (see useOpenPropsEffectOnOpenController).
|
|
44363
|
+
*
|
|
44360
44364
|
* Dialog/Popover also call `openController.requestClose(e, { isCancel })` for
|
|
44361
44365
|
* their own internal triggers (backdrop click, Escape).
|
|
44362
44366
|
*
|
|
@@ -44625,6 +44629,10 @@ const createOpenController = (
|
|
|
44625
44629
|
// openedDuringThisPress). Never any press before there has been one.
|
|
44626
44630
|
pressCountAtOpen: null,
|
|
44627
44631
|
openEffect: null,
|
|
44632
|
+
// The element openEffect acts on, asked for before the mount-time open is
|
|
44633
|
+
// let through: it has to be in the document for showModal()/showPopover()
|
|
44634
|
+
// to be legal at all (see useOpenPropsEffectOnOpenController).
|
|
44635
|
+
getElement: null,
|
|
44628
44636
|
// Set by the controlled element (see popup_content_mount.js) when its
|
|
44629
44637
|
// content is still waiting for a first open to be built. Called below,
|
|
44630
44638
|
// before openEffect, so the popup measures and positions the real thing.
|
|
@@ -44887,32 +44895,27 @@ const useOpenController = (openHandler) => {
|
|
|
44887
44895
|
// relative to each other, but there's no meaningful "correct" order between
|
|
44888
44896
|
// those anyway.
|
|
44889
44897
|
//
|
|
44890
|
-
// The
|
|
44891
|
-
//
|
|
44892
|
-
//
|
|
44893
|
-
// children and moves their dom into a detached <div>
|
|
44894
|
-
// then be opening a popup whose element has left the document.
|
|
44895
|
-
let pendingMountOpens =
|
|
44898
|
+
// The cancel this returns answers whether the open was still pending: a
|
|
44899
|
+
// `<Loading>` above the popup can park the whole subtree between the effect
|
|
44900
|
+
// and the flush (preact/compat's Suspense runs every hook cleanup of the
|
|
44901
|
+
// suspended children and moves their dom into a detached <div>), and the flush
|
|
44902
|
+
// would then be opening a popup whose element has left the document.
|
|
44903
|
+
let pendingMountOpens = new Set();
|
|
44896
44904
|
let mountOpenFlushScheduled = false;
|
|
44897
44905
|
const scheduleMountOpen = (run) => {
|
|
44898
|
-
pendingMountOpens.
|
|
44906
|
+
pendingMountOpens.add(run);
|
|
44899
44907
|
if (!mountOpenFlushScheduled) {
|
|
44900
44908
|
mountOpenFlushScheduled = true;
|
|
44901
44909
|
queueMicrotask(() => {
|
|
44902
|
-
const entries = pendingMountOpens;
|
|
44903
|
-
pendingMountOpens =
|
|
44910
|
+
const entries = [...pendingMountOpens];
|
|
44911
|
+
pendingMountOpens = new Set();
|
|
44904
44912
|
mountOpenFlushScheduled = false;
|
|
44905
44913
|
for (let i = entries.length - 1; i >= 0; i--) {
|
|
44906
44914
|
entries[i]();
|
|
44907
44915
|
}
|
|
44908
44916
|
});
|
|
44909
44917
|
}
|
|
44910
|
-
return () =>
|
|
44911
|
-
const index = pendingMountOpens.indexOf(run);
|
|
44912
|
-
if (index > -1) {
|
|
44913
|
-
pendingMountOpens.splice(index, 1);
|
|
44914
|
-
}
|
|
44915
|
-
};
|
|
44918
|
+
return () => pendingMountOpens.delete(run);
|
|
44916
44919
|
};
|
|
44917
44920
|
|
|
44918
44921
|
// Where the popup's open state is kept, when it is kept anywhere: `navState`
|
|
@@ -45073,6 +45076,9 @@ const useOpenPropsEffectOnOpenController = (
|
|
|
45073
45076
|
// subsequent `open` change is a real, later toggle and should animate
|
|
45074
45077
|
// normally like any other interactive open/close.
|
|
45075
45078
|
const isFirstRunRef = useRef(true);
|
|
45079
|
+
// The mount-time open, from the first run below until the effect after it
|
|
45080
|
+
// could schedule it.
|
|
45081
|
+
const mountOpenOwedRef = useRef(null);
|
|
45076
45082
|
|
|
45077
45083
|
useLayoutEffect(() => {
|
|
45078
45084
|
const isFirstRun = isFirstRunRef.current;
|
|
@@ -45089,15 +45095,10 @@ const useOpenPropsEffectOnOpenController = (
|
|
|
45089
45095
|
// shown as "closed" for the user to see it transition away from, so the
|
|
45090
45096
|
// entrance is skipped (`silent`, see popover.jsx's own openEffect).
|
|
45091
45097
|
//
|
|
45092
|
-
|
|
45093
|
-
// directly, so nested popups that both mount already-open end up
|
|
45094
|
-
// stacked ancestor-first instead of Preact's own child-first effect
|
|
45095
|
-
// order.
|
|
45096
|
-
return scheduleMountOpen(() =>
|
|
45098
|
+
mountOpenOwedRef.current = () =>
|
|
45097
45099
|
openController.open(new CustomEvent("open_by_prop", { detail: {} }), {
|
|
45098
45100
|
silent: mountOpenReason !== "interaction",
|
|
45099
|
-
})
|
|
45100
|
-
);
|
|
45101
|
+
});
|
|
45101
45102
|
}
|
|
45102
45103
|
return undefined;
|
|
45103
45104
|
}
|
|
@@ -45132,6 +45133,38 @@ const useOpenPropsEffectOnOpenController = (
|
|
|
45132
45133
|
}
|
|
45133
45134
|
return undefined;
|
|
45134
45135
|
}, [open]);
|
|
45136
|
+
|
|
45137
|
+
// Schedules the owed mount-time open — on every render, until it can. It has
|
|
45138
|
+
// to wait for the element to be IN THE DOCUMENT, and a mount does not
|
|
45139
|
+
// guarantee that: a `<Loading>` above the popup parks a suspended subtree by
|
|
45140
|
+
// moving its dom into a detached <div> while keeping its components alive
|
|
45141
|
+
// (preact/compat), and a render there re-creates the hooks, so the first run
|
|
45142
|
+
// above happens against dom that is not in the page — where showModal() and
|
|
45143
|
+
// showPopover() throw. The boundary settling re-renders the subtree with its
|
|
45144
|
+
// dom back, and that render is the one that schedules.
|
|
45145
|
+
//
|
|
45146
|
+
// Deferred + batched (see scheduleMountOpen) rather than called directly,
|
|
45147
|
+
// so nested popups that both mount already-open end up stacked
|
|
45148
|
+
// ancestor-first instead of Preact's own child-first effect order. An open
|
|
45149
|
+
// still pending when this cleans up goes back to being owed: the parking
|
|
45150
|
+
// itself runs this cleanup, and the fresh run that follows re-asks.
|
|
45151
|
+
useLayoutEffect(() => {
|
|
45152
|
+
const mountOpen = mountOpenOwedRef.current;
|
|
45153
|
+
if (!mountOpen) {
|
|
45154
|
+
return undefined;
|
|
45155
|
+
}
|
|
45156
|
+
const element = openController.getElement?.();
|
|
45157
|
+
if (element && !element.isConnected) {
|
|
45158
|
+
return undefined;
|
|
45159
|
+
}
|
|
45160
|
+
mountOpenOwedRef.current = null;
|
|
45161
|
+
const cancelMountOpen = scheduleMountOpen(mountOpen);
|
|
45162
|
+
return () => {
|
|
45163
|
+
if (cancelMountOpen()) {
|
|
45164
|
+
mountOpenOwedRef.current = mountOpen;
|
|
45165
|
+
}
|
|
45166
|
+
};
|
|
45167
|
+
});
|
|
45135
45168
|
};
|
|
45136
45169
|
|
|
45137
45170
|
const useOpenControllerByProps = (props, name) => {
|
|
@@ -46185,6 +46218,7 @@ const Expandable = props => {
|
|
|
46185
46218
|
// What opening LOOKS like here, and how to undo it — the one thing an
|
|
46186
46219
|
// expandable owns that a popup does not (see open_controller.js). Reassigned
|
|
46187
46220
|
// on every render so it always closes over the latest props.
|
|
46221
|
+
openController.getElement = () => rootRef.current;
|
|
46188
46222
|
openController.openEffect = openEvent => {
|
|
46189
46223
|
const contentContainer = contentContainerRef.current;
|
|
46190
46224
|
// `silent`: the expandable was already open when the page appeared
|
|
@@ -56483,8 +56517,11 @@ const getAvailableWidth = (layer, element) => {
|
|
|
56483
56517
|
* (a top-docked SidePanel: title and tabs at its top). So here the cut alone
|
|
56484
56518
|
* does the reveal — the same curtain descending from the container's top
|
|
56485
56519
|
* edge a full slide draws — while the box travels only `--popup-cover-travel`
|
|
56486
|
-
* (default
|
|
56487
|
-
*
|
|
56520
|
+
* (default 24px): the head is on screen from the first frame, settling its
|
|
56521
|
+
* last few pixels into place. A length, not a share of the panel: the travel
|
|
56522
|
+
* is a settle, the curtain is what reveals, and a share would grow with a
|
|
56523
|
+
* full-screen panel while its head does not — at 15% of 800px the head spent
|
|
56524
|
+
* the first 40% of the entrance above the cut. The exit is the same
|
|
56488
56525
|
* movement backwards and still reads as a slide, the head leading. One
|
|
56489
56526
|
* direction only: a bottom sheet leads with its head by itself, and a
|
|
56490
56527
|
* left/right panel keeps its head on the axis it does not travel.
|
|
@@ -56514,7 +56551,7 @@ const popupCss = /* css */ `
|
|
|
56514
56551
|
.navi_dialog {
|
|
56515
56552
|
--popup-animation-duration: 0.18s;
|
|
56516
56553
|
--popup-scale-from: 0.9;
|
|
56517
|
-
--popup-cover-travel:
|
|
56554
|
+
--popup-cover-travel: 24px;
|
|
56518
56555
|
|
|
56519
56556
|
--popup-opacity-duration: var(--popup-animation-duration);
|
|
56520
56557
|
--popup-translate-duration: var(--popup-animation-duration);
|
|
@@ -56695,7 +56732,7 @@ const popupCss = /* css */ `
|
|
|
56695
56732
|
|
|
56696
56733
|
/* cover — a top-docked popup unrolling from the top edge of its area (see
|
|
56697
56734
|
this file's top comment): the cut does the reveal, the box travels
|
|
56698
|
-
--popup-cover-travel
|
|
56735
|
+
--popup-cover-travel, a length. The far cut sits where the
|
|
56699
56736
|
popup's shadow ends (--navi-popup-box-shadow reaches about 50px) or
|
|
56700
56737
|
where the room does, whichever is nearer, so the reveal finishes on
|
|
56701
56738
|
the box and its shadow at the pace of the box's own settle. On the
|
|
@@ -58395,6 +58432,7 @@ const useDialogProps = props => {
|
|
|
58395
58432
|
// *when* this runs. openEffect runs outside of render (triggered by
|
|
58396
58433
|
// openController.open()), so it cannot call hooks — cleanup is a plain
|
|
58397
58434
|
// pub/sub.
|
|
58435
|
+
openController.getElement = () => ref.current;
|
|
58398
58436
|
openController.openEffect = e => {
|
|
58399
58437
|
const dialogEl = ref.current;
|
|
58400
58438
|
const backdropEl = backdropRef.current;
|
|
@@ -59852,6 +59890,7 @@ const usePopoverProps = props => {
|
|
|
59852
59890
|
// slower, flash-prone `toggle` event instead of the fast, pre-paint
|
|
59853
59891
|
// MutationObserver path.
|
|
59854
59892
|
|
|
59893
|
+
openController.getElement = () => ref.current;
|
|
59855
59894
|
openController.openEffect = e => {
|
|
59856
59895
|
const popoverEl = ref.current;
|
|
59857
59896
|
// backdropEl is null when pointerInteractionOutsideEffect is "none" —
|
|
@@ -61774,6 +61813,7 @@ const PickerCalloutPopup = ({
|
|
|
61774
61813
|
}
|
|
61775
61814
|
// Reassigned on every render, like Popover's own, so it closes over the
|
|
61776
61815
|
// latest props.
|
|
61816
|
+
openController.getElement = () => pickerRef.current;
|
|
61777
61817
|
openController.openEffect = openEvent => {
|
|
61778
61818
|
const pickerEl = pickerRef.current;
|
|
61779
61819
|
const calloutManager = getPickerInput(pickerEl).__uiStateController__.rules.callout;
|
|
@@ -81913,6 +81953,7 @@ const ANIMATION_BY_SIDE = {
|
|
|
81913
81953
|
};
|
|
81914
81954
|
const css = /* css */`.navi_side_panel {
|
|
81915
81955
|
--popup-border-radius: 0px;
|
|
81956
|
+
--popup-animation-duration: .3s;
|
|
81916
81957
|
width: var(--navi-side-panel-width, auto);
|
|
81917
81958
|
height: var(--navi-side-panel-height, auto);
|
|
81918
81959
|
|
|
@@ -82077,10 +82118,12 @@ const css = /* css */`.navi_side_panel {
|
|
|
82077
82118
|
* @param {boolean|"fading"} [props.animation] - Off by default (unlike
|
|
82078
82119
|
* `Dialog`/`Popover` themselves) — SidePanel is commonly toggled instead
|
|
82079
82120
|
* of opened/closed as a one-off, where a slide transition is more often
|
|
82080
|
-
* undesired noise than not. `true`
|
|
82081
|
-
* unrolls from its edge
|
|
82082
|
-
* `
|
|
82083
|
-
*
|
|
82121
|
+
* undesired noise than not. `true` plays the entrance of `side`:
|
|
82122
|
+
* `cover-from-top` for a top panel (it unrolls from its edge, head first),
|
|
82123
|
+
* `slide-from-<side>` for the three others — see `ANIMATION_BY_SIDE` for
|
|
82124
|
+
* why the top differs. `"fading"` is the other common choice. Other values
|
|
82125
|
+
* are forwarded as-is but not a documented/encouraged part of this
|
|
82126
|
+
* component's own API.
|
|
82084
82127
|
* @param {boolean} [props.closeOnClickOutside=false] - `false` (default):
|
|
82085
82128
|
* maps to `pointerInteractionOutsideEffect="none"` — in popover mode, no
|
|
82086
82129
|
* backdrop at all, outside clicks pass straight through; in dialog mode,
|