@bpmn-io/form-js-viewer 1.3.0-alpha.0 → 1.3.0

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
@@ -67,26 +67,26 @@ const getFlavouredFeelVariableNames = (feelString, feelFlavour = 'expression', o
67
67
  return [...new Set(variables)];
68
68
  };
69
69
 
70
- /**
71
- * Get the variable name at the specified index in a given path expression.
72
- *
73
- * @param {Object} root - The root node of the path expression tree.
74
- * @param {number} index - The index of the variable name to retrieve.
75
- * @returns {string|null} The variable name at the specified index or null if index is out of bounds.
70
+ /**
71
+ * Get the variable name at the specified index in a given path expression.
72
+ *
73
+ * @param {Object} root - The root node of the path expression tree.
74
+ * @param {number} index - The index of the variable name to retrieve.
75
+ * @returns {string|null} The variable name at the specified index or null if index is out of bounds.
76
76
  */
77
77
  const _getVariableNameAtPathIndex = (root, index) => {
78
78
  const accessors = _deconstructPathExpression(root);
79
79
  return accessors[index] || null;
80
80
  };
81
81
 
82
- /**
83
- * Extracts the variables which are required of the external context for a given path expression.
84
- * This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
85
- *
86
- * @param {Object} node - The root node of the path expression tree.
87
- * @param {number} initialDepth - The depth at which the root node is located in the outer context.
88
- * @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
89
- * @returns {Set} - A set containing the extracted variable names.
82
+ /**
83
+ * Extracts the variables which are required of the external context for a given path expression.
84
+ * This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
85
+ *
86
+ * @param {Object} node - The root node of the path expression tree.
87
+ * @param {number} initialDepth - The depth at which the root node is located in the outer context.
88
+ * @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
89
+ * @returns {Set} - A set containing the extracted variable names.
90
90
  */
91
91
  const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) => {
92
92
  // depth info represents the previous (initialised as null) and current depth of the current accessor in the path expression
@@ -132,11 +132,11 @@ const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) =
132
132
  return new Set(extractedVariables);
133
133
  };
134
134
 
135
- /**
136
- * Deconstructs a path expression tree into an array of components.
137
- *
138
- * @param {Object} root - The root node of the path expression tree.
139
- * @returns {Array<string>} An array of components in the path expression, in the correct order.
135
+ /**
136
+ * Deconstructs a path expression tree into an array of components.
137
+ *
138
+ * @param {Object} root - The root node of the path expression tree.
139
+ * @returns {Array<string>} An array of components in the path expression, in the correct order.
140
140
  */
