@jsenv/navi 0.29.490 → 0.29.492
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 +65 -36
- package/dist/dev/jsenv_navi.js.map +4 -4
- package/dist/jsenv_navi.js +65 -36
- package/dist/jsenv_navi.js.map +4 -4
- package/docs/create_and_edit.md +5 -3
- package/docs/popup_open.md +4 -1
- package/package.json +1 -1
package/dist/dev/jsenv_navi.js
CHANGED
|
@@ -15804,11 +15804,19 @@ const addInputEffect = (
|
|
|
15804
15804
|
(e) => {
|
|
15805
15805
|
onEvent(e, { skipDebounce: true });
|
|
15806
15806
|
},
|
|
15807
|
-
{ getState
|
|
15807
|
+
{ getState },
|
|
15808
15808
|
);
|
|
15809
15809
|
addTeardown(() => {
|
|
15810
15810
|
stop();
|
|
15811
15811
|
});
|
|
15812
|
+
// What the user gave up on (addInputCancel) does not go out later either.
|
|
15813
|
+
const oncancel = () => {
|
|
15814
|
+
clearTimeout(debounceTimeout);
|
|
15815
|
+
};
|
|
15816
|
+
input.addEventListener("navi_cancel", oncancel);
|
|
15817
|
+
addTeardown(() => {
|
|
15818
|
+
input.removeEventListener("navi_cancel", oncancel);
|
|
15819
|
+
});
|
|
15812
15820
|
} else {
|
|
15813
15821
|
onEvent = (e) => {
|
|
15814
15822
|
clearTimeout(timeout);
|
|
@@ -15891,36 +15899,38 @@ const addInputEffect = (
|
|
|
15891
15899
|
return teardown;
|
|
15892
15900
|
};
|
|
15893
15901
|
|
|
15894
|
-
const listenInputStateChange = (
|
|
15895
|
-
input,
|
|
15896
|
-
callback,
|
|
15897
|
-
{ getState, changeOnEnter },
|
|
15898
|
-
) => {
|
|
15902
|
+
const listenInputStateChange = (input, callback, { getState }) => {
|
|
15899
15903
|
const [teardown, addTeardown] = createPubSub();
|
|
15900
15904
|
|
|
15905
|
+
// Enter commits on its own keydown, not through the "change" the browser
|
|
15906
|
+
// fires after it: a field answering Enter for itself takes the key from its
|
|
15907
|
+
// <form> (keyDownDefaultOnInput in control_hooks.jsx), and the browser then
|
|
15908
|
+
// holds that "change" until the blur. Committed only when the user typed
|
|
15909
|
+
// since the last commit, which is when the browser would fire one.
|
|
15910
|
+
let typedSinceCommit = false;
|
|
15911
|
+
// A "change" carrying this value was answered by a key already: committed by
|
|
15912
|
+
// Enter, or given up by Escape.
|
|
15901
15913
|
let stateAtInteraction;
|
|
15902
|
-
const
|
|
15914
|
+
const commit = (e) => {
|
|
15915
|
+
typedSinceCommit = false;
|
|
15916
|
+
callback(e);
|
|
15917
|
+
};
|
|
15918
|
+
const oninput = (e) => {
|
|
15903
15919
|
stateAtInteraction = undefined;
|
|
15920
|
+
if (e.isTrusted) {
|
|
15921
|
+
typedSinceCommit = true;
|
|
15922
|
+
}
|
|
15904
15923
|
};
|
|
15905
15924
|
const onkeydown = (e) => {
|
|
15906
15925
|
if (e.key === "Enter") {
|
|
15907
|
-
/**
|
|
15908
|
-
* Browser trigger a "change" event right after the enter is pressed
|
|
15909
|
-
* if the input value has changed.
|
|
15910
|
-
* We need to prevent the next change event otherwise we would request action twice
|
|
15911
|
-
*/
|
|
15912
15926
|
stateAtInteraction = getState();
|
|
15913
|
-
if (
|
|
15914
|
-
|
|
15927
|
+
if (typedSinceCommit) {
|
|
15928
|
+
commit(e);
|
|
15915
15929
|
}
|
|
15930
|
+
return;
|
|
15916
15931
|
}
|
|
15917
15932
|
if (e.key === "Escape") {
|
|
15918
|
-
|
|
15919
|
-
* Browser trigger a "change" event right after the escape is pressed
|
|
15920
|
-
* if the input value has changed.
|
|
15921
|
-
* We need to prevent the next change event otherwise we would request action when
|
|
15922
|
-
* we actually want to cancel
|
|
15923
|
-
*/
|
|
15933
|
+
typedSinceCommit = false;
|
|
15924
15934
|
stateAtInteraction = getState();
|
|
15925
15935
|
}
|
|
15926
15936
|
};
|
|
@@ -15929,7 +15939,7 @@ const listenInputStateChange = (
|
|
|
15929
15939
|
stateAtInteraction = undefined;
|
|
15930
15940
|
return;
|
|
15931
15941
|
}
|
|
15932
|
-
|
|
15942
|
+
commit(e);
|
|
15933
15943
|
};
|
|
15934
15944
|
input.addEventListener("input", oninput);
|
|
15935
15945
|
// Capture: the guard is set before the control reacts to the key. Its
|
|
@@ -51342,26 +51352,22 @@ const useControlProps = (props, {
|
|
|
51342
51352
|
}
|
|
51343
51353
|
|
|
51344
51354
|
// A field with an action of its own has Enter answered already: the
|
|
51345
|
-
// input effect (input_effect.js) commits it
|
|
51346
|
-
// fires, or on the keydown itself under actionDebounce — and an action
|
|
51355
|
+
// input effect (input_effect.js) commits it on the keydown, and an action
|
|
51347
51356
|
// run on every keystroke has nothing left to commit. --navi-send would
|
|
51348
51357
|
// run that same action a second time. Nothing answers it under
|
|
51349
51358
|
// actionEvent="custom", where the field's caller does.
|
|
51350
51359
|
const enterAnsweredByInputEffect = Boolean(actionDebounce) || props.action !== undefined && actionEvent !== "custom";
|
|
51351
51360
|
const keyDownDefaultOnInput = e => {
|
|
51352
51361
|
if (e.key === "Enter") {
|
|
51353
|
-
if (props.enterSendsNothing) {
|
|
51354
|
-
// Left to the browser, so its
|
|
51355
|
-
//
|
|
51356
|
-
// implicit submission.
|
|
51362
|
+
if (props.enterSendsNothing || enterAnsweredByInputEffect) {
|
|
51363
|
+
// Nothing around the field hears it. Left to the browser, so its
|
|
51364
|
+
// own Enter still happens (a datalist choice) — except inside a
|
|
51365
|
+
// <form>, where that Enter is the form's implicit submission.
|
|
51357
51366
|
if (ref.current.form) {
|
|
51358
51367
|
e.preventDefault();
|
|
51359
51368
|
}
|
|
51360
51369
|
return null;
|
|
51361
51370
|
}
|
|
51362
|
-
if (enterAnsweredByInputEffect) {
|
|
51363
|
-
return null;
|
|
51364
|
-
}
|
|
51365
51371
|
return enterToSend(e);
|
|
51366
51372
|
}
|
|
51367
51373
|
return keyDownDefault(e);
|
|
@@ -80425,12 +80431,28 @@ const PickerCustom = props => {
|
|
|
80425
80431
|
// person's edit. Until they change something, what was there at open
|
|
80426
80432
|
// follows it: a look and a close then send nothing, and a cancel goes
|
|
80427
80433
|
// back to the record as it arrived.
|
|
80434
|
+
// A write the app makes in answer to the person — a seat chosen in a
|
|
80435
|
+
// sheet, a drag landed — arrives as the same event as that record, so
|
|
80436
|
+
// the event alone cannot end the following: a press or a key in the
|
|
80437
|
+
// picker does (its popup and the sheets opened from it stand in its
|
|
80438
|
+
// root). The press that opened it ended before these listeners.
|
|
80428
80439
|
let editedSinceOpen = false;
|
|
80440
|
+
let actedSinceOpen = false;
|
|
80441
|
+
const noteActed = () => {
|
|
80442
|
+
actedSinceOpen = true;
|
|
80443
|
+
};
|
|
80444
|
+
const pickerRoot = ref.current;
|
|
80445
|
+
pickerRoot.addEventListener("pointerdown", noteActed, {
|
|
80446
|
+
capture: true
|
|
80447
|
+
});
|
|
80448
|
+
pickerRoot.addEventListener("keydown", noteActed, {
|
|
80449
|
+
capture: true
|
|
80450
|
+
});
|
|
80429
80451
|
const followOutsideUntilEdited = e => {
|
|
80430
80452
|
if (editedSinceOpen) {
|
|
80431
80453
|
return;
|
|
80432
80454
|
}
|
|
80433
|
-
if (!isWrittenByTheOutside(e.detail.event)) {
|
|
80455
|
+
if (actedSinceOpen || !isWrittenByTheOutside(e.detail.event)) {
|
|
80434
80456
|
editedSinceOpen = true;
|
|
80435
80457
|
return;
|
|
80436
80458
|
}
|
|
@@ -80491,6 +80513,12 @@ const PickerCustom = props => {
|
|
|
80491
80513
|
},
|
|
80492
80514
|
onClose: closeEvent => {
|
|
80493
80515
|
pickerInput?.removeEventListener("navi_ui_state_change", followOutsideUntilEdited);
|
|
80516
|
+
pickerRoot.removeEventListener("pointerdown", noteActed, {
|
|
80517
|
+
capture: true
|
|
80518
|
+
});
|
|
80519
|
+
pickerRoot.removeEventListener("keydown", noteActed, {
|
|
80520
|
+
capture: true
|
|
80521
|
+
});
|
|
80494
80522
|
if (closeEvent.detail.isCancel) {
|
|
80495
80523
|
const pickerEl = ref.current;
|
|
80496
80524
|
const inputEl = getPickerInput(pickerEl);
|
|
@@ -81016,12 +81044,13 @@ const getTriggerLabelIds = pickerEl => {
|
|
|
81016
81044
|
}
|
|
81017
81045
|
return ids.length === 0 ? undefined : ids.join(" ");
|
|
81018
81046
|
};
|
|
81019
|
-
// What the picker
|
|
81020
|
-
// signal) moving, a default moving under it, and what its popup's controls
|
|
81021
|
-
// placed on as they mount. Read along the chain, never off the event alone:
|
|
81022
|
-
// control in the popup carries its change up to the picker as an event of its
|
|
81047
|
+
// What reaches the picker without a gesture of one of its controls: its `value`
|
|
81048
|
+
// (or signal) moving, a default moving under it, and what its popup's controls
|
|
81049
|
+
// are placed on as they mount. Read along the chain, never off the event alone:
|
|
81050
|
+
// a control in the popup carries its change up to the picker as an event of its
|
|
81023
81051
|
// own (see the facade in ui_state_controller.js), chained to what caused it —
|
|
81024
|
-
// an app writing that control's bound signal included.
|
|
81052
|
+
// an app writing that control's bound signal included. Whether that write
|
|
81053
|
+
// answers the person is not in the event (see actedSinceOpen).
|
|
81025
81054
|
const OUTSIDE_WRITE_TYPE_SET = new Set(["state_prop_change", "initial_state_push", "facade_child_mount_sync", "outside_value_follow"]);
|
|
81026
81055
|
const isWrittenByTheOutside = e => {
|
|
81027
81056
|
if (!e) {
|