@jsenv/navi 0.17.0 → 0.17.2

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.
@@ -4858,6 +4858,15 @@ window.addEventListener("unhandledrejection", (event) => {
4858
4858
  }
4859
4859
  });
4860
4860
 
4861
+ const useCancelPrevious = () => {
4862
+ const cancellerRef = useRef();
4863
+ if (!cancellerRef.current) {
4864
+ cancellerRef.current = createRequestCanceller();
4865
+ }
4866
+ const canceller = cancellerRef.current;
4867
+ return canceller;
4868
+ };
4869
+
4861
4870
  /**
4862
4871
  * Merges a component's base className with className received from props.
4863
4872
  *
@@ -12083,11 +12092,10 @@ const renderActionableComponent = (props, {
12083
12092
  }) => {
12084
12093
  const {
12085
12094
  action,
12086
- liveAction,
12087
12095
  shortcuts
12088
12096
  } = props;
12089
12097
  const formContext = useContext(FormContext);
12090
- const hasActionProps = Boolean(action || liveAction || shortcuts && shortcuts.length > 0);
12098
+ const hasActionProps = Boolean(action || shortcuts && shortcuts.length > 0);
12091
12099
  const considerInsideForm = Boolean(formContext);
12092
12100
  if (hasActionProps && WithAction) {
12093
12101
  if (considerInsideForm && WithActionInsideForm) {
@@ -15575,29 +15583,67 @@ const MAX_CONSTRAINT = {
15575
15583
  const listenInputValue = (
15576
15584
  input,
15577
15585
  callback,
15578
- { waitForChange = false } = {},
15586
+ { waitForChange = false, debounce = 0 } = {},
15579
15587
  ) => {
15580
15588
  if (waitForChange) {
15581
15589
  return listenInputValueChange(input, callback);
15582
15590
  }
15583
15591
  const [teardown, addTeardown] = createPubSub();
15584
15592
  let currentValue = input.value;
15585
-
15586
15593
  let timeout;
15594
+ let debounceTimeout;
15595
+
15587
15596
  const onAsyncEvent = (e) => {
15588
15597
  timeout = setTimeout(() => {
15589
15598
  onEvent(e);
15590
15599
  }, 0);
15591
15600
  };
15592
- const onEvent = (e) => {
15593
- clearTimeout(timeout);
15594
- const value = input.value;
15595
- if (value === currentValue) {
15596
- return;
15597
- }
15598
- currentValue = value;
15599
- callback(e);
15600
- };
15601
+
15602
+ let onEvent;
15603
+ if (debounce) {
15604
+ onEvent = (e, { skipDebounce } = {}) => {
15605
+ clearTimeout(timeout);
15606
+ clearTimeout(debounceTimeout);
15607
+
15608
+ const value = input.value;
15609
+ if (value === currentValue) {
15610
+ return;
15611
+ }
15612
+
15613
+ if (skipDebounce) {
15614
+ currentValue = value;
15615
+ callback(e);
15616
+ } else {
15617
+ debounceTimeout = setTimeout(() => {
15618
+ currentValue = value;
15619
+ callback(e);
15620
+ }, debounce);
15621
+ }
15622
+ };
15623
+ // no need to wait for change events (blur, enter key)
15624
+ // we consider this as strong interactions requesting an immediate response
15625
+ const stop = listenInputValueChange(input, (e) => {
15626
+ onEvent(e, { skipDebounce: true });
15627
+ });
15628
+ addTeardown(() => {
15629
+ stop();
15630
+ });
15631
+ } else {
15632
+ onEvent = (e) => {
15633
+ clearTimeout(timeout);
15634
+ const value = input.value;
15635
+ if (value === currentValue) {
15636
+ return;
15637
+ }
15638
+ currentValue = value;
15639
+ callback(e);
15640
+ };
15641
+ // Autocomplete, programmatic changes, form restoration
15642
+ input.addEventListener("change", onEvent);
15643
+ addTeardown(() => {
15644
+ input.removeEventListener("change", onEvent);
15645
+ });
15646
+ }
15601
15647
 
15602
15648
  // Standard user input (typing)
15603
15649
  input.addEventListener("input", onEvent);
@@ -15605,12 +15651,6 @@ const listenInputValue = (
15605
15651
  input.removeEventListener("input", onEvent);
15606
15652
  });
15607
15653
 
15608
- // Autocomplete, programmatic changes, form restoration
15609
- input.addEventListener("change", onEvent);
15610
- addTeardown(() => {
15611
- input.removeEventListener("change", onEvent);
15612
- });
15613
-
15614
15654
  // Form reset - need to check the form
15615
15655
  const form = input.form;
15616
15656
  if (form) {
@@ -16417,6 +16457,7 @@ const installCustomConstraintValidation = (
16417
16457
  if (!elementWithAction) {
16418
16458
  break request_on_input_value_change;
16419
16459
  }
16460
+ const closestElementWithActionAttr = element.closest("[data-action]");
16420
16461
  const stop = listenInputValue(
16421
16462
  element,
16422
16463
  (e) => {
@@ -16426,7 +16467,16 @@ const installCustomConstraintValidation = (
16426
16467
  });
16427
16468
  },
16428
16469
  {
16429
- waitForChange: !element.closest("[data-live-action]"),
16470
+ waitForChange: closestElementWithActionAttr.hasAttribute(
16471
+ "data-action-after-change",
16472
+ ),
16473
+ debounce: closestElementWithActionAttr.hasAttribute(
16474
+ "data-action-debounce",
16475
+ )
16476
+ ? parseFloat(
16477
+ closestElementWithActionAttr.getAttribute("data-action-debounce"),
16478
+ )
16479
+ : undefined,
16430
16480
  },
16431
16481
  );
16432
16482
  addTeardown(() => {
@@ -18800,8 +18850,8 @@ const useUIStateController = (
18800
18850
  ) => {
18801
18851
  const parentUIStateController = useContext(ParentUIStateControllerContext);
18802
18852
  const formContext = useContext(FormContext);
18803
- const { id, name, onUIStateChange, action, liveAction } = props;
18804
- const uncontrolled = !formContext && !action && !liveAction;
18853
+ const { id, name, onUIStateChange, action } = props;
18854
+ const uncontrolled = !formContext && !action;
18805
18855
  const [navState, setNavState] = useNavState$1(id);
18806
18856
 
18807
18857
  const uiStateControllerRef = useRef();
@@ -22191,7 +22241,7 @@ installImportMetaCss(import.meta);import.meta.css = /* css */`
22191
22241
 
22192
22242
  position: relative;
22193
22243
  box-sizing: border-box;
22194
- width: 100%;
22244
+ width: fit-content;
22195
22245
  height: var(--height);
22196
22246
  margin: 2px;
22197
22247
  flex-direction: inherit;
@@ -22203,8 +22253,6 @@ installImportMetaCss(import.meta);import.meta.css = /* css */`
22203
22253
  outline-offset: 2px;