141
141
  const _deconstructPathExpression = root => {
142
142
  let node = root;
@@ -155,13 +155,13 @@ const _deconstructPathExpression = root => {
155
155
  return parts.reverse();
156
156
  };
157
157
 
158
- /**
159
- * Builds a simplified feel structure tree from the given parse tree and feel string.
160
- * The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
161
- *
162
- * @param {Object} parseTree - The parse tree generated by a parser.
163
- * @param {string} feelString - The feel string used for parsing.
164
- * @returns {Object} The simplified feel structure tree.
158
+ /**
159
+ * Builds a simplified feel structure tree from the given parse tree and feel string.
160
+ * The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
161
+ *
162
+ * @param {Object} parseTree - The parse tree generated by a parser.
163
+ * @param {string} feelString - The feel string used for parsing.
164
+ * @returns {Object} The simplified feel structure tree.
165
165
  */
166
166
  const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
167
167
  const stack = [{
@@ -187,9 +187,9 @@ const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
187
187
  return _extractFilterExpressions(stack[0].children[0]);
188
188
  };
189
189
 
190
- /**
191
- * Restructure the tree in such a way to bring filters (which create new contexts) to the root of the tree.
192
- * This is done to simplify the extraction of variables and match the context hierarchy.
190
+ /**
191
+ * Restructure the tree in such a way to bring filters (which create new contexts) to the root of the tree.
192
+ * This is done to simplify the extraction of variables and match the context hierarchy.
193
193
  */
194
194
  const _extractFilterExpressions = tree => {
195
195
  const flattenedExpressionTree = {
@@ -230,25 +230,25 @@ class FeelExpressionLanguage {
230
230
  this._eventBus = eventBus;
231
231
  }
232
232
 
233
- /**
234
- * Determines if the given value is a FEEL expression.
235
- *
236
- * @param {any} value
237
- * @returns {boolean}
238
- *
233
+ /**
234
+ * Determines if the given value is a FEEL expression.
235
+ *
236
+ * @param {any} value
237
+ * @returns {boolean}
238
+ *
239
239
  */
240
240
  isExpression(value) {
241
241
  return minDash.isString(value) && value.startsWith('=');
242
242
  }
243
243
 
244
- /**
245
- * Retrieve variable names from a given FEEL expression.
246
- *
247
- * @param {string} expression
248
- * @param {object} [options]
249
- * @param {string} [options.type]
250
- *
251
- * @returns {string[]}
244
+ /**
245
+ * Retrieve variable names from a given FEEL expression.
246
+ *
247
+ * @param {string} expression
248
+ * @param {object} [options]
249
+ * @param {string} [options.type]
250
+ *
251
+ * @returns {string[]}
252
252
  */
253
253
  getVariableNames(expression, options = {}) {
254
254
  const {
@@ -263,13 +263,13 @@ class FeelExpressionLanguage {
263
263
  return getFlavouredFeelVariableNames(expression, type);
264
264
  }
265
265
 
266
- /**
267
- * Evaluate an expression.
268
- *
269
- * @param {string} expression
270
- * @param {import('../../types').Data} [data]
271
- *
272
- * @returns {any}
266
+ /**
267
+ * Evaluate an expression.
268
+ *
269
+ * @param {string} expression
270
+ * @param {import('../../types').Data} [data]
271
+ *
272
+ * @returns {any}
273
273
  */
274
274
  evaluate(expression, data = {}) {
275
275
  if (!expression) {
@@ -294,23 +294,23 @@ FeelExpressionLanguage.$inject = ['eventBus'];
294
294
  class FeelersTemplating {
295
295
  constructor() {}
296
296
 
297
- /**
298
- * Determines if the given value is a feelers template.
299
- *
300
- * @param {any} value
301
- * @returns {boolean}
302
- *
297
+ /**
298
+ * Determines if the given value is a feelers template.
299
+ *
300
+ * @param {any} value
301
+ * @returns {boolean}
302
+ *
303
303
  */
304
304
  isTemplate(value) {
305
305
  return minDash.isString(value) && (value.startsWith('=') || /{{.*?}}/.test(value));
306
306
  }
307
307
 
308
- /**
309
- * Retrieve variable names from a given feelers template.
310
- *
311
- * @param {string} template
312
- *
313
- * @returns {string[]}
308
+ /**
309
+ * Retrieve variable names from a given feelers template.
310
+ *
311
+ * @param {string} template
312
+ *
313
+ * @returns {string[]}
314
314
  */
315
315
  getVariableNames(template) {
316
316
  if (!this.isTemplate(template)) {
@@ -336,17 +336,17 @@ class FeelersTemplating {
336
336
  }, []);
337
337
  }
338
338
 
339
- /**
340
- * Evaluate a template.
341
- *
342
- * @param {string} template
343
- * @param {Object<string, any>} context
344
- * @param {Object} options
345
- * @param {boolean} [options.debug = false]
346
- * @param {boolean} [options.strict = false]
347
- * @param {Function} [options.buildDebugString]
348
- *
349
- * @returns
339
+ /**
340
+ * Evaluate a template.
341
+ *
342
+ * @param {string} template
343
+ * @param {Object<string, any>} context
344
+ * @param {Object} options
345
+ * @param {boolean} [options.debug = false]
346
+ * @param {boolean} [options.strict = false]
347
+ * @param {Function} [options.buildDebugString]
348
+ *
349
+ * @returns
350
350
  */
351
351
  evaluate(template, context = {}, options = {}) {
352
352
  const {
@@ -361,22 +361,22 @@ class FeelersTemplating {
361
361
  });
362
362
  }
363
363
 
364
- /**
365
- * @typedef {Object} ExpressionWithDepth
366
- * @property {number} depth - The depth of the expression in the syntax tree.
367
- * @property {string} expression - The extracted expression
364
+ /**
365
+ * @typedef {Object} ExpressionWithDepth
366
+ * @property {number} depth - The depth of the expression in the syntax tree.
367
+ * @property {string} expression - The extracted expression
368
368
  */
369
369
 
370
- /**
371
- * Extracts all feel expressions in the template along with their depth in the syntax tree.
372
- * The depth is incremented for child expressions of loops to account for context drilling.
373
- * @name extractExpressionsWithDepth
374
- * @param {string} template - A feelers template string.
375
- * @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
376
- *
377
- * @example
378
- * const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
379
- * const extractedExpressions = _extractExpressionsWithDepth(template);
370
+ /**
371
+ * Extracts all feel expressions in the template along with their depth in the syntax tree.
372
+ * The depth is incremented for child expressions of loops to account for context drilling.
373
+ * @name extractExpressionsWithDepth
374
+ * @param {string} template - A feelers template string.
375
+ * @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
376
+ *
377
+ * @example
378
+ * const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
379
+ * const extractedExpressions = _extractExpressionsWithDepth(template);
380
380
  */
381
381
  _extractExpressionsWithDepth(template) {
382
382
  // build simplified feelers syntax tree
@@ -482,10 +482,10 @@ function createInjector(bootstrapModules) {
482
482
  return injector;
483
483
  }
484
484
 
485
- /**
486
- * @param {string?} prefix
487
- *
488
- * @returns Element
485
+ /**
486
+ * @param {string?} prefix
487
+ *
488
+ * @returns Element
489
489
  */
490
490
  function createFormContainer(prefix = 'fjs') {
491
491
  const container = document.createElement('div');
@@ -522,22 +522,22 @@ function generateIdForType(type) {
522
522
  return `${type}${generateIndexForType(type)}`;
523
523
  }
524
524
 
525
- /**
526
- * @template T
527
- * @param {T} data
528
- * @param {(this: any, key: string, value: any) => any} [replacer]
529
- * @return {T}
525
+ /**
526
+ * @template T
527
+ * @param {T} data
528
+ * @param {(this: any, key: string, value: any) => any} [replacer]
529
+ * @return {T}
530
530
  */
531
531
  function clone(data, replacer) {
532
532
  return JSON.parse(JSON.stringify(data, replacer));
533
533
  }
534
534
 
535
- /**
536
- * Parse the schema for input variables a form might make use of
537
- *
538
- * @param {any} schema
539
- *
540
- * @return {string[]}
535
+ /**
536
+ * Parse the schema for input variables a form might make use of
537
+ *
538
+ * @param {any} schema
539
+ *
540
+ * @return {string[]}
541
541
  */
542
542
  function getSchemaVariables(schema, options = {}) {
543
543
  const {
@@ -622,9 +622,9 @@ function runRecursively(formField, fn) {
622
622
  fn(formField);
623
623
  }
624
624
 
625
- /**
626
- * @typedef {object} Condition
627
- * @property {string} [hide]
625
+ /**
626
+ * @typedef {object} Condition
627
+ * @property {string} [hide]
628
628
  */
629
629
 
630
630
  class ConditionChecker {
@@ -634,11 +634,11 @@ class ConditionChecker {
634
634
  this._eventBus = eventBus;
635
635
  }
636
636
 
637
- /**
638
- * For given data, remove properties based on condition.
639
- *
640
- * @param {Object<string, any>} properties
641
- * @param {Object<string, any>} data
637
+ /**
638
+ * For given data, remove properties based on condition.
639
+ *
640
+ * @param {Object<string, any>} properties
641
+ * @param {Object<string, any>} data
642
642
  */
643
643
  applyConditions(properties, data = {}) {
644
644
  const newProperties = clone(properties);
@@ -665,13 +665,13 @@ class ConditionChecker {
665
665
  return newProperties;
666
666
  }
667
667
 
668
- /**
669
- * Check if given condition is met. Returns null for invalid/missing conditions.
670
- *
671
- * @param {string} condition
672
- * @param {import('../../types').Data} [data]
673
- *
674
- * @returns {boolean|null}
668
+ /**
669
+ * Check if given condition is met. Returns null for invalid/missing conditions.
670
+ *
671
+ * @param {string} condition
672
+ * @param {import('../../types').Data} [data]
673
+ *
674
+ * @returns {boolean|null}
675
675
  */
676
676
  check(condition, data = {}) {
677
677
  if (!condition) {
@@ -692,12 +692,12 @@ class ConditionChecker {
692
692
  }
693
693
  }
694
694
 
695
- /**
696
- * Check if hide condition is met.
697
- *
698
- * @param {Condition} condition
699
- * @param {Object<string, any>} data
700
- * @returns {boolean}
695
+ /**
696
+ * Check if hide condition is met.
697
+ *
698
+ * @param {Condition} condition
699
+ * @param {Object<string, any>} data
700
+ * @returns {boolean}
701
701
  */
702
702
  _checkHideCondition(condition, data) {
703
703
  if (!condition.hide) {
@@ -733,12 +733,12 @@ class MarkdownRenderer {
733
733
  this._converter = new showdown.Converter();
734
734
  }
735
735
 
736
- /**
737
- * Render markdown to HTML.
738
- *
739
- * @param {string} markdown - The markdown to render
740
- *
741
- * @returns {string} HTML
736
+ /**
737
+ * Render markdown to HTML.
738
+ *
739
+ * @param {string} markdown - The markdown to render
740
+ *
741
+ * @returns {string} HTML
742
742
  */
743
743
  render(markdown) {
744
744
  return this._converter.makeHtml(markdown);
@@ -1886,8 +1886,8 @@ Validator.$inject = ['expressionLanguage', 'conditionChecker', 'form'];
1886
1886
 
1887
1887
  // helpers //////////
1888
1888
 
1889
- /**
1890
- * Helper function to evaluate optional FEEL validation values.
1889
+ /**
1890
+ * Helper function to evaluate optional FEEL validation values.
1891
1891
  */
1892
1892
  function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form) {
1893
1893
  const evaluatedValidate = {
@@ -1921,12 +1921,12 @@ function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form
1921
1921
  }
1922
1922
 
1923
1923
  class Importer {
1924
- /**
1925
- * @constructor
1926
- * @param { import('./FormFieldRegistry').default } formFieldRegistry
1927
- * @param { import('./PathRegistry').default } pathRegistry
1928
- * @param { import('./FieldFactory').default } fieldFactory
1929
- * @param { import('./FormLayouter').default } formLayouter
1924
+ /**
1925
+ * @constructor
1926
+ * @param { import('./FormFieldRegistry').default } formFieldRegistry
1927
+ * @param { import('./PathRegistry').default } pathRegistry
1928
+ * @param { import('./FieldFactory').default } fieldFactory
1929
+ * @param { import('./FormLayouter').default } formLayouter
1930
1930
  */
1931
1931
  constructor(formFieldRegistry, pathRegistry, fieldFactory, formLayouter) {
1932
1932
  this._formFieldRegistry = formFieldRegistry;
@@ -1935,21 +1935,21 @@ class Importer {
1935
1935
  this._formLayouter = formLayouter;
1936
1936
  }
1937
1937
 
1938
- /**
1939
- * Import schema creating rows, fields, attaching additional
1940
- * information to each field and adding fields to the
1941
- * field registry.
1942
- *
1943
- * Additional information attached:
1944
- *
1945
- * * `id` (unless present)
1946
- * * `_parent`
1947
- * * `_path`
1948
- *
1949
- * @param {any} schema
1950
- *
1951
- * @typedef {{ warnings: Error[], schema: any }} ImportResult
1952
- * @returns {ImportResult}
1938
+ /**
1939
+ * Import schema creating rows, fields, attaching additional
1940
+ * information to each field and adding fields to the
1941
+ * field registry.
1942
+ *
1943
+ * Additional information attached:
1944
+ *
1945
+ * * `id` (unless present)
1946
+ * * `_parent`
1947
+ * * `_path`
1948
+ *
1949
+ * @param {any} schema
1950
+ *
1951
+ * @typedef {{ warnings: Error[], schema: any }} ImportResult
1952
+ * @returns {ImportResult}
1953
1953
  */
1954
1954
  importSchema(schema) {
1955
1955
  // TODO: Add warnings
@@ -1974,12 +1974,12 @@ class Importer {
1974
1974
  this._pathRegistry.clear();
1975
1975
  }
1976
1976
 
1977
- /**
1978
- * @param {{[x: string]: any}} fieldAttrs
1979
- * @param {String} [parentId]
1980
- * @param {number} [index]
1981
- *
1982
- * @return {any} field
1977
+ /**
1978
+ * @param {{[x: string]: any}} fieldAttrs
1979
+ * @param {String} [parentId]
1980
+ * @param {number} [index]
1981
+ *
1982
+ * @return {any} field
1983
1983
  */
1984
1984
  importFormField(fieldAttrs, parentId, index) {
1985
1985
  const {
@@ -2004,11 +2004,11 @@ class Importer {
2004
2004
  return field;
2005
2005
  }
2006
2006
 
2007
- /**
2008
- * @param {Array<any>} components
2009
- * @param {string} parentId
2010
- *
2011
- * @return {Array<any>} imported components
2007
+ /**
2008
+ * @param {Array<any>} components
2009
+ * @param {string} parentId
2010
+ *
2011
+ * @return {Array<any>} imported components
2012
2012
  */
2013
2013
  importFormFields(components, parentId) {
2014
2014
  return components.map((component, index) => {
@@ -2019,11 +2019,11 @@ class Importer {
2019
2019
  Importer.$inject = ['formFieldRegistry', 'pathRegistry', 'fieldFactory', 'formLayouter'];
2020
2020
 
2021
2021
  class FieldFactory {
2022
- /**
2023
- * @constructor
2024
- *
2025
- * @param formFieldRegistry
2026
- * @param formFields
2022
+ /**
2023
+ * @constructor
2024
+ *
2025
+ * @param formFieldRegistry
2026
+ * @param formFields
2027
2027
  */
2028
2028
  constructor(formFieldRegistry, pathRegistry, formFields) {
2029
2029
  this._formFieldRegistry = formFieldRegistry;
@@ -2105,36 +2105,36 @@ class FieldFactory {
2105
2105
  }
2106
2106
  FieldFactory.$inject = ['formFieldRegistry', 'pathRegistry', 'formFields'];
2107
2107
 
2108
- /**
2109
- * The PathRegistry class manages a hierarchical structure of paths associated with form fields.
2110
- * It enables claiming, unclaiming, and validating paths within this structure.
2111
- *
2112
- * Example Tree Structure:
2113
- *
2114
- * [
2115
- * {
2116
- * segment: 'root',
2117
- * claimCount: 1,
2118
- * children: [
2119
- * {
2120
- * segment: 'child1',
2121
- * claimCount: 2,
2122
- * children: null // A leaf node (closed path)
2123
- * },
2124
- * {
2125
- * segment: 'child2',
2126
- * claimCount: 1,
2127
- * children: [
2128
- * {
2129
- * segment: 'subChild1',
2130
- * claimCount: 1,
2131
- * children: [] // An open node (open path)
2132
- * }
2133
- * ]
2134
- * }
2135
- * ]
2136
- * }
2137
- * ]
2108
+ /**
2109
+ * The PathRegistry class manages a hierarchical structure of paths associated with form fields.
2110
+ * It enables claiming, unclaiming, and validating paths within this structure.
2111
+ *
2112
+ * Example Tree Structure:
2113
+ *
2114
+ * [
2115
+ * {
2116
+ * segment: 'root',
2117
+ * claimCount: 1,
2118
+ * children: [
2119
+ * {
2120
+ * segment: 'child1',
2121
+ * claimCount: 2,
2122
+ * children: null // A leaf node (closed path)
2123
+ * },
2124
+ * {
2125
+ * segment: 'child2',
2126
+ * claimCount: 1,
2127
+ * children: [
2128
+ * {
2129
+ * segment: 'subChild1',
2130
+ * claimCount: 1,
2131
+ * children: [] // An open node (open path)
2132
+ * }
2133
+ * ]
2134
+ * }
2135
+ * ]
2136
+ * }
2137
+ * ]
2138
2138
  */
2139
2139
  class PathRegistry {
2140
2140
  constructor(formFieldRegistry, formFields) {
@@ -2217,16 +2217,16 @@ class PathRegistry {
2217
2217
  }
2218
2218
  }
2219
2219
 
2220
- /**
2221
- * Applies a function (fn) recursively on a given field and its children.
2222
- *
2223
- * - `field`: Starting field object.
2224
- * - `fn`: Function to apply.
2225
- * - `context`: Optional object for passing data between calls.
2226
- *
2227
- * Stops early if `fn` returns `false`. Useful for traversing the form field tree.
2228
- *
2229
- * @returns {boolean} Success status based on function execution.
2220
+ /**
2221
+ * Applies a function (fn) recursively on a given field and its children.
2222
+ *
2223
+ * - `field`: Starting field object.
2224
+ * - `fn`: Function to apply.
2225
+ * - `context`: Optional object for passing data between calls.
2226
+ *
2227
+ * Stops early if `fn` returns `false`. Useful for traversing the form field tree.
2228
+ *
2229
+ * @returns {boolean} Success status based on function execution.
2230
2230
  */
2231
2231
  executeRecursivelyOnFields(field, fn, context = {}) {
2232
2232
  let result = true;
@@ -2260,15 +2260,15 @@ class PathRegistry {
2260
2260
  return result;
2261
2261
  }
2262
2262
 
2263
- /**
2264
- * Generates an array representing the binding path to an underlying data object for a form field.
2265
- *
2266
- * @param {Object} field - The field object with properties: `key`, `path`, `id`, and optionally `_parent`.
2267
- * @param {Object} [options={}] - Configuration options.
2268
- * @param {Object} [options.replacements={}] - A map of field IDs to alternative path arrays.
2269
- * @param {Object} [options.cutoffNode] - The ID of the parent field at which to stop generating the path.
2270
- *
2271
- * @returns {(Array<string>|undefined)} An array of strings representing the binding path, or undefined if not determinable.
2263
+ /**
2264
+ * Generates an array representing the binding path to an underlying data object for a form field.
2265
+ *
2266
+ * @param {Object} field - The field object with properties: `key`, `path`, `id`, and optionally `_parent`.
2267
+ * @param {Object} [options={}] - Configuration options.
2268
+ * @param {Object} [options.replacements={}] - A map of field IDs to alternative path arrays.
2269
+ * @param {Object} [options.cutoffNode] - The ID of the parent field at which to stop generating the path.
2270
+ *
2271
+ * @returns {(Array<string>|undefined)} An array of strings representing the binding path, or undefined if not determinable.
2272
2272
  */
2273
2273
  getValuePath(field, options = {}) {
2274
2274
  const {
@@ -2312,23 +2312,23 @@ const _getNextSegment = (node, segment) => {
2312
2312
  };
2313
2313
  PathRegistry.$inject = ['formFieldRegistry', 'formFields'];
2314
2314
 
2315
- /**
2316
- * @typedef { { id: String, components: Array<String> } } FormRow
2317
- * @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
2315
+ /**
2316
+ * @typedef { { id: String, components: Array<String> } } FormRow
2317
+ * @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
2318
2318
  */
2319
2319
 
2320
- /**
2321
- * Maintains the Form layout in a given structure, for example
2322
- *
2323
- * [
2324
- * {
2325
- * formFieldId: 'FormField_1',
2326
- * rows: [
2327
- * { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
2328
- * ]
2329
- * }
2330
- * ]
2331
- *
2320
+ /**
2321
+ * Maintains the Form layout in a given structure, for example
2322
+ *
2323
+ * [
2324
+ * {
2325
+ * formFieldId: 'FormField_1',
2326
+ * rows: [
2327
+ * { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
2328
+ * ]
2329
+ * }
2330
+ * ]
2331
+ *
2332
2332
  */
2333
2333
  class FormLayouter {
2334
2334
  constructor(eventBus) {
@@ -2338,8 +2338,8 @@ class FormLayouter {
2338
2338
  this._eventBus = eventBus;
2339
2339
  }
2340
2340
 
2341
- /**
2342
- * @param {FormRow} row
2341
+ /**
2342
+ * @param {FormRow} row
2343
2343
  */
2344
2344
  addRow(formFieldId, row) {
2345
2345
  let rowsPerComponent = this._rows.find(r => r.formFieldId === formFieldId);
@@ -2353,18 +2353,18 @@ class FormLayouter {
2353
2353
  rowsPerComponent.rows.push(row);
2354
2354
  }
2355
2355
 
2356
- /**
2357
- * @param {String} id
2358
- * @returns {FormRow}
2356
+ /**
2357
+ * @param {String} id
2358
+ * @returns {FormRow}
2359
2359
  */
2360
2360
  getRow(id) {
2361
2361
  const rows = allRows(this._rows);
2362
2362
  return rows.find(r => r.id === id);
2363
2363
  }
2364
2364
 
2365
- /**
2366
- * @param {any} formField
2367
- * @returns {FormRow}
2365
+ /**
2366
+ * @param {any} formField
2367
+ * @returns {FormRow}
2368
2368
  */
2369
2369
  getRowForField(formField) {
2370
2370
  return allRows(this._rows).find(r => {
@@ -2375,9 +2375,9 @@ class FormLayouter {
2375
2375
  });
2376
2376
  }
2377
2377
 
2378
- /**
2379
- * @param {String} formFieldId
2380
- * @returns { Array<FormRow> }
2378
+ /**
2379
+ * @param {String} formFieldId
2380
+ * @returns { Array<FormRow> }
2381
2381
  */
2382
2382
  getRows(formFieldId) {
2383
2383
  const rowsForField = this._rows.find(r => formFieldId === r.formFieldId);
@@ -2387,15 +2387,15 @@ class FormLayouter {
2387
2387
  return rowsForField.rows;
2388
2388
  }
2389
2389
 
2390
- /**
2391
- * @returns {string}
2390
+ /**
2391
+ * @returns {string}
2392
2392
  */
2393
2393
  nextRowId() {
2394
2394
  return this._ids.nextPrefixed('Row_');
2395
2395
  }
2396
2396
 
2397
- /**
2398
- * @param {any} formField
2397
+ /**
2398
+ * @param {any} formField
2399
2399
  */
2400
2400
  calculateLayout(formField) {
2401
2401
  const {
@@ -2449,9 +2449,9 @@ function groupByRow(components, ids) {
2449
2449
  });
2450
2450
  }
2451
2451
 
2452
- /**
2453
- * @param {Array<FormRows>} formRows
2454
- * @returns {Array<FormRow>}
2452
+ /**
2453
+ * @param {Array<FormRows>} formRows
2454
+ * @returns {Array<FormRow>}
2455
2455
  */
2456
2456
  function allRows(formRows) {
2457
2457
  return minDash.flatten(formRows.map(c => c.rows));
@@ -2607,11 +2607,11 @@ const FormRenderContext = preact.createContext({
2607
2607
  });
2608
2608
  var FormRenderContext$1 = FormRenderContext;
2609
2609
 
2610
- /**
2611
- * @param {string} type
2612
- * @param {boolean} [strict]
2613
- *
2614
- * @returns {any}
2610
+ /**
2611
+ * @param {string} type
2612
+ * @param {boolean} [strict]
2613
+ *
2614
+ * @returns {any}
2615
2615
  */
2616
2616
  function getService(type, strict) {}
2617
2617
  const FormContext = preact.createContext({
@@ -2627,10 +2627,10 @@ function useService(type, strict) {
2627
2627
  return getService(type, strict);
2628
2628
  }
2629
2629
 
2630
- /**
2631
- * Returns the conditionally filtered data of a form reactively.
2632
- * Memoised to minimize re-renders
2633
- *
2630
+ /**
2631
+ * Returns the conditionally filtered data of a form reactively.
2632
+ * Memoised to minimize re-renders
2633
+ *
2634
2634
  */
2635
2635
  function useFilteredFormData() {
2636
2636
  const {
@@ -2647,12 +2647,12 @@ function useFilteredFormData() {
2647
2647
  }, [conditionChecker, data, initialData]);
2648
2648
  }
2649
2649
 
2650
- /**
2651
- * Evaluate if condition is met reactively based on the conditionChecker and form data.
2652
- *
2653
- * @param {string | undefined} condition
2654
- *
2655
- * @returns {boolean} true if condition is met or no condition or condition checker exists
2650
+ /**
2651
+ * Evaluate if condition is met reactively based on the conditionChecker and form data.
2652
+ *
2653
+ * @param {string | undefined} condition
2654
+ *
2655
+ * @returns {boolean} true if condition is met or no condition or condition checker exists
2656
2656
  */
2657
2657
  function useCondition(condition) {
2658
2658
  const conditionChecker = useService('conditionChecker', false);
@@ -2662,13 +2662,13 @@ function useCondition(condition) {
2662
2662
  }, [conditionChecker, condition, filteredData]);
2663
2663
  }
2664
2664
 
2665
- /**
2666
- * Evaluate a string reactively based on the expressionLanguage and form data.
2667
- * If the string is not an expression, it is returned as is.
2668
- * Memoised to minimize re-renders.
2669
- *
2670
- * @param {string} value
2671
- *
2665
+ /**
2666
+ * Evaluate a string reactively based on the expressionLanguage and form data.
2667
+ * If the string is not an expression, it is returned as is.
2668
+ * Memoised to minimize re-renders.
2669
+ *
2670
+ * @param {string} value
2671
+ *
2672
2672
  */
2673
2673
  function useExpressionEvaluation(value) {
2674
2674
  const formData = useFilteredFormData();
@@ -2697,16 +2697,16 @@ function useKeyDownAction(targetKey, action, listenerElement = window) {
2697
2697
  });
2698
2698
  }
2699
2699
 
2700
- /**
2701
- * Retrieve readonly value of a form field, given it can be an
2702
- * expression optionally or configured globally.
2703
- *
2704
- * @typedef { import('../../types').FormProperties } FormProperties
2705
- *
2706
- * @param {any} formField
2707
- * @param {FormProperties} properties
2708
- *
2709
- * @returns {boolean}
2700
+ /**
2701
+ * Retrieve readonly value of a form field, given it can be an
2702
+ * expression optionally or configured globally.
2703
+ *
2704
+ * @typedef { import('../../types').FormProperties } FormProperties
2705
+ *
2706
+ * @param {any} formField
2707
+ * @param {FormProperties} properties
2708
+ *
2709
+ * @returns {boolean}
2710
2710
  */
2711
2711
  function useReadonly(formField, properties = {}) {
2712
2712
  const expressionLanguage = useService('expressionLanguage');
@@ -2724,16 +2724,47 @@ function useReadonly(formField, properties = {}) {
2724
2724
  return readonly || false;
2725
2725
  }
2726
2726
 
2727
- /**
2728
- * Template a string reactively based on form data. If the string is not a template, it is returned as is.
2729
- * Memoised to minimize re-renders
2730
- *
2731
- * @param {string} value
2732
- * @param {Object} options
2733
- * @param {boolean} [options.debug = false]
2734
- * @param {boolean} [options.strict = false]
2735
- * @param {Function} [options.buildDebugString]
2736
- *
2727
+ function usePrevious(value, defaultValue, dependencies) {
2728
+ const ref = hooks.useRef(defaultValue);
2729
+ hooks.useEffect(() => ref.current = value, dependencies);
2730
+ return ref.current;
2731
+ }
2732
+
2733
+ /**
2734
+ * A custom hook to manage state changes with deep comparison.
2735
+ *
2736
+ * @param {any} value - The current value to manage.
2737
+ * @param {any} defaultValue - The initial default value for the state.
2738
+ * @returns {any} - Returns the current state.
2739
+ */
2740
+ function useDeepCompareState(value, defaultValue) {
2741
+ const [state, setState] = hooks.useState(defaultValue);
2742
+ const previous = usePrevious(value, defaultValue, [value]);
2743
+ const changed = !compare(previous, value);
2744
+ hooks.useEffect(() => {
2745
+ if (changed) {
2746
+ setState(value);
2747
+ }
2748
+ }, [changed, value]);
2749
+ return state;
2750
+ }
2751
+
2752
+ // helpers //////////////////////////
2753
+
2754
+ function compare(a, b) {
2755
+ return JSON.stringify(a) === JSON.stringify(b);
2756
+ }
2757
+
2758
+ /**
2759
+ * Template a string reactively based on form data. If the string is not a template, it is returned as is.
2760
+ * Memoised to minimize re-renders
2761
+ *
2762
+ * @param {string} value
2763
+ * @param {Object} options
2764
+ * @param {boolean} [options.debug = false]
2765
+ * @param {boolean} [options.strict = false]
2766
+ * @param {Function} [options.buildDebugString]
2767
+ *
2737
2768
  */
2738
2769
  function useTemplateEvaluation(value, options) {
2739
2770
  const filteredData = useFilteredFormData();
@@ -2746,17 +2777,17 @@ function useTemplateEvaluation(value, options) {
2746
2777
  }, [filteredData, templating, value, options]);
2747
2778
  }
2748
2779
 
2749
- /**
2750
- * Template a string reactively based on form data. If the string is not a template, it is returned as is.
2751
- * If the string contains multiple lines, only the first line is returned.
2752
- * Memoised to minimize re-renders
2753
- *
2754
- * @param {string} value
2755
- * @param {Object} [options]
2756
- * @param {boolean} [options.debug = false]
2757
- * @param {boolean} [options.strict = false]
2758
- * @param {Function} [options.buildDebugString]
2759
- *
2780
+ /**
2781
+ * Template a string reactively based on form data. If the string is not a template, it is returned as is.
2782
+ * If the string contains multiple lines, only the first line is returned.
2783
+ * Memoised to minimize re-renders
2784
+ *
2785
+ * @param {string} value
2786
+ * @param {Object} [options]
2787
+ * @param {boolean} [options.debug = false]
2788
+ * @param {boolean} [options.strict = false]
2789
+ * @param {Function} [options.buildDebugString]
2790
+ *
2760
2791
  */
2761
2792
  function useSingleLineTemplateEvaluation(value, options = {}) {
2762
2793
  const evaluatedTemplate = useTemplateEvaluation(value, options);
@@ -2960,8 +2991,8 @@ function createEmptyOptions(options = {}) {
2960
2991
  };
2961
2992
  }
2962
2993
 
2963
- /**
2964
- * @enum { String }
2994
+ /**
2995
+ * @enum { String }
2965
2996
  */
2966
2997
  const LOAD_STATES = {
2967
2998
  LOADING: 'loading',
@@ -2969,17 +3000,17 @@ const LOAD_STATES = {
2969
3000
  ERROR: 'error'
2970
3001
  };
2971
3002
 
2972
- /**
2973
- * @typedef {Object} ValuesGetter
2974
- * @property {Object[]} values - The values data
2975
- * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
3003
+ /**
3004
+ * @typedef {Object} ValuesGetter
3005
+ * @property {Object[]} values - The values data
3006
+ * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
2976
3007
  */
2977
3008
 
2978
- /**
2979
- * A hook to load values for single and multiselect components.
2980
- *
2981
- * @param {Object} field - The form field to handle values for
2982
- * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
3009
+ /**
3010
+ * A hook to load values for single and multiselect components.
3011
+ *
3012
+ * @param {Object} field - The form field to handle values for
3013
+ * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
2983
3014
  */
2984
3015
  function useValuesAsync (field) {
2985
3016
  const {
@@ -2993,11 +3024,8 @@ function useValuesAsync (field) {
2993
3024
  state: LOAD_STATES.LOADING
2994
3025
  });
2995
3026
  const initialData = useService('form')._getState().initialData;
2996
- const evaluatedValues = hooks.useMemo(() => {
2997
- if (valuesExpression) {
2998
- return useExpressionEvaluation(valuesExpression);
2999
- }
3000
- }, [valuesExpression]);
3027
+ const expressionEvaluation = useExpressionEvaluation(valuesExpression);
3028
+ const evaluatedValues = useDeepCompareState(expressionEvaluation || [], []);
3001
3029
  hooks.useEffect(() => {
3002
3030
  let values = [];
3003
3031
 
@@ -3013,8 +3041,10 @@ function useValuesAsync (field) {
3013
3041
  values = Array.isArray(staticValues) ? staticValues : [];
3014
3042
 
3015
3043
  // expression
3016
- } else if (evaluatedValues && Array.isArray(evaluatedValues)) {
3017
- values = evaluatedValues;
3044
+ } else if (valuesExpression) {
3045
+ if (evaluatedValues && Array.isArray(evaluatedValues)) {
3046
+ values = evaluatedValues;
3047
+ }
3018
3048
  } else {
3019
3049
  setValuesGetter(buildErrorState('No values source defined in the form definition'));
3020
3050
  return;
@@ -3023,7 +3053,7 @@ function useValuesAsync (field) {
3023
3053
  // normalize data to support primitives and partially defined objects
3024
3054
  values = normalizeValuesData(values);
3025
3055
  setValuesGetter(buildLoadedState(values));
3026
- }, [valuesKey, staticValues, initialData]);
3056
+ }, [valuesKey, staticValues, initialData, valuesExpression, evaluatedValues]);
3027
3057
  return valuesGetter;
3028
3058
  }
3029
3059
  const buildErrorState = error => ({
@@ -3489,12 +3519,12 @@ var SvgCalendar = function SvgCalendar(props) {
3489
3519
  };
3490
3520
  var CalendarIcon = SvgCalendar;
3491
3521
 
3492
- /**
3493
- * Returns date format for the provided locale.
3494
- * If the locale is not provided, uses the browser's locale.
3495
- *
3496
- * @param {string} [locale] - The locale to get date format for.
3497
- * @returns {string} The date format for the locale.
3522
+ /**
3523
+ * Returns date format for the provided locale.
3524
+ * If the locale is not provided, uses the browser's locale.
3525
+ *
3526
+ * @param {string} [locale] - The locale to get date format for.
3527
+ * @returns {string} The date format for the locale.
3498
3528
  */
3499
3529
  function getLocaleDateFormat(locale = 'default') {
3500
3530
  const parts = new Intl.DateTimeFormat(locale).formatToParts(new Date(Date.UTC(2020, 5, 5)));
@@ -3513,12 +3543,12 @@ function getLocaleDateFormat(locale = 'default') {
3513
3543
  }).join('');
3514
3544
  }
3515
3545
 
3516
- /**
3517
- * Returns readable date format for the provided locale.
3518
- * If the locale is not provided, uses the browser's locale.
3519
- *
3520
- * @param {string} [locale] - The locale to get readable date format for.
3521
- * @returns {string} The readable date format for the locale.
3546
+ /**
3547
+ * Returns readable date format for the provided locale.
3548
+ * If the locale is not provided, uses the browser's locale.
3549
+ *
3550
+ * @param {string} [locale] - The locale to get readable date format for.
3551
+ * @returns {string} The readable date format for the locale.
3522
3552
  */
3523
3553
  function getLocaleReadableDateFormat(locale) {
3524
3554
  let format = getLocaleDateFormat(locale).toLowerCase();
@@ -3535,12 +3565,12 @@ function getLocaleReadableDateFormat(locale) {
3535
3565
  return format;
3536
3566
  }
3537
3567
 
3538
- /**
3539
- * Returns flatpickr config for the provided locale.
3540
- * If the locale is not provided, uses the browser's locale.
3541
- *
3542
- * @param {string} [locale] - The locale to get flatpickr config for.
3543
- * @returns {object} The flatpickr config for the locale.
3568
+ /**
3569
+ * Returns flatpickr config for the provided locale.
3570
+ * If the locale is not provided, uses the browser's locale.
3571
+ *
3572
+ * @param {string} [locale] - The locale to get flatpickr config for.
3573
+ * @returns {object} The flatpickr config for the locale.
3544
3574
  */
3545
3575
  function getLocaleDateFlatpickrConfig(locale) {
3546
3576
  return flatpickerizeDateFormat(getLocaleDateFormat(locale));
@@ -3808,7 +3838,8 @@ function DropdownList(props) {
3808
3838
  hooks.useEffect(() => {
3809
3839
  const individualEntries = dropdownContainer.current.children;
3810
3840
  if (individualEntries.length && !mouseControl) {
3811
- individualEntries[focusedValueIndex].scrollIntoView({
3841
+ const focusedEntry = individualEntries[focusedValueIndex];
3842
+ focusedEntry && focusedEntry.scrollIntoView({
3812
3843
  block: 'nearest',
3813
3844
  inline: 'nearest'
3814
3845
  });
@@ -4219,10 +4250,10 @@ Datetime.config = {
4219
4250
  }
4220
4251
  };
4221
4252
 
4222
- /**
4223
- * This file must not be changed or exchanged.
4224
- *
4225
- * @see http://bpmn.io/license for more information.
4253
+ /**
4254
+ * This file must not be changed or exchanged.
4255
+ *
4256
+ * @see http://bpmn.io/license for more information.
4226
4257
  */
4227
4258
  function Logo() {
4228
4259
  return jsxRuntime.jsxs("svg", {
@@ -4400,11 +4431,11 @@ const ATTR_WHITESPACE_PATTERN = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u
4400
4431
 
4401
4432
  const FORM_ELEMENT = document.createElement('form');
4402
4433
 
4403
- /**
4404
- * Sanitize a HTML string and return the cleaned, safe version.
4405
- *
4406
- * @param {string} html
4407
- * @return {string}
4434
+ /**
4435
+ * Sanitize a HTML string and return the cleaned, safe version.
4436
+ *
4437
+ * @param {string} html
4438
+ * @return {string}
4408
4439
  */
4409
4440
 
4410
4441
  // see https://github.com/developit/snarkdown/issues/70
@@ -4422,29 +4453,29 @@ function sanitizeHTML(html) {
4422
4453
  }
4423
4454
  }
4424
4455
 
4425
- /**
4426
- * Sanitizes an image source to ensure we only allow for data URI and links
4427
- * that start with http(s).
4428
- *
4429
- * Note: Most browsers anyway do not support script execution in <img> elements.
4430
- *
4431
- * @param {string} src
4432
- * @returns {string}
4456
+ /**
4457
+ * Sanitizes an image source to ensure we only allow for data URI and links
4458
+ * that start with http(s).
4459
+ *
4460
+ * Note: Most browsers anyway do not support script execution in <img> elements.
4461
+ *
4462
+ * @param {string} src
4463
+ * @returns {string}
4433
4464
  */
4434
4465
  function sanitizeImageSource(src) {
4435
4466
  const valid = ALLOWED_IMAGE_SRC_PATTERN.test(src);
4436
4467
  return valid ? src : '';
4437
4468
  }
4438
4469
 
4439
- /**
4440
- * Recursively sanitize a HTML node, potentially
4441
- * removing it, its children or attributes.
4442
- *
4443
- * Inspired by https://github.com/developit/snarkdown/issues/70
4444
- * and https://github.com/cure53/DOMPurify. Simplified
4445
- * for our use-case.
4446
- *
4447
- * @param {Element} node
4470
+ /**
4471
+ * Recursively sanitize a HTML node, potentially
4472
+ * removing it, its children or attributes.
4473
+ *
4474
+ * Inspired by https://github.com/developit/snarkdown/issues/70
4475
+ * and https://github.com/cure53/DOMPurify. Simplified
4476
+ * for our use-case.
4477
+ *
4478
+ * @param {Element} node
4448
4479
  */
4449
4480
  function sanitizeNode(node) {
4450
4481
  // allow text nodes
@@ -4488,13 +4519,13 @@ function sanitizeNode(node) {
4488
4519
  }
4489
4520
  }
4490
4521
 
4491
- /**
4492
- * Validates attributes for validity.
4493
- *
4494
- * @param {string} lcTag
4495
- * @param {string} lcName
4496
- * @param {string} value
4497
- * @return {boolean}
4522
+ /**
4523
+ * Validates attributes for validity.
4524
+ *
4525
+ * @param {string} lcTag
4526
+ * @param {string} lcName
4527
+ * @param {string} value
4528
+ * @return {boolean}
4498
4529
  */
4499
4530
  function isValidAttribute(lcTag, lcName, value) {
4500
4531
  // disallow most attributes based on whitelist
@@ -6222,55 +6253,55 @@ var core = {
6222
6253
  validator: ['type', Validator]
6223
6254
  };
6224
6255
 
6225
- /**
6226
- * @typedef { import('./types').Injector } Injector
6227
- * @typedef { import('./types').Data } Data
6228
- * @typedef { import('./types').Errors } Errors
6229
- * @typedef { import('./types').Schema } Schema
6230
- * @typedef { import('./types').FormProperties } FormProperties
6231
- * @typedef { import('./types').FormProperty } FormProperty
6232
- * @typedef { import('./types').FormEvent } FormEvent
6233
- * @typedef { import('./types').FormOptions } FormOptions
6234
- *
6235
- * @typedef { {
6236
- * data: Data,
6237
- * initialData: Data,
6238
- * errors: Errors,
6239
- * properties: FormProperties,
6240
- * schema: Schema
6241
- * } } State
6242
- *
6243
- * @typedef { (type:FormEvent, priority:number, handler:Function) => void } OnEventWithPriority
6244
- * @typedef { (type:FormEvent, handler:Function) => void } OnEventWithOutPriority
6245
- * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
6256
+ /**
6257
+ * @typedef { import('./types').Injector } Injector
6258
+ * @typedef { import('./types').Data } Data
6259
+ * @typedef { import('./types').Errors } Errors
6260
+ * @typedef { import('./types').Schema } Schema
6261
+ * @typedef { import('./types').FormProperties } FormProperties
6262
+ * @typedef { import('./types').FormProperty } FormProperty
6263
+ * @typedef { import('./types').FormEvent } FormEvent
6264
+ * @typedef { import('./types').FormOptions } FormOptions
6265
+ *
6266
+ * @typedef { {
6267
+ * data: Data,
6268
+ * initialData: Data,
6269
+ * errors: Errors,
6270
+ * properties: FormProperties,
6271
+ * schema: Schema
6272
+ * } } State
6273
+ *
6274
+ * @typedef { (type:FormEvent, priority:number, handler:Function) => void } OnEventWithPriority
6275
+ * @typedef { (type:FormEvent, handler:Function) => void } OnEventWithOutPriority
6276
+ * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
6246
6277
  */
6247
6278
 
6248
6279
  const ids = new Ids([32, 36, 1]);
6249
6280
 
6250
- /**
6251
- * The form.
6281
+ /**
6282
+ * The form.
6252
6283
  */
6253
6284
  class Form {
6254
- /**
6255
- * @constructor
6256
- * @param {FormOptions} options
6285
+ /**
6286
+ * @constructor
6287
+ * @param {FormOptions} options
6257
6288
  */
6258
6289
  constructor(options = {}) {
6259
- /**
6260
- * @public
6261
- * @type {OnEventType}
6290
+ /**
6291
+ * @public
6292
+ * @type {OnEventType}
6262
6293
  */
6263
6294
  this.on = this._onEvent;
6264
6295
 
6265
- /**
6266
- * @public
6267
- * @type {String}
6296
+ /**
6297
+ * @public
6298
+ * @type {String}
6268
6299
  */
6269
6300
  this._id = ids.next();
6270
6301
 
6271
- /**
6272
- * @private
6273
- * @type {Element}
6302
+ /**
6303
+ * @private
6304
+ * @type {Element}
6274
6305
  */
6275
6306
  this._container = createFormContainer();
6276
6307
  const {
@@ -6279,9 +6310,9 @@ class Form {
6279
6310
  properties = {}
6280
6311
  } = options;
6281
6312
 
6282
- /**
6283
- * @private
6284
- * @type {State}
6313
+ /**
6314
+ * @private
6315
+ * @type {State}
6285
6316
  */
6286
6317
  this._state = {
6287
6318
  initialData: null,
@@ -6305,9 +6336,9 @@ class Form {
6305
6336
  this._emit('form.clear');
6306
6337
  }
6307
6338
 
6308
- /**
6309
- * Destroy the form, removing it from DOM,
6310
- * if attached.
6339
+ /**
6340
+ * Destroy the form, removing it from DOM,
6341
+ * if attached.
6311
6342
  */
6312
6343
  destroy() {
6313
6344
  // destroy form services
@@ -6318,13 +6349,13 @@ class Form {
6318
6349
  this._detach(false);
6319
6350
  }
6320
6351
 
6321
- /**
6322
- * Open a form schema with the given initial data.
6323
- *
6324
- * @param {Schema} schema
6325
- * @param {Data} [data]
6326
- *
6327
- * @return Promise<{ warnings: Array<any> }>
6352
+ /**
6353
+ * Open a form schema with the given initial data.
6354
+ *
6355
+ * @param {Schema} schema
6356
+ * @param {Data} [data]
6357
+ *
6358
+ * @return Promise<{ warnings: Array<any> }>
6328
6359
  */
6329
6360
  importSchema(schema, data = {}) {
6330
6361
  return new Promise((resolve, reject) => {
@@ -6357,10 +6388,10 @@ class Form {
6357
6388
  });
6358
6389
  }
6359
6390
 
6360
- /**
6361
- * Submit the form, triggering all field validations.
6362
- *
6363
- * @returns { { data: Data, errors: Errors } }
6391
+ /**
6392
+ * Submit the form, triggering all field validations.
6393
+ *
6394
+ * @returns { { data: Data, errors: Errors } }
6364
6395
  */
6365
6396
  submit() {
6366
6397
  const {
@@ -6387,8 +6418,8 @@ class Form {
6387
6418
  });
6388
6419
  }
6389
6420
 
6390
- /**
6391
- * @returns {Errors}
6421
+ /**
6422
+ * @returns {Errors}
6392
6423
  */
6393
6424
  validate() {
6394
6425
  const formFieldRegistry = this.get('formFieldRegistry'),
@@ -6414,8 +6445,8 @@ class Form {
6414
6445
  return errors;
6415
6446
  }
6416
6447
 
6417
- /**
6418
- * @param {Element|string} parentNode
6448
+ /**
6449
+ * @param {Element|string} parentNode
6419
6450
  */
6420
6451
  attachTo(parentNode) {
6421
6452
  if (!parentNode) {
@@ -6433,10 +6464,10 @@ class Form {
6433
6464
  this._detach();
6434
6465
  }
6435
6466
 
6436
- /**
6437
- * @private
6438
- *
6439
- * @param {boolean} [emit]
6467
+ /**
6468
+ * @private
6469
+ *
6470
+ * @param {boolean} [emit]
6440
6471
  */
6441
6472
  _detach(emit = true) {
6442
6473
  const container = this._container,
@@ -6450,9 +6481,9 @@ class Form {
6450
6481
  parentNode.removeChild(container);
6451
6482
  }
6452
6483
 
6453
- /**
6454
- * @param {FormProperty} property
6455
- * @param {any} value
6484
+ /**
6485
+ * @param {FormProperty} property
6486
+ * @param {any} value
6456
6487
  */
6457
6488
  setProperty(property, value) {
6458
6489
  const properties = minDash.set(this._getState().properties, [property], value);
@@ -6461,21 +6492,21 @@ class Form {
6461
6492
  });
6462
6493
  }
6463
6494
 
6464
- /**
6465
- * @param {FormEvent} type
6466
- * @param {Function} handler
6495
+ /**
6496
+ * @param {FormEvent} type
6497
+ * @param {Function} handler
6467
6498
  */
6468
6499
  off(type, handler) {
6469
6500
  this.get('eventBus').off(type, handler);
6470
6501
  }
6471
6502
 
6472
- /**
6473
- * @private
6474
- *
6475
- * @param {FormOptions} options
6476
- * @param {Element} container
6477
- *
6478
- * @returns {Injector}
6503
+ /**
6504
+ * @private
6505
+ *
6506
+ * @param {FormOptions} options
6507
+ * @param {Element} container
6508
+ *
6509
+ * @returns {Injector}
6479
6510
  */
6480
6511
  _createInjector(options, container) {
6481
6512
  const {
@@ -6494,17 +6525,17 @@ class Form {
6494
6525
  }, core, ...modules, ...additionalModules]);
6495
6526
  }
6496
6527
 
6497
- /**
6498
- * @private
6528
+ /**
6529
+ * @private
6499
6530
  */
6500
6531
  _emit(type, data) {
6501
6532
  this.get('eventBus').fire(type, data);
6502
6533
  }
6503
6534
 
6504
- /**
6505
- * @internal
6506
- *
6507
- * @param { { add?: boolean, field: any, remove?: number, value?: any } } update
6535
+ /**
6536
+ * @internal
6537
+ *
6538
+ * @param { { add?: boolean, field: any, remove?: number, value?: any } } update
6508
6539
  */
6509
6540
  _update(update) {
6510
6541
  const {
@@ -6526,15 +6557,15 @@ class Form {
6526
6557
  });
6527
6558
  }
6528
6559
 
6529
- /**
6530
- * @internal
6560
+ /**
6561
+ * @internal
6531
6562
  */
6532
6563
  _getState() {
6533
6564
  return this._state;
6534
6565
  }
6535
6566
 
6536
- /**
6537
- * @internal
6567
+ /**
6568
+ * @internal
6538
6569
  */
6539
6570
  _setState(state) {
6540
6571
  this._state = {
@@ -6544,22 +6575,22 @@ class Form {
6544
6575
  this._emit('changed', this._getState());
6545
6576
  }
6546
6577
 
6547
- /**
6548
- * @internal
6578
+ /**
6579
+ * @internal
6549
6580
  */
6550
6581
  _getModules() {
6551
6582
  return [ExpressionLanguageModule, MarkdownModule, ViewerCommandsModule];
6552
6583
  }
6553
6584
 
6554
- /**
6555
- * @internal
6585
+ /**
6586
+ * @internal
6556
6587
  */
6557
6588
  _onEvent(type, priority, handler) {
6558
6589
  this.get('eventBus').on(type, priority, handler);
6559
6590
  }
6560
6591
 
6561
- /**
6562
- * @internal
6592
+ /**
6593
+ * @internal
6563
6594
  */
6564
6595
  _getSubmitData() {
6565
6596
  const formFieldRegistry = this.get('formFieldRegistry'),
@@ -6587,16 +6618,16 @@ class Form {
6587
6618
  return filteredSubmitData;
6588
6619
  }
6589
6620
 
6590
- /**
6591
- * @internal
6621
+ /**
6622
+ * @internal
6592
6623
  */
6593
6624
  _applyConditions(toFilter, data) {
6594
6625
  const conditionChecker = this.get('conditionChecker');
6595
6626
  return conditionChecker.applyConditions(toFilter, data);
6596
6627
  }
6597
6628
 
6598
- /**
6599
- * @internal
6629
+ /**
6630
+ * @internal
6600
6631
  */
6601
6632
  _initializeFieldData(data) {
6602
6633
  const formFieldRegistry = this.get('formFieldRegistry'),
@@ -6676,6 +6707,7 @@ exports.FieldFactory = FieldFactory;
6676
6707
  exports.Form = Form;
6677
6708
  exports.FormComponent = FormComponent;
6678
6709
  exports.FormContext = FormContext$1;
6710
+ exports.FormField = FormField;
6679
6711
  exports.FormFieldRegistry = FormFieldRegistry;
6680
6712
  exports.FormFields = FormFields;
6681
6713
  exports.FormLayouter = FormLayouter;