@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/jsenv_navi.js
CHANGED
|
@@ -15059,11 +15059,19 @@ const addInputEffect = (
|
|
|
15059
15059
|
(e) => {
|
|
15060
15060
|
onEvent(e, { skipDebounce: true });
|
|
15061
15061
|
},
|
|
15062
|
-
{ getState
|
|
15062
|
+
{ getState },
|
|
15063
15063
|
);
|
|
15064
15064
|
addTeardown(() => {
|
|
15065
15065
|
stop();
|
|
15066
15066
|
});
|
|
15067
|
+
// What the user gave up on (addInputCancel) does not go out later either.
|
|
15068
|
+
const oncancel = () => {
|
|
15069
|
+
clearTimeout(debounceTimeout);
|
|
15070
|
+
};
|
|
15071
|
+
input.addEventListener("navi_cancel", oncancel);
|
|
15072
|
+
addTeardown(() => {
|
|
15073
|
+
input.removeEventListener("navi_cancel", oncancel);
|
|
15074
|
+
});
|
|
15067
15075
|
} else {
|
|
15068
15076
|
onEvent = (e) => {
|
|
15069
15077
|
clearTimeout(timeout);
|
|
@@ -15146,36 +15154,38 @@ const addInputEffect = (
|
|
|
15146
15154
|
return teardown;
|
|
15147
15155
|
};
|
|
15148
15156
|
|
|
15149
|
-
const listenInputStateChange = (
|
|
15150
|
-
input,
|
|
15151
|
-
callback,
|
|
15152
|
-
{ getState, changeOnEnter },
|
|
15153
|
-
) => {
|
|
15157
|
+
const listenInputStateChange = (input, callback, { getState }) => {
|
|
15154
15158
|
const [teardown, addTeardown] = createPubSub();
|
|
15155
15159
|
|
|
15160
|
+
// Enter commits on its own keydown, not through the "change" the browser
|
|
15161
|
+
// fires after it: a field answering Enter for itself takes the key from its
|
|
15162
|
+
// <form> (keyDownDefaultOnInput in control_hooks.jsx), and the browser then
|
|
15163
|
+
// holds that "change" until the blur. Committed only when the user typed
|
|
15164
|
+
// since the last commit, which is when the browser would fire one.
|
|
15165
|
+
let typedSinceCommit = false;
|
|
15166
|
+
// A "change" carrying this value was answered by a key already: committed by
|
|
15167
|
+
// Enter, or given up by Escape.
|
|
15156
15168
|
let stateAtInteraction;
|
|
15157
|
-
const
|
|
15169
|
+
const commit = (e) => {
|
|
15170
|
+
typedSinceCommit = false;
|
|
15171
|
+
callback(e);
|
|
15172
|
+
};
|
|
15173
|
+
const oninput = (e) => {
|
|
15158
15174
|
stateAtInteraction = undefined;
|
|
15175
|
+
if (e.isTrusted) {
|
|
15176
|
+
typedSinceCommit = true;
|
|
15177
|
+
}
|
|
15159
15178
|
};
|
|
15160
15179
|
const onkeydown = (e) => {
|
|
15161
15180
|
if (e.key === "Enter") {
|
|
15162
|
-
/**
|
|
15163
|
-
* Browser trigger a "change" event right after the enter is pressed
|
|
15164
|
-
* if the input value has changed.
|
|
15165
|
-
* We need to prevent the next change event otherwise we would request action twice
|
|
15166
|
-
*/
|
|
15167
15181
|
stateAtInteraction = getState();
|
|
15168
|
-
if (
|
|
15169
|
-
|
|
15182
|
+
if (typedSinceCommit) {
|
|
15183
|
+
commit(e);
|
|
15170
15184
|
}
|
|
15185
|
+
return;
|
|
15171
15186
|
}
|
|
15172
15187
|
if (e.key === "Escape") {
|
|
15173
|
-
|
|
15174
|
-
* Browser trigger a "change" event right after the escape is pressed
|
|
15175
|
-
* if the input value has changed.
|
|
15176
|
-
* We need to prevent the next change event otherwise we would request action when
|
|
15177
|
-
* we actually want to cancel
|
|
15178
|
-
*/
|
|
15188
|
+
typedSinceCommit = false;
|
|
15179
15189
|
stateAtInteraction = getState();
|
|
15180
15190
|
}
|
|
15181
15191
|
};
|
|
@@ -15184,7 +15194,7 @@ const listenInputStateChange = (
|
|
|
15184
15194
|
stateAtInteraction = undefined;
|
|
15185
15195
|
return;
|
|
15186
15196
|
}
|
|
15187
|
-
|
|
15197
|
+
commit(e);
|
|
15188
15198
|
};
|
|
15189
15199
|
input.addEventListener("input", oninput);
|
|
15190
15200
|
// Capture: the guard is set before the control reacts to the key. Its
|
|
@@ -49830,26 +49840,22 @@ const useControlProps = (props, {
|
|
|
49830
49840
|
}
|
|
49831
49841
|
|
|
49832
49842
|
// A field with an action of its own has Enter answered already: the
|
|
49833
|
-
// input effect (input_effect.js) commits it
|
|
49834
|
-
// fires, or on the keydown itself under actionDebounce — and an action
|
|
49843
|
+
// input effect (input_effect.js) commits it on the keydown, and an action
|
|
49835
49844
|
// run on every keystroke has nothing left to commit. --navi-send would
|
|
49836
49845
|
// run that same action a second time. Nothing answers it under
|
|
49837
49846
|
// actionEvent="custom", where the field's caller does.
|
|
49838
49847
|
const enterAnsweredByInputEffect = Boolean(actionDebounce) || props.action !== undefined && actionEvent !== "custom";
|
|
49839
49848
|
const keyDownDefaultOnInput = e => {
|
|
49840
49849
|
if (e.key === "Enter") {
|
|
49841
|
-
if (props.enterSendsNothing) {
|
|
49842
|
-
// Left to the browser, so its
|
|
49843
|
-
//
|
|
49844
|
-
// implicit submission.
|
|
49850
|
+
if (props.enterSendsNothing || enterAnsweredByInputEffect) {
|
|
49851
|
+
// Nothing around the field hears it. Left to the browser, so its
|
|
49852
|
+
// own Enter still happens (a datalist choice) — except inside a
|
|
49853
|
+
// <form>, where that Enter is the form's implicit submission.
|
|
49845
49854
|
if (ref.current.form) {
|
|
49846
49855
|
e.preventDefault();
|
|
49847
49856
|
}
|
|
49848
49857
|
return null;
|
|
49849
49858
|
}
|
|
49850
|
-
if (enterAnsweredByInputEffect) {
|
|
49851
|
-
return null;
|
|
49852
|
-
}
|
|
49853
49859
|
return enterToSend(e);
|
|
49854
49860
|
}
|
|
49855
49861
|
return keyDownDefault(e);
|
|
@@ -78649,12 +78655,28 @@ const PickerCustom = props => {
|
|
|
78649
78655
|
// person's edit. Until they change something, what was there at open
|
|
78650
78656
|
// follows it: a look and a close then send nothing, and a cancel goes
|
|
78651
78657
|
// back to the record as it arrived.
|
|
78658
|
+
// A write the app makes in answer to the person — a seat chosen in a
|
|
78659
|
+
// sheet, a drag landed — arrives as the same event as that record, so
|
|
78660
|
+
// the event alone cannot end the following: a press or a key in the
|
|
78661
|
+
// picker does (its popup and the sheets opened from it stand in its
|
|
78662
|
+
// root). The press that opened it ended before these listeners.
|
|
78652
78663
|
let editedSinceOpen = false;
|
|
78664
|
+
let actedSinceOpen = false;
|
|
78665
|
+
const noteActed = () => {
|
|
78666
|
+
actedSinceOpen = true;
|
|
78667
|
+
};
|
|
78668
|
+
const pickerRoot = ref.current;
|
|
78669
|
+
pickerRoot.addEventListener("pointerdown", noteActed, {
|
|
78670
|
+
capture: true
|
|
78671
|
+
});
|
|
78672
|
+
pickerRoot.addEventListener("keydown", noteActed, {
|
|
78673
|
+
capture: true
|
|
78674
|
+
});
|
|
78653
78675
|
const followOutsideUntilEdited = e => {
|
|
78654
78676
|
if (editedSinceOpen) {
|
|
78655
78677
|
return;
|
|
78656
78678
|
}
|
|
78657
|
-
if (!isWrittenByTheOutside(e.detail.event)) {
|
|
78679
|
+
if (actedSinceOpen || !isWrittenByTheOutside(e.detail.event)) {
|
|
78658
78680
|
editedSinceOpen = true;
|
|
78659
78681
|
return;
|
|
78660
78682
|
}
|
|
@@ -78714,6 +78736,12 @@ const PickerCustom = props => {
|
|
|
78714
78736
|
},
|
|
78715
78737
|
onClose: closeEvent => {
|
|
78716
78738
|
pickerInput?.removeEventListener("navi_ui_state_change", followOutsideUntilEdited);
|
|
78739
|
+
pickerRoot.removeEventListener("pointerdown", noteActed, {
|
|
78740
|
+
capture: true
|
|
78741
|
+
});
|
|
78742
|
+
pickerRoot.removeEventListener("keydown", noteActed, {
|
|
78743
|
+
capture: true
|
|
78744
|
+
});
|
|
78717
78745
|
if (closeEvent.detail.isCancel) {
|
|
78718
78746
|
const pickerEl = ref.current;
|
|
78719
78747
|
const inputEl = getPickerInput(pickerEl);
|
|
@@ -79227,12 +79255,13 @@ const getTriggerLabelIds = pickerEl => {
|
|
|
79227
79255
|
}
|
|
79228
79256
|
return ids.length === 0 ? undefined : ids.join(" ");
|
|
79229
79257
|
};
|
|
79230
|
-
// What the picker
|
|
79231
|
-
// signal) moving, a default moving under it, and what its popup's controls
|
|
79232
|
-
// placed on as they mount. Read along the chain, never off the event alone:
|
|
79233
|
-
// control in the popup carries its change up to the picker as an event of its
|
|
79258
|
+
// What reaches the picker without a gesture of one of its controls: its `value`
|
|
79259
|
+
// (or signal) moving, a default moving under it, and what its popup's controls
|
|
79260
|
+
// are placed on as they mount. Read along the chain, never off the event alone:
|
|
79261
|
+
// a control in the popup carries its change up to the picker as an event of its
|
|
79234
79262
|
// own (see the facade in ui_state_controller.js), chained to what caused it —
|
|
79235
|
-
// an app writing that control's bound signal included.
|
|
79263
|
+
// an app writing that control's bound signal included. Whether that write
|
|
79264
|
+
// answers the person is not in the event (see actedSinceOpen).
|
|
79236
79265
|
const OUTSIDE_WRITE_TYPE_SET = new Set(["state_prop_change", "initial_state_push", "facade_child_mount_sync", "outside_value_follow"]);
|
|
79237
79266
|
const isWrittenByTheOutside = e => {
|
|
79238
79267
|
if (!e) {
|