@jsenv/navi 0.30.27 → 0.30.29
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 +55 -30
- package/dist/dev/jsenv_navi.js.map +5 -4
- package/dist/jsenv_navi.js +55 -30
- package/dist/jsenv_navi.js.map +5 -4
- package/docs/data_states.md +4 -2
- package/package.json +1 -1
package/dist/jsenv_navi.js
CHANGED
|
@@ -13490,7 +13490,7 @@ const CLICK_TO_EXPAND_SELECTOR = "summary, [aria-expanded]";
|
|
|
13490
13490
|
// A popup is written inside whatever opened it, but it is not part of it on
|
|
13491
13491
|
// screen: a control inside a popup must not be read as a click on the region
|
|
13492
13492
|
// the popup happens to be nested in.
|
|
13493
|
-
const POPUP_SELECTOR = "[navi-control='popover'], [navi-control='dialog']";
|
|
13493
|
+
const POPUP_SELECTOR$1 = "[navi-control='popover'], [navi-control='dialog']";
|
|
13494
13494
|
|
|
13495
13495
|
/**
|
|
13496
13496
|
* Cancels `event` when the control consumed a click that a surrounding
|
|
@@ -13528,7 +13528,7 @@ const findClickToExpandRegion = (element) => {
|
|
|
13528
13528
|
while (ancestor) {
|
|
13529
13529
|
// Tested first: a popup carries `aria-expanded` of its own, so it would
|
|
13530
13530
|
// otherwise pass for the region containing its own content.
|
|
13531
|
-
if (ancestor.matches(POPUP_SELECTOR)) {
|
|
13531
|
+
if (ancestor.matches(POPUP_SELECTOR$1)) {
|
|
13532
13532
|
return null;
|
|
13533
13533
|
}
|
|
13534
13534
|
if (ancestor.matches(CLICK_TO_EXPAND_SELECTOR)) {
|
|
@@ -32391,6 +32391,16 @@ const useActionAsyncData = (action, {
|
|
|
32391
32391
|
if (runningState === COMPLETED) {
|
|
32392
32392
|
return [action.dataSignal.peek(), false, undefined];
|
|
32393
32393
|
}
|
|
32394
|
+
// Called off (abort(), a route left with nothing else asking for it): nothing
|
|
32395
|
+
// is on its way until something runs it again. What it held stays drawn and
|
|
32396
|
+
// no wait is claimed. A delegated wait holding nothing has nothing to draw,
|
|
32397
|
+
// and suspends below until the next run.
|
|
32398
|
+
if (runningState === ABORTED) {
|
|
32399
|
+
const dataHeld = action.dataSignal.peek();
|
|
32400
|
+
if (dataHeld !== undefined || loadingEffect === "use") {
|
|
32401
|
+
return [dataHeld, false, undefined];
|
|
32402
|
+
}
|
|
32403
|
+
}
|
|
32394
32404
|
if (runningState === FAILED) {
|
|
32395
32405
|
if (prerun) {
|
|
32396
32406
|
// Neither shown nor reported from a head start: the failure is the
|
|
@@ -32466,8 +32476,7 @@ const useActionAsyncData = (action, {
|
|
|
32466
32476
|
|
|
32467
32477
|
// `loading: true` says the component draws its own wait, so this hook never
|
|
32468
32478
|
// suspends: running, or holding params nobody has started yet — a debounced
|
|
32469
|
-
// binding that just retargeted,
|
|
32470
|
-
// about to issue. Either way what is on screen is not the current answer,
|
|
32479
|
+
// binding that just retargeted, a run this very render is about to issue. Either way what is on screen is not the current answer,
|
|
32471
32480
|
// which is what `loading` says. Suspending would not draw a spinner: it swaps
|
|
32472
32481
|
// the subtree for the boundary, and everything under it remounts — a dialog
|
|
32473
32482
|
// open inside it is then closed, by a hook the caller told to stay out of it.
|
|
@@ -32475,7 +32484,8 @@ const useActionAsyncData = (action, {
|
|
|
32475
32484
|
return [action.dataSignal.peek(), true, undefined];
|
|
32476
32485
|
}
|
|
32477
32486
|
|
|
32478
|
-
// IDLE or
|
|
32487
|
+
// IDLE, RUNNING, or called off holding nothing, with loadingEffect:
|
|
32488
|
+
// "delegate" — suspend
|
|
32479
32489
|
const reason = runningState === RUNNING ? "loading" : "idle";
|
|
32480
32490
|
loadingRef.current = {
|
|
32481
32491
|
reason,
|
|
@@ -32497,7 +32507,7 @@ const useActionAsyncData = (action, {
|
|
|
32497
32507
|
} else if (reason === "loading" && state === ABORTED) {
|
|
32498
32508
|
// The run waited on was called off: drawn again, this reader asks
|
|
32499
32509
|
// for it again when nothing else will (calledOffBeforeThisReader),
|
|
32500
|
-
// or waits for the next run as idle.
|
|
32510
|
+
// draws what the instance held, or waits for the next run as idle.
|
|
32501
32511
|
actionPendingPromiseWeakMap.delete(action);
|
|
32502
32512
|
unsubscribe();
|
|
32503
32513
|
resolve();
|
|
@@ -43703,6 +43713,17 @@ const resolveClosestExpandable = (el) => {
|
|
|
43703
43713
|
}
|
|
43704
43714
|
return expandableRepeatedBy(expandable) || expandable;
|
|
43705
43715
|
};
|
|
43716
|
+
// The popup a decision taken inside it answers (a clear, a send). A section
|
|
43717
|
+
// revealed in the page flow (<Expandable>, data-in-flow) is not one: it belongs
|
|
43718
|
+
// to whatever holds it, a page or a popup, so the walk goes through it.
|
|
43719
|
+
const POPUP_SELECTOR = "[aria-expanded]:not([data-in-flow])";
|
|
43720
|
+
const resolveClosestPopup = (el) => {
|
|
43721
|
+
const popup = el.closest(POPUP_SELECTOR);
|
|
43722
|
+
if (!popup) {
|
|
43723
|
+
return null;
|
|
43724
|
+
}
|
|
43725
|
+
return expandableRepeatedBy(popup) || popup;
|
|
43726
|
+
};
|
|
43706
43727
|
// A control's host repeats the aria-expanded of its root, beside its role, for
|
|
43707
43728
|
// assistive tech to read (a picker's <input>, a combobox or a button). The root
|
|
43708
43729
|
// is the expandable: the host is a leaf the walk lands on only when it is the
|
|
@@ -43719,16 +43740,16 @@ const expandableRepeatedBy = (el) => {
|
|
|
43719
43740
|
}
|
|
43720
43741
|
return null;
|
|
43721
43742
|
};
|
|
43722
|
-
// The surface a send is decided on: the
|
|
43723
|
-
//
|
|
43724
|
-
//
|
|
43743
|
+
// The surface a send is decided on: the popup holding the CONTROL that sends,
|
|
43744
|
+
// never one that control is itself. A picker's own root carries aria-expanded
|
|
43745
|
+
// for its popup, and a confirm picker pressed as a whole (see
|
|
43725
43746
|
// picker_confirm.jsx) sends from its input: what it answers is the surface
|
|
43726
43747
|
// around the picker, not the picker. Same for a popup told to send upward
|
|
43727
43748
|
// once it has closed (data-after-send="--navi-send"): the surface above it.
|
|
43728
|
-
const
|
|
43749
|
+
const resolvePopupAround = (source) => {
|
|
43729
43750
|
const sender = findControlRoot(source) || source;
|
|
43730
43751
|
const parent = sender.parentElement;
|
|
43731
|
-
return parent ?
|
|
43752
|
+
return parent ? resolveClosestPopup(parent) : null;
|
|
43732
43753
|
};
|
|
43733
43754
|
// An element carrying navi-command-proxy-for="anchorId" stands in for that
|
|
43734
43755
|
// other element as the command's source when the source is forwarded to
|
|
@@ -43754,16 +43775,14 @@ const resolveClosestControlWithAction = (el) => {
|
|
|
43754
43775
|
return findClosestControlWithAction(el);
|
|
43755
43776
|
};
|
|
43756
43777
|
// Both can enclose the send's source: a form inside a dialog is a control with
|
|
43757
|
-
// an action, inside
|
|
43758
|
-
//
|
|
43759
|
-
//
|
|
43760
|
-
const resolveClosestSendTarget = (
|
|
43761
|
-
if (!
|
|
43762
|
-
return
|
|
43778
|
+
// an action, inside a popup. The nearer one owns the send — a button inside
|
|
43779
|
+
// that form means "submit this form", not "confirm the dialog around it", and
|
|
43780
|
+
// the same button placed directly in the dialog means the opposite.
|
|
43781
|
+
const resolveClosestSendTarget = (popup, controlWithAction) => {
|
|
43782
|
+
if (!popup || !controlWithAction) {
|
|
43783
|
+
return popup || controlWithAction;
|
|
43763
43784
|
}
|
|
43764
|
-
return
|
|
43765
|
-
? controlWithAction
|
|
43766
|
-
: expandable;
|
|
43785
|
+
return popup.contains(controlWithAction) ? controlWithAction : popup;
|
|
43767
43786
|
};
|
|
43768
43787
|
|
|
43769
43788
|
const resolveCommandValue = (source, event) => {
|
|
@@ -43949,9 +43968,10 @@ const clearCommand = (source, event) => {
|
|
|
43949
43968
|
}
|
|
43950
43969
|
// Only what is open: the clear cross of a picker sits on the closed
|
|
43951
43970
|
// trigger, with nothing to close. A clear pressed INSIDE an open popup is
|
|
43952
|
-
// the one this is for: it answers the popup, so the popup goes away.
|
|
43953
|
-
|
|
43954
|
-
|
|
43971
|
+
// the one this is for: it answers the popup, so the popup goes away. An
|
|
43972
|
+
// open section of the page is answered by nothing pressed in it.
|
|
43973
|
+
const popup = resolveClosestPopup(source);
|
|
43974
|
+
if (popup?.getAttribute("aria-expanded") !== "true") {
|
|
43955
43975
|
return;
|
|
43956
43976
|
}
|
|
43957
43977
|
// Asked of the popup itself, not resolved again from the source: a
|
|
@@ -43959,7 +43979,7 @@ const clearCommand = (source, event) => {
|
|
|
43959
43979
|
// picker names the input it empties), and a close resolved from it would
|
|
43960
43980
|
// aim at that input's picker — busy with the send it was just handed —
|
|
43961
43981
|
// rather than at the popup the cross is in.
|
|
43962
|
-
triggerNaviCommand(
|
|
43982
|
+
triggerNaviCommand(popup, "--navi-close", clearEvent, {
|
|
43963
43983
|
optional: true,
|
|
43964
43984
|
});
|
|
43965
43985
|
};
|
|
@@ -44003,7 +44023,8 @@ const resetCommand = (source, event) => {
|
|
|
44003
44023
|
* same act, a level down. A popup opened from another popup answers for
|
|
44004
44024
|
* itself only — say `data-after-send="--navi-send"` on the sending control
|
|
44005
44025
|
* to make the decision travel up to the surface holding it;
|
|
44006
|
-
* - the document: nothing. A form on a page stays where it is
|
|
44026
|
+
* - the document: nothing. A form on a page stays where it is, open
|
|
44027
|
+
* <Expandable> sections around it included (see resolveClosestPopup).
|
|
44007
44028
|
*/
|
|
44008
44029
|
// What follows a send that went through — and it is asked of the button that
|
|
44009
44030
|
// sent before the form it sent, because a form with two submit buttons has two
|
|
@@ -44034,7 +44055,7 @@ const resolveAfterSend = (target, requester, surface) => {
|
|
|
44034
44055
|
// the target: a popup that IS the send target is handled on its own (see the
|
|
44035
44056
|
// aria-expanded branch in sendCommand), and must not answer twice.
|
|
44036
44057
|
const resolveSendSurface = (target) =>
|
|
44037
|
-
target.parentElement?.closest(`[data-slide],
|
|
44058
|
+
target.parentElement?.closest(`[data-slide], ${POPUP_SELECTOR}`);
|
|
44038
44059
|
// What follows a send is caused by the send, not by the gesture: the send
|
|
44039
44060
|
// answered the gesture and may have prevented it (an Enter must not also click
|
|
44040
44061
|
// the submit button, nor activate the trigger of the popup it closed), and a
|
|
@@ -44047,11 +44068,10 @@ const createSentEvent = (event) => {
|
|
|
44047
44068
|
};
|
|
44048
44069
|
|
|
44049
44070
|
const sendCommand = (source, event, { requester }) => {
|
|
44050
|
-
const expandable = resolveExpandableAround(source);
|
|
44051
44071
|
const target =
|
|
44052
44072
|
resolveExplicitTarget(source) ||
|
|
44053
44073
|
resolveClosestSendTarget(
|
|
44054
|
-
|
|
44074
|
+
resolvePopupAround(source),
|
|
44055
44075
|
resolveClosestControlWithAction(source),
|
|
44056
44076
|
);
|
|
44057
44077
|
if (!target) {
|
|
@@ -44062,7 +44082,7 @@ const sendCommand = (source, event, { requester }) => {
|
|
|
44062
44082
|
// looking at, and a decision just taken there is a reason to leave it. The
|
|
44063
44083
|
// NEAREST surface answers, and only that one — a form inside a slide inside a
|
|
44064
44084
|
// dialog goes back a slide, it does not also close the dialog.
|
|
44065
|
-
// send inside
|
|
44085
|
+
// send inside popup — the control itself when it sends from its host,
|
|
44066
44086
|
// whose aria-expanded is its root's (see expandableRepeatedBy)
|
|
44067
44087
|
if (
|
|
44068
44088
|
target.getAttribute("aria-expanded") === "true" &&
|
|
@@ -61491,7 +61511,11 @@ const Expandable = props => {
|
|
|
61491
61511
|
return jsx(Box, {
|
|
61492
61512
|
ref: rootRef,
|
|
61493
61513
|
baseClassName: "navi_expandable",
|
|
61494
|
-
"aria-expanded": opened ? "true" : "false"
|
|
61514
|
+
"aria-expanded": opened ? "true" : "false"
|
|
61515
|
+
// Read by commands.js: open or not, this is no popup — a clear or a send
|
|
61516
|
+
// pressed inside does not close it (see resolveClosestPopup).
|
|
61517
|
+
,
|
|
61518
|
+
"data-in-flow": "",
|
|
61495
61519
|
"data-layout": isColumn ? "column" : undefined,
|
|
61496
61520
|
"data-open-direction": revealDirection,
|
|
61497
61521
|
"data-animation": animation ? "" : undefined,
|
|
@@ -61586,6 +61610,7 @@ const ExpandableUI = ({
|
|
|
61586
61610
|
role: "button",
|
|
61587
61611
|
tabIndex: 0,
|
|
61588
61612
|
"aria-expanded": opened,
|
|
61613
|
+
"data-in-flow": "",
|
|
61589
61614
|
"aria-controls": contentId,
|
|
61590
61615
|
onClick: onUIClick,
|
|
61591
61616
|
onPointerDown: onUIPointerDown,
|