@bpmn-io/properties-panel 3.27.4 → 3.27.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
@@ -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, isString, isArray, get, assign, set, 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
@@ -1939,6 +1951,50 @@ function prefixId$6(id) {
1939
1951
  return `bio-properties-panel-${id}`;
1940
1952
  }
1941
1953
 
1954
+ function TextInput({
1955
+ debounce,
1956
+ element,
1957
+ id,
1958
+ getValue,
1959
+ onBlur,
1960
+ setValue,
1961
+ validate,
1962
+ Component,
1963
+ ...props
1964
+ }) {
1965
+ const modelValue = getValue(element);
1966
+ const setModelValue = useCallback((newValue, error) => {
1967
+ if (isFunction(validate)) {
1968
+ error = validate(newValue) || null;
1969
+ }
1970
+ setValue(newValue, error);
1971
+ }, [setValue, validate]);
1972
+ const debouncedSetValue = useDebounce(setModelValue, debounce);
1973
+ const handleInput = useCallback(newValue => {
1974
+ if (newValue !== modelValue) {
1975
+ debouncedSetValue(newValue);
1976
+ }
1977
+ }, [modelValue, debouncedSetValue]);
1978
+ const handleBlur = useCallback(value => {
1979
+ const newValue = value.trim?.() || value;
1980
+ if (newValue !== modelValue) {
1981
+ setModelValue(newValue);
1982
+ }
1983
+ if (isFunction(onBlur)) {
1984
+ onBlur(newValue);
1985
+ }
1986
+ }, [modelValue, setModelValue]);
1987
+ return jsx(Component, {
1988
+ ...props,
1989
+ debounce: debounce,
1990
+ element: element,
1991
+ id: id,
1992
+ onInput: handleInput,
1993
+ onBlur: handleBlur,
1994
+ value: modelValue
1995
+ });
1996
+ }
1997
+
1942
1998
  const noop$2 = () => {};
1943
1999
 
1944
2000
  /**
@@ -1968,7 +2024,6 @@ const noop$2 = () => {};
1968
2024
 
1969
2025
  function FeelTextfieldComponent(props) {
1970
2026
  const {
1971
- debounce,
1972
2027
  id,
1973
2028
  element,
1974
2029
  label,
@@ -2004,20 +2059,11 @@ function FeelTextfieldComponent(props) {
2004
2059
  const position = hasFocus ? document.activeElement.selectionStart : Infinity;
2005
2060
  _setFocus(position + offset);
2006
2061
  };
2007
-
2008
- /**
2009
- * @type { import('min-dash').DebouncedFunction }
2010
- */
2011
- const handleInputCallback = useMemo(() => {
2012
- return debounce(newValue => {
2013
- onInput(newValue);
2014
- });
2015
- }, [onInput, debounce]);
2016
2062
  const handleInput = newValue => {
2017
2063
  // we don't commit empty FEEL expressions,
2018
2064
  // but instead serialize them as <undefined>
2019
2065
  const newModelValue = newValue === '' || newValue === '=' ? undefined : newValue;
2020
- handleInputCallback(newModelValue);
2066
+ onInput(newModelValue);
2021
2067
  };
