@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.esm.js CHANGED
@@ -551,10 +551,10 @@ function useDescriptionContext(id, element) {
551
551
  function useDebounce(callback, debounceFn) {
552
552
  const debouncedCallback = useCallback(debounceFn(callback), [callback, debounceFn]);
553
553
 
554
- // make sure previous call is not stalled
554
+ // flush pending calls before unmount the debounced function
555
555
  useEffect(() => {
556
556
  return () => {
557
- debouncedCallback.cancel?.();
557
+ debouncedCallback.flush?.();
558
558
  };
559
559
  }, [debouncedCallback]);
560
560
  return debouncedCallback;
@@ -1971,6 +1971,7 @@ const FeelEditor = forwardRef((props, ref) => {
1971
1971
  value,
1972
1972
  onInput,
1973
1973
  onKeyDown: onKeyDownProp = noop$4,
1974
+ onBlur = noop$4,
1974
1975
  onFeelToggle = noop$4,
1975
1976
  onLint = noop$4,
1976
1977
  onOpenPopup = noop$4,
@@ -1994,6 +1995,9 @@ const FeelEditor = forwardRef((props, ref) => {
1994
1995
  onInput(newValue);
1995
1996
  setLocalValue(newValue);
1996
1997
  });
1998
+ const handleBlur = useStaticCallback(() => {
1999
+ onBlur();
2000
+ });
1997
2001
  useEffect(() => {
1998
2002
  let editor;
1999
2003
 
@@ -2020,13 +2024,16 @@ const FeelEditor = forwardRef((props, ref) => {
2020
2024
  onKeyDown: onKeyDown,
2021
2025
  onLint: onLint,
2022
2026
  placeholder: placeholder,
2027
+ readOnly: disabled,
2023
2028
  tooltipContainer: tooltipContainer,
2024
2029
  value: localValue,
2025
2030
  variables,
2026
2031
  builtins,
2027
2032
  dialect,
2028
2033
  parserDialect,
2029
- extensions: [...(enableGutters ? [lineNumbers()] : []), EditorView.lineWrapping],
2034
+ extensions: [...(enableGutters ? [lineNumbers()] : []), EditorView.lineWrapping, EditorView.domEventHandlers({
2035
+ blur: handleBlur
2036
+ })],
2030
2037
  contentAttributes
2031
2038
  });
2032
2039
  setEditor(editor);
@@ -2495,19 +2502,23 @@ function FeelTextfield(props) {
2495
2502
  * @type { import('min-dash').DebouncedFunction }
2496
2503
  */
2497
2504
  const handleInput = useDebounce(onInput, debounce);
2505
+ const setAndCommitValue = newValue => {
2506
+ // cancel any pending debounced value
2507
+ handleInput.cancel?.();
2508
+ setLocalValue(newValue);
2509
+ onInput(newValue);
2510
+ };
2498
2511
  const handleFeelToggle = useStaticCallback(() => {
2499
2512
  if (feel === 'required') {
2500
2513
  return;
2501
2514
  }
2502
2515
  if (!feelActive) {
2503
- setLocalValue('=' + localValue);
2504
- handleInput('=' + localValue);
2516
+ setAndCommitValue('=' + localValue);
2505
2517
  } else {
2506
- setLocalValue(feelOnlyValue);
2507
- handleInput(feelOnlyValue);
2518
+ setAndCommitValue(feelOnlyValue);
2508
2519
  }
2509
2520
  });
2510
- const handleLocalInput = (newValue, useDebounce = true) => {
2521
+ const handleInputChange = newValue => {
2511
2522
  if (feelActive) {
2512
2523
  newValue = '=' + newValue;
2513
2524
  }
@@ -2515,28 +2526,32 @@ function FeelTextfield(props) {
2515
2526
  return;
2516
2527
  }
2517
2528
  setLocalValue(newValue);
2518
- if (useDebounce) {
2519
- handleInput(newValue);
2520
- } else {
2521
- onInput(newValue);
2522
- }
2529
+ handleInput(newValue);
2523
2530
  if (!feelActive && isString(newValue) && newValue.startsWith('=')) {
2524
2531
  // focus is behind `=` sign that will be removed
2525
2532
  setFocus(-1);
2526
2533
  }
2527
2534
  };
2528
- const handleOnBlur = e => {
2529
- handleInput.cancel?.();
2535
+ const handleOptionalInputOnBlur = e => {
2530
2536
  if (e.target.type === 'checkbox') {
2531
- onInput(e.target.checked);
2537
+ setAndCommitValue(e.target.checked);
2532
2538
  } else {
2533
2539
  const trimmedValue = e.target.value.trim();
2534
- handleLocalInput(trimmedValue, false);
2540
+ if (trimmedValue !== localValue) {
2541
+ // Trim changed the value — commit trimmed
2542
+ setAndCommitValue(trimmedValue);
2543
+ } else {
2544
+ // Value unchanged — flush any pending debounce
2545
+ handleInput.flush?.();
2546
+ }
2535
2547
  }
2536
2548
  if (onBlur) {
2537
2549
  onBlur(e);
2538
2550
  }
2539
2551
  };
2552
+ const handleFeelEditorOnBlur = () => {
2553
+ handleInput.flush?.();
2554
+ };
2540
2555
  const handleOnKeyDown = e => {
2541
2556
  if (isCmdWithChar(e)) {
2542
2557
  handleInput.flush?.();
@@ -2556,7 +2571,7 @@ function FeelTextfield(props) {
2556
2571
  entryId: id,
2557
2572
  hostLanguage,
2558
2573
  label,
2559
- onInput: handleLocalInput,
2574
+ onInput: handleInputChange,
2560
2575
  singleLine,
2561
2576
  sourceElement: editorRef.current,
2562
2577
  tooltipContainer,
@@ -2622,8 +2637,7 @@ function FeelTextfield(props) {
2622
2637
  if (isFieldEmpty || isAllSelected) {
2623
2638
  const textData = event.clipboardData.getData('text');
2624
2639
  const trimmedValue = textData.trim();
2625
- setLocalValue(trimmedValue);
2626
- handleInput(trimmedValue);
2640
+ setAndCommitValue(trimmedValue);
2627
2641
  if (!feelActive && isString(trimmedValue) && trimmedValue.startsWith('=')) {
2628
2642
  setFocus(trimmedValue.length - 1);
2629
2643
  }
@@ -2667,7 +2681,8 @@ function FeelTextfield(props) {
2667
2681
  onClick: handleFeelToggle
2668
2682
  }), feelActive ? jsx(FeelEditor, {
2669
2683
  name: id,
2670
- onInput: handleLocalInput,
2684
+ onInput: handleInputChange,
2685
+ onBlur: handleFeelEditorOnBlur,
2671
2686
  onKeyDown: handleOnKeyDown,
2672
2687
  contentAttributes: {
2673
2688
  'id': prefixId$5(id),
@@ -2690,9 +2705,9 @@ function FeelTextfield(props) {
2690
2705
  }) : jsx(OptionalComponent, {
2691
2706
  ...props,
2692
2707
  popupOpen: isPopupOpen,
2693
- onInput: handleLocalInput,
2708
+ onInput: handleInputChange,
2694
2709
  onKeyDown: handleOnKeyDown,
2695
- onBlur: handleOnBlur,
2710
+ onBlur: handleOptionalInputOnBlur,
2696
2711
  contentAttributes: {
2697
2712
  'id': prefixId$5(id),
2698
2713
  'aria-label': label