@bpmn-io/form-js-viewer 1.6.2 → 1.6.4

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.es.js CHANGED
@@ -54,26 +54,26 @@ const getFlavouredFeelVariableNames = (feelString, feelFlavour = 'expression', o
54
54
  return [...new Set(variables)];
55
55
  };
56
56
 
57
- /**
58
- * Get the variable name at the specified index in a given path expression.
59
- *
60
- * @param {Object} root - The root node of the path expression tree.
61
- * @param {number} index - The index of the variable name to retrieve.
62
- * @returns {string|null} The variable name at the specified index or null if index is out of bounds.
57
+ /**
58
+ * Get the variable name at the specified index in a given path expression.
59
+ *
60
+ * @param {Object} root - The root node of the path expression tree.
61
+ * @param {number} index - The index of the variable name to retrieve.
62
+ * @returns {string|null} The variable name at the specified index or null if index is out of bounds.
63
63
  */
64
64
  const _getVariableNameAtPathIndex = (root, index) => {
65
65
  const nodes = _linearizePathExpression(root);
66
66
  return nodes[index].variableName || null;
67
67
  };
68
68
 
69
- /**
70
- * Extracts the variables which are required of the external context for a given path expression.
71
- * This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
72
- *
73
- * @param {Object} node - The root node of the path expression tree.
74
- * @param {number} initialDepth - The depth at which the root node is located in the outer context.
75
- * @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
76
- * @returns {Set} - A set containing the extracted variable names.
69
+ /**
70
+ * Extracts the variables which are required of the external context for a given path expression.
71
+ * This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
72
+ *
73
+ * @param {Object} node - The root node of the path expression tree.
74
+ * @param {number} initialDepth - The depth at which the root node is located in the outer context.
75
+ * @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
76
+ * @returns {Set} - A set containing the extracted variable names.
77
77
  */
78
78
  const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) => {
79
79
  // depth info represents the previous (initialised as null) and current depth of the current accessor in the path expression
@@ -119,11 +119,11 @@ const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) =
119
119
  return new Set(extractedVariables);
120
120
  };
121
121
 
122
- /**
123
- * Deconstructs a path expression tree into an array of components.
124
- *
125
- * @param {Object} root - The root node of the path expression tree.
126
- * @returns {Array<object>} An array of components in the path expression, in the correct order.
122
+ /**
123
+ * Deconstructs a path expression tree into an array of components.
124
+ *
125
+ * @param {Object} root - The root node of the path expression tree.
126
+ * @returns {Array<object>} An array of components in the path expression, in the correct order.
127
127
  */
