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