@bpmn-io/properties-panel 3.28.1 → 3.28.3

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
@@ -1,4 +1,4 @@
1
- import { useContext, useState, useRef, useEffect, useMemo, useCallback, useLayoutEffect } from '../preact/hooks';
1
+ import { useContext, useState, useRef, useCallback, useEffect, useMemo, useLayoutEffect } from '../preact/hooks';
2
2
  import { isFunction, isArray, get, assign, set, isString, isNumber, debounce } from 'min-dash';
3
3
  import { createPortal, forwardRef } from '../preact/compat';
4
4
  import { jsx, jsxs, Fragment } from '../preact/jsx-runtime';
@@ -402,6 +402,18 @@ function useDescriptionContext(id, element) {
402
402
  return getDescriptionForId(id, element);
403
403
  }
404
404
 
405
+ function useDebounce(callback, debounceFn) {
406
+ const debouncedCallback = useCallback(debounceFn(callback), [callback, debounceFn]);
407
+
408
+ // make sure previous call is not stalled
409
+ useEffect(() => {
410
+ return () => {
411
+ debouncedCallback.flush?.();
412
+ };
413
+ }, [debouncedCallback]);
414
+ return debouncedCallback;
415
+ }
416
+
405
417
  function useError(id) {
406
418
  const {
407
419
  errors
@@ -2131,6 +2143,50 @@ function prefixId$6(id) {
2131
2143
  return `bio-properties-panel-${id}`;
2132
2144
  }
2133
2145
 
2146
+ function TextInput({
2147
+ debounce,
2148
+ element,
2149
+ id,
2150
+ getValue,
2151
+ onBlur,
2152
+ setValue,
2153
+ validate,
2154
+ Component,
2155
+ ...props
2156
+ }) {
2157
+ const modelValue = getValue(element);
2158
+ const setModelValue = useCallback((newValue, error) => {
2159
+ if (isFunction(validate)) {
2160
+ error = validate(newValue) || null;
2161
+ }
2162
+ setValue(newValue, error);
2163
+ }, [setValue, validate]);
2164
+ const debouncedSetValue = useDebounce(setModelValue, debounce);
2165
+ const handleInput = useCallback(newValue => {
2166
+ if (newValue !== modelValue) {
2167
+ debouncedSetValue(newValue);
2168
+ }
2169
+ }, [modelValue, debouncedSetValue]);
2170
+ const handleBlur = useCallback(value => {
2171
+ const newValue = value.trim?.() || value;
2172
+ if (newValue !== modelValue) {
2173
+ setModelValue(newValue);
2174
+ }
2175
+ if (isFunction(onBlur)) {
2176
+ onBlur(newValue);
2177
+ }
2178
+ }, [modelValue, setModelValue]);
2179
+ return jsx(Component, {
2180
+ ...props,
2181
+ debounce: debounce,
2182
+ element: element,
2183
+ id: id,
2184
+ onInput: handleInput,
2185
+ onBlur: handleBlur,
2186
+ value: modelValue
2187
+ });
2188
+ }
2189
+
2134
2190
  const noop$2 = () => {};
2135
2191
 
2136
2192
  /**
@@ -2159,7 +2215,6 @@ const noop$2 = () => {};
2159
2215
  */
2160
2216
  function FeelTextfield(props) {
2161
2217
  const {
2162
- debounce,
2163
2218
  id,
2164
2219
  element,
2165
2220
  label,
@@ -2194,20 +2249,11 @@ function FeelTextfield(props) {
2194
2249
  const position = hasFocus ? document.activeElement.selectionStart : Infinity;
2195
2250
  _setFocus(position + offset);
2196
2251
  };
2197
-
2198
- /**
2199
- * @type { import('min-dash').DebouncedFunction }
2200
- */
2201
- const handleInputCallback = useMemo(() => {
2202
- return debounce(newValue => {
2203
- onInput(newValue);
2204
- });
2205
- }, [onInput, debounce]);
2206
2252
  const handleInput = newValue => {
2207
2253
  // we don't commit empty FEEL expressions,
2208
2254
  // but instead serialize them as <undefined>
2209
2255
  const newModelValue = newValue === '' || newValue === '=' ? undefined : newValue;
2210
- handleInputCallback(newModelValue);
2256
+ onInput(newModelValue);
2211
2257
  };
2212
2258
  const handleFeelToggle = useStaticCallback(() => {
2213
2259
  if (feel === 'required') {
@@ -2235,18 +2281,8 @@ function FeelTextfield(props) {
2235
2281
  setFocus(-1);
2236
2282
  }
2237
2283
  };
2238
- const handleOnBlur = e => {
2239
- const value = e.target.value;
2240
-
2241
- // we trim the value, if it is needed
2242
- // and update input accordingly
2243
- if (value.trim() !== value) {
2244
- setLocalValue(value.trim());
2245
- handleInput(value.trim());
2246
- }
2247
- if (onBlur) {
2248
- onBlur(e);
2249
- }
2284
+ const handleOnBlur = () => {
2285
+ onBlur?.(localValue);
2250
2286
  };
2251
2287
  const handleLint = useStaticCallback((lint = []) => {
2252
2288
  const syntaxError = lint.some(report => report.type === 'Syntax Error');
@@ -2643,46 +2679,28 @@ function FeelEntry(props) {
2643
2679
  placeholder,
2644
2680
  tooltip
2645
2681
  } = props;
2646
- const [validationError, setValidationError] = useState(null);
2647
2682
  const [localError, setLocalError] = useState(null);
2648
- let value = getValue(element);
2649
- useEffect(() => {
2650
- if (isFunction(validate)) {
2651
- const newValidationError = validate(value) || null;
2652
- setValidationError(newValidationError);
2653
- }
2654
- }, [value, validate]);
2655
- const onInput = useCallback(newValue => {
2656
- const value = getValue(element);
2657
- let newValidationError = null;
2658
- if (isFunction(validate)) {
2659
- newValidationError = validate(newValue) || null;
2660
- }
2661
-
2662
- // don't create multiple commandStack entries for the same value
2663
- if (newValue !== value) {
2664
- setValue(newValue, newValidationError);
2665
- }
2666
- setValidationError(newValidationError);
2667
- }, [element, getValue, setValue, validate]);
2668
- const onError = useCallback(err => {
2669
- setLocalError(err);
2670
- }, []);
2683
+ const value = getValue(element);
2684
+ const validationError = validate?.(value) || null;
2671
2685
  const temporaryError = useError(id);
2672
2686
  const error = temporaryError || localError || validationError;
2673
2687
  return jsxs("div", {
2674
2688
  class: classnames(props.class, 'bio-properties-panel-entry', error ? 'has-error' : ''),
2675
2689
  "data-entry-id": id,
2676
- children: [createElement$1(FeelTextfield, {
2690
+ children: [createElement$1(TextInput, {
2677
2691
  ...props,
2692
+ Component: FeelTextfield,
2693
+ element: element,
2694
+ getValue: getValue,
2678
2695
  debounce: debounce,
2696
+ setValue: setValue,
2697
+ validate: validate,
2679
2698
  disabled: disabled,
2680
2699
  feel: feel,
2681
2700
  id: id,
2682
2701
  key: element,
2683
2702
  label: label,
2684
- onInput: onInput,
2685
- onError: onError,
2703
+ onError: setLocalError,
2686
2704
  onFocus: onFocus,
2687
2705
  onBlur: onBlur,
2688
2706
  placeholder: placeholder,
@@ -3411,11 +3429,7 @@ function TextArea(props) {
3411
3429
  /**
3412
3430
  * @type { import('min-dash').DebouncedFunction }
3413
3431
  */
3414
- const handleInputCallback = useMemo(() => {
3415
- return debounce(newValue => {
3416
- onInput(newValue);
3417
- });
3418
- }, [onInput, debounce]);
3432
+ const handleInputCallback = useDebounce(onInput, debounce);
3419
3433
  const handleInput = newValue => {
3420
3434
  const newModelValue = newValue === '' ? undefined : newValue;
3421
3435
  handleInputCallback(newModelValue);
@@ -3428,15 +3442,8 @@ function TextArea(props) {
3428
3442
  setLocalValue(e.target.value);
3429
3443
  handleInput(e.target.value);
3430
3444
  };
3431
- const handleOnBlur = e => {
3432
- const value = e.target.value;
3433
- if (value.trim() !== value) {
3434
- setLocalValue(value.trim());
3435
- handleInput(value.trim());
3436
- }
3437
- if (onBlur) {
3438
- onBlur(e);
3439
- }
3445
+ const handleOnBlur = () => {
3446
+ onBlur?.(localValue);
3440
3447
  };
3441
3448
  useLayoutEffect(() => {
3442
3449
  autoResize && resizeToContents(ref.current);
@@ -3514,35 +3521,21 @@ function TextAreaEntry(props) {
3514
3521
  autoResize,
3515
3522
  tooltip
3516
3523
  } = props;
3524
+ const value = getValue(element);
3517
3525
  const globalError = useError(id);
3518
- const [localError, setLocalError] = useState(null);
3519
- let value = getValue(element);
3520
- useEffect(() => {
3521
- if (isFunction(validate)) {
3522
- const newValidationError = validate(value) || null;
3523
- setLocalError(newValidationError);
3524
- }
3525
- }, [value, validate]);
3526
- const onInput = useCallback(newValue => {
3527
- const value = getValue(element);
3528
- let newValidationError = null;
3529
- if (isFunction(validate)) {
3530
- newValidationError = validate(newValue) || null;
3531
- }
3532
- if (newValue !== value) {
3533
- setValue(newValue, newValidationError);
3534
- }
3535
- setLocalError(newValidationError);
3536
- }, [element, getValue, setValue, validate]);
3526
+ const localError = validate?.(value) || null;
3537
3527
  const error = globalError || localError;
3538
3528
  return jsxs("div", {
3539
3529
  class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
3540
3530
  "data-entry-id": id,
3541
- children: [jsx(TextArea, {
3531
+ children: [jsx(TextInput, {
3532
+ Component: TextArea,
3533
+ getValue: getValue,
3534
+ setValue: setValue,
3535
+ validate: validate,
3542
3536
  id: id,
3543
3537
  label: label,
3544
3538
  value: value,
3545
- onInput: onInput,
3546
3539
  onFocus: onFocus,
3547
3540
  onBlur: onBlur,
3548
3541
  rows: rows,
@@ -3575,7 +3568,6 @@ function prefixId$2(id) {
3575
3568
 
3576
3569
  function Textfield(props) {
3577
3570
  const {
3578
- debounce,
3579
3571
  disabled = false,
3580
3572
  id,
3581
3573
  label,
@@ -3588,28 +3580,12 @@ function Textfield(props) {
3588
3580
  } = props;
3589
3581
  const [localValue, setLocalValue] = useState(value || '');
3590
3582
  const ref = useShowEntryEvent(id);
3591
-
3592
- /**
3593
- * @type { import('min-dash').DebouncedFunction }
3594
- */
3595
- const handleInputCallback = useMemo(() => {
3596
- return debounce(newValue => {
3597
- onInput(newValue);
3598
- });
3599
- }, [onInput, debounce]);
3600
- const handleOnBlur = e => {
3601
- const value = e.target.value;
3602
- if (value.trim() !== value) {
3603
- setLocalValue(value.trim());
3604
- handleInput(value.trim());
3605
- }
3606
- if (onBlur) {
3607
- onBlur(e);
3608
- }
3583
+ const handleOnBlur = () => {
3584
+ onBlur?.(localValue);
3609
3585
  };
3610
3586
  const handleInput = newValue => {
3611
3587
  const newModelValue = newValue === '' ? undefined : newValue;
3612
- handleInputCallback(newModelValue);
3588
+ onInput(newModelValue);
3613
3589
  };
3614
3590
  const handleLocalInput = e => {
3615
3591
  if (e.target.value === localValue) {
@@ -3684,39 +3660,25 @@ function TextfieldEntry(props) {
3684
3660
  placeholder,
3685
3661
  tooltip
3686
3662
  } = props;
3663
+ const value = getValue(element);
3687
3664
  const globalError = useError(id);
3688
- const [localError, setLocalError] = useState(null);
3689
- let value = getValue(element);
3690
- useEffect(() => {
3691
- if (isFunction(validate)) {
3692
- const newValidationError = validate(value) || null;
3693
- setLocalError(newValidationError);
3694
- }
3695
- }, [value, validate]);
3696
- const onInput = useCallback(newValue => {
3697
- const value = getValue(element);
3698
- let newValidationError = null;
3699
- if (isFunction(validate)) {
3700
- newValidationError = validate(newValue) || null;
3701
- }
3702
- if (newValue !== value) {
3703
- setValue(newValue, newValidationError);
3704
- }
3705
- setLocalError(newValidationError);
3706
- }, [element, getValue, setValue, validate]);
3665
+ const localError = validate?.(value) || null;
3707
3666
  const error = globalError || localError;
3708
3667
  return jsxs("div", {
3709
3668
  class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
3710
3669
  "data-entry-id": id,
3711
- children: [jsx(Textfield, {
3670
+ children: [jsx(TextInput, {
3671
+ Component: Textfield,
3712
3672
  debounce: debounce,
3713
3673
  disabled: disabled,
3674
+ getValue: getValue,
3714
3675
  id: id,
3715
3676
  label: label,
3716
- onInput: onInput,
3717
3677
  onFocus: onFocus,
3718
3678
  onBlur: onBlur,
3719
3679
  placeholder: placeholder,
3680
+ setValue: setValue,
3681
+ validate: validate,
3720
3682
  value: value,
3721
3683
  tooltip: tooltip,
3722
3684
  element: element
@@ -4378,5 +4340,5 @@ var index = {
4378
4340
  feelPopupRenderer: ['type', FeelPopupRenderer]
4379
4341
  };
4380
4342
 
4381
- export { ArrowIcon, CheckboxEntry, CloseIcon, CollapsibleEntry, CreateIcon, index$1 as DebounceInputModule, DeleteIcon, DescriptionContext, Description as DescriptionEntry, DragIcon, DropdownButton, ErrorsContext, EventContext, ExternalLinkIcon, FeelCheckboxEntry, FeelEntry, FeelIcon$1 as FeelIcon, FeelNumberEntry, index as FeelPopupModule, FeelTemplatingEntry, FeelTextAreaEntry, FeelToggleSwitchEntry, Group, Header, HeaderButton, LaunchIcon, LayoutContext, List as ListEntry, ListGroup, ListItem, NumberFieldEntry, OpenPopupIcon, Placeholder, PropertiesPanel, LayoutContext as PropertiesPanelContext, SelectEntry, Simple as SimpleEntry, TemplatingEntry, TextAreaEntry, TextfieldEntry as TextFieldEntry, ToggleSwitchEntry, TooltipContext, TooltipWrapper as TooltipEntry, isEdited$8 as isCheckboxEntryEdited, isEdited$5 as isFeelEntryEdited, isEdited$6 as isNumberFieldEntryEdited, isEdited$3 as isSelectEntryEdited, isEdited$2 as isSimpleEntryEdited, isEdited$4 as isTemplatingEntryEdited, isEdited$1 as isTextAreaEntryEdited, isEdited as isTextFieldEntryEdited, isEdited$7 as isToggleSwitchEntryEdited, useDescriptionContext, useElementVisible, useError, useErrors, useEvent, useKeyFactory, useLayoutState, usePrevious, useShowEntryEvent, useStaticCallback, useStickyIntersectionObserver, useTooltipContext };
4343
+ export { ArrowIcon, CheckboxEntry, CloseIcon, CollapsibleEntry, CreateIcon, index$1 as DebounceInputModule, DeleteIcon, DescriptionContext, Description as DescriptionEntry, DragIcon, DropdownButton, ErrorsContext, EventContext, ExternalLinkIcon, FeelCheckboxEntry, FeelEntry, FeelIcon$1 as FeelIcon, FeelNumberEntry, index as FeelPopupModule, FeelTemplatingEntry, FeelTextAreaEntry, FeelToggleSwitchEntry, Group, Header, HeaderButton, LaunchIcon, LayoutContext, List as ListEntry, ListGroup, ListItem, NumberFieldEntry, OpenPopupIcon, Placeholder, PropertiesPanel, LayoutContext as PropertiesPanelContext, SelectEntry, Simple as SimpleEntry, TemplatingEntry, TextAreaEntry, TextfieldEntry as TextFieldEntry, ToggleSwitchEntry, TooltipContext, TooltipWrapper as TooltipEntry, isEdited$8 as isCheckboxEntryEdited, isEdited$5 as isFeelEntryEdited, isEdited$6 as isNumberFieldEntryEdited, isEdited$3 as isSelectEntryEdited, isEdited$2 as isSimpleEntryEdited, isEdited$4 as isTemplatingEntryEdited, isEdited$1 as isTextAreaEntryEdited, isEdited as isTextFieldEntryEdited, isEdited$7 as isToggleSwitchEntryEdited, useDebounce, useDescriptionContext, useElementVisible, useError, useErrors, useEvent, useKeyFactory, useLayoutState, usePrevious, useShowEntryEvent, useStaticCallback, useStickyIntersectionObserver, useTooltipContext };
4382
4344
  //# sourceMappingURL=index.esm.js.map