@jsenv/navi 0.29.463 → 0.29.464
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 +50 -39
- package/dist/dev/jsenv_navi.js.map +4 -4
- package/dist/jsenv_navi.js +50 -39
- package/dist/jsenv_navi.js.map +4 -4
- package/docs/navigation.md +24 -9
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -11409,6 +11409,8 @@ const keptNameWeakMap = new WeakMap();
|
|
|
11409
11409
|
const getRouteActionKeptName = (routeAction) => {
|
|
11410
11410
|
return keptNameWeakMap.get(routeAction);
|
|
11411
11411
|
};
|
|
11412
|
+
// Shared by every route action without a `when`.
|
|
11413
|
+
const NOT_GATED_SIGNAL = signal(false);
|
|
11412
11414
|
let activeRouteActionsPrevious = new Set();
|
|
11413
11415
|
/**
|
|
11414
11416
|
* The route actions asking something for the page on screen: their route
|
|
@@ -11435,19 +11437,17 @@ const activeRouteActionsSignal = computed(() => {
|
|
|
11435
11437
|
});
|
|
11436
11438
|
|
|
11437
11439
|
/**
|
|
11438
|
-
* Whether a route action of the page on screen
|
|
11439
|
-
* matches and its
|
|
11440
|
-
*
|
|
11441
|
-
*
|
|
11440
|
+
* Whether a route action of the page on screen waits for app state to ask: its
|
|
11441
|
+
* route matches and its `when` says no. Params that say no are not waiting:
|
|
11442
|
+
* they read the address, and this one asks nothing of the action — a later ask
|
|
11443
|
+
* is the page changing under the reader (a search typed), not arriving. Read
|
|
11444
|
+
* by the scroll restoration, which stays ready for it.
|
|
11442
11445
|
*
|
|
11443
11446
|
* @type {import("@preact/signals").ReadonlySignal<boolean>}
|
|
11444
11447
|
*/
|
|
11445
11448
|
const routeActionYetToAskSignal = computed(() => {
|
|
11446
|
-
for (const {
|
|
11447
|
-
|
|
11448
|
-
askingSignal,
|
|
11449
|
-
} of routeActionEntriesSignal.value) {
|
|
11450
|
-
if (routeMatchingSignal.value && !askingSignal.value) {
|
|
11449
|
+
for (const { gatedSignal } of routeActionEntriesSignal.value) {
|
|
11450
|
+
if (gatedSignal.value) {
|
|
11451
11451
|
return true;
|
|
11452
11452
|
}
|
|
11453
11453
|
}
|
|
@@ -11520,7 +11520,9 @@ const activeRouteReadsSignal = computed(() => {
|
|
|
11520
11520
|
* params when the condition holds at that moment — a page's code only some
|
|
11521
11521
|
* readers may download (`() => meIsAdminSignal.value`). A condition reading
|
|
11522
11522
|
* the address belongs in the params: a link reads `when` as it is, not as
|
|
11523
|
-
* the address it leads to will make it.
|
|
11523
|
+
* the address it leads to will make it. It is also what a reload's scroll
|
|
11524
|
+
* position waits for: the page is not whole while a `when` says no, whereas
|
|
11525
|
+
* params that say no ask nothing on this page (see scroll_restoration.js).
|
|
11524
11526
|
* @param {boolean} [options.prefetch=true] - `false` keeps the action from
|
|
11525
11527
|
* being prerun ahead of what asks for it, when the read is not worth a
|
|
11526
11528
|
* hover or a press that may not end in an opening.
|
|
@@ -11567,8 +11569,10 @@ const routeAction = (
|
|
|
11567
11569
|
...routeActionEntriesSignal.peek(),
|
|
11568
11570
|
{
|
|
11569
11571
|
routeAction: actionBoundToRoute,
|
|
11570
|
-
routeMatchingSignal,
|
|
11571
11572
|
askingSignal: computed(() => Boolean(readParamsAsked())),
|
|
11573
|
+
gatedSignal: when
|
|
11574
|
+
? computed(() => Boolean(routeMatchingSignal.value) && !when())
|
|
11575
|
+
: NOT_GATED_SIGNAL,
|
|
11572
11576
|
},
|
|
11573
11577
|
];
|
|
11574
11578
|
for (const route of routes) {
|
|
@@ -11726,8 +11730,8 @@ const haveSameMembers = (setA, setB) => {
|
|
|
11726
11730
|
* mount="after-paint">` is built before the offset that shows it is written
|
|
11727
11731
|
* (see mount_after_paint.jsx), and a reload or a return waits for the route
|
|
11728
11732
|
* actions the page has nothing to draw for — its code among them — including
|
|
11729
|
-
* one
|
|
11730
|
-
*
|
|
11733
|
+
* one whose `when` lets it ask after the position is written (see
|
|
11734
|
+
* stayForLateAsks). Anything else only the page knows, and it says so
|
|
11731
11735
|
* (useHoldScrollRestoration). A wait can be long, so the reader reaching for
|
|
11732
11736
|
* the page during it cancels the position: moved afterwards, they would lose
|
|
11733
11737
|
* whatever they had started on.
|
|
@@ -11932,7 +11936,7 @@ const holdScrollRestoration = () => {
|
|
|
11932
11936
|
* meantime (a finger, a click, a wheel, a key), or gone elsewhere.
|
|
11933
11937
|
*
|
|
11934
11938
|
* The page's route actions are waited for without this — its code, a read
|
|
11935
|
-
* with no answer yet, one
|
|
11939
|
+
* with no answer yet, one whose `when` holds later. This is for
|
|
11936
11940
|
* what navi cannot see: a read the page starts itself, content whose height
|
|
11937
11941
|
* arrives late.
|
|
11938
11942
|
*
|
|
@@ -12073,14 +12077,15 @@ const readUnansweredRouteActions = () => {
|
|
|
12073
12077
|
return unanswered;
|
|
12074
12078
|
};
|
|
12075
12079
|
|
|
12076
|
-
// A page can
|
|
12077
|
-
// app state not there yet (
|
|
12078
|
-
//
|
|
12079
|
-
//
|
|
12080
|
-
//
|
|
12081
|
-
//
|
|
12082
|
-
//
|
|
12083
|
-
// signal): it notices at its
|
|
12080
|
+
// A page can still be arriving after the position is written: an action whose
|
|
12081
|
+
// `when` waits for app state not there yet (see routeActionYetToAskSignal). So
|
|
12082
|
+
// a written position stays pending while one does: the next one that starts
|
|
12083
|
+
// without an answer is waited for like the first ones, and the position put
|
|
12084
|
+
// back once it is drawn. Params that say no are not waited for: the address
|
|
12085
|
+
// asks nothing of the action, and one that asks later — a search typed — is
|
|
12086
|
+
// the page moving on under the reader, not arriving. Not told when the
|
|
12087
|
+
// restoration is dropped (pendingRestoration is no signal): it notices at its
|
|
12088
|
+
// next run.
|
|
12084
12089
|
const stayForLateAsks = (restoration) => {
|
|
12085
12090
|
effect(function () {
|
|
12086
12091
|
let running = false;
|
|
@@ -82835,6 +82840,24 @@ const PickerButton = props => {
|
|
|
82835
82840
|
clearConfirm,
|
|
82836
82841
|
requestValue
|
|
82837
82842
|
};
|
|
82843
|
+
// `--navi-select`/`--navi-unselect` about one entry of the list the picker
|
|
82844
|
+
// holds — a chip on the façade, a suggestion beside the field. Answered here
|
|
82845
|
+
// rather than by the control drawing that list in the popup, even though rows
|
|
82846
|
+
// are what such a control owns: a picker given its own value builds its popup
|
|
82847
|
+
// only on first open (see popup_content_mount.js), so before that there is no
|
|
82848
|
+
// such control at all — and building the whole popup to have someone to talk
|
|
82849
|
+
// to, for a cross, is the wrong price. The picker holds the value in the first
|
|
82850
|
+
// place and hands it down whenever the popup is built.
|
|
82851
|
+
//
|
|
82852
|
+
// Heard on both elements, like every request a control answers: a chip inside
|
|
82853
|
+
// the picker aims at its root (the parent control), one standing elsewhere
|
|
82854
|
+
// names it with `commandFor`, and the picker's id is on its input.
|
|
82855
|
+
const onRequestSelect = e => {
|
|
82856
|
+
requestPickerListEntry(ref.current, inputRef.current, e, "select");
|
|
82857
|
+
};
|
|
82858
|
+
const onRequestUnselect = e => {
|
|
82859
|
+
requestPickerListEntry(ref.current, inputRef.current, e, "unselect");
|
|
82860
|
+
};
|
|
82838
82861
|
return (
|
|
82839
82862
|
/* Read-only crosses into everything the picker is made of: what it really
|
|
82840
82863
|
holds is drawn by controls of their own — in the popup, and on the façade
|
|
@@ -82895,23 +82918,9 @@ const PickerButton = props => {
|
|
|
82895
82918
|
,
|
|
82896
82919
|
onnavi_request_open: inputProps.onnavi_request_open,
|
|
82897
82920
|
onnavi_request_close: inputProps.onnavi_request_close,
|
|
82898
|
-
onnavi_open_press: inputProps.onnavi_open_press
|
|
82899
|
-
|
|
82900
|
-
|
|
82901
|
-
// Answered here rather than by the control drawing that list in the
|
|
82902
|
-
// popup, even though rows are what such a control owns: a picker given
|
|
82903
|
-
// its own value builds its popup only on first open (see
|
|
82904
|
-
// popup_content_mount.js), so before that there is no such control at
|
|
82905
|
-
// all — and building the whole popup to have someone to talk to, for a
|
|
82906
|
-
// cross, is the wrong price. The picker holds the value in the first
|
|
82907
|
-
// place and hands it down whenever the popup is built.
|
|
82908
|
-
,
|
|
82909
|
-
onnavi_request_select: e => {
|
|
82910
|
-
requestPickerListEntry(ref.current, inputRef.current, e, "select");
|
|
82911
|
-
},
|
|
82912
|
-
onnavi_request_unselect: e => {
|
|
82913
|
-
requestPickerListEntry(ref.current, inputRef.current, e, "unselect");
|
|
82914
|
-
},
|
|
82921
|
+
onnavi_open_press: inputProps.onnavi_open_press,
|
|
82922
|
+
onnavi_request_select: onRequestSelect,
|
|
82923
|
+
onnavi_request_unselect: onRequestUnselect,
|
|
82915
82924
|
children: [jsx("span", {
|
|
82916
82925
|
className: "navi_picker_box",
|
|
82917
82926
|
style: hangingChevronSize === undefined ? undefined : {
|
|
@@ -82933,6 +82942,8 @@ const PickerButton = props => {
|
|
|
82933
82942
|
children: undefined // we will render children into the div
|
|
82934
82943
|
,
|
|
82935
82944
|
ui: ui,
|
|
82945
|
+
onnavi_request_select: onRequestSelect,
|
|
82946
|
+
onnavi_request_unselect: onRequestUnselect,
|
|
82936
82947
|
onCopy: e => {
|
|
82937
82948
|
const pickerEl = ref.current;
|
|
82938
82949
|
if (isWithinPickerContent(e.target, pickerEl)) {
|