@bpmn-io/properties-panel 3.40.4 → 3.40.5

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/index.js CHANGED
@@ -572,10 +572,10 @@ function useDescriptionContext(id, element) {
572
572
  function useDebounce(callback, debounceFn) {
573
573
  const debouncedCallback = hooks.useCallback(debounceFn(callback), [callback, debounceFn]);
574
574
 
575
- // make sure previous call is not stalled
575
+ // flush pending calls before unmount the debounced function
576
576
  hooks.useEffect(() => {
577
577
  return () => {
578
- debouncedCallback.cancel?.();
578
+ debouncedCallback.flush?.();
579
579
  };
580
580
  }, [debouncedCallback]);
581
581
  return debouncedCallback;
@@ -1992,6 +1992,7 @@ const FeelEditor = compat.forwardRef((props, ref) => {
1992
1992
  value,
1993
1993
  onInput,
1994
1994
  onKeyDown: onKeyDownProp = noop$4,
1995
+ onBlur = noop$4,
1995
1996
  onFeelToggle = noop$4,
1996
1997
  onLint = noop$4,
1997
1998
  onOpenPopup = noop$4,
@@ -2015,6 +2016,9 @@ const FeelEditor = compat.forwardRef((props, ref) => {
2015
2016
  onInput(newValue);
2016
2017
  setLocalValue(newValue);
2017
2018
  });
2019
+ const handleBlur = useStaticCallback(() => {
2020
+ onBlur();
2021
+ });
2018
2022
  hooks.useEffect(() => {
2019
2023
  let editor;
2020
2024
 
@@ -2047,7 +2051,9 @@ const FeelEditor = compat.forwardRef((props, ref) => {
2047
2051
  builtins,
2048
2052
  dialect,
2049
2053
  parserDialect,
2050
- extensions: [...(enableGutters ? [view.lineNumbers()] : []), view.EditorView.lineWrapping],
2054
+ extensions: [...(enableGutters ? [view.lineNumbers()] : []), view.EditorView.lineWrapping, view.EditorView.domEventHandlers({
2055
+ blur: handleBlur
2056
+ })],
2051
2057
  contentAttributes
2052
2058
  });
2053
2059
  setEditor(editor);
@@ -2516,19 +2522,23 @@ function FeelTextfield(props) {
2516
2522
  * @type { import('min-dash').DebouncedFunction }
2517
2523
  */
2518
2524
  const handleInput = useDebounce(onInput, debounce);
2525
+ const setAndCommitValue = newValue => {
2526
+ // cancel any pending debounced value
2527
+ handleInput.cancel?.();
2528
+ setLocalValue(newValue);
2529
+ onInput(newValue);
2530
+ };
2519
2531
  const handleFeelToggle = useStaticCallback(() => {
2520
2532
  if (feel === 'required') {
2521
2533
  return;
2522
2534
  }
2523
2535
  if (!feelActive) {
2524
- setLocalValue('=' + localValue);
2525
- handleInput('=' + localValue);
2536
+ setAndCommitValue('=' + localValue);
2526
2537
  } else {
2527
- setLocalValue(feelOnlyValue);
2528
- handleInput(feelOnlyValue);
2538
+ setAndCommitValue(feelOnlyValue);
2529
2539
  }
2530
2540
  });
2531
- const handleLocalInput = (newValue, useDebounce = true) => {
2541
+ const handleInputChange = newValue => {
2532
2542
  if (feelActive) {
2533
2543
  newValue = '=' + newValue;
2534
2544
  }
@@ -2536,28 +2546,32 @@ function FeelTextfield(props) {
2536
2546
  return;
2537
2547
  }
2538
2548
  setLocalValue(newValue);
2539
- if (useDebounce) {
2540
- handleInput(newValue);
2541
- } else {
2542
- onInput(newValue);
2543
- }
2549
+ handleInput(newValue);
2544
2550
  if (!feelActive && minDash.isString(newValue) && newValue.startsWith('=')) {
2545
2551
  // focus is behind `=` sign that will be removed
2546
2552
  setFocus(-1);
2547
2553
  }
2548
2554
  };
2549
- const handleOnBlur = e => {
2550
- handleInput.cancel?.();
2555
+ const handleOptionalInputOnBlur = e => {
2551
2556
  if (e.target.type === 'checkbox') {
2552
- onInput(e.target.checked);
2557
+ setAndCommitValue(e.target.checked);
2553
2558
  } else {
2554
2559
  const trimmedValue = e.target.value.trim();
2555
- handleLocalInput(trimmedValue, false);
2560
+ if (trimmedValue !== localValue) {
2561
+ // Trim changed the value — commit trimmed
2562
+ setAndCommitValue(trimmedValue);
2563
+ } else {
2564
+ // Value unchanged — flush any pending debounce
2565
+ handleInput.flush?.();
2566
+ }
2556
2567
  }
2557
2568
  if (onBlur) {
2558
2569
  onBlur(e);
2559
2570
  }
2560
2571
  };
2572
+ const handleFeelEditorOnBlur = () => {
2573
+ handleInput.flush?.();
2574
+ };
2561
2575
  const handleOnKeyDown = e => {
2562
2576
  if (isCmdWithChar(e)) {
2563
2577
  handleInput.flush?.();
@@ -2577,7 +2591,7 @@ function FeelTextfield(props) {
2577
2591
  entryId: id,
2578
2592
  hostLanguage,
2579
2593
  label,
2580
- onInput: handleLocalInput,
2594
+ onInput: handleInputChange,
2581
2595
  singleLine,
2582
2596
  sourceElement: editorRef.current,
2583
2597
  tooltipContainer,
@@ -2643,8 +2657,7 @@ function FeelTextfield(props) {
2643
2657
  if (isFieldEmpty || isAllSelected) {
2644
2658
  const textData = event.clipboardData.getData('text');
2645
2659
  const trimmedValue = textData.trim();
2646
- setLocalValue(trimmedValue);
2647
- handleInput(trimmedValue);
2660
+ setAndCommitValue(trimmedValue);
2648
2661
  if (!feelActive && minDash.isString(trimmedValue) && trimmedValue.startsWith('=')) {
2649
2662
  setFocus(trimmedValue.length - 1);
2650
2663
  }
@@ -2688,7 +2701,8 @@ function FeelTextfield(props) {
2688
2701
  onClick: handleFeelToggle
2689
2702
  }), feelActive ? jsxRuntime.jsx(FeelEditor, {
2690
2703
  name: id,
2691
- onInput: handleLocalInput,
2704
+ onInput: handleInputChange,
2705
+ onBlur: handleFeelEditorOnBlur,
2692
2706
  onKeyDown: handleOnKeyDown,
2693
2707
  contentAttributes: {
2694
2708
  'id': prefixId$5(id),
@@ -2711,9 +2725,9 @@ function FeelTextfield(props) {
2711
2725
  }) : jsxRuntime.jsx(OptionalComponent, {
2712
2726
  ...props,
2713
2727
  popupOpen: isPopupOpen,
2714
- onInput: handleLocalInput,
2728
+ onInput: handleInputChange,
2715
2729
  onKeyDown: handleOnKeyDown,
2716
- onBlur: handleOnBlur,
2730
+ onBlur: handleOptionalInputOnBlur,
2717
2731
  contentAttributes: {
2718
2732
  'id': prefixId$5(id),
2719
2733
  'aria-label': label