128
128
  const _linearizePathExpression = root => {
129
129
  let node = root;
@@ -142,13 +142,13 @@ const _linearizePathExpression = root => {
142
142
  return parts.reverse();
143
143
  };
144
144
 
145
- /**
146
- * Builds a simplified feel structure tree from the given parse tree and feel string.
147
- * The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
148
- *
149
- * @param {Object} parseTree - The parse tree generated by a parser.
150
- * @param {string} feelString - The feel string used for parsing.
151
- * @returns {Object} The simplified feel structure tree.
145
+ /**
146
+ * Builds a simplified feel structure tree from the given parse tree and feel string.
147
+ * The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
148
+ *
149
+ * @param {Object} parseTree - The parse tree generated by a parser.
150
+ * @param {string} feelString - The feel string used for parsing.
151
+ * @returns {Object} The simplified feel structure tree.
152
152
  */
153
153
  const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
154
154
  const stack = [{
@@ -174,9 +174,9 @@ const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
174
174
  return _extractFilterExpressions(stack[0].children[0]);
175
175
  };
176
176
 
177
- /**
178
- * Restructure the tree in such a way to bring filters (which create new contexts) to the root of the tree.
179
- * This is done to simplify the extraction of variables and match the context hierarchy.
177
+ /**
178
+ * Restructure the tree in such a way to bring filters (which create new contexts) to the root of the tree.
179
+ * This is done to simplify the extraction of variables and match the context hierarchy.
180
180
  */
181
181
  const _extractFilterExpressions = tree => {
182
182
  const flattenedExpressionTree = {
@@ -217,25 +217,25 @@ class FeelExpressionLanguage {
217
217
  this._eventBus = eventBus;
218
218
  }
219
219
 
220
- /**
221
- * Determines if the given value is a FEEL expression.
222
- *
223
- * @param {any} value
224
- * @returns {boolean}
225
- *
220
+ /**
221
+ * Determines if the given value is a FEEL expression.
222
+ *
223
+ * @param {any} value
224
+ * @returns {boolean}
225
+ *
226
226
  */
227
227
  isExpression(value) {
228
228
  return isString(value) && value.startsWith('=');
229
229
  }
230
230
 
231
- /**
232
- * Retrieve variable names from a given FEEL expression.
233
- *
234
- * @param {string} expression
235
- * @param {object} [options]
236
- * @param {string} [options.type]
237
- *
238
- * @returns {string[]}
231
+ /**
232
+ * Retrieve variable names from a given FEEL expression.
233
+ *
234
+ * @param {string} expression
235
+ * @param {object} [options]
236
+ * @param {string} [options.type]
237
+ *
238
+ * @returns {string[]}
239
239
  */
240
240
  getVariableNames(expression, options = {}) {
241
241
  const {
@@ -250,13 +250,13 @@ class FeelExpressionLanguage {
250
250
  return getFlavouredFeelVariableNames(expression, type);
251
251
  }
252
252
 
253
- /**
254
- * Evaluate an expression.
255
- *
256
- * @param {string} expression
257
- * @param {import('../../types').Data} [data]
258
- *
259
- * @returns {any}
253
+ /**
254
+ * Evaluate an expression.
255
+ *
256
+ * @param {string} expression
257
+ * @param {import('../../types').Data} [data]
258
+ *
259
+ * @returns {any}
260
260
  */
261
261
  evaluate(expression, data = {}) {
262
262
  if (!expression) {
@@ -281,23 +281,23 @@ FeelExpressionLanguage.$inject = ['eventBus'];
281
281
  class FeelersTemplating {
282
282
  constructor() {}
283
283
 
284
- /**
285
- * Determines if the given value is a feelers template.
286
- *
287
- * @param {any} value
288
- * @returns {boolean}
289
- *
284
+ /**
285
+ * Determines if the given value is a feelers template.
286
+ *
287
+ * @param {any} value
288
+ * @returns {boolean}
289
+ *
290
290
  */
291
291
  isTemplate(value) {
292
292
  return isString(value) && (value.startsWith('=') || /{{.*?}}/.test(value));
293
293
  }
294
294
 
295
- /**
296
- * Retrieve variable names from a given feelers template.
297
- *
298
- * @param {string} template
299
- *
300
- * @returns {string[]}
295
+ /**
296
+ * Retrieve variable names from a given feelers template.
297
+ *
298
+ * @param {string} template
299
+ *
300
+ * @returns {string[]}
301
301
  */
302
302
  getVariableNames(template) {
303
303
  if (!this.isTemplate(template)) {
@@ -323,17 +323,17 @@ class FeelersTemplating {
323
323
  }, []);
324
324
  }
325
325
 
326
- /**
327
- * Evaluate a template.
328
- *
329
- * @param {string} template
330
- * @param {Object<string, any>} context
331
- * @param {Object} options
332
- * @param {boolean} [options.debug = false]
333
- * @param {boolean} [options.strict = false]
334
- * @param {Function} [options.buildDebugString]
335
- *
336
- * @returns
326
+ /**
327
+ * Evaluate a template.
328
+ *
329
+ * @param {string} template
330
+ * @param {Object<string, any>} context
331
+ * @param {Object} options
332
+ * @param {boolean} [options.debug = false]
333
+ * @param {boolean} [options.strict = false]
334
+ * @param {Function} [options.buildDebugString]
335
+ *
336
+ * @returns
337
337
  */
338
338
  evaluate(template, context = {}, options = {}) {
339
339
  const {
@@ -348,22 +348,22 @@ class FeelersTemplating {
348
348
  });
349
349
  }
350
350
 
351
- /**
352
- * @typedef {Object} ExpressionWithDepth
353
- * @property {number} depth - The depth of the expression in the syntax tree.
354
- * @property {string} expression - The extracted expression
351
+ /**
352
+ * @typedef {Object} ExpressionWithDepth
353
+ * @property {number} depth - The depth of the expression in the syntax tree.
354
+ * @property {string} expression - The extracted expression
355
355
  */
356
356
 
357
- /**
358
- * Extracts all feel expressions in the template along with their depth in the syntax tree.
359
- * The depth is incremented for child expressions of loops to account for context drilling.
360
- * @name extractExpressionsWithDepth
361
- * @param {string} template - A feelers template string.
362
- * @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
363
- *
364
- * @example
365
- * const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
366
- * const extractedExpressions = _extractExpressionsWithDepth(template);
357
+ /**
358
+ * Extracts all feel expressions in the template along with their depth in the syntax tree.
359
+ * The depth is incremented for child expressions of loops to account for context drilling.
360
+ * @name extractExpressionsWithDepth
361
+ * @param {string} template - A feelers template string.
362
+ * @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
363
+ *
364
+ * @example
365
+ * const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
366
+ * const extractedExpressions = _extractExpressionsWithDepth(template);
367
367
  */
368
368
  _extractExpressionsWithDepth(template) {
369
369
  // build simplified feelers syntax tree
@@ -469,10 +469,10 @@ function createInjector(bootstrapModules) {
469
469
  return injector;
470
470
  }
471
471
 
472
- /**
473
- * @param {string?} prefix
474
- *
475
- * @returns Element
472
+ /**
473
+ * @param {string?} prefix
474
+ *
475
+ * @returns Element
476
476
  */
477
477
  function createFormContainer(prefix = 'fjs') {
478
478
  const container = document.createElement('div');
@@ -603,11 +603,11 @@ const LocalExpressionContext = createContext({
603
603
  });
604
604
  var LocalExpressionContext$1 = LocalExpressionContext;
605
605
 
606
- /**
607
- * @param {string} type
608
- * @param {boolean} [strict]
609
- *
610
- * @returns {any}
606
+ /**
607
+ * @param {string} type
608
+ * @param {boolean} [strict]
609
+ *
610
+ * @returns {any}
611
611
  */
612
612
  function getService(type, strict) {}
613
613
  const FormContext = createContext({
@@ -650,21 +650,21 @@ function generateIdForType(type) {
650
650
  return `${type}${generateIndexForType(type)}`;
651
651
  }
652
652
 
653
- /**
654
- * @template T
655
- * @param {T} data
656
- * @param {(this: any, key: string, value: any) => any} [replacer]
657
- * @return {T}
653
+ /**
654
+ * @template T
655
+ * @param {T} data
656
+ * @param {(this: any, key: string, value: any) => any} [replacer]
657
+ * @return {T}
658
658
  */
659
659
  function clone(data, replacer) {
660
660
  return JSON.parse(JSON.stringify(data, replacer));
661
661
  }
662
662
 
663
- /**
664
- * Transform a LocalExpressionContext object into a usable FEEL context.
665
- *
666
- * @param {Object} context - The LocalExpressionContext object.
667
- * @returns {Object} The usable FEEL context.
663
+ /**
664
+ * Transform a LocalExpressionContext object into a usable FEEL context.
665
+ *
666
+ * @param {Object} context - The LocalExpressionContext object.
667
+ * @returns {Object} The usable FEEL context.
668
668
  */
669
669
 
670
670
  function buildExpressionContext(context) {
@@ -696,12 +696,12 @@ function _wrapObjectKeysWithUnderscores(obj) {
696
696
  return newObj;
697
697
  }
698
698
 
699
- /**
700
- * Evaluate if condition is met reactively based on the conditionChecker and form data.
701
- *
702
- * @param {string | undefined} condition
703
- *
704
- * @returns {boolean} true if condition is met or no condition or condition checker exists
699
+ /**
700
+ * Evaluate if condition is met reactively based on the conditionChecker and form data.
701
+ *
702
+ * @param {string | undefined} condition
703
+ *
704
+ * @returns {boolean} true if condition is met or no condition or condition checker exists
705
705
  */
706
706
  function useCondition(condition) {
707
707
  const conditionChecker = useService('conditionChecker', false);
@@ -711,17 +711,17 @@ function useCondition(condition) {
711
711
  }, [conditionChecker, condition, expressionContextInfo]);
712
712
  }
713
713
 
714
- /**
715
- * Custom hook to scroll an element into view only when it is not visible within the viewport.
716
- *
717
- * @param {Object} targetRef - A ref pointing to the DOM element to scroll into view.
718
- * @param {Array} deps - An array of dependencies that trigger the effect.
719
- * @param {Array} flagRefs - An array of refs that are used as flags to control when to scroll.
720
- * @param {Object} [scrollOptions={}] - Options defining the behavior of the scrolling.
721
- * @param {String} [scrollOptions.align='center'] - The alignment of the element within the viewport.
722
- * @param {String} [scrollOptions.behavior='auto'] - The scrolling behavior.
723
- * @param {Number} [scrollOptions.offset=0] - An offset that is added to the scroll position.
724
- * @param {Boolean} [scrollOptions.scrollIfVisible=false] - Whether to scroll even if the element is visible.
714
+ /**
715
+ * Custom hook to scroll an element into view only when it is not visible within the viewport.
716
+ *
717
+ * @param {Object} targetRef - A ref pointing to the DOM element to scroll into view.
718
+ * @param {Array} deps - An array of dependencies that trigger the effect.
719
+ * @param {Array} flagRefs - An array of refs that are used as flags to control when to scroll.
720
+ * @param {Object} [scrollOptions={}] - Options defining the behavior of the scrolling.
721
+ * @param {String} [scrollOptions.align='center'] - The alignment of the element within the viewport.
722
+ * @param {String} [scrollOptions.behavior='auto'] - The scrolling behavior.
723
+ * @param {Number} [scrollOptions.offset=0] - An offset that is added to the scroll position.
724
+ * @param {Boolean} [scrollOptions.scrollIfVisible=false] - Whether to scroll even if the element is visible.
725
725
  */
726
726
  function useScrollIntoView(targetRef, deps, scrollOptions = null, flagRefs = []) {
727
727
  useEffect(() => {
@@ -786,13 +786,13 @@ function _getTopOffset(item, scrollContainer, options) {
786
786
  return 0;
787
787
  }
788
788
 
789
- /**
790
- * Evaluate a string reactively based on the expressionLanguage and form data.
791
- * If the string is not an expression, it is returned as is.
792
- * The function is memoized to minimize re-renders.
793
- *
794
- * @param {string} value - The string to evaluate.
795
- * @returns {any} - Evaluated value or the original value if not an expression.
789
+ /**
790
+ * Evaluate a string reactively based on the expressionLanguage and form data.
791
+ * If the string is not an expression, it is returned as is.
792
+ * The function is memoized to minimize re-renders.
793
+ *
794
+ * @param {string} value - The string to evaluate.
795
+ * @returns {any} - Evaluated value or the original value if not an expression.
796
796
  */
797
797
  function useExpressionEvaluation(value) {
798
798
  const expressionLanguage = useService('expressionLanguage');
@@ -805,11 +805,11 @@ function useExpressionEvaluation(value) {
805
805
  }, [expressionLanguage, expressionContextInfo, value]);
806
806
  }
807
807
 
808
- /**
809
- * Returns the conditionally filtered data of a form reactively.
810
- * Memoised to minimize re-renders
811
- *
812
- * Warning: costly operation, use with care
808
+ /**
809
+ * Returns the conditionally filtered data of a form reactively.
810
+ * Memoised to minimize re-renders
811
+ *
812
+ * Warning: costly operation, use with care
813
813
  */
814
814
  function useFilteredFormData() {
815
815
  const {
@@ -842,16 +842,16 @@ function useKeyDownAction(targetKey, action, listenerElement = window) {
842
842
  });
843
843
  }
844
844
 
845
- /**
846
- * Retrieve readonly value of a form field, given it can be an
847
- * expression optionally or configured globally.
848
- *
849
- * @typedef { import('../../types').FormProperties } FormProperties
850
- *
851
- * @param {any} formField
852
- * @param {FormProperties} properties
853
- *
854
- * @returns {boolean}
845
+ /**
846
+ * Retrieve readonly value of a form field, given it can be an
847
+ * expression optionally or configured globally.
848
+ *
849
+ * @typedef { import('../../types').FormProperties } FormProperties
850
+ *
851
+ * @param {any} formField
852
+ * @param {FormProperties} properties
853
+ *
854
+ * @returns {boolean}
855
855
  */
856
856
  function useReadonly(formField, properties = {}) {
857
857
  const expressionLanguage = useService('expressionLanguage');
@@ -875,12 +875,12 @@ function usePrevious(value, defaultValue, dependencies) {
875
875
  return ref.current;
876
876
  }
877
877
 
878
- /**
879
- * A custom hook to manage state changes with deep comparison.
880
- *
881
- * @param {any} value - The current value to manage.
882
- * @param {any} defaultValue - The initial default value for the state.
883
- * @returns {any} - Returns the current state.
878
+ /**
879
+ * A custom hook to manage state changes with deep comparison.
880
+ *
881
+ * @param {any} value - The current value to manage.
882
+ * @param {any} defaultValue - The initial default value for the state.
883
+ * @returns {any} - Returns the current state.
884
884
  */
885
885
  function useDeepCompareState(value, defaultValue) {
886
886
  const [state, setState] = useState(defaultValue);
@@ -900,16 +900,16 @@ function compare(a, b) {
900
900
  return JSON.stringify(a) === JSON.stringify(b);
901
901
  }
902
902
 
903
- /**
904
- * Template a string reactively based on form data. If the string is not a template, it is returned as is.
905
- * Memoised to minimize re-renders
906
- *
907
- * @param {string} value
908
- * @param {Object} options
909
- * @param {boolean} [options.debug = false]
910
- * @param {boolean} [options.strict = false]
911
- * @param {Function} [options.buildDebugString]
912
- *
903
+ /**
904
+ * Template a string reactively based on form data. If the string is not a template, it is returned as is.
905
+ * Memoised to minimize re-renders
906
+ *
907
+ * @param {string} value
908
+ * @param {Object} options
909
+ * @param {boolean} [options.debug = false]
910
+ * @param {boolean} [options.strict = false]
911
+ * @param {Function} [options.buildDebugString]
912
+ *
913
913
  */
914
914
  function useTemplateEvaluation(value, options = {}) {
915
915
  const templating = useService('templating');
@@ -922,17 +922,17 @@ function useTemplateEvaluation(value, options = {}) {
922
922
  }, [templating, value, expressionContextInfo, options]);
923
923
  }
924
924
 
925
- /**
926
- * Template a string reactively based on form data. If the string is not a template, it is returned as is.
927
- * If the string contains multiple lines, only the first line is returned.
928
- * Memoised to minimize re-renders
929
- *
930
- * @param {string} value
931
- * @param {Object} [options]
932
- * @param {boolean} [options.debug = false]
933
- * @param {boolean} [options.strict = false]
934
- * @param {Function} [options.buildDebugString]
935
- *
925
+ /**
926
+ * Template a string reactively based on form data. If the string is not a template, it is returned as is.
927
+ * If the string contains multiple lines, only the first line is returned.
928
+ * Memoised to minimize re-renders
929
+ *
930
+ * @param {string} value
931
+ * @param {Object} [options]
932
+ * @param {boolean} [options.debug = false]
933
+ * @param {boolean} [options.strict = false]
934
+ * @param {Function} [options.buildDebugString]
935
+ *
936
936
  */
937
937
  function useSingleLineTemplateEvaluation(value, options = {}) {
938
938
  const evaluatedTemplate = useTemplateEvaluation(value, options);
@@ -1088,15 +1088,15 @@ function normalizeOptionsData(optionsData) {
1088
1088
  return optionsData.filter(_isAllowedValue).map(_normalizeOption).filter(o => !isNil(o));
1089
1089
  }
1090
1090
 
1091
- /**
1092
- * Converts the provided option to a normalized format.
1093
- * If the option is not valid, null is returned.
1094
- *
1095
- * @param {object} option
1096
- * @param {string} option.label
1097
- * @param {*} option.value
1098
- *
1099
- * @returns
1091
+ /**
1092
+ * Converts the provided option to a normalized format.
1093
+ * If the option is not valid, null is returned.
1094
+ *
1095
+ * @param {object} option
1096
+ * @param {string} option.label
1097
+ * @param {*} option.value
1098
+ *
1099
+ * @returns
1100
1100
  */
1101
1101
  function _normalizeOption(option) {
1102
1102
  // (1) simple primitive case, use it as both label and value
@@ -1154,8 +1154,8 @@ function createEmptyOptions(options = {}) {
1154
1154
  };
1155
1155
  }
1156
1156
 
1157
- /**
1158
- * @enum { String }
1157
+ /**
1158
+ * @enum { String }
1159
1159
  */
1160
1160
  const LOAD_STATES = {
1161
1161
  LOADING: 'loading',
@@ -1163,17 +1163,17 @@ const LOAD_STATES = {
1163
1163
  ERROR: 'error'
1164
1164
  };
1165
1165
 
1166
- /**
1167
- * @typedef {Object} OptionsGetter
1168
- * @property {Object[]} options - The options data
1169
- * @property {(LOAD_STATES)} loadState - The options data's loading state, to use for conditional rendering
1166
+ /**
1167
+ * @typedef {Object} OptionsGetter
1168
+ * @property {Object[]} options - The options data
1169
+ * @property {(LOAD_STATES)} loadState - The options data's loading state, to use for conditional rendering
1170
1170
  */
1171
1171
 
1172
- /**
1173
- * A hook to load options for single and multiselect components.
1174
- *
1175
- * @param {Object} field - The form field to handle options for
1176
- * @return {OptionsGetter} optionsGetter - A options getter object providing loading state and options
1172
+ /**
1173
+ * A hook to load options for single and multiselect components.
1174
+ *
1175
+ * @param {Object} field - The form field to handle options for
1176
+ * @return {OptionsGetter} optionsGetter - A options getter object providing loading state and options
1177
1177
  */
1178
1178
  function useOptionsAsync (field) {
1179
1179
  const {
@@ -1820,12 +1820,12 @@ FormComponent$1.config = {
1820
1820
  })
1821
1821
  };
1822
1822
 
1823
- /**
1824
- * Returns date format for the provided locale.
1825
- * If the locale is not provided, uses the browser's locale.
1826
- *
1827
- * @param {string} [locale] - The locale to get date format for.
1828
- * @returns {string} The date format for the locale.
1823
+ /**
1824
+ * Returns date format for the provided locale.
1825
+ * If the locale is not provided, uses the browser's locale.
1826
+ *
1827
+ * @param {string} [locale] - The locale to get date format for.
1828
+ * @returns {string} The date format for the locale.
1829
1829
  */
1830
1830
  function getLocaleDateFormat(locale = 'default') {
1831
1831
  const parts = new Intl.DateTimeFormat(locale).formatToParts(new Date(Date.UTC(2020, 5, 5)));
@@ -1844,12 +1844,12 @@ function getLocaleDateFormat(locale = 'default') {
1844
1844
  }).join('');
1845
1845
  }
1846
1846
 
1847
- /**
1848
- * Returns readable date format for the provided locale.
1849
- * If the locale is not provided, uses the browser's locale.
1850
- *
1851
- * @param {string} [locale] - The locale to get readable date format for.
1852
- * @returns {string} The readable date format for the locale.
1847
+ /**
1848
+ * Returns readable date format for the provided locale.
1849
+ * If the locale is not provided, uses the browser's locale.
1850
+ *
1851
+ * @param {string} [locale] - The locale to get readable date format for.
1852
+ * @returns {string} The readable date format for the locale.
1853
1853
  */
1854
1854
  function getLocaleReadableDateFormat(locale) {
1855
1855
  let format = getLocaleDateFormat(locale).toLowerCase();
@@ -1866,12 +1866,12 @@ function getLocaleReadableDateFormat(locale) {
1866
1866
  return format;
1867
1867
  }
1868
1868
 
1869
- /**
1870
- * Returns flatpickr config for the provided locale.
1871
- * If the locale is not provided, uses the browser's locale.
1872
- *
1873
- * @param {string} [locale] - The locale to get flatpickr config for.
1874
- * @returns {object} The flatpickr config for the locale.
1869
+ /**
1870
+ * Returns flatpickr config for the provided locale.
1871
+ * If the locale is not provided, uses the browser's locale.
1872
+ *
1873
+ * @param {string} [locale] - The locale to get flatpickr config for.
1874
+ * @returns {object} The flatpickr config for the locale.
1875
1875
  */
1876
1876
  function getLocaleDateFlatpickrConfig(locale) {
1877
1877
  return flatpickerizeDateFormat(getLocaleDateFormat(locale));
@@ -2583,10 +2583,10 @@ Datetime.config = {
2583
2583
  }
2584
2584
  };
2585
2585
 
2586
- /**
2587
- * This file must not be changed or exchanged.
2588
- *
2589
- * @see http://bpmn.io/license for more information.
2586
+ /**
2587
+ * This file must not be changed or exchanged.
2588
+ *
2589
+ * @see http://bpmn.io/license for more information.
2590
2590
  */
2591
2591
  function Logo() {
2592
2592
  return jsxs("svg", {
@@ -2772,11 +2772,11 @@ const ATTR_WHITESPACE_PATTERN = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u
2772
2772
 
2773
2773
  const FORM_ELEMENT = document.createElement('form');
2774
2774
 
2775
- /**
2776
- * Sanitize a HTML string and return the cleaned, safe version.
2777
- *
2778
- * @param {string} html
2779
- * @return {string}
2775
+ /**
2776
+ * Sanitize a HTML string and return the cleaned, safe version.
2777
+ *
2778
+ * @param {string} html
2779
+ * @return {string}
2780
2780
  */
2781
2781
 
2782
2782
  // see https://github.com/developit/snarkdown/issues/70
@@ -2794,41 +2794,41 @@ function sanitizeHTML(html) {
2794
2794
  }
2795
2795
  }
2796
2796
 
2797
- /**
2798
- * Sanitizes an image source to ensure we only allow for data URI and links
2799
- * that start with http(s).
2800
- *
2801
- * Note: Most browsers anyway do not support script execution in <img> elements.
2802
- *
2803
- * @param {string} src
2804
- * @returns {string}
2797
+ /**
2798
+ * Sanitizes an image source to ensure we only allow for data URI and links
2799
+ * that start with http(s).
2800
+ *
2801
+ * Note: Most browsers anyway do not support script execution in <img> elements.
2802
+ *
2803
+ * @param {string} src
2804
+ * @returns {string}
2805
2805
  */
2806
2806
  function sanitizeImageSource(src) {
2807
2807
  const valid = ALLOWED_IMAGE_SRC_PATTERN.test(src);
2808
2808
  return valid ? src : '';
2809
2809
  }
2810
2810
 
2811
- /**
2812
- * Sanitizes an iframe source to ensure we only allow for links
2813
- * that start with http(s).
2814
- *
2815
- * @param {string} src
2816
- * @returns {string}
2811
+ /**
2812
+ * Sanitizes an iframe source to ensure we only allow for links
2813
+ * that start with http(s).
2814
+ *
2815
+ * @param {string} src
2816
+ * @returns {string}
2817
2817
  */
2818
2818
  function sanitizeIFrameSource(src) {
2819
2819
  const valid = ALLOWED_IFRAME_SRC_PATTERN.test(src);
2820
2820
  return valid ? src : '';
2821
2821
  }
2822
2822
 
2823
- /**
2824
- * Recursively sanitize a HTML node, potentially
2825
- * removing it, its children or attributes.
2826
- *
2827
- * Inspired by https://github.com/developit/snarkdown/issues/70
2828
- * and https://github.com/cure53/DOMPurify. Simplified
2829
- * for our use-case.
2830
- *
2831
- * @param {Element} node
2823
+ /**
2824
+ * Recursively sanitize a HTML node, potentially
2825
+ * removing it, its children or attributes.
2826
+ *
2827
+ * Inspired by https://github.com/developit/snarkdown/issues/70
2828
+ * and https://github.com/cure53/DOMPurify. Simplified
2829
+ * for our use-case.
2830
+ *
2831
+ * @param {Element} node
2832
2832
  */
2833
2833
  function sanitizeNode(node) {
2834
2834
  // allow text nodes
@@ -2872,13 +2872,13 @@ function sanitizeNode(node) {
2872
2872
  }
2873
2873
  }
2874
2874
 
2875
- /**
2876
- * Validates attributes for validity.
2877
- *
2878
- * @param {string} lcTag
2879
- * @param {string} lcName
2880
- * @param {string} value
2881
- * @return {boolean}
2875
+ /**
2876
+ * Validates attributes for validity.
2877
+ *
2878
+ * @param {string} lcTag
2879
+ * @param {string} lcName
2880
+ * @param {string} value
2881
+ * @return {boolean}
2882
2882
  */
2883
2883
  function isValidAttribute(lcTag, lcName, value) {
2884
2884
  // disallow most attributes based on whitelist
@@ -3058,40 +3058,6 @@ Image.config = {
3058
3058
  })
3059
3059
  };
3060
3060
 
3061
- function useFlushDebounce(func, additionalDeps = []) {
3062
- const timeoutRef = useRef(null);
3063
- const lastArgsRef = useRef(null);
3064
- const config = useService('config', false);
3065
- const debounce = config && config.debounce;
3066
- const shouldDebounce = debounce !== false && debounce !== 0;
3067
- const delay = typeof debounce === 'number' ? debounce : 300;
3068
- const debounceFunc = useCallback((...args) => {
3069
- if (!shouldDebounce) {
3070
- func(...args);
3071
- return;
3072
- }
3073
- lastArgsRef.current = args;
3074
- if (timeoutRef.current) {
3075
- clearTimeout(timeoutRef.current);
3076
- }
3077
- timeoutRef.current = setTimeout(() => {
3078
- func(...lastArgsRef.current);
3079
- lastArgsRef.current = null;
3080
- }, delay);
3081
- }, [func, delay, shouldDebounce, ...additionalDeps]);
3082
- const flushFunc = useCallback(() => {
3083
- if (timeoutRef.current) {
3084
- clearTimeout(timeoutRef.current);
3085
- if (lastArgsRef.current !== null) {
3086
- func(...lastArgsRef.current);
3087
- lastArgsRef.current = null;
3088
- }
3089
- timeoutRef.current = null;
3090
- }
3091
- }, [func, ...additionalDeps]);
3092
- return [debounceFunc, flushFunc];
3093
- }
3094
-
3095
3061
  function TemplatedInputAdorner(props) {
3096
3062
  const {
3097
3063
  pre,
@@ -3182,7 +3148,8 @@ function Numberfield(props) {
3182
3148
  onFocus,
3183
3149
  field,
3184
3150
  value,
3185
- readonly
3151
+ readonly,
3152
+ onChange
3186
3153
  } = props;
3187
3154
  const {
3188
3155
  description,
@@ -3202,16 +3169,6 @@ function Numberfield(props) {
3202
3169
  } = validate;
3203
3170
  const inputRef = useRef();
3204
3171
  const [stringValueCache, setStringValueCache] = useState('');
3205
- const [onChangeDebounced, flushOnChange] = useFlushDebounce(params => {
3206
- props.onChange(params);
3207
- }, [props.onChange]);
3208
- const onInputBlur = () => {
3209
- flushOnChange && flushOnChange();
3210
- onBlur && onBlur();
3211
- };
3212
- const onInputFocus = () => {
3213
- onFocus && onFocus();
3214
- };
3215
3172
 
3216
3173
  // checks whether the value currently in the form data is practically different from the one in the input field cache
3217
3174
  // this allows us to guarantee the field always displays valid form data, but without auto-simplifying values like 1.000 to 1
@@ -3235,7 +3192,7 @@ function Numberfield(props) {
3235
3192
  const setValue = useCallback(stringValue => {
3236
3193
  if (isNullEquivalentValue(stringValue)) {
3237
3194
  setStringValueCache('');
3238
- onChangeDebounced({
3195
+ onChange({
3239
3196
  field,
3240
3197
  value: null
3241
3198
  });
@@ -3250,18 +3207,18 @@ function Numberfield(props) {
3250
3207
  }
3251
3208
  if (isNaN(Number(stringValue))) {
3252
3209
  setStringValueCache('NaN');
3253
- onChangeDebounced({
3210
+ onChange({
3254
3211
  field,
3255
3212
  value: 'NaN'
3256
3213
  });
3257
3214
  return;
3258
3215
  }
3259
3216
  setStringValueCache(stringValue);
3260
- onChangeDebounced({
3217
+ onChange({
3261
3218
  field,
3262
3219
  value: serializeToString ? stringValue : Number(stringValue)
3263
3220
  });
3264
- }, [field, onChangeDebounced, serializeToString]);
3221
+ }, [field, onChange, serializeToString]);
3265
3222
  const increment = () => {
3266
3223
  if (readonly) {
3267
3224
  return;
@@ -3345,8 +3302,8 @@ function Numberfield(props) {
3345
3302
  id: domId,
3346
3303
  onKeyDown: onKeyDown,
3347
3304
  onKeyPress: onKeyPress,
3348
- onBlur: onInputBlur,
3349
- onFocus: onInputFocus
3305
+ onBlur: onBlur,
3306
+ onFocus: onFocus
3350
3307
 
3351
3308
  // @ts-ignore
3352
3309
  ,
@@ -3536,9 +3493,9 @@ Radio.config = {
3536
3493
  create: createEmptyOptions
3537
3494
  };
3538
3495
 
3539
- /**
3540
- * This hook allows us to retrieve the label from a value in linear time by caching it in a map
3541
- * @param {Array} options
3496
+ /**
3497
+ * This hook allows us to retrieve the label from a value in linear time by caching it in a map
3498
+ * @param {Array} options
3542
3499
  */
3543
3500
  function useGetLabelCorrelation(options) {
3544
3501
  // This allows us to retrieve the label from a value in linear time
@@ -4356,6 +4313,40 @@ function DisabledLink({
4356
4313
  });
4357
4314
  }
4358
4315
 
4316
+ function useFlushDebounce(func, additionalDeps = []) {
4317
+ const timeoutRef = useRef(null);
4318
+ const lastArgsRef = useRef(null);
4319
+ const config = useService('config', false);
4320
+ const debounce = config && config.debounce;
4321
+ const shouldDebounce = debounce !== false && debounce !== 0;
4322
+ const delay = typeof debounce === 'number' ? debounce : 300;
4323
+ const debounceFunc = useCallback((...args) => {
4324
+ if (!shouldDebounce) {
4325
+ func(...args);
4326
+ return;
4327
+ }
4328
+ lastArgsRef.current = args;
4329
+ if (timeoutRef.current) {
4330
+ clearTimeout(timeoutRef.current);
4331
+ }
4332
+ timeoutRef.current = setTimeout(() => {
4333
+ func(...lastArgsRef.current);
4334
+ lastArgsRef.current = null;
4335
+ }, delay);
4336
+ }, [func, delay, shouldDebounce, ...additionalDeps]);
4337
+ const flushFunc = useCallback(() => {
4338
+ if (timeoutRef.current) {
4339
+ clearTimeout(timeoutRef.current);
4340
+ if (lastArgsRef.current !== null) {
4341
+ func(...lastArgsRef.current);
4342
+ lastArgsRef.current = null;
4343
+ }
4344
+ timeoutRef.current = null;
4345
+ }
4346
+ }, [func, ...additionalDeps]);
4347
+ return [debounceFunc, flushFunc];
4348
+ }
4349
+
4359
4350
  const type$2 = 'textfield';
4360
4351
  function Textfield(props) {
4361
4352
  const {
@@ -4616,28 +4607,28 @@ var CaretRightIcon = SvgCaretRight;
4616
4607
 
4617
4608
  const type = 'table';
4618
4609
 
4619
- /**
4620
- * @typedef {('asc'|'desc')} Direction
4621
- *
4622
- * @typedef Sorting
4623
- * @property {string} key
4624
- * @property {Direction} direction
4625
- *
4626
- * @typedef Column
4627
- * @property {string} label
4628
- * @property {string} key
4629
- *
4630
- * @typedef Props
4631
- * @property {Object} field
4632
- * @property {string} field.id
4633
- * @property {Array<Column>} [field.columns]
4634
- * @property {string} [field.columnsExpression]
4635
- * @property {string} [field.label]
4636
- * @property {number} [field.rowCount]
4637
- * @property {string} [field.dataSource]
4638
- *
4639
- * @param {Props} props
4640
- * @returns {import("preact").JSX.Element}
4610
+ /**
4611
+ * @typedef {('asc'|'desc')} Direction
4612
+ *
4613
+ * @typedef Sorting
4614
+ * @property {string} key
4615
+ * @property {Direction} direction
4616
+ *
4617
+ * @typedef Column
4618
+ * @property {string} label
4619
+ * @property {string} key
4620
+ *
4621
+ * @typedef Props
4622
+ * @property {Object} field
4623
+ * @property {string} field.id
4624
+ * @property {Array<Column>} [field.columns]
4625
+ * @property {string} [field.columnsExpression]
4626
+ * @property {string} [field.label]
4627
+ * @property {number} [field.rowCount]
4628
+ * @property {string} [field.dataSource]
4629
+ *
4630
+ * @param {Props} props
4631
+ * @returns {import("preact").JSX.Element}
4641
4632
  */
4642
4633
  function Table(props) {
4643
4634
  const {
@@ -4847,10 +4838,10 @@ Table.config = {
4847
4838
 
4848
4839
  // helpers /////////////////////////////
4849
4840
 
4850
- /**
4851
- * @param {string|void} columnsExpression
4852
- * @param {Column[]} fallbackColumns
4853
- * @returns {Column[]}
4841
+ /**
4842
+ * @param {string|void} columnsExpression
4843
+ * @param {Column[]} fallbackColumns
4844
+ * @returns {Column[]}
4854
4845
  */
4855
4846
  function useEvaluatedColumns(columnsExpression, fallbackColumns) {
4856
4847
  /** @type {Column[]|null} */
@@ -4858,18 +4849,18 @@ function useEvaluatedColumns(columnsExpression, fallbackColumns) {
4858
4849
  return Array.isArray(evaluation) && evaluation.every(isColumn) ? evaluation : fallbackColumns;
4859
4850
  }
4860
4851
 
4861
- /**
4862
- * @param {any} column
4863
- * @returns {column is Column}
4852
+ /**
4853
+ * @param {any} column
4854
+ * @returns {column is Column}
4864
4855
  */
4865
4856
  function isColumn(column) {
4866
4857
  return isObject(column) && isString(column['label']) && isString(column['key']);
4867
4858
  }
4868
4859
 
4869
- /**
4870
- * @param {Array} array
4871
- * @param {number} size
4872
- * @returns {Array}
4860
+ /**
4861
+ * @param {Array} array
4862
+ * @param {number} size
4863
+ * @returns {Array}
4873
4864
  */
4874
4865
  function chunk(array, size) {
4875
4866
  return array.reduce((chunks, item, index) => {
@@ -4882,11 +4873,11 @@ function chunk(array, size) {
4882
4873
  }, []);
4883
4874
  }
4884
4875
 
4885
- /**
4886
- * @param {unknown[]} array
4887
- * @param {string} key
4888
- * @param {Direction} direction
4889
- * @returns {unknown[]}
4876
+ /**
4877
+ * @param {unknown[]} array
4878
+ * @param {string} key
4879
+ * @param {Direction} direction
4880
+ * @returns {unknown[]}
4890
4881
  */
4891
4882
  function sortByColumn(array, key, direction) {
4892
4883
  return [...array].sort((a, b) => {
@@ -4900,10 +4891,10 @@ function sortByColumn(array, key, direction) {
4900
4891
  });
4901
4892
  }
4902
4893
 
4903
- /**
4904
- * @param {null|Sorting} sortBy
4905
- * @param {string} key
4906
- * @param {string} label
4894
+ /**
4895
+ * @param {null|Sorting} sortBy
4896
+ * @param {string} key
4897
+ * @param {string} label
4907
4898
  */
4908
4899
  function getHeaderAriaLabel(sortBy, key, label) {
4909
4900
  if (sortBy === null || sortBy.key !== key) {
@@ -5278,37 +5269,37 @@ class FormFields {
5278
5269
  const EXPRESSION_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'conditional.hide', 'description', 'label', 'source', 'readonly', 'text', 'validate.min', 'validate.max', 'validate.minLength', 'validate.maxLength', 'valuesExpression', 'url', 'dataSource', 'columnsExpression'];
5279
5270
  const TEMPLATE_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'description', 'label', 'source', 'text', 'url'];
5280
5271
 
5281
- /**
5282
- * @typedef { import('../types').Schema } Schema
5272
+ /**
5273
+ * @typedef { import('../types').Schema } Schema
5283
5274
  */
5284
5275
 
5285
- /**
5286
- * Parse the schema for variables a form might make use of.
5287
- *
5288
- * @example
5289
- *
5290
- * // retrieve variables from schema
5291
- * const variables = getSchemaVariables(schema);
5292
- *
5293
- * @example
5294
- *
5295
- * // retrieve input variables from schema
5296
- * const inputVariables = getSchemaVariables(schema, { outputs: false });
5297
- *
5298
- * @example
5299
- *
5300
- * // retrieve output variables from schema
5301
- * const outputVariables = getSchemaVariables(schema, { inputs: false });
5302
- *
5303
- * @param {Schema} schema
5304
- * @param {object} [options]
5305
- * @param {any} [options.expressionLanguage]
5306
- * @param {any} [options.templating]
5307
- * @param {any} [options.formFields]
5308
- * @param {boolean} [options.inputs=true]
5309
- * @param {boolean} [options.outputs=true]
5310
- *
5311
- * @return {string[]}
5276
+ /**
5277
+ * Parse the schema for variables a form might make use of.
5278
+ *
5279
+ * @example
5280
+ *
5281
+ * // retrieve variables from schema
5282
+ * const variables = getSchemaVariables(schema);
5283
+ *
5284
+ * @example
5285
+ *
5286
+ * // retrieve input variables from schema
5287
+ * const inputVariables = getSchemaVariables(schema, { outputs: false });
5288
+ *
5289
+ * @example
5290
+ *
5291
+ * // retrieve output variables from schema
5292
+ * const outputVariables = getSchemaVariables(schema, { inputs: false });
5293
+ *
5294
+ * @param {Schema} schema
5295
+ * @param {object} [options]
5296
+ * @param {any} [options.expressionLanguage]
5297
+ * @param {any} [options.templating]
5298
+ * @param {any} [options.formFields]
5299
+ * @param {boolean} [options.inputs=true]
5300
+ * @param {boolean} [options.outputs=true]
5301
+ *
5302
+ * @return {string[]}
5312
5303
  */
5313
5304
  function getSchemaVariables(schema, options = {}) {
5314
5305
  const {
@@ -5384,13 +5375,13 @@ function getSchemaVariables(schema, options = {}) {
5384
5375
  return Array.from(new Set(variables));
5385
5376
  }
5386
5377
 
5387
- /**
5388
- * Get the ancestry list of a form field.
5389
- *
5390
- * @param {string} formFieldId
5391
- * @param {import('../core/FormFieldRegistry').default} formFieldRegistry
5392
- *
5393
- * @return {Array<string>} ancestry list
5378
+ /**
5379
+ * Get the ancestry list of a form field.
5380
+ *
5381
+ * @param {string} formFieldId
5382
+ * @param {import('../core/FormFieldRegistry').default} formFieldRegistry
5383
+ *
5384
+ * @return {Array<string>} ancestry list
5394
5385
  */
5395
5386
  const getAncestryList = (formFieldId, formFieldRegistry) => {
5396
5387
  const ids = [];
@@ -5402,9 +5393,9 @@ const getAncestryList = (formFieldId, formFieldRegistry) => {
5402
5393
  return ids;
5403
5394
  };
5404
5395
 
5405
- /**
5406
- * @typedef {object} Condition
5407
- * @property {string} [hide]
5396
+ /**
5397
+ * @typedef {object} Condition
5398
+ * @property {string} [hide]
5408
5399
  */
5409
5400
 
5410
5401
  class ConditionChecker {
@@ -5414,14 +5405,14 @@ class ConditionChecker {
5414
5405
  this._eventBus = eventBus;
5415
5406
  }
5416
5407
 
5417
- /**
5418
- * For given data, remove properties based on condition.
5419
- *
5420
- * @param {Object<string, any>} data
5421
- * @param {Object<string, any>} contextData
5422
- * @param {Object} [options]
5423
- * @param {Function} [options.getFilterPath]
5424
- * @param {boolean} [options.leafNodeDeletionOnly]
5408
+ /**
5409
+ * For given data, remove properties based on condition.
5410
+ *
5411
+ * @param {Object<string, any>} data
5412
+ * @param {Object<string, any>} contextData
5413
+ * @param {Object} [options]
5414
+ * @param {Function} [options.getFilterPath]
5415
+ * @param {boolean} [options.leafNodeDeletionOnly]
5425
5416
  */
5426
5417
  applyConditions(data, contextData = {}, options = {}) {
5427
5418
  const workingData = clone(data);
@@ -5515,13 +5506,13 @@ class ConditionChecker {
5515
5506
  return workingData;
5516
5507
  }
5517
5508
 
5518
- /**
5519
- * Check if given condition is met. Returns null for invalid/missing conditions.
5520
- *
5521
- * @param {string} condition
5522
- * @param {import('../../types').Data} [data]
5523
- *
5524
- * @returns {boolean|null}
5509
+ /**
5510
+ * Check if given condition is met. Returns null for invalid/missing conditions.
5511
+ *
5512
+ * @param {string} condition
5513
+ * @param {import('../../types').Data} [data]
5514
+ *
5515
+ * @returns {boolean|null}
5525
5516
  */
5526
5517
  check(condition, data = {}) {
5527
5518
  if (!condition) {
@@ -5542,12 +5533,12 @@ class ConditionChecker {
5542
5533
  }
5543
5534
  }
5544
5535
 
5545
- /**
5546
- * Check if hide condition is met.
5547
- *
5548
- * @param {Condition} condition
5549
- * @param {Object<string, any>} data
5550
- * @returns {boolean}
5536
+ /**
5537
+ * Check if hide condition is met.
5538
+ *
5539
+ * @param {Condition} condition
5540
+ * @param {Object<string, any>} data
5541
+ * @returns {boolean}
5551
5542
  */
5552
5543
  _checkHideCondition(condition, data) {
5553
5544
  if (!condition.hide) {
@@ -5589,12 +5580,12 @@ class MarkdownRenderer {
5589
5580
  this._converter = new showdown.Converter();
5590
5581
  }
5591
5582
 
5592
- /**
5593
- * Render markdown to HTML.
5594
- *
5595
- * @param {string} markdown - The markdown to render
5596
- *
5597
- * @returns {string} HTML
5583
+ /**
5584
+ * Render markdown to HTML.
5585
+ *
5586
+ * @param {string} markdown - The markdown to render
5587
+ *
5588
+ * @returns {string} HTML
5598
5589
  */
5599
5590
  render(markdown) {
5600
5591
  return this._converter.makeHtml(markdown);
@@ -6215,11 +6206,11 @@ class RepeatRenderManager {
6215
6206
  this.RepeatFooter = this.RepeatFooter.bind(this);
6216
6207
  }
6217
6208
 
6218
- /**
6219
- * Checks whether a field is currently repeating its children.
6220
- *
6221
- * @param {string} id - The id of the field to check
6222
- * @returns {boolean} - True if repeatable, false otherwise
6209
+ /**
6210
+ * Checks whether a field is currently repeating its children.
6211
+ *
6212
+ * @param {string} id - The id of the field to check
6213
+ * @returns {boolean} - True if repeatable, false otherwise
6223
6214
  */
6224
6215
  isFieldRepeating(id) {
6225
6216
  if (!id) {
@@ -6979,8 +6970,8 @@ Validator.$inject = ['expressionLanguage', 'conditionChecker', 'form'];
6979
6970
 
6980
6971
  // helpers //////////
6981
6972
 
6982
- /**
6983
- * Helper function to evaluate optional FEEL validation values.
6973
+ /**
6974
+ * Helper function to evaluate optional FEEL validation values.
6984
6975
  */
6985
6976
  function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form) {
6986
6977
  const evaluatedValidate = {
@@ -7014,12 +7005,12 @@ function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form
7014
7005
  }
7015
7006
 
7016
7007
  class Importer {
7017
- /**
7018
- * @constructor
7019
- * @param { import('./FormFieldRegistry').default } formFieldRegistry
7020
- * @param { import('./PathRegistry').default } pathRegistry
7021
- * @param { import('./FieldFactory').default } fieldFactory
7022
- * @param { import('./FormLayouter').default } formLayouter
7008
+ /**
7009
+ * @constructor
7010
+ * @param { import('./FormFieldRegistry').default } formFieldRegistry
7011
+ * @param { import('./PathRegistry').default } pathRegistry
7012
+ * @param { import('./FieldFactory').default } fieldFactory
7013
+ * @param { import('./FormLayouter').default } formLayouter
7023
7014
  */
7024
7015
  constructor(formFieldRegistry, pathRegistry, fieldFactory, formLayouter) {
7025
7016
  this._formFieldRegistry = formFieldRegistry;
@@ -7028,21 +7019,21 @@ class Importer {
7028
7019
  this._formLayouter = formLayouter;
7029
7020
  }
7030
7021
 
7031
- /**
7032
- * Import schema creating rows, fields, attaching additional
7033
- * information to each field and adding fields to the
7034
- * field registry.
7035
- *
7036
- * Additional information attached:
7037
- *
7038
- * * `id` (unless present)
7039
- * * `_parent`
7040
- * * `_path`
7041
- *
7042
- * @param {any} schema
7043
- *
7044
- * @typedef {{ warnings: Error[], schema: any }} ImportResult
7045
- * @returns {ImportResult}
7022
+ /**
7023
+ * Import schema creating rows, fields, attaching additional
7024
+ * information to each field and adding fields to the
7025
+ * field registry.
7026
+ *
7027
+ * Additional information attached:
7028
+ *
7029
+ * * `id` (unless present)
7030
+ * * `_parent`
7031
+ * * `_path`
7032
+ *
7033
+ * @param {any} schema
7034
+ *
7035
+ * @typedef {{ warnings: Error[], schema: any }} ImportResult
7036
+ * @returns {ImportResult}
7046
7037
  */
7047
7038
  importSchema(schema) {
7048
7039
  // TODO: Add warnings
@@ -7067,12 +7058,12 @@ class Importer {
7067
7058
  this._pathRegistry.clear();
7068
7059
  }
7069
7060
 
7070
- /**
7071
- * @param {{[x: string]: any}} fieldAttrs
7072
- * @param {String} [parentId]
7073
- * @param {number} [index]
7074
- *
7075
- * @return {any} field
7061
+ /**
7062
+ * @param {{[x: string]: any}} fieldAttrs
7063
+ * @param {String} [parentId]
7064
+ * @param {number} [index]
7065
+ *
7066
+ * @return {any} field
7076
7067
  */
7077
7068
  importFormField(fieldAttrs, parentId, index) {
7078
7069
  const {
@@ -7097,11 +7088,11 @@ class Importer {
7097
7088
  return field;
7098
7089
  }
7099
7090
 
7100
- /**
7101
- * @param {Array<any>} components
7102
- * @param {string} parentId
7103
- *
7104
- * @return {Array<any>} imported components
7091
+ /**
7092
+ * @param {Array<any>} components
7093
+ * @param {string} parentId
7094
+ *
7095
+ * @return {Array<any>} imported components
7105
7096
  */
7106
7097
  importFormFields(components, parentId) {
7107
7098
  return components.map((component, index) => {
@@ -7112,11 +7103,11 @@ class Importer {
7112
7103
  Importer.$inject = ['formFieldRegistry', 'pathRegistry', 'fieldFactory', 'formLayouter'];
7113
7104
 
7114
7105
  class FieldFactory {
7115
- /**
7116
- * @constructor
7117
- *
7118
- * @param formFieldRegistry
7119
- * @param formFields
7106
+ /**
7107
+ * @constructor
7108
+ *
7109
+ * @param formFieldRegistry
7110
+ * @param formFields
7120
7111
  */
7121
7112
  constructor(formFieldRegistry, pathRegistry, formFields) {
7122
7113
  this._formFieldRegistry = formFieldRegistry;
@@ -7226,36 +7217,36 @@ class FieldFactory {
7226
7217
  }
7227
7218
  FieldFactory.$inject = ['formFieldRegistry', 'pathRegistry', 'formFields'];
7228
7219
 
7229
- /**
7230
- * The PathRegistry class manages a hierarchical structure of paths associated with form fields.
7231
- * It enables claiming, unclaiming, and validating paths within this structure.
7232
- *
7233
- * Example Tree Structure:
7234
- *
7235
- * [
7236
- * {
7237
- * segment: 'root',
7238
- * claimCount: 1,
7239
- * children: [
7240
- * {
7241
- * segment: 'child1',
7242
- * claimCount: 2,
7243
- * children: null // A leaf node (closed path)
7244
- * },
7245
- * {
7246
- * segment: 'child2',
7247
- * claimCount: 1,
7248
- * children: [
7249
- * {
7250
- * segment: 'subChild1',
7251
- * claimCount: 1,
7252
- * children: [] // An open node (open path)
7253
- * }
7254
- * ]
7255
- * }
7256
- * ]
7257
- * }
7258
- * ]
7220
+ /**
7221
+ * The PathRegistry class manages a hierarchical structure of paths associated with form fields.
7222
+ * It enables claiming, unclaiming, and validating paths within this structure.
7223
+ *
7224
+ * Example Tree Structure:
7225
+ *
7226
+ * [
7227
+ * {
7228
+ * segment: 'root',
7229
+ * claimCount: 1,
7230
+ * children: [
7231
+ * {
7232
+ * segment: 'child1',
7233
+ * claimCount: 2,
7234
+ * children: null // A leaf node (closed path)
7235
+ * },
7236
+ * {
7237
+ * segment: 'child2',
7238
+ * claimCount: 1,
7239
+ * children: [
7240
+ * {
7241
+ * segment: 'subChild1',
7242
+ * claimCount: 1,
7243
+ * children: [] // An open node (open path)
7244
+ * }
7245
+ * ]
7246
+ * }
7247
+ * ]
7248
+ * }
7249
+ * ]
7259
7250
  */
7260
7251
  class PathRegistry {
7261
7252
  constructor(formFieldRegistry, formFields, injector) {
@@ -7371,16 +7362,16 @@ class PathRegistry {
7371
7362
  }
7372
7363
  }
7373
7364
 
7374
- /**
7375
- * Applies a function (fn) recursively on a given field and its children.
7376
- *
7377
- * - `field`: Starting field object.
7378
- * - `fn`: Function to apply.
7379
- * - `context`: Optional object for passing data between calls.
7380
- *
7381
- * Stops early if `fn` returns `false`. Useful for traversing the form field tree.
7382
- *
7383
- * @returns {boolean} Success status based on function execution.
7365
+ /**
7366
+ * Applies a function (fn) recursively on a given field and its children.
7367
+ *
7368
+ * - `field`: Starting field object.
7369
+ * - `fn`: Function to apply.
7370
+ * - `context`: Optional object for passing data between calls.
7371
+ *
7372
+ * Stops early if `fn` returns `false`. Useful for traversing the form field tree.
7373
+ *
7374
+ * @returns {boolean} Success status based on function execution.
7384
7375
  */
7385
7376
  executeRecursivelyOnFields(field, fn, context = {}) {
7386
7377
  let result = true;
@@ -7421,16 +7412,16 @@ class PathRegistry {
7421
7412
  return result;
7422
7413
  }
7423
7414
 
7424
- /**
7425
- * Generates an array representing the binding path to an underlying data object for a form field.
7426
- *
7427
- * @param {Object} field - The field object with properties: `key`, `path`, `id`, and optionally `_parent`.
7428
- * @param {Object} [options={}] - Configuration options.
7429
- * @param {Object} [options.replacements={}] - A map of field IDs to alternative path arrays.
7430
- * @param {Object} [options.indexes=null] - A map of parent IDs to the index of the field within said parent, leave null to get an unindexed path.
7431
- * @param {Object} [options.cutoffNode] - The ID of the parent field at which to stop generating the path.
7432
- *
7433
- * @returns {(Array<string>|undefined)} An array of strings representing the binding path, or undefined if not determinable.
7415
+ /**
7416
+ * Generates an array representing the binding path to an underlying data object for a form field.
7417
+ *
7418
+ * @param {Object} field - The field object with properties: `key`, `path`, `id`, and optionally `_parent`.
7419
+ * @param {Object} [options={}] - Configuration options.
7420
+ * @param {Object} [options.replacements={}] - A map of field IDs to alternative path arrays.
7421
+ * @param {Object} [options.indexes=null] - A map of parent IDs to the index of the field within said parent, leave null to get an unindexed path.
7422
+ * @param {Object} [options.cutoffNode] - The ID of the parent field at which to stop generating the path.
7423
+ *
7424
+ * @returns {(Array<string>|undefined)} An array of strings representing the binding path, or undefined if not determinable.
7434
7425
  */
7435
7426
  getValuePath(field, options = {}) {
7436
7427
  const {
@@ -7491,23 +7482,23 @@ const _getNextSegment = (node, segment) => {
7491
7482
  };
7492
7483
  PathRegistry.$inject = ['formFieldRegistry', 'formFields', 'injector'];
7493
7484
 
7494
- /**
7495
- * @typedef { { id: String, components: Array<String> } } FormRow
7496
- * @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
7485
+ /**
7486
+ * @typedef { { id: String, components: Array<String> } } FormRow
7487
+ * @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
7497
7488
  */
7498
7489
 
7499
- /**
7500
- * Maintains the Form layout in a given structure, for example
7501
- *
7502
- * [
7503
- * {
7504
- * formFieldId: 'FormField_1',
7505
- * rows: [
7506
- * { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
7507
- * ]
7508
- * }
7509
- * ]
7510
- *
7490
+ /**
7491
+ * Maintains the Form layout in a given structure, for example
7492
+ *
7493
+ * [
7494
+ * {
7495
+ * formFieldId: 'FormField_1',
7496
+ * rows: [
7497
+ * { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
7498
+ * ]
7499
+ * }
7500
+ * ]
7501
+ *
7511
7502
  */
7512
7503
  class FormLayouter {
7513
7504
  constructor(eventBus) {
@@ -7517,8 +7508,8 @@ class FormLayouter {
7517
7508
  this._eventBus = eventBus;
7518
7509
  }
7519
7510
 
7520
- /**
7521
- * @param {FormRow} row
7511
+ /**
7512
+ * @param {FormRow} row
7522
7513
  */
7523
7514
  addRow(formFieldId, row) {
7524
7515
  let rowsPerComponent = this._rows.find(r => r.formFieldId === formFieldId);
@@ -7532,18 +7523,18 @@ class FormLayouter {
7532
7523
  rowsPerComponent.rows.push(row);
7533
7524
  }
7534
7525
 
7535
- /**
7536
- * @param {String} id
7537
- * @returns {FormRow}
7526
+ /**
7527
+ * @param {String} id
7528
+ * @returns {FormRow}
7538
7529
  */
7539
7530
  getRow(id) {
7540
7531
  const rows = allRows(this._rows);
7541
7532
  return rows.find(r => r.id === id);
7542
7533
  }
7543
7534
 
7544
- /**
7545
- * @param {any} formField
7546
- * @returns {FormRow}
7535
+ /**
7536
+ * @param {any} formField
7537
+ * @returns {FormRow}
7547
7538
  */
7548
7539
  getRowForField(formField) {
7549
7540
  return allRows(this._rows).find(r => {
@@ -7554,9 +7545,9 @@ class FormLayouter {
7554
7545
  });
7555
7546
  }
7556
7547
 
7557
- /**
7558
- * @param {String} formFieldId
7559
- * @returns { Array<FormRow> }
7548
+ /**
7549
+ * @param {String} formFieldId
7550
+ * @returns { Array<FormRow> }
7560
7551
  */
7561
7552
  getRows(formFieldId) {
7562
7553
  const rowsForField = this._rows.find(r => formFieldId === r.formFieldId);
@@ -7566,15 +7557,15 @@ class FormLayouter {
7566
7557
  return rowsForField.rows;
7567
7558
  }
7568
7559
 
7569
- /**
7570
- * @returns {string}
7560
+ /**
7561
+ * @returns {string}
7571
7562
  */
7572
7563
  nextRowId() {
7573
7564
  return this._ids.nextPrefixed('Row_');
7574
7565
  }
7575
7566
 
7576
- /**
7577
- * @param {any} formField
7567
+ /**
7568
+ * @param {any} formField
7578
7569
  */
7579
7570
  calculateLayout(formField) {
7580
7571
  const {
@@ -7628,9 +7619,9 @@ function groupByRow(components, ids) {
7628
7619
  });
7629
7620
  }
7630
7621
 
7631
- /**
7632
- * @param {Array<FormRows>} formRows
7633
- * @returns {Array<FormRow>}
7622
+ /**
7623
+ * @param {Array<FormRows>} formRows
7624
+ * @returns {Array<FormRow>}
7634
7625
  */
7635
7626
  function allRows(formRows) {
7636
7627
  return flatten(formRows.map(c => c.rows));
@@ -7755,55 +7746,55 @@ var core = {
7755
7746
  validator: ['type', Validator]
7756
7747
  };
7757
7748
 
7758
- /**
7759
- * @typedef { import('./types').Injector } Injector
7760
- * @typedef { import('./types').Data } Data
7761
- * @typedef { import('./types').Errors } Errors
7762
- * @typedef { import('./types').Schema } Schema
7763
- * @typedef { import('./types').FormProperties } FormProperties
7764
- * @typedef { import('./types').FormProperty } FormProperty
7765
- * @typedef { import('./types').FormEvent } FormEvent
7766
- * @typedef { import('./types').FormOptions } FormOptions
7767
- *
7768
- * @typedef { {
7769
- * data: Data,
7770
- * initialData: Data,
7771
- * errors: Errors,
7772
- * properties: FormProperties,
7773
- * schema: Schema
7774
- * } } State
7775
- *
7776
- * @typedef { (type:FormEvent, priority:number, handler:Function) => void } OnEventWithPriority
7777
- * @typedef { (type:FormEvent, handler:Function) => void } OnEventWithOutPriority
7778
- * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
7749
+ /**
7750
+ * @typedef { import('./types').Injector } Injector
7751
+ * @typedef { import('./types').Data } Data
7752
+ * @typedef { import('./types').Errors } Errors
7753
+ * @typedef { import('./types').Schema } Schema
7754
+ * @typedef { import('./types').FormProperties } FormProperties
7755
+ * @typedef { import('./types').FormProperty } FormProperty
7756
+ * @typedef { import('./types').FormEvent } FormEvent
7757
+ * @typedef { import('./types').FormOptions } FormOptions
7758
+ *
7759
+ * @typedef { {
7760
+ * data: Data,
7761
+ * initialData: Data,
7762
+ * errors: Errors,
7763
+ * properties: FormProperties,
7764
+ * schema: Schema
7765
+ * } } State
7766
+ *
7767
+ * @typedef { (type:FormEvent, priority:number, handler:Function) => void } OnEventWithPriority
7768
+ * @typedef { (type:FormEvent, handler:Function) => void } OnEventWithOutPriority
7769
+ * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
7779
7770
  */
7780
7771
 
7781
7772
  const ids = new Ids([32, 36, 1]);
7782
7773
 
7783
- /**
7784
- * The form.
7774
+ /**
7775
+ * The form.
7785
7776
  */
7786
7777
  class Form {
7787
- /**
7788
- * @constructor
7789
- * @param {FormOptions} options
7778
+ /**
7779
+ * @constructor
7780
+ * @param {FormOptions} options
7790
7781
  */
7791
7782
  constructor(options = {}) {
7792
- /**
7793
- * @public
7794
- * @type {OnEventType}
7783
+ /**
7784
+ * @public
7785
+ * @type {OnEventType}
7795
7786
  */
7796
7787
  this.on = this._onEvent;
7797
7788
 
7798
- /**
7799
- * @public
7800
- * @type {String}
7789
+ /**
7790
+ * @public
7791
+ * @type {String}
7801
7792
  */
7802
7793
  this._id = ids.next();
7803
7794
 
7804
- /**
7805
- * @private
7806
- * @type {Element}
7795
+ /**
7796
+ * @private
7797
+ * @type {Element}
7807
7798
  */
7808
7799
  this._container = createFormContainer();
7809
7800
  const {
@@ -7812,9 +7803,9 @@ class Form {
7812
7803
  properties = {}
7813
7804
  } = options;
7814
7805
 
7815
- /**
7816
- * @private
7817
- * @type {State}
7806
+ /**
7807
+ * @private
7808
+ * @type {State}
7818
7809
  */
7819
7810
  this._state = {
7820
7811
  initialData: null,
@@ -7838,9 +7829,9 @@ class Form {
7838
7829
  this._emit('form.clear');
7839
7830
  }
7840
7831
 
7841
- /**
7842
- * Destroy the form, removing it from DOM,
7843
- * if attached.
7832
+ /**
7833
+ * Destroy the form, removing it from DOM,
7834
+ * if attached.
7844
7835
  */
7845
7836
  destroy() {
7846
7837
  // destroy form services
@@ -7851,13 +7842,13 @@ class Form {
7851
7842
  this._detach(false);
7852
7843
  }
7853
7844
 
7854
- /**
7855
- * Open a form schema with the given initial data.
7856
- *
7857
- * @param {Schema} schema
7858
- * @param {Data} [data]
7859
- *
7860
- * @return Promise<{ warnings: Array<any> }>
7845
+ /**
7846
+ * Open a form schema with the given initial data.
7847
+ *
7848
+ * @param {Schema} schema
7849
+ * @param {Data} [data]
7850
+ *
7851
+ * @return Promise<{ warnings: Array<any> }>
7861
7852
  */
7862
7853
  importSchema(schema, data = {}) {
7863
7854
  return new Promise((resolve, reject) => {
@@ -7890,10 +7881,10 @@ class Form {
7890
7881
  });
7891
7882
  }
7892
7883
 
7893
- /**
7894
- * Submit the form, triggering all field validations.
7895
- *
7896
- * @returns { { data: Data, errors: Errors } }
7884
+ /**
7885
+ * Submit the form, triggering all field validations.
7886
+ *
7887
+ * @returns { { data: Data, errors: Errors } }
7897
7888
  */
7898
7889
  submit() {
7899
7890
  const {
@@ -7919,8 +7910,8 @@ class Form {
7919
7910
  });
7920
7911
  }
7921
7912
 
7922
- /**
7923
- * @returns {Errors}
7913
+ /**
7914
+ * @returns {Errors}
7924
7915
  */
7925
7916
  validate() {
7926
7917
  const formFields = this.get('formFields'),
@@ -7992,8 +7983,8 @@ class Form {
7992
7983
  return filteredErrors;
7993
7984
  }
7994
7985
 
7995
- /**
7996
- * @param {Element|string} parentNode
7986
+ /**
7987
+ * @param {Element|string} parentNode
7997
7988
  */
7998
7989
  attachTo(parentNode) {
7999
7990
  if (!parentNode) {
@@ -8011,10 +8002,10 @@ class Form {
8011
8002
  this._detach();
8012
8003
  }
8013
8004
 
8014
- /**
8015
- * @private
8016
- *
8017
- * @param {boolean} [emit]
8005
+ /**
8006
+ * @private
8007
+ *
8008
+ * @param {boolean} [emit]
8018
8009
  */
8019
8010
  _detach(emit = true) {
8020
8011
  const container = this._container,
@@ -8028,9 +8019,9 @@ class Form {
8028
8019
  parentNode.removeChild(container);
8029
8020
  }
8030
8021
 
8031
- /**
8032
- * @param {FormProperty} property
8033
- * @param {any} value
8022
+ /**
8023
+ * @param {FormProperty} property
8024
+ * @param {any} value
8034
8025
  */
8035
8026
  setProperty(property, value) {
8036
8027
  const properties = set(this._getState().properties, [property], value);
@@ -8039,21 +8030,21 @@ class Form {
8039
8030
  });
8040
8031
  }
8041
8032
 
8042
- /**
8043
- * @param {FormEvent} type
8044
- * @param {Function} handler
8033
+ /**
8034
+ * @param {FormEvent} type
8035
+ * @param {Function} handler
8045
8036
  */
8046
8037
  off(type, handler) {
8047
8038
  this.get('eventBus').off(type, handler);
8048
8039
  }
8049
8040
 
8050
- /**
8051
- * @private
8052
- *
8053
- * @param {FormOptions} options
8054
- * @param {Element} container
8055
- *
8056
- * @returns {Injector}
8041
+ /**
8042
+ * @private
8043
+ *
8044
+ * @param {FormOptions} options
8045
+ * @param {Element} container
8046
+ *
8047
+ * @returns {Injector}
8057
8048
  */
8058
8049
  _createInjector(options, container) {
8059
8050
  const {
@@ -8074,17 +8065,17 @@ class Form {
8074
8065
  }, core, ...modules, ...additionalModules]);
8075
8066
  }
8076
8067
 
8077
- /**
8078
- * @private
8068
+ /**
8069
+ * @private
8079
8070
  */
8080
8071
  _emit(type, data) {
8081
8072
  this.get('eventBus').fire(type, data);
8082
8073
  }
8083
8074
 
8084
- /**
8085
- * @internal
8086
- *
8087
- * @param { { add?: boolean, field: any, indexes: object, remove?: number, value?: any } } update
8075
+ /**
8076
+ * @internal
8077
+ *
8078
+ * @param { { add?: boolean, field: any, indexes: object, remove?: number, value?: any } } update
8088
8079
  */
8089
8080
  _update(update) {
8090
8081
  const {
@@ -8110,15 +8101,15 @@ class Form {
8110
8101
  });
8111
8102
  }
8112
8103
 
8113
- /**
8114
- * @internal
8104
+ /**
8105
+ * @internal
8115
8106
  */
8116
8107
  _getState() {
8117
8108
  return this._state;
8118
8109
  }
8119
8110
 
8120
- /**
8121
- * @internal
8111
+ /**
8112
+ * @internal
8122
8113
  */
8123
8114
  _setState(state) {
8124
8115
  this._state = {
@@ -8128,22 +8119,22 @@ class Form {
8128
8119
  this._emit('changed', this._getState());
8129
8120
  }
8130
8121
 
8131
- /**
8132
- * @internal
8122
+ /**
8123
+ * @internal
8133
8124
  */
8134
8125
  _getModules() {
8135
8126
  return [ExpressionLanguageModule, MarkdownModule, ViewerCommandsModule, RepeatRenderModule];
8136
8127
  }
8137
8128
 
8138
- /**
8139
- * @internal
8129
+ /**
8130
+ * @internal
8140
8131
  */
8141
8132
  _onEvent(type, priority, handler) {
8142
8133
  this.get('eventBus').on(type, priority, handler);
8143
8134
  }
8144
8135
 
8145
- /**
8146
- * @internal
8136
+ /**
8137
+ * @internal
8147
8138
  */
8148
8139
  _getSubmitData() {
8149
8140
  const formFieldRegistry = this.get('formFieldRegistry');
@@ -8200,16 +8191,16 @@ class Form {
8200
8191
  return this._applyConditions(workingSubmitData, formData);
8201
8192
  }
8202
8193
 
8203
- /**
8204
- * @internal
8194
+ /**
8195
+ * @internal
8205
8196
  */
8206
8197
  _applyConditions(toFilter, data, options = {}) {
8207
8198
  const conditionChecker = this.get('conditionChecker');
8208
8199
  return conditionChecker.applyConditions(toFilter, data, options);
8209
8200
  }
8210
8201
 
8211
- /**
8212
- * @internal
8202
+ /**
8203
+ * @internal
8213
8204
  */
8214
8205
  _getInitializedFieldData(data, options = {}) {
8215
8206
  const formFieldRegistry = this.get('formFieldRegistry');