2022
2068
  const handleFeelToggle = useStaticCallback(() => {
2023
2069
  if (feel === 'required') {
@@ -2045,18 +2091,8 @@ function FeelTextfieldComponent(props) {
2045
2091
  setFocus(-1);
2046
2092
  }
2047
2093
  };
2048
- const handleOnBlur = e => {
2049
- const value = e.target.value;
2050
-
2051
- // we trim the value, if it is needed
2052
- // and update input accordingly
2053
- if (value.trim() !== value) {
2054
- setLocalValue(value.trim());
2055
- handleInput(value.trim());
2056
- }
2057
- if (onBlur) {
2058
- onBlur(e);
2059
- }
2094
+ const handleOnBlur = () => {
2095
+ onBlur?.(localValue);
2060
2096
  };
2061
2097
  const handleLint = useStaticCallback((lint = []) => {
2062
2098
  const syntaxError = lint.some(report => report.type === 'Syntax Error');
@@ -2443,46 +2479,28 @@ function FeelEntry(props) {
2443
2479
  placeholder,
2444
2480
  tooltip
2445
2481
  } = props;
2446
- const [validationError, setValidationError] = useState(null);
2447
2482
  const [localError, setLocalError] = useState(null);
2448
- let value = getValue(element);
2449
- useEffect(() => {
2450
- if (isFunction(validate)) {
2451
- const newValidationError = validate(value) || null;
2452
- setValidationError(newValidationError);
2453
- }
2454
- }, [value, validate]);
2455
- const onInput = useCallback(newValue => {
2456
- const value = getValue(element);
2457
- let newValidationError = null;
2458
- if (isFunction(validate)) {
2459
- newValidationError = validate(newValue) || null;
2460
- }
2461
-
2462
- // don't create multiple commandStack entries for the same value
2463
- if (newValue !== value) {
2464
- setValue(newValue, newValidationError);
2465
- }
2466
- setValidationError(newValidationError);
2467
- }, [element, getValue, setValue, validate]);
2468
- const onError = useCallback(err => {
2469
- setLocalError(err);
2470
- }, []);
2483
+ const value = getValue(element);
2484
+ const validationError = validate?.(value) || null;
2471
2485
  const temporaryError = useError(id);
2472
2486
  const error = temporaryError || localError || validationError;
2473
2487
  return jsxs("div", {
2474
2488
  class: classnames(props.class, 'bio-properties-panel-entry', error ? 'has-error' : ''),
2475
2489
  "data-entry-id": id,
2476
- children: [createElement(FeelTextfield, {
2490
+ children: [createElement(TextInput, {
2477
2491
  ...props,
2492
+ Component: FeelTextfield,
2493
+ element: element,
2494
+ getValue: getValue,
2478
2495
  debounce: debounce,
2496
+ setValue: setValue,
2497
+ validate: validate,
2479
2498
  disabled: disabled,
2480
2499
  feel: feel,
2481
2500
  id: id,
2482
2501
  key: element,
2483
2502
  label: label,
2484
- onInput: onInput,
2485
- onError: onError,
2503
+ onError: setLocalError,
2486
2504
  onFocus: onFocus,
2487
2505
  onBlur: onBlur,
2488
2506
  placeholder: placeholder,
@@ -4005,11 +4023,7 @@ function TextArea(props) {
4005
4023
  /**
4006
4024
  * @type { import('min-dash').DebouncedFunction }
4007
4025
  */
4008
- const handleInputCallback = useMemo(() => {
4009
- return debounce(newValue => {
4010
- onInput(newValue);
4011
- });
4012
- }, [onInput, debounce]);
4026
+ const handleInputCallback = useDebounce(onInput, debounce);
4013
4027
  const handleInput = newValue => {
4014
4028
  const newModelValue = newValue === '' ? undefined : newValue;
4015
4029
  handleInputCallback(newModelValue);
@@ -4022,15 +4036,8 @@ function TextArea(props) {
4022
4036
  setLocalValue(e.target.value);
4023
4037
  handleInput(e.target.value);
4024
4038
  };
4025
- const handleOnBlur = e => {
4026
- const value = e.target.value;
4027
- if (value.trim() !== value) {
4028
- setLocalValue(value.trim());
4029
- handleInput(value.trim());
4030
- }
4031
- if (onBlur) {
4032
- onBlur(e);
4033
- }
4039
+ const handleOnBlur = () => {
4040
+ onBlur?.(localValue);
4034
4041
  };
4035
4042
  useLayoutEffect(() => {
4036
4043
  autoResize && resizeToContents(ref.current);
@@ -4108,35 +4115,21 @@ function TextAreaEntry(props) {
4108
4115
  autoResize,
4109
4116
  tooltip
4110
4117
  } = props;
4118
+ const value = getValue(element);
4111
4119
  const globalError = useError(id);
4112
- const [localError, setLocalError] = useState(null);
4113
- let value = getValue(element);
4114
- useEffect(() => {
4115
- if (isFunction(validate)) {
4116
- const newValidationError = validate(value) || null;
4117
- setLocalError(newValidationError);
4118
- }
4119
- }, [value, validate]);
4120
- const onInput = useCallback(newValue => {
4121
- const value = getValue(element);
4122
- let newValidationError = null;
4123
- if (isFunction(validate)) {
4124
- newValidationError = validate(newValue) || null;
4125
- }
4126
- if (newValue !== value) {
4127
- setValue(newValue, newValidationError);
4128
- }
4129
- setLocalError(newValidationError);
4130
- }, [element, getValue, setValue, validate]);
4120
+ const localError = validate?.(value) || null;
4131
4121
  const error = globalError || localError;
4132
4122
  return jsxs("div", {
4133
4123
  class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
4134
4124
  "data-entry-id": id,
4135
- children: [jsx(TextArea, {
4125
+ children: [jsx(TextInput, {
4126
+ Component: TextArea,
4127
+ getValue: getValue,
4128
+ setValue: setValue,
4129
+ validate: validate,
4136
4130
  id: id,
4137
4131
  label: label,
4138
4132
  value: value,
4139
- onInput: onInput,
4140
4133
  onFocus: onFocus,
4141
4134
  onBlur: onBlur,
4142
4135
  rows: rows,
@@ -4169,7 +4162,6 @@ function prefixId$1(id) {
4169
4162
 
4170
4163
  function Textfield(props) {
4171
4164
  const {
4172
- debounce,
4173
4165
  disabled = false,
4174
4166
  id,
4175
4167
  label,
@@ -4182,28 +4174,12 @@ function Textfield(props) {
4182
4174
  } = props;
4183
4175
  const [localValue, setLocalValue] = useState(value || '');
4184
4176
  const ref = useShowEntryEvent(id);
4185
-
4186
- /**
4187
- * @type { import('min-dash').DebouncedFunction }
4188
- */
4189
- const handleInputCallback = useMemo(() => {
4190
- return debounce(newValue => {
4191
- onInput(newValue);
4192
- });
4193
- }, [onInput, debounce]);
4194
- const handleOnBlur = e => {
4195
- const value = e.target.value;
4196
- if (value.trim() !== value) {
4197
- setLocalValue(value.trim());
4198
- handleInput(value.trim());
4199
- }
4200
- if (onBlur) {
4201
- onBlur(e);
4202
- }
4177
+ const handleOnBlur = () => {
4178
+ onBlur?.(localValue);
4203
4179
  };
4204
4180
  const handleInput = newValue => {
4205
4181
  const newModelValue = newValue === '' ? undefined : newValue;
4206
- handleInputCallback(newModelValue);
4182
+ onInput(newModelValue);
4207
4183
  };
4208
4184
  const handleLocalInput = e => {
4209
4185
  if (e.target.value === localValue) {
@@ -4278,39 +4254,25 @@ function TextfieldEntry(props) {
4278
4254
  placeholder,
4279
4255
  tooltip
4280
4256
  } = props;
4257
+ const value = getValue(element);
4281
4258
  const globalError = useError(id);
4282
- const [localError, setLocalError] = useState(null);
4283
- let value = getValue(element);
4284
- useEffect(() => {
4285
- if (isFunction(validate)) {
4286
- const newValidationError = validate(value) || null;
4287
- setLocalError(newValidationError);
4288
- }
4289
- }, [value, validate]);
4290
- const onInput = useCallback(newValue => {
4291
- const value = getValue(element);
4292
- let newValidationError = null;
4293
- if (isFunction(validate)) {
4294
- newValidationError = validate(newValue) || null;
4295
- }
4296
- if (newValue !== value) {
4297
- setValue(newValue, newValidationError);
4298
- }
4299
- setLocalError(newValidationError);
4300
- }, [element, getValue, setValue, validate]);
4259
+ const localError = validate?.(value) || null;
4301
4260
  const error = globalError || localError;
4302
4261
  return jsxs("div", {
4303
4262
  class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
4304
4263
  "data-entry-id": id,
4305
- children: [jsx(Textfield, {
4264
+ children: [jsx(TextInput, {
4265
+ Component: Textfield,
4306
4266
  debounce: debounce,
4307
4267
  disabled: disabled,
4268
+ getValue: getValue,
4308
4269
  id: id,
4309
4270
  label: label,
4310
- onInput: onInput,
4311
4271
  onFocus: onFocus,
4312
4272
  onBlur: onBlur,
4313
4273
  placeholder: placeholder,
4274
+ setValue: setValue,
4275
+ validate: validate,
4314
4276
  value: value,
4315
4277
  tooltip: tooltip,
4316
4278
  element: element
@@ -4415,5 +4377,5 @@ var index = {
4415
4377
  feelPopup: ['type', FeelPopupModule]
4416
4378
  };
4417
4379
 
4418
- 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, Placeholder, Popup, PopupIcon, PropertiesPanel, LayoutContext as PropertiesPanelContext, SelectEntry, Simple as SimpleEntry, TemplatingEntry, TextAreaEntry, TextfieldEntry as TextFieldEntry, ToggleSwitchEntry, TooltipContext, TooltipWrapper as TooltipEntry, isEdited$5 as isCheckboxEntryEdited, isEdited$6 as isFeelEntryEdited, isEdited$7 as isNumberFieldEntryEdited, isEdited$3 as isSelectEntryEdited, isEdited$2 as isSimpleEntryEdited, isEdited$4 as isTemplatingEntryEdited, isEdited$1 as isTextAreaEntryEdited, isEdited as isTextFieldEntryEdited, isEdited$8 as isToggleSwitchEntryEdited, useDescriptionContext, useElementVisible, useError, useErrors, useEvent, useKeyFactory, useLayoutState, usePrevious, useShowEntryEvent, useStaticCallback, useStickyIntersectionObserver, useTooltipContext };
4380
+ 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, Placeholder, Popup, PopupIcon, PropertiesPanel, LayoutContext as PropertiesPanelContext, SelectEntry, Simple as SimpleEntry, TemplatingEntry, TextAreaEntry, TextfieldEntry as TextFieldEntry, ToggleSwitchEntry, TooltipContext, TooltipWrapper as TooltipEntry, isEdited$5 as isCheckboxEntryEdited, isEdited$6 as isFeelEntryEdited, isEdited$7 as isNumberFieldEntryEdited, isEdited$3 as isSelectEntryEdited, isEdited$2 as isSimpleEntryEdited, isEdited$4 as isTemplatingEntryEdited, isEdited$1 as isTextAreaEntryEdited, isEdited as isTextFieldEntryEdited, isEdited$8 as isToggleSwitchEntryEdited, useDebounce, useDescriptionContext, useElementVisible, useError, useErrors, useEvent, useKeyFactory, useLayoutState, usePrevious, useShowEntryEvent, useStaticCallback, useStickyIntersectionObserver, useTooltipContext };
4419
4381
  //# sourceMappingURL=index.esm.js.map