@jsenv/navi 0.29.490 → 0.29.491

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.
@@ -15059,11 +15059,19 @@ const addInputEffect = (
15059
15059
  (e) => {
15060
15060
  onEvent(e, { skipDebounce: true });
15061
15061
  },
15062
- { getState, changeOnEnter: true },
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 oninput = () => {
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 (changeOnEnter) {
15169
- onchange(e);
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
- callback(e);
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 — through the change Enter
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 own Enter still happens (a datalist
49843
- // choice) — except inside a <form>, where that Enter is the form's
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);