@bpmn-io/properties-panel 3.40.4 → 3.40.6

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
 
@@ -2041,13 +2045,16 @@ const FeelEditor = compat.forwardRef((props, ref) => {
2041
2045
  onKeyDown: onKeyDown,
2042
2046
  onLint: onLint,
2043
2047
  placeholder: placeholder,
2048
+ readOnly: disabled,
2044
2049
  tooltipContainer: tooltipContainer,
2045
2050
  value: localValue,
2046
2051
  variables,
2047
2052
  builtins,
2048
2053
  dialect,
2049
2054
  parserDialect,
2050
- extensions: [...(enableGutters ? [view.lineNumbers()] : []), view.EditorView.lineWrapping],
2055
+ extensions: [...(enableGutters ? [view.lineNumbers()] : []), view.EditorView.lineWrapping, view.EditorView.domEventHandlers({
2056
+ blur: handleBlur
2057
+ })],
2051
2058
  contentAttributes
2052
2059
  });
2053
2060
  setEditor(editor);
@@ -2516,19 +2523,23 @@ function FeelTextfield(props) {
2516
2523
  * @type { import('min-dash').DebouncedFunction }
2517
2524
  */
2518
2525
  const handleInput = useDebounce(onInput, debounce);
2526
+ const setAndCommitValue = newValue => {
2527
+ // cancel any pending debounced value
2528
+ handleInput.cancel?.();
2529
+ setLocalValue(newValue);
2530
+ onInput(newValue);
2531
+ };
2519
2532
  const handleFeelToggle = useStaticCallback(() => {
2520
2533
  if (feel === 'required') {
2521
2534
  return;
2522
2535
  }
2523
2536
  if (!feelActive) {
2524
- setLocalValue('=' + localValue);
2525
- handleInput('=' + localValue);
2537
+ setAndCommitValue('=' + localValue);
2526
2538
  } else {
2527
- setLocalValue(feelOnlyValue);
2528
- handleInput(feelOnlyValue);
2539
+ setAndCommitValue(feelOnlyValue);
2529
2540
  }
2530
2541
  });
2531
- const handleLocalInput = (newValue, useDebounce = true) => {
2542
+ const handleInputChange = newValue => {
2532
2543
  if (feelActive) {
2533
2544
  newValue = '=' + newValue;
2534
2545
  }
@@ -2536,28 +2547,32 @@ function FeelTextfield(props) {
2536
2547
  return;
2537
2548
  }
2538
2549
  setLocalValue(newValue);
2539
- if (useDebounce) {
2540
- handleInput(newValue);
2541
- } else {
2542
- onInput(newValue);
2543
- }
2550
+ handleInput(newValue);
2544
2551
  if (!feelActive && minDash.isString(newValue) && newValue.startsWith('=')) {
2545
2552
  // focus is behind `=` sign that will be removed
2546
2553
  setFocus(-1);
2547
2554
  }
2548
2555
  };
2549
- const handleOnBlur = e => {
2550
- handleInput.cancel?.();
2556
+ const handleOptionalInputOnBlur = e => {
2551
2557
  if (e.target.type === 'checkbox') {
2552
- onInput(e.target.checked);
2558
+ setAndCommitValue(e.target.checked);
2553
2559
  } else {
2554
2560
  const trimmedValue = e.target.value.trim();
2555
- handleLocalInput(trimmedValue, false);
2561
+ if (trimmedValue !== localValue) {
2562
+ // Trim changed the value — commit trimmed
2563
+ setAndCommitValue(trimmedValue);
2564
+ } else {
2565
+ // Value unchanged — flush any pending debounce
2566
+ handleInput.flush?.();
2567
+ }
2556
2568
  }
2557
2569
  if (onBlur) {
2558
2570
  onBlur(e);
2559
2571
  }
2560
2572
  };
2573
+ const handleFeelEditorOnBlur = () => {
2574
+ handleInput.flush?.();
2575
+ };
2561
2576
  const handleOnKeyDown = e => {
2562
2577
  if (isCmdWithChar(e)) {
2563
2578
  handleInput.flush?.();
@@ -2577,7 +2592,7 @@ function FeelTextfield(props) {
2577
2592
  entryId: id,
2578
2593
  hostLanguage,
2579
2594
  label,
2580
- onInput: handleLocalInput,
2595
+ onInput: handleInputChange,
2581
2596
  singleLine,
2582
2597
  sourceElement: editorRef.current,
2583
2598
  tooltipContainer,
@@ -2643,8 +2658,7 @@ function FeelTextfield(props) {
2643
2658
  if (isFieldEmpty || isAllSelected) {
2644
2659
  const textData = event.clipboardData.getData('text');
2645
2660
  const trimmedValue = textData.trim();
2646
- setLocalValue(trimmedValue);
2647
- handleInput(trimmedValue);
2661
+ setAndCommitValue(trimmedValue);
2648
2662
  if (!feelActive && minDash.isString(trimmedValue) && trimmedValue.startsWith('=')) {
2649
2663
  setFocus(trimmedValue.length - 1);
2650
2664
  }
@@ -2688,7 +2702,8 @@ function FeelTextfield(props) {
2688
2702
  onClick: handleFeelToggle
2689
2703
  }), feelActive ? jsxRuntime.jsx(FeelEditor, {
2690
2704
  name: id,
2691
- onInput: handleLocalInput,
2705
+ onInput: handleInputChange,
2706
+ onBlur: handleFeelEditorOnBlur,
2692
2707
  onKeyDown: handleOnKeyDown,
2693
2708
  contentAttributes: {
2694
2709
  'id': prefixId$5(id),
@@ -2711,9 +2726,9 @@ function FeelTextfield(props) {
2711
2726
  }) : jsxRuntime.jsx(OptionalComponent, {
2712
2727
  ...props,
2713
2728
  popupOpen: isPopupOpen,
2714
- onInput: handleLocalInput,
2729
+ onInput: handleInputChange,
2715
2730
  onKeyDown: handleOnKeyDown,
2716
- onBlur: handleOnBlur,
2731
+ onBlur: handleOptionalInputOnBlur,
2717
2732
  contentAttributes: {
2718
2733
  'id': prefixId$5(id),
2719
2734
  'aria-label': label