@bpmn-io/form-js-viewer 1.8.3 → 1.8.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.cjs CHANGED
@@ -11,6 +11,7 @@ var isEqual = require('lodash/isEqual');
11
11
  var flatpickr = require('flatpickr');
12
12
  var React = require('preact/compat');
13
13
  var DOMPurify = require('dompurify');
14
+ var lodash = require('lodash');
14
15
  var didi = require('didi');
15
16
  var feelin = require('feelin');
16
17
  var feelers = require('feelers');
@@ -372,10 +373,10 @@ class FeelersTemplating {
372
373
  }
373
374
 
374
375
  /**
375
- * @typedef {Object} ExpressionWithDepth
376
- * @property {number} depth - The depth of the expression in the syntax tree.
377
- * @property {string} expression - The extracted expression
378
- */
376
+ * @typedef {Object} ExpressionWithDepth
377
+ * @property {number} depth - The depth of the expression in the syntax tree.
378
+ * @property {string} expression - The extracted expression
379
+ */
379
380
 
380
381
  /**
381
382
  * Extracts all feel expressions in the template along with their depth in the syntax tree.
@@ -740,6 +741,20 @@ function generateIdForType(type) {
740
741
  function clone(data, replacer) {
741
742
  return JSON.parse(JSON.stringify(data, replacer));
742
743
  }
744
+ function runRecursively(formField, fn) {
745
+ const components = formField.components || [];
746
+ components.forEach((component, _) => {
747
+ runRecursively(component, fn);
748
+ });
749
+ fn(formField);
750
+ }
751
+ function wrapObjectKeysWithUnderscores(obj) {
752
+ const newObj = {};
753
+ for (const [key, value] of Object.entries(obj)) {
754
+ newObj[`_${key}_`] = value;
755
+ }
756
+ return newObj;
757
+ }
743
758
 
744
759
  /**
745
760
  * Transform a LocalExpressionContext object into a usable FEEL context.
@@ -756,25 +771,24 @@ function buildExpressionContext(context) {
756
771
  return {
757
772
  ...specialContextKeys,
758
773
  ...data,
759
- ..._wrapObjectKeysWithUnderscores(specialContextKeys)
774
+ ...wrapObjectKeysWithUnderscores(specialContextKeys)
760
775
  };
761
776
  }
762
- function runRecursively(formField, fn) {
763
- const components = formField.components || [];
764
- components.forEach((component, index) => {
765
- runRecursively(component, fn);
766
- });
767
- fn(formField);
768
- }
769
777
 
770
- // helpers //////////////////////
771
-
772
- function _wrapObjectKeysWithUnderscores(obj) {
773
- const newObj = {};
774
- for (const [key, value] of Object.entries(obj)) {
775
- newObj[`_${key}_`] = value;
778
+ /**
779
+ * Evaluate a string based on the expressionLanguage and context information.
780
+ * If the string is not an expression, it is returned as is.
781
+ *
782
+ * @param {any} expressionLanguage - The expression language to use.
783
+ * @param {string} value - The string to evaluate.
784
+ * @param {Object} expressionContextInfo - The context information to use.
785
+ * @returns {any} - Evaluated value or the original value if not an expression.
786
+ */
787
+ function runExpressionEvaluation(expressionLanguage, value, expressionContextInfo) {
788
+ if (expressionLanguage && expressionLanguage.isExpression(value)) {
789
+ return expressionLanguage.evaluate(value, buildExpressionContext(expressionContextInfo));
776
790
  }
777
- return newObj;
791
+ return value;
778
792
  }
779
793
 
780
794
  /**
@@ -907,12 +921,7 @@ function _isAllowedValue(value) {
907
921
  function useExpressionEvaluation(value) {
908
922
  const expressionLanguage = useService('expressionLanguage');
909
923
  const expressionContextInfo = hooks.useContext(LocalExpressionContext);
910
- return hooks.useMemo(() => {
911
- if (expressionLanguage && expressionLanguage.isExpression(value)) {
912
- return expressionLanguage.evaluate(value, buildExpressionContext(expressionContextInfo));
913
- }
914
- return value;
915
- }, [expressionLanguage, expressionContextInfo, value]);
924
+ return hooks.useMemo(() => runExpressionEvaluation(expressionLanguage, value, expressionContextInfo), [expressionLanguage, expressionContextInfo, value]);
916
925
  }
917
926
 
918
927
  /**
@@ -1029,11 +1038,11 @@ const getDOMPurifyConfig = sanitizeStyleTags => {
1029
1038
  };
1030
1039
  };
1031
1040
 
1032
- /**
1033
- * A custom hook to build up security attributes from form configuration.
1034
- *
1035
- * @param {Object} security - The security configuration.
1036
- * @returns {Array} - Returns a tuple with sandbox and allow attributes.
1041
+ /**
1042
+ * A custom hook to build up security attributes from form configuration.
1043
+ *
1044
+ * @param {Object} security - The security configuration.
1045
+ * @returns {Array} - Returns a tuple with sandbox and allow attributes.
1037
1046
  */
1038
1047
  function useSecurityAttributesMap(security) {
1039
1048
  const securityMemoized = useDeepCompareMemoize(security);
@@ -1789,7 +1798,6 @@ function Checkbox(props) {
1789
1798
  target
1790
1799
  }) => {
1791
1800
  props.onChange({
1792
- field,
1793
1801
  value: target.checked
1794
1802
  });
1795
1803
  };
@@ -1868,7 +1876,6 @@ function Checklist(props) {
1868
1876
  const toggleCheckbox = toggledValue => {
1869
1877
  const newValues = hasEqualValue(toggledValue, values) ? values.filter(value => !isEqual(value, toggledValue)) : [...values, toggledValue];
1870
1878
  props.onChange({
1871
- field,
1872
1879
  value: newValues
1873
1880
  });
1874
1881
  };
@@ -1956,10 +1963,11 @@ function FormField(props) {
1956
1963
  const {
1957
1964
  field,
1958
1965
  indexes,
1959
- onChange
1966
+ onChange: _onChange
1960
1967
  } = props;
1961
1968
  const formFields = useService('formFields'),
1962
1969
  viewerCommands = useService('viewerCommands', false),
1970
+ formFieldInstanceRegistry = useService('formFieldInstanceRegistry', false),
1963
1971
  pathRegistry = useService('pathRegistry'),
1964
1972
  eventBus = useService('eventBus'),
1965
1973
  form = useService('form');
@@ -1986,6 +1994,7 @@ function FormField(props) {
1986
1994
  throw new Error(`cannot render field <${field.type}>`);
1987
1995
  }
1988
1996
  const fieldConfig = FormFieldComponent.config;
1997
+ const localExpressionContext = hooks.useContext(LocalExpressionContext);
1989
1998
  const valuePath = hooks.useMemo(() => pathRegistry.getValuePath(field, {
1990
1999
  indexes
1991
2000
  }), [field, indexes, pathRegistry]);
@@ -1995,6 +2004,23 @@ function FormField(props) {
1995
2004
 
1996
2005
  // add precedence: global readonly > form field disabled
1997
2006
  const disabled = !properties.readOnly && (properties.disabled || field.disabled || false);
2007
+ const hidden = useCondition(field.conditional && field.conditional.hide || null);
2008
+ const fieldInstance = hooks.useMemo(() => ({
2009
+ id: field.id,
2010
+ expressionContextInfo: localExpressionContext,
2011
+ valuePath,
2012
+ indexes
2013
+ }), [field.id, valuePath, localExpressionContext, indexes]);
2014
+
2015
+ // register form field instance
2016
+ hooks.useEffect(() => {
2017
+ if (formFieldInstanceRegistry && !hidden) {
2018
+ const instanceId = formFieldInstanceRegistry.add(fieldInstance);
2019
+ return () => {
2020
+ formFieldInstanceRegistry.remove(instanceId);
2021
+ };
2022
+ }
2023
+ }, [fieldInstance, formFieldInstanceRegistry, hidden]);
1998
2024
 
1999
2025
  // ensures the initial validation behavior can be re-triggered upon form reset
2000
2026
  hooks.useEffect(() => {
@@ -2015,35 +2041,33 @@ function FormField(props) {
2015
2041
  const hasInitialValue = initialValue && !isEqual(initialValue, []);
2016
2042
  if (initialValidationTrigger && hasInitialValue) {
2017
2043
  setInitialValidationTrigger(false);
2018
- viewerCommands.updateFieldValidation(field, initialValue, indexes);
2044
+ viewerCommands.updateFieldInstanceValidation(fieldInstance, initialValue);
2019
2045
  }
2020
- }, [viewerCommands, field, initialValue, initialValidationTrigger, indexes]);
2046
+ }, [fieldInstance, initialValidationTrigger, initialValue, viewerCommands]);
2021
2047
  const onBlur = hooks.useCallback(() => {
2022
2048
  const value = minDash.get(data, valuePath);
2023
2049
  if (initialValidationTrigger) {
2024
2050
  setInitialValidationTrigger(false);
2025
- viewerCommands.updateFieldValidation(field, value, indexes);
2051
+ viewerCommands.updateFieldInstanceValidation(fieldInstance, value);
2026
2052
  }
2027
2053
  eventBus.fire('formField.blur', {
2028
2054
  formField: field
2029
2055
  });
2030
- }, [eventBus, field, indexes, viewerCommands, initialValidationTrigger, data, valuePath]);
2056
+ }, [data, eventBus, field, fieldInstance, initialValidationTrigger, valuePath, viewerCommands]);
2031
2057
  const onFocus = hooks.useCallback(() => {
2032
2058
  eventBus.fire('formField.focus', {
2033
2059
  formField: field
2034
2060
  });
2035
2061
  }, [eventBus, field]);
