@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/dev/jsenv_navi.js
CHANGED
|
@@ -13987,7 +13987,7 @@ const CLICK_TO_EXPAND_SELECTOR = "summary, [aria-expanded]";
|
|
|
13987
13987
|
// A popup is written inside whatever opened it, but it is not part of it on
|
|
13988
13988
|
// screen: a control inside a popup must not be read as a click on the region
|
|
13989
13989
|
// the popup happens to be nested in.
|
|
13990
|
-
const POPUP_SELECTOR = "[navi-control='popover'], [navi-control='dialog']";
|
|
13990
|
+
const POPUP_SELECTOR$1 = "[navi-control='popover'], [navi-control='dialog']";
|
|
13991
13991
|
|
|
13992
13992
|
/**
|
|
13993
13993
|
* Cancels `event` when the control consumed a click that a surrounding
|
|
@@ -14025,7 +14025,7 @@ const findClickToExpandRegion = (element) => {
|
|
|
14025
14025
|
while (ancestor) {
|
|
14026
14026
|
// Tested first: a popup carries `aria-expanded` of its own, so it would
|
|
14027
14027
|
// otherwise pass for the region containing its own content.
|
|
14028
|
-
if (ancestor.matches(POPUP_SELECTOR)) {
|
|
14028
|
+
if (ancestor.matches(POPUP_SELECTOR$1)) {
|
|
14029
14029
|
return null;
|
|
14030
14030
|
}
|
|
14031
14031
|
if (ancestor.matches(CLICK_TO_EXPAND_SELECTOR)) {
|
|
@@ -33521,6 +33521,16 @@ const useActionAsyncData = (action, {
|
|
|
33521
33521
|
if (runningState === COMPLETED) {
|
|
33522
33522
|
return [action.dataSignal.peek(), false, undefined];
|
|
33523
33523
|
}
|
|
33524
|
+
// Called off (abort(), a route left with nothing else asking for it): nothing
|
|
33525
|
+
// is on its way until something runs it again. What it held stays drawn and
|
|
33526
|
+
// no wait is claimed. A delegated wait holding nothing has nothing to draw,
|
|
33527
|
+
// and suspends below until the next run.
|
|
33528
|
+
if (runningState === ABORTED) {
|
|
33529
|
+
const dataHeld = action.dataSignal.peek();
|
|
33530
|
+
if (dataHeld !== undefined || loadingEffect === "use") {
|
|
33531
|
+
return [dataHeld, false, undefined];
|
|
33532
|
+
}
|
|
33533
|
+
}
|
|
33524
33534
|
if (runningState === FAILED) {
|
|
33525
33535
|
if (prerun) {
|
|
33526
33536
|
// Neither shown nor reported from a head start: the failure is the
|
|
@@ -33596,8 +33606,7 @@ const useActionAsyncData = (action, {
|
|
|
33596
33606
|
|
|
33597
33607
|
// `loading: true` says the component draws its own wait, so this hook never
|
|
33598
33608
|
// suspends: running, or holding params nobody has started yet — a debounced
|
|
33599
|
-
// binding that just retargeted,
|
|
33600
|
-
// about to issue. Either way what is on screen is not the current answer,
|
|
33609
|
+
// binding that just retargeted, a run this very render is about to issue. Either way what is on screen is not the current answer,
|
|
33601
33610
|
// which is what `loading` says. Suspending would not draw a spinner: it swaps
|
|
33602
33611
|
// the subtree for the boundary, and everything under it remounts — a dialog
|
|
33603
33612
|
// open inside it is then closed, by a hook the caller told to stay out of it.
|
|
@@ -33605,7 +33614,8 @@ const useActionAsyncData = (action, {
|
|
|
33605
33614
|
return [action.dataSignal.peek(), true, undefined];
|
|
33606
33615
|
}
|
|
33607
33616
|
|
|
33608
|
-
// IDLE or
|
|
33617
|
+
// IDLE, RUNNING, or called off holding nothing, with loadingEffect:
|
|
33618
|
+
// "delegate" — suspend
|
|
33609
33619
|
const reason = runningState === RUNNING ? "loading" : "idle";
|
|
33610
33620
|
loadingRef.current = {
|
|
33611
33621
|
reason,
|
|
@@ -33627,7 +33637,7 @@ const useActionAsyncData = (action, {
|
|
|
33627
33637
|
} else if (reason === "loading" && state === ABORTED) {
|
|
33628
33638
|
// The run waited on was called off: drawn again, this reader asks
|
|
33629
33639
|
// for it again when nothing else will (calledOffBeforeThisReader),
|
|
33630
|
-
// or waits for the next run as idle.
|
|
33640
|
+
// draws what the instance held, or waits for the next run as idle.
|
|
33631
33641
|
actionPendingPromiseWeakMap.delete(action);
|
|
33632
33642
|
unsubscribe();
|
|
33633
33643
|
resolve();
|
|
@@ -45038,6 +45048,17 @@ const resolveClosestExpandable = (el) => {
|
|
|
45038
45048
|
}
|
|
45039
45049
|
return expandableRepeatedBy(expandable) || expandable;
|
|
45040
45050
|
};
|
|
45051
|
+
// The popup a decision taken inside it answers (a clear, a send). A section
|
|
45052
|
+
// revealed in the page flow (<Expandable>, data-in-flow) is not one: it belongs
|
|
45053
|
+
// to whatever holds it, a page or a popup, so the walk goes through it.
|
|
45054
|
+
const POPUP_SELECTOR = "[aria-expanded]:not([data-in-flow])";
|
|
45055
|
+
const resolveClosestPopup = (el) => {
|
|
45056
|
+
const popup = el.closest(POPUP_SELECTOR);
|
|
45057
|
+
if (!popup) {
|
|
45058
|
+
return null;
|
|
45059
|
+
}
|
|
45060
|
+
return expandableRepeatedBy(popup) || popup;
|
|
45061
|
+
};
|
|
45041
45062
|
// A control's host repeats the aria-expanded of its root, beside its role, for
|
|
45042
45063
|
// assistive tech to read (a picker's <input>, a combobox or a button). The root
|
|
45043
45064
|
// is the expandable: the host is a leaf the walk lands on only when it is the
|
|
@@ -45054,16 +45075,16 @@ const expandableRepeatedBy = (el) => {
|
|
|
45054
45075
|
}
|
|
45055
45076
|
return null;
|
|
45056
45077
|
};
|
|
45057
|
-
// The surface a send is decided on: the
|
|
45058
|
-
//
|
|
45059
|
-
//
|
|
45078
|
+
// The surface a send is decided on: the popup holding the CONTROL that sends,
|
|
45079
|
+
// never one that control is itself. A picker's own root carries aria-expanded
|
|
45080
|
+
// for its popup, and a confirm picker pressed as a whole (see
|
|
45060
45081
|
// picker_confirm.jsx) sends from its input: what it answers is the surface
|
|
45061
45082
|
// around the picker, not the picker. Same for a popup told to send upward
|
|
45062
45083
|
// once it has closed (data-after-send="--navi-send"): the surface above it.
|
|
45063
|
-
const
|
|
45084
|
+
const resolvePopupAround = (source) => {
|
|
45064
45085
|
const sender = findControlRoot(source) || source;
|
|
45065
45086
|
const parent = sender.parentElement;
|
|
45066
|
-
return parent ?
|
|
45087
|
+
return parent ? resolveClosestPopup(parent) : null;
|
|
45067
45088
|
};
|
|
45068
45089
|
// An element carrying navi-command-proxy-for="anchorId" stands in for that
|
|
45069
45090
|
// other element as the command's source when the source is forwarded to
|
|
@@ -45089,16 +45110,14 @@ const resolveClosestControlWithAction = (el) => {
|
|
|
45089
45110
|
return findClosestControlWithAction(el);
|
|
45090
45111
|
};
|
|
45091
45112
|
// Both can enclose the send's source: a form inside a dialog is a control with
|
|
45092
|
-
// an action, inside
|
|
45093
|
-
//
|
|
45094
|
-
//
|
|
45095
|
-
const resolveClosestSendTarget = (
|
|
45096
|
-
if (!
|
|
45097
|
-
return
|
|
45113
|
+
// an action, inside a popup. The nearer one owns the send — a button inside
|
|
45114
|
+
// that form means "submit this form", not "confirm the dialog around it", and
|
|
45115
|
+
// the same button placed directly in the dialog means the opposite.
|
|
45116
|
+
const resolveClosestSendTarget = (popup, controlWithAction) => {
|
|
45117
|
+
if (!popup || !controlWithAction) {
|
|
45118
|
+
return popup || controlWithAction;
|
|
45098
45119
|
}
|
|
45099
|
-
return
|
|
45100
|
-
? controlWithAction
|
|
45101
|
-
: expandable;
|
|
45120
|
+
return popup.contains(controlWithAction) ? controlWithAction : popup;
|
|
45102
45121
|
};
|
|
45103
45122
|
|
|
45104
45123
|
// An id that names something that is not a control — a layout box, a label, a
|
|
@@ -45300,9 +45319,10 @@ const clearCommand = (source, event) => {
|
|
|
45300
45319
|
}
|
|
45301
45320
|
// Only what is open: the clear cross of a picker sits on the closed
|
|
45302
45321
|
// trigger, with nothing to close. A clear pressed INSIDE an open popup is
|
|
45303
|
-
// the one this is for: it answers the popup, so the popup goes away.
|
|
45304
|
-
|
|
45305
|
-
|
|
45322
|
+
// the one this is for: it answers the popup, so the popup goes away. An
|
|
45323
|
+
// open section of the page is answered by nothing pressed in it.
|
|
45324
|
+
const popup = resolveClosestPopup(source);
|
|
45325
|
+
if (popup?.getAttribute("aria-expanded") !== "true") {
|
|
45306
45326
|
return;
|
|
45307
45327
|
}
|
|
45308
45328
|
// Asked of the popup itself, not resolved again from the source: a
|
|
@@ -45310,7 +45330,7 @@ const clearCommand = (source, event) => {
|
|
|
45310
45330
|
// picker names the input it empties), and a close resolved from it would
|
|
45311
45331
|
// aim at that input's picker — busy with the send it was just handed —
|
|
45312
45332
|
// rather than at the popup the cross is in.
|
|
45313
|
-
triggerNaviCommand(
|
|
45333
|
+
triggerNaviCommand(popup, "--navi-close", clearEvent, {
|
|
45314
45334
|
optional: true,
|
|
45315
45335
|
});
|
|
45316
45336
|
};
|
|
@@ -45354,7 +45374,8 @@ const resetCommand = (source, event) => {
|
|
|
45354
45374
|
* same act, a level down. A popup opened from another popup answers for
|
|
45355
45375
|
* itself only — say `data-after-send="--navi-send"` on the sending control
|
|
45356
45376
|
* to make the decision travel up to the surface holding it;
|
|
45357
|
-
* - the document: nothing. A form on a page stays where it is
|
|
45377
|
+
* - the document: nothing. A form on a page stays where it is, open
|
|
45378
|
+
* <Expandable> sections around it included (see resolveClosestPopup).
|
|
45358
45379
|
*/
|
|
45359
45380
|
// What follows a send that went through — and it is asked of the button that
|
|
45360
45381
|
// sent before the form it sent, because a form with two submit buttons has two
|
|
@@ -45385,7 +45406,7 @@ const resolveAfterSend = (target, requester, surface) => {
|
|
|
45385
45406
|
// the target: a popup that IS the send target is handled on its own (see the
|
|
45386
45407
|
// aria-expanded branch in sendCommand), and must not answer twice.
|
|
45387
45408
|
const resolveSendSurface = (target) =>
|
|
45388
|
-
target.parentElement?.closest(`[data-slide],
|
|
45409
|
+
target.parentElement?.closest(`[data-slide], ${POPUP_SELECTOR}`);
|
|
45389
45410
|
// What follows a send is caused by the send, not by the gesture: the send
|
|
45390
45411
|
// answered the gesture and may have prevented it (an Enter must not also click
|
|
45391
45412
|
// the submit button, nor activate the trigger of the popup it closed), and a
|
|
@@ -45398,11 +45419,10 @@ const createSentEvent = (event) => {
|
|
|
45398
45419
|
};
|
|
45399
45420
|
|
|
45400
45421
|
const sendCommand = (source, event, { requester }) => {
|
|
45401
|
-
const expandable = resolveExpandableAround(source);
|
|
45402
45422
|
const target =
|
|
45403
45423
|
resolveExplicitTarget(source) ||
|
|
45404
45424
|
resolveClosestSendTarget(
|
|
45405
|
-
|
|
45425
|
+
resolvePopupAround(source),
|
|
45406
45426
|
resolveClosestControlWithAction(source),
|
|
45407
45427
|
);
|
|
45408
45428
|
if (!target) {
|
|
@@ -45413,7 +45433,7 @@ const sendCommand = (source, event, { requester }) => {
|
|
|
45413
45433
|
// looking at, and a decision just taken there is a reason to leave it. The
|
|
45414
45434
|
// NEAREST surface answers, and only that one — a form inside a slide inside a
|
|
45415
45435
|
// dialog goes back a slide, it does not also close the dialog.
|
|
45416
|
-
// send inside
|
|
45436
|
+
// send inside popup — the control itself when it sends from its host,
|
|
45417
45437
|
// whose aria-expanded is its root's (see expandableRepeatedBy)
|
|
45418
45438
|
if (
|
|
45419
45439
|
target.getAttribute("aria-expanded") === "true" &&
|
|
@@ -63046,7 +63066,11 @@ const Expandable = props => {
|
|
|
63046
63066
|
return jsx(Box, {
|
|
63047
63067
|
ref: rootRef,
|
|
63048
63068
|
baseClassName: "navi_expandable",
|
|
63049
|
-
"aria-expanded": opened ? "true" : "false"
|
|
63069
|
+
"aria-expanded": opened ? "true" : "false"
|
|
63070
|
+
// Read by commands.js: open or not, this is no popup — a clear or a send
|
|
63071
|
+
// pressed inside does not close it (see resolveClosestPopup).
|
|
63072
|
+
,
|
|
63073
|
+
"data-in-flow": "",
|
|
63050
63074
|
"data-layout": isColumn ? "column" : undefined,
|
|
63051
63075
|
"data-open-direction": revealDirection,
|
|
63052
63076
|
"data-animation": animation ? "" : undefined,
|
|
@@ -63141,6 +63165,7 @@ const ExpandableUI = ({
|
|
|
63141
63165
|
role: "button",
|
|
63142
63166
|
tabIndex: 0,
|
|
63143
63167
|
"aria-expanded": opened,
|
|
63168
|
+
"data-in-flow": "",
|
|
63144
63169
|
"aria-controls": contentId,
|
|
63145
63170
|
onClick: onUIClick,
|
|
63146
63171
|
onPointerDown: onUIPointerDown,
|