22204
22254
 
22205
22255
  .navi_native_input {
22206
- position: absolute;
22207
- inset: 0;
22208
22256
  margin: 0;
22209
22257
  opacity: 0;
22210
22258
  --webkit-appearance: none;
@@ -22510,6 +22558,8 @@ const InputRangeWithAction = props => {
22510
22558
  const uiState = useContext(UIStateContext);
22511
22559
  const {
22512
22560
  action,
22561
+ actionDebounce,
22562
+ actionAfterChange,
22513
22563
  loading,
22514
22564
  onCancel,
22515
22565
  onActionPrevented,
@@ -22564,6 +22614,8 @@ const InputRangeWithAction = props => {
22564
22614
  });
22565
22615
  return jsx(InputRangeBasic, {
22566
22616
  "data-action": boundAction.name,
22617
+ "data-action-debounce": actionDebounce,
22618
+ "data-action-after-change": actionAfterChange ? "" : undefined,
22567
22619
  ...rest,
22568
22620
  ref: ref,
22569
22621
  loading: loading || actionLoading
@@ -22971,7 +23023,8 @@ const InputTextualWithAction = props => {
22971
23023
  const uiState = useContext(UIStateContext);
22972
23024
  const {
22973
23025
  action,
22974
- liveAction,
23026
+ actionDebounce,
23027
+ actionAfterChange,
22975
23028
  loading,
22976
23029
  onCancel,
22977
23030
  onActionPrevented,
@@ -22985,7 +23038,7 @@ const InputTextualWithAction = props => {
22985
23038
  } = props;
22986
23039
  const defaultRef = useRef();
22987
23040
  const ref = props.ref || defaultRef;
22988
- const [boundAction] = useActionBoundToOneParam(liveAction || action, uiState);
23041
+ const [boundAction] = useActionBoundToOneParam(action, uiState);
22989
23042
  const {
22990
23043
  loading: actionLoading
22991
23044
  } = useActionStatus(boundAction);
@@ -23026,7 +23079,8 @@ const InputTextualWithAction = props => {
23026
23079
  });
23027
23080
  return jsx(InputTextualBasic, {
23028
23081
  "data-action": boundAction.name,
23029
- "data-live-action": liveAction ? "" : undefined,
23082
+ "data-action-debounce": actionDebounce,
23083
+ "data-action-after-change": actionAfterChange ? "" : undefined,
23030
23084
  ...rest,
23031
23085
  ref: ref,
23032
23086
  loading: loading || actionLoading
@@ -28865,5 +28919,5 @@ const UserSvg = () => jsx("svg", {
28865
28919
  })
28866
28920
  });
28867
28921
 
28868
- export { ActionRenderer, ActiveKeyboardShortcuts, Address, BadgeCount, Box, Button, ButtonCopyToClipboard, Caption, CheckSvg, Checkbox, CheckboxList, Code, Col, Colgroup, ConstructionSvg, Details, DialogLayout, Editable, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Form, Group, HeartSvg, HomeSvg, Icon, Image, Input, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, MessageBox, Paragraph, Radio, RadioList, Route, RouteLink, Routes, RowNumberCol, RowNumberTableCell, SINGLE_SPACE_CONSTRAINT, SVGMaskOverlay, SearchSvg, Select, SelectionContext, Separator, SettingsSvg, StarSvg, SummaryMarker, Svg, Tab, TabList, Table, TableCell, Tbody, Text, Thead, Title, Tr, UITransition, UserSvg, ViewportLayout, actionIntegratedVia, addCustomMessage, clearAllRoutes, compareTwoJsValues, createAction, createAvailableConstraint, createRequestCanceller, createSelectionKeyboardShortcuts, enableDebugActions, enableDebugOnDocumentLoading, forwardActionRequested, installCustomConstraintValidation, isCellSelected, isColumnSelected, isRowSelected, localStorageSignal, navBack, navForward, navTo, openCallout, rawUrlPart, reload, removeCustomMessage, requestAction, rerunActions, resource, setBaseUrl, setupRoutes, stateSignal, stopLoad, stringifyTableSelectionValue, updateActions, useActionData, useActionStatus, useArraySignalMembership, useCalloutClose, useCellsAndColumns, useConstraintValidityState, useDependenciesDiff, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useMatchingRouteInfo, useNavState$1 as useNavState, useRouteStatus, useRunOnMount, useSelectableElement, useSelectionController, useSignalSync, useStateArray, useTitleLevel, useUrlSearchParam, valueInLocalStorage };
28922
+ export { ActionRenderer, ActiveKeyboardShortcuts, Address, BadgeCount, Box, Button, ButtonCopyToClipboard, Caption, CheckSvg, Checkbox, CheckboxList, Code, Col, Colgroup, ConstructionSvg, Details, DialogLayout, Editable, ErrorBoundaryContext, ExclamationSvg, EyeClosedSvg, EyeSvg, Form, Group, HeartSvg, HomeSvg, Icon, Image, Input, Label, Link, LinkAnchorSvg, LinkBlankTargetSvg, MessageBox, Paragraph, Radio, RadioList, Route, RouteLink, Routes, RowNumberCol, RowNumberTableCell, SINGLE_SPACE_CONSTRAINT, SVGMaskOverlay, SearchSvg, Select, SelectionContext, Separator, SettingsSvg, StarSvg, SummaryMarker, Svg, Tab, TabList, Table, TableCell, Tbody, Text, Thead, Title, Tr, UITransition, UserSvg, ViewportLayout, actionIntegratedVia, addCustomMessage, clearAllRoutes, compareTwoJsValues, createAction, createAvailableConstraint, createRequestCanceller, createSelectionKeyboardShortcuts, enableDebugActions, enableDebugOnDocumentLoading, forwardActionRequested, installCustomConstraintValidation, isCellSelected, isColumnSelected, isRowSelected, localStorageSignal, navBack, navForward, navTo, openCallout, rawUrlPart, reload, removeCustomMessage, requestAction, rerunActions, resource, setBaseUrl, setupRoutes, stateSignal, stopLoad, stringifyTableSelectionValue, updateActions, useActionData, useActionStatus, useArraySignalMembership, useCalloutClose, useCancelPrevious, useCellsAndColumns, useConstraintValidityState, useDependenciesDiff, useDocumentResource, useDocumentState, useDocumentUrl, useEditionController, useFocusGroup, useKeyboardShortcuts, useMatchingRouteInfo, useNavState$1 as useNavState, useRouteStatus, useRunOnMount, useSelectableElement, useSelectionController, useSignalSync, useStateArray, useTitleLevel, useUrlSearchParam, valueInLocalStorage };
28869
28923
  //# sourceMappingURL=jsenv_navi.js.map