2036
- const hidden = useCondition(field.conditional && field.conditional.hide || null);
2037
- const onChangeIndexed = hooks.useCallback(update => {
2038
- // any data change will trigger validation
2062
+ const onChange = hooks.useCallback(update => {
2039
2063
  setInitialValidationTrigger(false);
2040
-
2041
- // add indexes of the keyed field to the update, if any
2042
- onChange(fieldConfig.keyed ? {
2043
- ...update,
2044
- indexes
2045
- } : update);
2046
- }, [onChange, fieldConfig.keyed, indexes]);
2064
+ _onChange({
2065
+ field,
2066
+ indexes,
2067
+ fieldInstance,
2068
+ ...update
2069
+ });
2070
+ }, [_onChange, field, fieldInstance, indexes]);
2047
2071
  if (hidden) {
2048
2072
  return jsxRuntime.jsx(Hidden, {
2049
2073
  field: field
@@ -2056,11 +2080,12 @@ function FormField(props) {
2056
2080
  disabled: disabled,
2057
2081
  errors: fieldErrors,
2058
2082
  domId: domId,
2059
- onChange: disabled || readonly ? noop$1 : onChangeIndexed,
2083
+ onChange: disabled || readonly ? noop$1 : onChange,
2060
2084
  onBlur: disabled || readonly ? noop$1 : onBlur,
2061
2085
  onFocus: disabled || readonly ? noop$1 : onFocus,
2062
2086
  readonly: readonly,
2063
- value: value
2087
+ value: value,
2088
+ fieldInstance: fieldInstance
2064
2089
  });
2065
2090
  if (fieldConfig.escapeGridRender) {
2066
2091
  return formFieldElement;
@@ -2178,7 +2203,7 @@ function RowsRenderer(props) {
2178
2203
  Row
2179
2204
  } = hooks.useContext(FormRenderContext);
2180
2205
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
2181
- children: [" ", rows.map(row => {
2206
+ children: [' ', rows.map(row => {
2182
2207
  const {
2183
2208
  components = []
2184
2209
  } = row;
@@ -2204,7 +2229,7 @@ function RowsRenderer(props) {
2204
2229
  });
2205
2230
  })
2206
2231
  });
2207
- }), " "]
2232
+ }), ' ']
2208
2233
  });
2209
2234
  }
2210
2235
 
@@ -2334,23 +2359,23 @@ function InputAdorner(props) {
2334
2359
  'fjs-disabled': disabled,
2335
2360
  'fjs-readonly': readonly
2336
2361
  }, {
2337
- 'hasErrors': hasErrors
2362
+ hasErrors: hasErrors
2338
2363
  }),
2339
2364
  ref: rootRef,
2340
2365
  children: [pre && jsxRuntime.jsxs("span", {
2341
2366
  class: "fjs-input-adornment border-right border-radius-left",
2342
2367
  onClick: onAdornmentClick,
2343
- children: [" ", minDash.isString(pre) ? jsxRuntime.jsx("span", {
2368
+ children: [' ', minDash.isString(pre) ? jsxRuntime.jsx("span", {
2344
2369
  class: "fjs-input-adornment-text",
2345
2370
  children: pre
2346
- }) : pre, " "]
2371
+ }) : pre, ' ']
2347
2372
  }), children, post && jsxRuntime.jsxs("span", {
2348
2373
  class: "fjs-input-adornment border-left border-radius-right",
2349
2374
  onClick: onAdornmentClick,
2350
- children: [" ", minDash.isString(post) ? jsxRuntime.jsx("span", {
2375
+ children: [' ', minDash.isString(post) ? jsxRuntime.jsx("span", {
2351
2376
  class: "fjs-input-adornment-text",
2352
2377
  children: post
2353
- }) : post, " "]
2378
+ }) : post, ' ']
2354
2379
  })]
2355
2380
  });
2356
2381
  }
@@ -2399,7 +2424,9 @@ function Datepicker(props) {
2399
2424
  clickOpens: false,
2400
2425
  // TODO: support dates prior to 1900 (https://github.com/bpmn-io/form-js/issues/533)
2401
2426
  minDate: disallowPassedDates ? 'today' : '01/01/1900',
2402
- errorHandler: () => {/* do nothing, we expect the values to sometimes be erronous and we don't want warnings polluting the console */}
2427
+ errorHandler: () => {
2428
+ /* do nothing, we expect the values to sometimes be erronous and we don't want warnings polluting the console */
2429
+ }
2403
2430
  };
2404
2431
  const instance = flatpickr(dateInputRef.current, config);
2405
2432
  setFlatpickrInstance(instance);
@@ -2504,7 +2531,7 @@ function Datepicker(props) {
2504
2531
  });
2505
2532
  }
2506
2533
 
2507
- var _path$v, _path2$5;
2534
+ var _path$v, _path2$4;
2508
2535
  function _extends$w() { _extends$w = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$w.apply(this, arguments); }
2509
2536
  var SvgClock = function SvgClock(props) {
2510
2537
  return /*#__PURE__*/React__namespace.createElement("svg", _extends$w({
@@ -2516,7 +2543,7 @@ var SvgClock = function SvgClock(props) {
2516
2543
  }, props), _path$v || (_path$v = /*#__PURE__*/React__namespace.createElement("path", {
2517
2544
  fill: "currentColor",
2518
2545
  d: "M13 14.41 18.59 20 20 18.59l-5-5.01V5h-2v9.41Z"
2519
- })), _path2$5 || (_path2$5 = /*#__PURE__*/React__namespace.createElement("path", {
2546
+ })), _path2$4 || (_path2$4 = /*#__PURE__*/React__namespace.createElement("path", {
2520
2547
  fill: "currentColor",
2521
2548
  fillRule: "evenodd",
2522
2549
  d: "M6.222 25.64A14 14 0 1 0 21.778 2.36 14 14 0 0 0 6.222 25.64ZM7.333 4.023a12 12 0 1 1 13.334 19.955A12 12 0 0 1 7.333 4.022Z",
@@ -2607,7 +2634,7 @@ function DropdownList(props) {
2607
2634
  children: [values.length > 0 && values.map((v, i) => {
2608
2635
  return jsxRuntime.jsx("div", {
2609
2636
  class: classNames('fjs-dropdownlist-item', {
2610
- 'focused': focusedValueIndex === i
2637
+ focused: focusedValueIndex === i
2611
2638
  }),
2612
2639
  onMouseMove: mouseControl ? undefined : e => onMouseMovedInKeyboardMode(e, i),
2613
2640
  onMouseEnter: mouseControl ? () => setFocusedValueIndex(i) : undefined,
@@ -2759,11 +2786,9 @@ function Timepicker(props) {
2759
2786
  disabled: disabled,
2760
2787
  readOnly: readonly,
2761
2788
  placeholder: use24h ? 'hh:mm' : 'hh:mm ?m',
2762
- autoComplete: "off"
2763
-
2764
- // @ts-ignore
2765
- ,
2789
+ autoComplete: "off",
2766
2790
  onInput: e => {
2791
+ // @ts-expect-error
2767
2792
  setRawValue(e.target.value);
2768
2793
  useDropdown && setDropdownIsOpen(false);
2769
2794
  },
@@ -3162,7 +3187,7 @@ var SvgChecklist = function SvgChecklist(props) {
3162
3187
  };
3163
3188
  var ChecklistIcon = SvgChecklist;
3164
3189
 
3165
- var _path$r, _path2$4, _path3;
3190
+ var _path$r, _path2$3, _path3;
3166
3191
  function _extends$s() { _extends$s = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$s.apply(this, arguments); }
3167
3192
  var SvgDatetime = function SvgDatetime(props) {
3168
3193
  return /*#__PURE__*/React__namespace.createElement("svg", _extends$s({
@@ -3173,7 +3198,7 @@ var SvgDatetime = function SvgDatetime(props) {
3173
3198
  }, props), _path$r || (_path$r = /*#__PURE__*/React__namespace.createElement("path", {
3174
3199
  fillRule: "evenodd",
3175
3200
  d: "M37.908 13.418h-5.004v-2.354h-1.766v2.354H21.13v-2.354h-1.766v2.354H14.36a2.07 2.07 0 0 0-2.06 2.06v23.549a2.07 2.07 0 0 0 2.06 2.06h6.77v-1.766h-6.358a.707.707 0 0 1-.706-.706V15.89c0-.39.316-.707.706-.707h4.592v2.355h1.766v-2.355h10.008v2.355h1.766v-2.355h4.592a.71.71 0 0 1 .707.707v6.358h1.765v-6.77c0-1.133-.927-2.06-2.06-2.06z"
3176
- })), _path2$4 || (_path2$4 = /*#__PURE__*/React__namespace.createElement("path", {
3201
+ })), _path2$3 || (_path2$3 = /*#__PURE__*/React__namespace.createElement("path", {
3177
3202
  d: "m35.13 37.603 1.237-1.237-3.468-3.475v-5.926h-1.754v6.654l3.984 3.984Z"
3178
3203
  })), _path3 || (_path3 = /*#__PURE__*/React__namespace.createElement("path", {
3179
3204
  fillRule: "evenodd",
@@ -3182,7 +3207,7 @@ var SvgDatetime = function SvgDatetime(props) {
3182
3207
  };
3183
3208
  var DatetimeIcon = SvgDatetime;
3184
3209
 
3185
- var _path$q, _path2$3;
3210
+ var _path$q, _path2$2;
3186
3211
  function _extends$r() { _extends$r = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$r.apply(this, arguments); }
3187
3212
  var SvgTaglist = function SvgTaglist(props) {
3188
3213
  return /*#__PURE__*/React__namespace.createElement("svg", _extends$r({
@@ -3193,7 +3218,7 @@ var SvgTaglist = function SvgTaglist(props) {
3193
3218
  }, props), _path$q || (_path$q = /*#__PURE__*/React__namespace.createElement("path", {
3194
3219
  fillRule: "evenodd",
3195
3220
  d: "M45 16a3 3 0 0 1 3 3v16a3 3 0 0 1-3 3H9a3 3 0 0 1-3-3V19a3 3 0 0 1 3-3h36Zm0 2H9a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h36a1 1 0 0 0 1-1V19a1 1 0 0 0-1-1Z"
3196
- })), _path2$3 || (_path2$3 = /*#__PURE__*/React__namespace.createElement("path", {
3221
+ })), _path2$2 || (_path2$2 = /*#__PURE__*/React__namespace.createElement("path", {
3197
3222
  d: "M11 22a1 1 0 0 1 1-1h19a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H12a1 1 0 0 1-1-1V22Z"
3198
3223
  })));
3199
3224
  };
@@ -3235,10 +3260,12 @@ var SvgGroup = function SvgGroup(props) {
3235
3260
  xmlns: "http://www.w3.org/2000/svg",
3236
3261
  width: 54,
3237
3262
  height: 54,
3238
- fill: "currentcolor"
3263
+ fill: "none"
3239
3264
  }, props), _path$p || (_path$p = /*#__PURE__*/React__namespace.createElement("path", {
3265
+ fill: "#000",
3240
3266
  fillRule: "evenodd",
3241
- d: "M8 33v5a1 1 0 0 0 1 1h4v2H9a3 3 0 0 1-3-3v-5h2Zm18 6v2H15v-2h11Zm13 0v2H28v-2h11Zm9-6v5a3 3 0 0 1-3 3h-4v-2h4a1 1 0 0 0 .993-.883L46 38v-5h2ZM8 22v9H6v-9h2Zm40 0v9h-2v-9h2Zm-35-9v2H9a1 1 0 0 0-.993.883L8 16v4H6v-4a3 3 0 0 1 3-3h4Zm32 0a3 3 0 0 1 3 3v4h-2v-4a1 1 0 0 0-.883-.993L45 15h-4v-2h4Zm-6 0v2H28v-2h11Zm-13 0v2H15v-2h11Z"
3267
+ d: "M4.05 42.132v1.164c0 .693.604 1.254 1.35 1.254h1.35v-2.507h-2.7v.09Zm0-2.328h2.7v-2.328h-2.7v2.328Zm0-4.656h2.7V32.82h-2.7v2.328Zm0-4.656h2.7v-2.328h-2.7v2.328Zm0-4.656h2.7v-2.328h-2.7v2.328Zm0-4.656h2.7v-2.328h-2.7v2.328Zm0-4.656h2.7v-2.328h-2.7v2.328Zm0-4.656v.09h2.7V9.45H5.4c-.746 0-1.35.561-1.35 1.254v1.164Zm5.4-2.418v2.507h2.7V9.45h-2.7Zm5.4 0v2.507h2.7V9.45h-2.7Zm5.4 0v2.507h2.7V9.45h-2.7Zm5.4 0v2.507h2.7V9.45h-2.7Zm5.4 0v2.507h2.7V9.45h-2.7Zm5.4 0v2.507h2.7V9.45h-2.7Zm5.4 0v2.507h2.7V9.45h-2.7Zm5.4 0v2.507h2.7v-1.253c0-.693-.604-1.254-1.35-1.254h-1.35Zm2.7 4.746h-2.7v2.328h2.7v-2.328Zm0 4.656h-2.7v2.328h2.7v-2.328Zm0 4.656h-2.7v2.328h2.7v-2.328Zm0 4.656h-2.7v2.328h2.7v-2.328Zm0 4.656h-2.7v2.328h2.7V32.82Zm0 4.656h-2.7v2.328h2.7v-2.328Zm0 4.656v-.09h-2.7v2.508h1.35c.746 0 1.35-.561 1.35-1.254v-1.164Zm-5.4 2.418v-2.507h-2.7v2.507h2.7Zm-5.4 0v-2.507h-2.7v2.507h2.7Zm-5.4 0v-2.507h-2.7v2.507h2.7Zm-5.4 0v-2.507h-2.7v2.507h2.7Zm-5.4 0v-2.507h-2.7v2.507h2.7Zm-5.4 0v-2.507h-2.7v2.507h2.7Zm-5.4 0v-2.507h-2.7v2.507h2.7Z",
3268
+ clipRule: "evenodd"
3242
3269
  })));
3243
3270
  };
3244
3271
  var GroupIcon = SvgGroup;
@@ -3328,7 +3355,7 @@ var SvgDynamicList = function SvgDynamicList(props) {
3328
3355
  }, props), _path$j || (_path$j = /*#__PURE__*/React__namespace.createElement("path", {
3329
3356
  fill: "currentColor",
3330
3357
  fillRule: "evenodd",
3331
- d: "M2.7 43.296v1.254c0 .746.604 1.35 1.35 1.35h1.275v-1.795c.049.14.075.29.075.445v-1.254h-.075V43.2H4.05c.177 0 .347.034.502.096H2.7Zm2.7-2.507v-2.507H2.7v2.507h2.7Zm0-5.014v-2.507H2.7v2.507h2.7Zm0-5.014v-2.507H2.7v2.507h2.7Zm0-5.015V23.24H2.7v2.507h2.7Zm0-5.014v-2.507H2.7v2.507h2.7Zm0-5.014V13.21H2.7v2.507h2.7Zm-2.7-5.014h1.852a1.346 1.346 0 0 1-.502.096h1.275v-.096H5.4V9.45c0 .156-.026.306-.075.445V8.1H4.05A1.35 1.35 0 0 0 2.7 9.45v1.254Zm5.175.096h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1-2.7v1.795a1.348 1.348 0 0 1-.075-.445v1.254h.075v.096h1.275c-.177 0-.347-.034-.502-.096H51.3V9.45a1.35 1.35 0 0 0-1.35-1.35h-1.275Zm-.075 5.11v2.508h2.7V13.21h-2.7Zm0 5.015v2.507h2.7v-2.507h-2.7Zm0 5.014v2.507h2.7V23.24h-2.7Zm0 5.015v2.507h2.7v-2.507h-2.7Zm0 5.014v2.507h2.7v-2.507h-2.7Zm0 5.014v2.507h2.7v-2.507h-2.7Zm2.7 5.014h-1.852c.155-.062.325-.096.502-.096h-1.275v.096H48.6v1.254c0-.156.026-.305.075-.445V45.9h1.275a1.35 1.35 0 0 0 1.35-1.35v-1.254Zm-5.175-.096h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7ZM16.2 17.55a4.05 4.05 0 0 1 4.05 4.05v1.35A4.05 4.05 0 0 1 16.2 27h-1.35a4.05 4.05 0 0 1-4.05-4.05V21.6a4.05 4.05 0 0 1 4.05-4.05h1.35Zm0 2.7h-1.35a1.35 1.35 0 0 0-1.35 1.35v1.35c0 .746.604 1.35 1.35 1.35h1.35a1.35 1.35 0 0 0 1.35-1.35V21.6a1.35 1.35 0 0 0-1.35-1.35Zm27 1.35a4.05 4.05 0 0 0-4.05-4.05H29.7a4.05 4.05 0 0 0-4.05 4.05v1.35A4.05 4.05 0 0 0 29.7 27h9.45a4.05 4.05 0 0 0 4.05-4.05V21.6Zm-13.5-1.35h9.45c.746 0 1.35.604 1.35 1.35v1.35a1.35 1.35 0 0 1-1.35 1.35H29.7a1.35 1.35 0 0 1-1.35-1.35V21.6c0-.746.604-1.35 1.35-1.35ZM43.2 37.8a4.05 4.05 0 0 0-4.05-4.05H29.7a4.05 4.05 0 0 0-4.05 4.05v1.35h2.7V37.8c0-.746.604-1.35 1.35-1.35h9.45c.746 0 1.35.604 1.35 1.35v1.35h2.7V37.8Zm-27-4.05a4.05 4.05 0 0 1 4.05 4.05v1.35h-2.7V37.8a1.35 1.35 0 0 0-1.35-1.35h-1.35a1.35 1.35 0 0 0-1.35 1.35v1.35h-2.7V37.8a4.05 4.05 0 0 1 4.05-4.05h1.35Z",
3358
+ d: "M2.7 43.296v1.254c0 .746.604 1.35 1.35 1.35h1.275v-1.795c.049.14.075.29.075.445v-1.254h-.075V43.2H4.05c.177 0 .347.034.502.096H2.7Zm2.7-2.507v-2.507H2.7v2.507h2.7Zm0-5.014v-2.507H2.7v2.507h2.7Zm0-5.014v-2.507H2.7v2.507h2.7Zm0-5.015V23.24H2.7v2.507h2.7Zm0-5.014v-2.507H2.7v2.507h2.7Zm0-5.014V13.21H2.7v2.507h2.7Zm-2.7-5.014h1.852a1.346 1.346 0 0 1-.502.096h1.275v-.096H5.4V9.45c0 .156-.026.306-.075.445V8.1H4.05A1.35 1.35 0 0 0 2.7 9.45v1.254Zm5.175.096h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1 0h2.55V8.1h-2.55v2.7Zm5.1-2.7v1.795a1.348 1.348 0 0 1-.075-.445v1.254h.075v.096h1.275a1.35 1.35 0 0 1-.502-.096H51.3V9.45a1.35 1.35 0 0 0-1.35-1.35h-1.275Zm-.075 5.11v2.508h2.7V13.21h-2.7Zm0 5.015v2.507h2.7v-2.507h-2.7Zm0 5.014v2.507h2.7V23.24h-2.7Zm0 5.015v2.507h2.7v-2.507h-2.7Zm0 5.014v2.507h2.7v-2.507h-2.7Zm0 5.014v2.507h2.7v-2.507h-2.7Zm2.7 5.014h-1.852a1.35 1.35 0 0 1 .502-.096h-1.275v.096H48.6v1.254c0-.156.026-.305.075-.445V45.9h1.275a1.35 1.35 0 0 0 1.35-1.35v-1.254Zm-5.175-.096h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7Zm-5.1 0h-2.55v2.7h2.55v-2.7ZM16.2 17.55a4.05 4.05 0 0 1 4.05 4.05v1.35A4.05 4.05 0 0 1 16.2 27h-1.35a4.05 4.05 0 0 1-4.05-4.05V21.6a4.05 4.05 0 0 1 4.05-4.05h1.35Zm0 2.7h-1.35a1.35 1.35 0 0 0-1.35 1.35v1.35c0 .746.604 1.35 1.35 1.35h1.35a1.35 1.35 0 0 0 1.35-1.35V21.6a1.35 1.35 0 0 0-1.35-1.35Zm27 1.35a4.05 4.05 0 0 0-4.05-4.05H29.7a4.05 4.05 0 0 0-4.05 4.05v1.35A4.05 4.05 0 0 0 29.7 27h9.45a4.05 4.05 0 0 0 4.05-4.05V21.6Zm-13.5-1.35h9.45c.746 0 1.35.604 1.35 1.35v1.35a1.35 1.35 0 0 1-1.35 1.35H29.7a1.35 1.35 0 0 1-1.35-1.35V21.6c0-.746.604-1.35 1.35-1.35ZM43.2 37.8a4.05 4.05 0 0 0-4.05-4.05H29.7a4.05 4.05 0 0 0-4.05 4.05v1.35h2.7V37.8c0-.746.604-1.35 1.35-1.35h9.45c.746 0 1.35.604 1.35 1.35v1.35h2.7V37.8Zm-27-4.05a4.05 4.05 0 0 1 4.05 4.05v1.35h-2.7V37.8a1.35 1.35 0 0 0-1.35-1.35h-1.35a1.35 1.35 0 0 0-1.35 1.35v1.35h-2.7V37.8a4.05 4.05 0 0 1 4.05-4.05h1.35Z",
3332
3359
  clipRule: "evenodd"
3333
3360
  })));
3334
3361
  };
@@ -3412,7 +3439,7 @@ var SvgTextarea = function SvgTextarea(props) {
3412
3439
  };
3413
3440
  var TextareaIcon = SvgTextarea;
3414
3441
 
3415
- var _path$d, _path2$2;
3442
+ var _path$d;
3416
3443
  function _extends$d() { _extends$d = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$d.apply(this, arguments); }
3417
3444
  var SvgIFrame = function SvgIFrame(props) {
3418
3445
  return /*#__PURE__*/React__namespace.createElement("svg", _extends$d({
@@ -3421,12 +3448,9 @@ var SvgIFrame = function SvgIFrame(props) {
3421
3448
  height: 54,
3422
3449
  fill: "none"
3423
3450
  }, props), _path$d || (_path$d = /*#__PURE__*/React__namespace.createElement("path", {
3424
- fill: "currentcolor",
3425
- d: "M34.467 37.3 41 31l-6.533-6.3-1.32 1.273L38.36 31l-5.213 5.027 1.32 1.273ZM19.533 24.7 13 31l6.533 6.3 1.32-1.273L15.64 31l5.214-5.027-1.32-1.273Zm4.127 14.832 1.805.468 4.875-17.532L28.535 22 23.66 39.532Z"
3426
- })), _path2$2 || (_path2$2 = /*#__PURE__*/React__namespace.createElement("path", {
3427
- fill: "currentcolor",
3451
+ fill: "currentColor",
3428
3452
  fillRule: "evenodd",
3429
- d: "M46 9a3 3 0 0 1 3 3v30a3 3 0 0 1-3 3H8a3 3 0 0 1-3-3V12a3 3 0 0 1 3-3h38Zm0 2H8a1 1 0 0 0-1 1v4h40v-4a1 1 0 0 0-1-1ZM7 42V18h40v24a1 1 0 0 1-1 1H8a1 1 0 0 1-1-1Z",
3453
+ d: "M45.658 9.45c1.625 0 2.942 1.36 2.942 3.039V22.95h-1.961v-4.383H7.36V41.51c0 .56.44 1.013.98 1.013H27v2.026H8.342c-1.625 0-2.942-1.36-2.942-3.039V12.489c0-1.678 1.317-3.039 2.942-3.039h37.316Zm0 2.026H8.342c-.542 0-.98.454-.98 1.013v4.052h39.277v-4.052c0-.56-.44-1.013-.98-1.013ZM31.05 35.775A8.768 8.768 0 0 1 39.825 27a8.768 8.768 0 0 1 8.775 8.775 8.768 8.768 0 0 1-8.775 8.775 8.768 8.768 0 0 1-8.775-8.775Zm12.388-.516h3.097c-.206-2.581-1.858-4.646-4.026-5.678.62 1.548.93 3.613.93 5.678Zm-5.162 2.065c.207 3.303 1.136 4.955 1.549 5.161.413-.206 1.239-1.858 1.445-5.161h-2.994Zm1.446-8.26c-.31.207-1.342 2.272-1.446 6.195h2.994c-.103-3.923-1.135-5.988-1.548-6.194Zm-3.51 6.195c.103-2.065.31-4.13.929-5.678-2.168 1.032-3.82 3.097-4.026 5.678h3.097Zm0 2.065h-2.89c.515 2.064 1.96 3.82 3.819 4.645-.516-1.342-.826-2.994-.93-4.645Zm7.226 0c-.103 1.755-.413 3.303-.929 4.645 1.858-.826 3.304-2.58 3.923-4.645h-2.994Z",
3430
3454
  clipRule: "evenodd"
3431
3455
  })));
3432
3456
  };
@@ -3797,7 +3821,7 @@ function Numberfield(props) {
3797
3821
  'fjs-disabled': disabled,
3798
3822
  'fjs-readonly': readonly
3799
3823
  }, {
3800
- 'hasErrors': errors.length
3824
+ hasErrors: errors.length
3801
3825
  }),
3802
3826
  children: [jsxRuntime.jsx("input", {
3803
3827
  ref: inputRef,
@@ -3809,7 +3833,6 @@ function Numberfield(props) {
3809
3833
  onKeyPress: onKeyPress,
3810
3834
  onBlur: onInputBlur,
3811
3835
  onFocus: onInputFocus
3812
-
3813
3836
  // @ts-ignore
3814
3837
  ,
3815
3838
  onInput: e => setValue(e.target.value, true),
@@ -3898,7 +3921,6 @@ function Radio(props) {
3898
3921
  } = validate;
3899
3922
  const onChange = v => {
3900
3923
  props.onChange({
3901
- field,
3902
3924
  value: v
3903
3925
  });
3904
3926
  };
@@ -4046,10 +4068,9 @@ function SearchableSelect(props) {
4046
4068
  const setValue = hooks.useCallback(option => {
4047
4069
  setFilter(option && option.label || '');
4048
4070
  props.onChange({
4049
- value: option && option.value || null,
4050
- field
4071
+ value: option && option.value || null
4051
4072
  });
4052
- }, [field, props]);
4073
+ }, [props]);
4053
4074
  const displayState = hooks.useMemo(() => {
4054
4075
  const ds = {};
4055
4076
  ds.componentReady = !disabled && !readonly && loadState === LOAD_STATES.LOADED;
@@ -4118,10 +4139,10 @@ function SearchableSelect(props) {
4118
4139
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
4119
4140
  children: [jsxRuntime.jsxs("div", {
4120
4141
  class: classNames('fjs-input-group', {
4121
- 'disabled': disabled,
4122
- 'readonly': readonly
4142
+ disabled: disabled,
4143
+ readonly: readonly
4123
4144
  }, {
4124
- 'hasErrors': errors.length
4145
+ hasErrors: errors.length
4125
4146
  }),
4126
4147
  children: [jsxRuntime.jsx("input", {
4127
4148
  disabled: disabled,
@@ -4145,7 +4166,7 @@ function SearchableSelect(props) {
4145
4166
  setValue(null);
4146
4167
  e.preventDefault();
4147
4168
  },
4148
- children: [jsxRuntime.jsx(XMarkIcon, {}), " "]
4169
+ children: [jsxRuntime.jsx(XMarkIcon, {}), ' ']
4149
4170
  }), jsxRuntime.jsx("span", {
4150
4171
  class: "fjs-select-arrow",
4151
4172
  onMouseDown: e => onAngelMouseDown(e),
@@ -4195,10 +4216,9 @@ function SimpleSelect(props) {
4195
4216
  const valueLabel = hooks.useMemo(() => value && getLabelCorrelation(value), [value, getLabelCorrelation]);
4196
4217
  const setValue = hooks.useCallback(option => {
4197
4218
  props.onChange({
4198
- value: option && option.value || null,
4199
- field
4219
+ value: option && option.value || null
4200
4220
  });
4201
- }, [field, props]);
4221
+ }, [props]);
4202
4222
  const displayState = hooks.useMemo(() => {
4203
4223
  const ds = {};
4204
4224
  ds.componentReady = !disabled && !readonly && loadState === LOAD_STATES.LOADED;
@@ -4239,7 +4259,7 @@ function SimpleSelect(props) {
4239
4259
  disabled,
4240
4260
  readonly
4241
4261
  }, {
4242
- 'hasErrors': errors.length
4262
+ hasErrors: errors.length
4243
4263
  }),
4244
4264
  onFocus: onInputFocus,
4245
4265
  onBlur: onInputBlur,
@@ -4536,15 +4556,13 @@ function Taglist(props) {
4536
4556
  return;
4537
4557
  }
4538
4558
  props.onChange({
4539
- value: [...values, value],
4540
- field
4559
+ value: [...values, value]
4541
4560
  });
4542
4561
  };
4543
4562
  const deselectValue = value => {
4544
4563
  const newValues = values.filter(v => !isEqual(v, value));
4545
4564
  props.onChange({
4546
- value: newValues,
4547
- field
4565
+ value: newValues
4548
4566
  });
4549
4567
  };
4550
4568
  const onInputChange = ({
@@ -4969,18 +4987,20 @@ function ExpressionField(props) {
4969
4987
  const evaluation = useExpressionEvaluation(expression);
4970
4988
  const evaluationMemo = useDeepCompareMemoize(evaluation);
4971
4989
  const eventBus = useService('eventBus');
4990
+ const expressionLoopPreventer = useService('expressionLoopPreventer');
4972
4991
  const sendValue = hooks.useCallback(() => {
4973
4992
  onChange && onChange({
4974
4993
  field,
4975
- value: evaluationMemo
4994
+ value: evaluationMemo,
4995
+ shouldNotRecompute: true
4976
4996
  });
4977
4997
  }, [field, evaluationMemo, onChange]);
4978
4998
  hooks.useEffect(() => {
4979
- if (computeOn !== 'change' || evaluationMemo === value) {
4999
+ if (computeOn !== 'change' || lodash.isEqual(evaluationMemo, value) || !expressionLoopPreventer.registerExpressionExecution(this)) {
4980
5000
  return;
4981
5001
  }
4982
5002
  sendValue();
4983
- }, [computeOn, evaluationMemo, sendValue, value]);
5003
+ });
4984
5004
  hooks.useEffect(() => {
4985
5005
  if (computeOn === 'presubmit') {
4986
5006
  eventBus.on('presubmit', sendValue);
@@ -5031,7 +5051,6 @@ function Textfield(props) {
5031
5051
  target
5032
5052
  }) => {
5033
5053
  props.onChange({
5034
- field,
5035
5054
  value: target.value
5036
5055
  });
5037
5056
  });
@@ -5131,7 +5150,6 @@ function Textarea(props) {
5131
5150
  target
5132
5151
  }) => {
5133
5152
  props.onChange({
5134
- field,
5135
5153
  value: target.value
5136
5154
  });
5137
5155
  });
@@ -5645,7 +5663,7 @@ function Lightbox(props) {
5645
5663
  style: "margin: 15px 20px 15px 10px; align-self: center; color: var(--cds-icon-primary, #404040)",
5646
5664
  children: jsxRuntime.jsx(Logo, {})
5647
5665
  }), jsxRuntime.jsxs("span", {
5648
- children: ["Web-based tooling for BPMN, DMN, and forms powered by ", jsxRuntime.jsx("a", {
5666
+ children: ["Web-based tooling for BPMN, DMN, and forms powered by", ' ', jsxRuntime.jsx("a", {
5649
5667
  href: "https://bpmn.io",
5650
5668
  target: "_blank",
5651
5669
  rel: "noopener",
@@ -5735,7 +5753,12 @@ function FormComponent(props) {
5735
5753
  });
5736
5754
  }
5737
5755
 
5738
- const formFields = [Button, Checkbox, Checklist, Default, DynamicList, Numberfield, Datetime, Radio, Select, Taglist, Textfield, Textarea, ExpressionField, Text, Image, Table, Html, Spacer, Separator, Group, DynamicList, IFrame];
5756
+ const formFields = [/* Input */
5757
+ Textfield, Textarea, Numberfield, Datetime, ExpressionField, /* Selection */
5758
+ Checkbox, Checklist, Radio, Select, Taglist, /* Presentation */
5759
+ Text, Image, Table, Html, Spacer, Separator, /* Containers */
5760
+ Group, DynamicList, IFrame, /* Other */
5761
+ Button, Default];
5739
5762
 
5740
5763
  class FormFields {
5741
5764
  constructor() {
@@ -5905,8 +5928,7 @@ class ConditionChecker {
5905
5928
  const {
5906
5929
  getFilterPath = (field, indexes) => this._pathRegistry.getValuePath(field, {
5907
5930
  indexes
5908
- }),
5909
- leafNodeDeletionOnly = false
5931
+ })
5910
5932
  } = options;
5911
5933
  const _applyConditionsWithinScope = (rootField, scopeContext, startHidden = false) => {
5912
5934
  const {
@@ -5937,7 +5959,7 @@ class ConditionChecker {
5937
5959
  context.isHidden = startHidden || context.isHidden || conditional && this._checkHideCondition(conditional, localExpressionContext);
5938
5960
 
5939
5961
  // if a field is repeatable and visible, we need to implement custom recursion on its children
5940
- if (isRepeatable && (!context.isHidden || leafNodeDeletionOnly)) {
5962
+ if (isRepeatable && !context.isHidden) {
5941
5963
  // prevent the regular recursion behavior of executeRecursivelyOnFields
5942
5964
  context.preventRecursion = true;
5943
5965
  const repeaterValuePath = this._pathRegistry.getValuePath(field, {
@@ -5969,7 +5991,7 @@ class ConditionChecker {
5969
5991
  }
5970
5992
 
5971
5993
  // if we have a hidden repeatable field, and the data structure allows, we clear it directly at the root and stop recursion
5972
- if (context.isHidden && !leafNodeDeletionOnly && isRepeatable) {
5994
+ if (context.isHidden && isRepeatable) {
5973
5995
  context.preventRecursion = true;
5974
5996
  this._cleanlyClearDataAtPath(getFilterPath(field, indexes), workingData);
5975
5997
  }
@@ -6059,6 +6081,49 @@ const ExpressionLanguageModule = {
6059
6081
  conditionChecker: ['type', ConditionChecker]
6060
6082
  };
6061
6083
 
6084
+ class ExpressionLoopPreventer {
6085
+ constructor(eventBus) {
6086
+ this._computedExpressions = [];
6087
+ eventBus.on('field.updated', ({
6088
+ shouldNotRecompute
6089
+ }) => {
6090
+ if (shouldNotRecompute) {
6091
+ return;
6092
+ }
6093
+ this.reset();
6094
+ });
6095
+ eventBus.on('import.done', this.reset.bind(this));
6096
+ eventBus.on('reset', this.reset.bind(this));
6097
+ }
6098
+
6099
+ /**
6100
+ * Checks if the expression field has already been computed, and registers it if not.
6101
+ *
6102
+ * @param {any} expressionField
6103
+ * @returns {boolean} - whether the expression field has already been computed within the current cycle
6104
+ */
6105
+ registerExpressionExecution(expressionField) {
6106
+ if (this._computedExpressions.includes(expressionField)) {
6107
+ return false;
6108
+ }
6109
+ this._computedExpressions.push(expressionField);
6110
+ return true;
6111
+ }
6112
+
6113
+ /**
6114
+ * Resets the list of computed expressions.
6115
+ */
6116
+ reset() {
6117
+ this._computedExpressions = [];
6118
+ }
6119
+ }
6120
+ ExpressionLoopPreventer.$inject = ['eventBus'];
6121
+
6122
+ const ExpressionFieldModule = {
6123
+ __init__: ['expressionLoopPreventer'],
6124
+ expressionLoopPreventer: ['type', ExpressionLoopPreventer]
6125
+ };
6126
+
6062
6127
  class MarkdownRenderer {
6063
6128
  /**
6064
6129
  * Render markdown to HTML.
@@ -6553,6 +6618,9 @@ var commandModule = {
6553
6618
  commandStack: ['type', CommandStack]
6554
6619
  };
6555
6620
 
6621
+ /**
6622
+ * @deprecated
6623
+ */
6556
6624
  class UpdateFieldValidationHandler {
6557
6625
  constructor(form, validator) {
6558
6626
  this._form = form;
@@ -6582,6 +6650,38 @@ class UpdateFieldValidationHandler {
6582
6650
  }
6583
6651
  UpdateFieldValidationHandler.$inject = ['form', 'validator'];
6584
6652
 
6653
+ class UpdateFieldInstanceValidationHandler {
6654
+ constructor(form, validator) {
6655
+ this._form = form;
6656
+ this._validator = validator;
6657
+ }
6658
+ execute(context) {
6659
+ const {
6660
+ fieldInstance,
6661
+ value
6662
+ } = context;
6663
+ const {
6664
+ id,
6665
+ indexes
6666
+ } = fieldInstance;
6667
+ const {
6668
+ errors
6669
+ } = this._form._getState();
6670
+ context.oldErrors = clone(errors);
6671
+ const fieldErrors = this._validator.validateFieldInstance(fieldInstance, value);
6672
+ const updatedErrors = minDash.set(errors, [id, ...Object.values(indexes || {})], fieldErrors.length ? fieldErrors : undefined);
6673
+ this._form._setState({
6674
+ errors: updatedErrors
6675
+ });
6676
+ }
6677
+ revert(context) {
6678
+ this._form._setState({
6679
+ errors: context.oldErrors
6680
+ });
6681
+ }
6682
+ }
6683
+ UpdateFieldInstanceValidationHandler.$inject = ['form', 'validator'];
6684
+
6585
6685
  class ViewerCommands {
6586
6686
  constructor(commandStack, eventBus) {
6587
6687
  this._commandStack = commandStack;
@@ -6596,9 +6696,14 @@ class ViewerCommands {
6596
6696
  }
6597
6697
  getHandlers() {
6598
6698
  return {
6599
- 'formField.validation.update': UpdateFieldValidationHandler
6699
+ 'formField.validation.update': UpdateFieldValidationHandler,
6700
+ 'formFieldInstance.validation.update': UpdateFieldInstanceValidationHandler
6600
6701
  };
6601
6702
  }
6703
+
6704
+ /**
6705
+ * @deprecated
6706
+ */
6602
6707
  updateFieldValidation(field, value, indexes) {
6603
6708
  const context = {
6604
6709
  field,
@@ -6607,6 +6712,13 @@ class ViewerCommands {
6607
6712
  };
6608
6713
  this._commandStack.execute('formField.validation.update', context);
6609
6714
  }
6715
+ updateFieldInstanceValidation(fieldInstance, value) {
6716
+ const context = {
6717
+ fieldInstance,
6718
+ value
6719
+ };
6720
+ this._commandStack.execute('formFieldInstance.validation.update', context);
6721
+ }
6610
6722
  }
6611
6723
  ViewerCommands.$inject = ['commandStack', 'eventBus'];
6612
6724
 
@@ -6791,9 +6903,7 @@ class RepeatRenderManager {
6791
6903
  updatedValues.push(newItem);
6792
6904
  shouldScroll.current = true;
6793
6905
  props.onChange({
6794
- field: repeaterField,
6795
- value: updatedValues,
6796
- indexes
6906
+ value: updatedValues
6797
6907
  });
6798
6908
  setSharedRepeatState(state => ({
6799
6909
  ...state,
@@ -7452,11 +7562,18 @@ const EMAIL_PATTERN = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-
7452
7562
  const PHONE_PATTERN = /(\+|00)(297|93|244|1264|358|355|376|971|54|374|1684|1268|61|43|994|257|32|229|226|880|359|973|1242|387|590|375|501|1441|591|55|1246|673|975|267|236|1|61|41|56|86|225|237|243|242|682|57|269|238|506|53|5999|61|1345|357|420|49|253|1767|45|1809|1829|1849|213|593|20|291|212|34|372|251|358|679|500|33|298|691|241|44|995|44|233|350|224|590|220|245|240|30|1473|299|502|594|1671|592|852|504|385|509|36|62|44|91|246|353|98|964|354|972|39|1876|44|962|81|76|77|254|996|855|686|1869|82|383|965|856|961|231|218|1758|423|94|266|370|352|371|853|590|212|377|373|261|960|52|692|389|223|356|95|382|976|1670|258|222|1664|596|230|265|60|262|264|687|227|672|234|505|683|31|47|977|674|64|968|92|507|64|51|63|680|675|48|1787|1939|850|351|595|970|689|974|262|40|7|250|966|249|221|65|500|4779|677|232|503|378|252|508|381|211|239|597|421|386|46|268|1721|248|963|1649|235|228|66|992|690|993|670|676|1868|216|90|688|886|255|256|380|598|1|998|3906698|379|1784|58|1284|1340|84|678|681|685|967|27|260|263)(9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)\d{4,20}$/;
7453
7563
  const VALIDATE_FEEL_PROPERTIES = ['min', 'max', 'minLength', 'maxLength'];
7454
7564
  class Validator {
7455
- constructor(expressionLanguage, conditionChecker, form) {
7565
+ constructor(expressionLanguage, conditionChecker, form, formFieldRegistry) {
7456
7566
  this._expressionLanguage = expressionLanguage;
7457
7567
  this._conditionChecker = conditionChecker;
7458
7568
  this._form = form;
7569
+ this._formFieldRegistry = formFieldRegistry;
7459
7570
  }
7571
+
7572
+ /**
7573
+ * Validate against a field definition, does not support proper expression evaluation.
7574
+ *
7575
+ * @deprecated use validateFieldInstance instead
7576
+ */
7460
7577
  validateField(field, value) {
7461
7578
  const {
7462
7579
  type,
@@ -7464,72 +7581,121 @@ class Validator {
7464
7581
  } = field;
7465
7582
  let errors = [];
7466
7583
  if (type === 'number') {
7467
- const {
7468
- decimalDigits,
7469
- increment
7470
- } = field;
7471
- if (value === 'NaN') {
7472
- errors = [...errors, 'Value is not a number.'];
7473
- } else if (value) {
7474
- if (decimalDigits >= 0 && countDecimals(value) > decimalDigits) {
7475
- errors = [...errors, 'Value is expected to ' + (decimalDigits === 0 ? 'be an integer' : `have at most ${decimalDigits} decimal digit${decimalDigits > 1 ? 's' : ''}`) + '.'];
7476
- }
7477
- if (increment) {
7478
- const bigValue = Big(value);
7479
- const bigIncrement = Big(increment);
7480
- const offset = bigValue.mod(bigIncrement);
7481
- if (offset.cmp(0) !== 0) {
7482
- const previousValue = bigValue.minus(offset);
7483
- const nextValue = previousValue.plus(bigIncrement);
7484
- errors = [...errors, `Please select a valid value, the two nearest valid values are ${previousValue} and ${nextValue}.`];
7485
- }
7486
- }
7487
- }
7584
+ errors = [...errors, ...runNumberValidation(field, value)];
7488
7585
  }
7489
7586
  if (!validate) {
7490
7587
  return errors;
7491
7588
  }
7492
- const evaluatedValidation = evaluateFEELValues(validate, this._expressionLanguage, this._conditionChecker, this._form);
7493
- if (evaluatedValidation.pattern && value && !new RegExp(evaluatedValidation.pattern).test(value)) {
7494
- errors = [...errors, `Field must match pattern ${evaluatedValidation.pattern}.`];
7495
- }
7496
- if (evaluatedValidation.required) {
7497
- const isUncheckedCheckbox = type === 'checkbox' && value === false;
7498
- const isUnsetValue = minDash.isNil(value) || value === '';
7499
- const isEmptyMultiselect = Array.isArray(value) && value.length === 0;
7500
- if (isUncheckedCheckbox || isUnsetValue || isEmptyMultiselect) {
7501
- errors = [...errors, 'Field is required.'];
7502
- }
7503
- }
7504
- if ('min' in evaluatedValidation && (value || value === 0) && value < evaluatedValidation.min) {
7505
- errors = [...errors, `Field must have minimum value of ${evaluatedValidation.min}.`];
7506
- }
7507
- if ('max' in evaluatedValidation && (value || value === 0) && value > evaluatedValidation.max) {
7508
- errors = [...errors, `Field must have maximum value of ${evaluatedValidation.max}.`];
7509
- }
7510
- if ('minLength' in evaluatedValidation && value && value.trim().length < evaluatedValidation.minLength) {
7511
- errors = [...errors, `Field must have minimum length of ${evaluatedValidation.minLength}.`];
7512
- }
7513
- if ('maxLength' in evaluatedValidation && value && value.trim().length > evaluatedValidation.maxLength) {
7514
- errors = [...errors, `Field must have maximum length of ${evaluatedValidation.maxLength}.`];
7515
- }
7516
- if ('validationType' in evaluatedValidation && value && evaluatedValidation.validationType === 'phone' && !PHONE_PATTERN.test(value)) {
7517
- errors = [...errors, 'Field must be a valid international phone number. (e.g. +4930664040900)'];
7589
+ const evaluatedValidation = oldEvaluateFEELValues(validate, this._expressionLanguage, this._conditionChecker, this._form);
7590
+ errors = [...errors, ...runPresetValidation(field, evaluatedValidation, value)];
7591
+ return errors;
7592
+ }
7593
+
7594
+ /**
7595
+ * Validate a field instance.
7596
+ *
7597
+ * @param {Object} fieldInstance
7598
+ * @param {string} value
7599
+ *
7600
+ * @returns {Array<string>}
7601
+ */
7602
+ validateFieldInstance(fieldInstance, value) {
7603
+ const {
7604
+ id,
7605
+ expressionContextInfo
7606
+ } = fieldInstance;
7607
+ const field = this._formFieldRegistry.get(id);
7608
+ const {
7609
+ type,
7610
+ validate
7611
+ } = field;
7612
+ let errors = [];
7613
+ if (type === 'number') {
7614
+ errors = [...errors, ...runNumberValidation(field, value)];
7518
7615
  }
7519
- if ('validationType' in evaluatedValidation && value && evaluatedValidation.validationType === 'email' && !EMAIL_PATTERN.test(value)) {
7520
- errors = [...errors, 'Field must be a valid email.'];
7616
+ if (!validate) {
7617
+ return errors;
7521
7618
  }
7619
+ const evaluatedValidation = evaluateFEELValues(validate, this._expressionLanguage, expressionContextInfo);
7620
+ errors = [...errors, ...runPresetValidation(field, evaluatedValidation, value)];
7522
7621
  return errors;
7523
7622
  }
7524
7623
  }
7525
- Validator.$inject = ['expressionLanguage', 'conditionChecker', 'form'];
7624
+ Validator.$inject = ['expressionLanguage', 'conditionChecker', 'form', 'formFieldRegistry'];
7526
7625
 
7527
7626
  // helpers //////////
7528
7627
 
7529
- /**
7530
- * Helper function to evaluate optional FEEL validation values.
7531
- */
7532
- function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form) {
7628
+ function runNumberValidation(field, value) {
7629
+ const {
7630
+ decimalDigits,
7631
+ increment
7632
+ } = field;
7633
+ const errors = [];
7634
+ if (value === 'NaN') {
7635
+ errors.push('Value is not a number.');
7636
+ } else if (value) {
7637
+ if (decimalDigits >= 0 && countDecimals(value) > decimalDigits) {
7638
+ errors.push('Value is expected to ' + (decimalDigits === 0 ? 'be an integer' : `have at most ${decimalDigits} decimal digit${decimalDigits > 1 ? 's' : ''}`) + '.');
7639
+ }
7640
+ if (increment) {
7641
+ const bigValue = Big(value);
7642
+ const bigIncrement = Big(increment);
7643
+ const offset = bigValue.mod(bigIncrement);
7644
+ if (offset.cmp(0) !== 0) {
7645
+ const previousValue = bigValue.minus(offset);
7646
+ const nextValue = previousValue.plus(bigIncrement);
7647
+ errors.push(`Please select a valid value, the two nearest valid values are ${previousValue} and ${nextValue}.`);
7648
+ }
7649
+ }
7650
+ }
7651
+ return errors;
7652
+ }
7653
+ function runPresetValidation(field, validation, value) {
7654
+ const errors = [];
7655
+ if (validation.pattern && value && !new RegExp(validation.pattern).test(value)) {
7656
+ errors.push(`Field must match pattern ${validation.pattern}.`);
7657
+ }
7658
+ if (validation.required) {
7659
+ const isUncheckedCheckbox = field.type === 'checkbox' && value === false;
7660
+ const isUnsetValue = minDash.isNil(value) || value === '';
7661
+ const isEmptyMultiselect = Array.isArray(value) && value.length === 0;
7662
+ if (isUncheckedCheckbox || isUnsetValue || isEmptyMultiselect) {
7663
+ errors.push('Field is required.');
7664
+ }
7665
+ }
7666
+ if ('min' in validation && (value || value === 0) && value < validation.min) {
7667
+ errors.push(`Field must have minimum value of ${validation.min}.`);
7668
+ }
7669
+ if ('max' in validation && (value || value === 0) && value > validation.max) {
7670
+ errors.push(`Field must have maximum value of ${validation.max}.`);
7671
+ }
7672
+ if ('minLength' in validation && value && value.trim().length < validation.minLength) {
7673
+ errors.push(`Field must have minimum length of ${validation.minLength}.`);
7674
+ }
7675
+ if ('maxLength' in validation && value && value.trim().length > validation.maxLength) {
7676
+ errors.push(`Field must have maximum length of ${validation.maxLength}.`);
7677
+ }
7678
+ if ('validationType' in validation && value && validation.validationType === 'phone' && !PHONE_PATTERN.test(value)) {
7679
+ errors.push('Field must be a valid international phone number. (e.g. +4930664040900)');
7680
+ }
7681
+ if ('validationType' in validation && value && validation.validationType === 'email' && !EMAIL_PATTERN.test(value)) {
7682
+ errors.push('Field must be a valid email.');
7683
+ }
7684
+ return errors;
7685
+ }
7686
+ function evaluateFEELValues(validate, expressionLanguage, expressionContextInfo) {
7687
+ const evaluatedValidate = {
7688
+ ...validate
7689
+ };
7690
+ VALIDATE_FEEL_PROPERTIES.forEach(property => {
7691
+ const path = property.split('.');
7692
+ const value = minDash.get(evaluatedValidate, path);
7693
+ const evaluatedValue = runExpressionEvaluation(expressionLanguage, value, expressionContextInfo);
7694
+ minDash.set(evaluatedValidate, path, evaluatedValue === null ? undefined : evaluatedValue);
7695
+ });
7696
+ return evaluatedValidate;
7697
+ }
7698
+ function oldEvaluateFEELValues(validate, expressionLanguage, conditionChecker, form) {
7533
7699
  const evaluatedValidate = {
7534
7700
  ...validate
7535
7701
  };
@@ -8233,6 +8399,66 @@ class FormFieldRegistry {
8233
8399
  }
8234
8400
  FormFieldRegistry.$inject = ['eventBus'];
8235
8401
 
8402
+ class FormFieldInstanceRegistry {
8403
+ constructor(eventBus, formFieldRegistry, formFields) {
8404
+ this._eventBus = eventBus;
8405
+ this._formFieldRegistry = formFieldRegistry;
8406
+ this._formFields = formFields;
8407
+ this._formFieldInstances = {};
8408
+ eventBus.on('form.clear', () => this.clear());
8409
+ }
8410
+ add(instance) {
8411
+ const {
8412
+ id,
8413
+ expressionContextInfo,
8414
+ valuePath,
8415
+ indexes
8416
+ } = instance;
8417
+ const instanceId = [id, ...Object.values(indexes || {})].join('_');
8418
+ if (this._formFieldInstances[instanceId]) {
8419
+ throw new Error('this form field instance is already registered');
8420
+ }
8421
+ this._formFieldInstances[instanceId] = {
8422
+ id,
8423
+ instanceId,
8424
+ expressionContextInfo,
8425
+ valuePath,
8426
+ indexes
8427
+ };
8428
+ return instanceId;
8429
+ }
8430
+ remove(instanceId) {
8431
+ if (!this._formFieldInstances[instanceId]) {
8432
+ return;
8433
+ }
8434
+ delete this._formFieldInstances[instanceId];
8435
+ }
8436
+ getAll() {
8437
+ return Object.values(this._formFieldInstances);
8438
+ }
8439
+ getAllKeyed() {
8440
+ return this.getAll().filter(({
8441
+ id
8442
+ }) => {
8443
+ const formFieldDefinition = this._formFieldRegistry.get(id);
8444
+ if (!formFieldDefinition) {
8445
+ return false;
8446
+ }
8447
+ const {
8448
+ type
8449
+ } = formFieldDefinition;
8450
+ const {
8451
+ config
8452
+ } = this._formFields.get(type);
8453
+ return config.keyed;
8454
+ });
8455
+ }
8456
+ clear() {
8457
+ this._formFieldInstances = {};
8458
+ }
8459
+ }
8460
+ FormFieldInstanceRegistry.$inject = ['eventBus', 'formFieldRegistry', 'formFields'];
8461
+
8236
8462
  function Renderer(config, eventBus, form, injector) {
8237
8463
  const App = () => {
8238
8464
  const [state, setState] = hooks.useState(form._getState());
@@ -8297,6 +8523,7 @@ const CoreModule = {
8297
8523
  importer: ['type', Importer],
8298
8524
  fieldFactory: ['type', FieldFactory],
8299
8525
  formFieldRegistry: ['type', FormFieldRegistry],
8526
+ formFieldInstanceRegistry: ['type', FormFieldInstanceRegistry],
8300
8527
  pathRegistry: ['type', PathRegistry],
8301
8528
  formLayouter: ['type', FormLayouter],
8302
8529
  validator: ['type', Validator]
@@ -8471,73 +8698,40 @@ class Form {
8471
8698
  * @returns {Errors}
8472
8699
  */
8473
8700
  validate() {
8474
- const formFields = this.get('formFields'),
8475
- formFieldRegistry = this.get('formFieldRegistry'),
8476
- pathRegistry = this.get('pathRegistry'),
8701
+ const formFieldRegistry = this.get('formFieldRegistry'),
8702
+ formFieldInstanceRegistry = this.get('formFieldInstanceRegistry'),
8477
8703
  validator = this.get('validator');
8478
8704
  const {
8479
8705
  data
8480
8706
  } = this._getState();
8481
- const getErrorPath = (field, indexes) => [field.id, ...Object.values(indexes || {})];
8482
- function validateFieldRecursively(errors, field, indexes) {
8483
- const {
8484
- disabled,
8485
- type,
8486
- isRepeating
8487
- } = field;
8707
+ const errors = {};
8708
+ const getErrorPath = (id, indexes) => [id, ...Object.values(indexes || {})];
8709
+ formFieldInstanceRegistry.getAllKeyed().forEach(fieldInstance => {
8488
8710
  const {
8489
- config: fieldConfig
8490
- } = formFields.get(type);
8711
+ id,
8712
+ valuePath,
8713
+ indexes
8714
+ } = fieldInstance;
8715
+ const field = formFieldRegistry.get(id);
8491
8716
 
8492
8717
  // (1) Skip disabled fields
8493
- if (disabled) {
8718
+ if (field.disabled) {
8494
8719
  return;
8495
8720
  }
8496
8721
 
8497
- // (2) Validate the field
8498
- const valuePath = pathRegistry.getValuePath(field, {
8499
- indexes
8500
- });
8501
- const valueData = minDash.get(data, valuePath);
8502
- const fieldErrors = validator.validateField(field, valueData);
8722
+ // (2) Validate the field instance
8723
+ const value = minDash.get(data, valuePath);
8724
+ const fieldErrors = validator.validateFieldInstance(fieldInstance, value);
8503
8725
  if (fieldErrors.length) {
8504
- minDash.set(errors, getErrorPath(field, indexes), fieldErrors);
8505
- }
8506
-
8507
- // (3) Process parents
8508
- if (!Array.isArray(field.components)) {
8509
- return;
8726
+ minDash.set(errors, getErrorPath(field.id, indexes), fieldErrors);
8510
8727
  }
8511
-
8512
- // (4a) Recurse repeatable parents both across the indexes of repetition and the children
8513
- if (fieldConfig.repeatable && isRepeating) {
8514
- if (!Array.isArray(valueData)) {
8515
- return;
8516
- }
8517
- valueData.forEach((_, index) => {
8518
- field.components.forEach(component => {
8519
- validateFieldRecursively(errors, component, {
8520
- ...indexes,
8521
- [field.id]: index
8522
- });
8523
- });
8524
- });
8525
- return;
8526
- }
8527
-
8528
- // (4b) Recurse non-repeatable parents only across the children
8529
- field.components.forEach(component => validateFieldRecursively(errors, component, indexes));
8530
- }
8531
- const workingErrors = {};
8532
- validateFieldRecursively(workingErrors, formFieldRegistry.getForm());
8533
- const filteredErrors = this._applyConditions(workingErrors, data, {
8534
- getFilterPath: getErrorPath,
8535
- leafNodeDeletionOnly: true
8536
8728
  });
8537
8729
  this._setState({
8538
- errors: filteredErrors
8730
+ errors
8539
8731
  });
8540
- return filteredErrors;
8732
+
8733
+ // @ts-ignore
8734
+ return errors;
8541
8735
  }
8542
8736
 
8543
8737
  /**
@@ -8632,26 +8826,27 @@ class Form {
8632
8826
  /**
8633
8827
  * @internal
8634
8828
  *
8635
- * @param { { add?: boolean, field: any, indexes: object, remove?: number, value?: any } } update
8829
+ * @param { { fieldInstance: any, value: any } } update
8636
8830
  */
8637
8831
  _update(update) {
8638
8832
  const {
8639
- field,
8640
- indexes,
8833
+ fieldInstance,
8641
8834
  value
8642
8835
  } = update;
8836
+ const {
8837
+ id,
8838
+ valuePath,
8839
+ indexes
8840
+ } = fieldInstance;
8643
8841
  const {
8644
8842
  data,
8645
8843
  errors
8646
8844
  } = this._getState();
8647
- const validator = this.get('validator'),
8648
- pathRegistry = this.get('pathRegistry');
8649
- const fieldErrors = validator.validateField(field, value);
8650
- const valuePath = pathRegistry.getValuePath(field, {
8651
- indexes
8652
- });
8845
+ const validator = this.get('validator');
8846
+ const fieldErrors = validator.validateFieldInstance(fieldInstance, value);
8653
8847
  minDash.set(data, valuePath, value);
8654
- minDash.set(errors, [field.id, ...Object.values(indexes || {})], fieldErrors.length ? fieldErrors : undefined);
8848
+ minDash.set(errors, [id, ...Object.values(indexes || {})], fieldErrors.length ? fieldErrors : undefined);
8849
+ this._emit('field.updated', update);
8655
8850
  this._setState({
8656
8851
  data: clone(data),
8657
8852
  errors: clone(errors)
@@ -8677,10 +8872,10 @@ class Form {
8677
8872
  }
8678
8873
 
8679
8874
  /**
8680
- * @internal
8681
- */
8875
+ * @internal
8876
+ */
8682
8877
  _getModules() {
8683
- return [ExpressionLanguageModule, MarkdownRendererModule, ViewerCommandsModule, RepeatRenderModule];
8878
+ return [ExpressionLanguageModule, ExpressionFieldModule, MarkdownRendererModule, ViewerCommandsModule, RepeatRenderModule];
8684
8879
  }
8685
8880
 
8686
8881
  /**
@@ -8695,65 +8890,24 @@ class Form {
8695
8890
  */
8696
8891
  _getSubmitData() {
8697
8892
  const formFieldRegistry = this.get('formFieldRegistry');
8698
- const formFields = this.get('formFields');
8699
- const pathRegistry = this.get('pathRegistry');
8893
+ const formFieldInstanceRegistry = this.get('formFieldInstanceRegistry');
8700
8894
  const formData = this._getState().data;
8701
- function collectSubmitDataRecursively(submitData, formField, indexes) {
8895
+ const submitData = {};
8896
+ formFieldInstanceRegistry.getAllKeyed().forEach(formFieldInstance => {
8702
8897
  const {
8703
- disabled,
8704
- type
8705
- } = formField;
8898
+ id,
8899
+ valuePath
8900
+ } = formFieldInstance;
8706
8901
  const {
8707
- config: fieldConfig
8708
- } = formFields.get(type);
8709
-
8710
- // (1) Process keyed fields
8711
- if (!disabled && fieldConfig.keyed) {
8712
- const valuePath = pathRegistry.getValuePath(formField, {
8713
- indexes
8714
- });
8715
- const value = minDash.get(formData, valuePath);
8716
- minDash.set(submitData, valuePath, value);
8717
- }
8718
-
8719
- // (2) Process parents
8720
- if (!Array.isArray(formField.components)) {
8721
- return;
8722
- }
8723
-
8724
- // (3a) Recurse repeatable parents both across the indexes of repetition and the children
8725
- if (fieldConfig.repeatable && formField.isRepeating) {
8726
- const valueData = minDash.get(formData, pathRegistry.getValuePath(formField, {
8727
- indexes
8728
- }));
8729
- if (!Array.isArray(valueData)) {
8730
- return;
8731
- }
8732
- valueData.forEach((_, index) => {
8733
- formField.components.forEach(component => {
8734
- collectSubmitDataRecursively(submitData, component, {
8735
- ...indexes,
8736
- [formField.id]: index
8737
- });
8738
- });
8739
- });
8902
+ disabled
8903
+ } = formFieldRegistry.get(id);
8904
+ if (disabled) {
8740
8905
  return;
8741
8906
  }
8742
-
8743
- // (3b) Recurse non-repeatable parents only across the children
8744
- formField.components.forEach(component => collectSubmitDataRecursively(submitData, component, indexes));
8745
- }
8746
- const workingSubmitData = {};
8747
- collectSubmitDataRecursively(workingSubmitData, formFieldRegistry.getForm(), {});
8748
- return this._applyConditions(workingSubmitData, formData);
8749
- }
8750
-
8751
- /**
8752
- * @internal
8753
- */
8754
- _applyConditions(toFilter, data, options = {}) {
8755
- const conditionChecker = this.get('conditionChecker');
8756
- return conditionChecker.applyConditions(toFilter, data, options);
8907
+ const value = minDash.get(formData, valuePath);
8908
+ minDash.set(submitData, valuePath, value);
8909
+ });
8910
+ return submitData;
8757
8911
  }
8758
8912
 
8759
8913
  /**
@@ -8848,16 +9002,16 @@ class Form {
8848
9002
 
8849
9003
  const schemaVersion = 16;
8850
9004
 
8851
- /**
8852
- * @typedef { import('./types').CreateFormOptions } CreateFormOptions
9005
+ /**
9006
+ * @typedef { import('./types').CreateFormOptions } CreateFormOptions
8853
9007
  */
8854
9008
 
8855
- /**
8856
- * Create a form.
8857
- *
8858
- * @param {CreateFormOptions} options
8859
- *
8860
- * @return {Promise<Form>}
9009
+ /**
9010
+ * Create a form.
9011
+ *
9012
+ * @param {CreateFormOptions} options
9013
+ *
9014
+ * @return {Promise<Form>}
8861
9015
  */
8862
9016
  function createForm(options) {
8863
9017
  const {
@@ -8887,7 +9041,9 @@ exports.Description = Description;
8887
9041
  exports.DynamicList = DynamicList;
8888
9042
  exports.Errors = Errors;
8889
9043
  exports.ExpressionField = ExpressionField;
9044
+ exports.ExpressionFieldModule = ExpressionFieldModule;
8890
9045
  exports.ExpressionLanguageModule = ExpressionLanguageModule;
9046
+ exports.ExpressionLoopPreventer = ExpressionLoopPreventer;
8891
9047
  exports.FeelExpressionLanguage = FeelExpressionLanguage;
8892
9048
  exports.FeelersTemplating = FeelersTemplating;
8893
9049
  exports.FieldFactory = FieldFactory;
@@ -8956,6 +9112,7 @@ exports.iconsByType = iconsByType;
8956
9112
  exports.isRequired = isRequired;
8957
9113
  exports.pathParse = pathParse;
8958
9114
  exports.pathsEqual = pathsEqual;
9115
+ exports.runExpressionEvaluation = runExpressionEvaluation;
8959
9116
  exports.runRecursively = runRecursively;
8960
9117
  exports.sanitizeDateTimePickerValue = sanitizeDateTimePickerValue;
8961
9118
  exports.sanitizeHTML = sanitizeHTML;
@@ -8968,4 +9125,5 @@ exports.useExpressionEvaluation = useExpressionEvaluation;
8968
9125
  exports.useSingleLineTemplateEvaluation = useSingleLineTemplateEvaluation;
8969
9126
  exports.useTemplateEvaluation = useTemplateEvaluation;
8970
9127
  exports.wrapCSSStyles = wrapCSSStyles;
9128
+ exports.wrapObjectKeysWithUnderscores = wrapObjectKeysWithUnderscores;
8971
9129
  //# sourceMappingURL=index.cjs.map