@bpmn-io/form-js-viewer 1.0.0-alpha.6 → 1.0.0-alpha.7

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
@@ -44,26 +44,26 @@ const getFlavouredFeelVariableNames = (feelString, feelFlavour, options = {}) =>
44
44
  }(simpleExpressionTree);
45
45
  };
46
46
 
47
- /**
48
- * Get the variable name at the specified index in a given path expression.
49
- *
50
- * @param {Object} root - The root node of the path expression tree.
51
- * @param {number} index - The index of the variable name to retrieve.
52
- * @returns {string|null} The variable name at the specified index or null if index is out of bounds.
47
+ /**
48
+ * Get the variable name at the specified index in a given path expression.
49
+ *
50
+ * @param {Object} root - The root node of the path expression tree.
51
+ * @param {number} index - The index of the variable name to retrieve.
52
+ * @returns {string|null} The variable name at the specified index or null if index is out of bounds.
53
53
  */
54
54
  const _getVariableNameAtPathIndex = (root, index) => {
55
55
  const accessors = _deconstructPathExpression(root);
56
56
  return accessors[index] || null;
57
57
  };
58
58
 
59
- /**
60
- * Extracts the variables which are required of the external context for a given path expression.
61
- * This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
62
- *
63
- * @param {Object} node - The root node of the path expression tree.
64
- * @param {number} initialDepth - The depth at which the root node is located in the outer context.
65
- * @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
66
- * @returns {Set} - A set containing the extracted variable names.
59
+ /**
60
+ * Extracts the variables which are required of the external context for a given path expression.
61
+ * This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
62
+ *
63
+ * @param {Object} node - The root node of the path expression tree.
64
+ * @param {number} initialDepth - The depth at which the root node is located in the outer context.
65
+ * @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
66
+ * @returns {Set} - A set containing the extracted variable names.
67
67
  */
68
68
  const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) => {
69
69
  // depth info represents the previous (initialised as null) and current depth of the current accessor in the path expression
@@ -109,11 +109,11 @@ const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) =
109
109
  return new Set(extractedVariables);
110
110
  };
111
111
 
112
- /**
113
- * Deconstructs a path expression tree into an array of components.
114
- *
115
- * @param {Object} root - The root node of the path expression tree.
116
- * @returns {Array<string>} An array of components in the path expression, in the correct order.
112
+ /**
113
+ * Deconstructs a path expression tree into an array of components.
114
+ *
115
+ * @param {Object} root - The root node of the path expression tree.
116
+ * @returns {Array<string>} An array of components in the path expression, in the correct order.
117
117
  */
118
118
  const _deconstructPathExpression = root => {
119
119
  let node = root;
@@ -132,13 +132,13 @@ const _deconstructPathExpression = root => {
132
132
  return parts.reverse();
133
133
  };
134
134
 
135
- /**
136
- * Builds a simplified feel structure tree from the given parse tree and feel string.
137
- * The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
138
- *
139
- * @param {Object} parseTree - The parse tree generated by a parser.
140
- * @param {string} feelString - The feel string used for parsing.
141
- * @returns {Object} The simplified feel structure tree.
135
+ /**
136
+ * Builds a simplified feel structure tree from the given parse tree and feel string.
137
+ * The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
138
+ *
139
+ * @param {Object} parseTree - The parse tree generated by a parser.
140
+ * @param {string} feelString - The feel string used for parsing.
141
+ * @returns {Object} The simplified feel structure tree.
142
142
  */
143
143
  const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
144
144
  const stack = [{
@@ -169,25 +169,25 @@ class FeelExpressionLanguage {
169
169
  this._eventBus = eventBus;
170
170
  }
171
171
 
172
- /**
173
- * Determines if the given value is a FEEL expression.
174
- *
175
- * @param {any} value
176
- * @returns {boolean}
177
- *
172
+ /**
173
+ * Determines if the given value is a FEEL expression.
174
+ *
175
+ * @param {any} value
176
+ * @returns {boolean}
177
+ *
178
178
  */
179
179
  isExpression(value) {
180
180
  return minDash.isString(value) && value.startsWith('=');
181
181
  }
182
182
 
183
- /**
184
- * Retrieve variable names from a given FEEL expression.
185
- *
186
- * @param {string} expression
187
- * @param {object} [options]
188
- * @param {string} [options.type]
189
- *
190
- * @returns {string[]}
183
+ /**
184
+ * Retrieve variable names from a given FEEL expression.
185
+ *
186
+ * @param {string} expression
187
+ * @param {object} [options]
188
+ * @param {string} [options.type]
189
+ *
190
+ * @returns {string[]}
191
191
  */
192
192
  getVariableNames(expression, options = {}) {
193
193
  const {
@@ -202,13 +202,13 @@ class FeelExpressionLanguage {
202
202
  return getFlavouredFeelVariableNames(expression, type);
203
203
  }
204
204
 
205
- /**
206
- * Evaluate an expression.
207
- *
208
- * @param {string} expression
209
- * @param {import('../../types').Data} [data]
210
- *
211
- * @returns {any}
205
+ /**
206
+ * Evaluate an expression.
207
+ *
208
+ * @param {string} expression
209
+ * @param {import('../../types').Data} [data]
210
+ *
211
+ * @returns {any}
212
212
  */
213
213
  evaluate(expression, data = {}) {
214
214
  if (!expression) {
@@ -233,23 +233,23 @@ FeelExpressionLanguage.$inject = ['eventBus'];
233
233
  class FeelersTemplating {
234
234
  constructor() {}
235
235
 
236
- /**
237
- * Determines if the given value is a feelers template.
238
- *
239
- * @param {any} value
240
- * @returns {boolean}
241
- *
236
+ /**
237
+ * Determines if the given value is a feelers template.
238
+ *
239
+ * @param {any} value
240
+ * @returns {boolean}
241
+ *
242
242
  */
243
243
  isTemplate(value) {
244
244
  return minDash.isString(value) && (value.startsWith('=') || /{{.*?}}/.test(value));
245
245
  }
246
246
 
247
- /**
248
- * Retrieve variable names from a given feelers template.
249
- *
250
- * @param {string} template
251
- *
252
- * @returns {string[]}
247
+ /**
248
+ * Retrieve variable names from a given feelers template.
249
+ *
250
+ * @param {string} template
251
+ *
252
+ * @returns {string[]}
253
253
  */
254
254
  getVariableNames(template) {
255
255
  if (!this.isTemplate(template)) {
@@ -275,17 +275,17 @@ class FeelersTemplating {
275
275
  }, []);
276
276
  }
277
277
 
278
- /**
279
- * Evaluate a template.
280
- *
281
- * @param {string} template
282
- * @param {Object<string, any>} context
283
- * @param {Object} options
284
- * @param {boolean} [options.debug = false]
285
- * @param {boolean} [options.strict = false]
286
- * @param {Function} [options.buildDebugString]
287
- *
288
- * @returns
278
+ /**
279
+ * Evaluate a template.
280
+ *
281
+ * @param {string} template
282
+ * @param {Object<string, any>} context
283
+ * @param {Object} options
284
+ * @param {boolean} [options.debug = false]
285
+ * @param {boolean} [options.strict = false]
286
+ * @param {Function} [options.buildDebugString]
287
+ *
288
+ * @returns
289
289
  */
290
290
  evaluate(template, context = {}, options = {}) {
291
291
  const {
@@ -300,22 +300,22 @@ class FeelersTemplating {
300
300
  });
301
301
  }
302
302
 
303
- /**
304
- * @typedef {Object} ExpressionWithDepth
305
- * @property {number} depth - The depth of the expression in the syntax tree.
306
- * @property {string} expression - The extracted expression
303
+ /**
304
+ * @typedef {Object} ExpressionWithDepth
305
+ * @property {number} depth - The depth of the expression in the syntax tree.
306
+ * @property {string} expression - The extracted expression
307
307
  */
308
308
 
309
- /**
310
- * Extracts all feel expressions in the template along with their depth in the syntax tree.
311
- * The depth is incremented for child expressions of loops to account for context drilling.
312
- * @name extractExpressionsWithDepth
313
- * @param {string} template - A feelers template string.
314
- * @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
315
- *
316
- * @example
317
- * const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
318
- * const extractedExpressions = _extractExpressionsWithDepth(template);
309
+ /**
310
+ * Extracts all feel expressions in the template along with their depth in the syntax tree.
311
+ * The depth is incremented for child expressions of loops to account for context drilling.
312
+ * @name extractExpressionsWithDepth
313
+ * @param {string} template - A feelers template string.
314
+ * @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
315
+ *
316
+ * @example
317
+ * const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
318
+ * const extractedExpressions = _extractExpressionsWithDepth(template);
319
319
  */
320
320
  _extractExpressionsWithDepth(template) {
321
321
  // build simplified feelers syntax tree
@@ -346,9 +346,9 @@ class FeelersTemplating {
346
346
  }
347
347
  FeelersTemplating.$inject = [];
348
348
 
349
- /**
350
- * @typedef {object} Condition
351
- * @property {string} [hide]
349
+ /**
350
+ * @typedef {object} Condition
351
+ * @property {string} [hide]
352
352
  */
353
353
 
354
354
  class ConditionChecker {
@@ -357,11 +357,11 @@ class ConditionChecker {
357
357
  this._eventBus = eventBus;
358
358
  }
359
359
 
360
- /**
361
- * For given data, remove properties based on condition.
362
- *
363
- * @param {Object<string, any>} properties
364
- * @param {Object<string, any>} data
360
+ /**
361
+ * For given data, remove properties based on condition.
362
+ *
363
+ * @param {Object<string, any>} properties
364
+ * @param {Object<string, any>} data
365
365
  */
366
366
  applyConditions(properties, data = {}) {
367
367
  const conditions = this._getConditions();
@@ -380,13 +380,13 @@ class ConditionChecker {
380
380
  return newProperties;
381
381
  }
382
382
 
383
- /**
384
- * Check if given condition is met. Returns null for invalid/missing conditions.
385
- *
386
- * @param {string} condition
387
- * @param {import('../../types').Data} [data]
388
- *
389
- * @returns {boolean|null}
383
+ /**
384
+ * Check if given condition is met. Returns null for invalid/missing conditions.
385
+ *
386
+ * @param {string} condition
387
+ * @param {import('../../types').Data} [data]
388
+ *
389
+ * @returns {boolean|null}
390
390
  */
391
391
  check(condition, data = {}) {
392
392
  if (!condition) {
@@ -407,12 +407,12 @@ class ConditionChecker {
407
407
  }
408
408
  }
409
409
 
410
- /**
411
- * Check if hide condition is met.
412
- *
413
- * @param {Condition} condition
414
- * @param {Object<string, any>} data
415
- * @returns {boolean}
410
+ /**
411
+ * Check if hide condition is met.
412
+ *
413
+ * @param {Condition} condition
414
+ * @param {Object<string, any>} data
415
+ * @returns {boolean}
416
416
  */
417
417
  _checkHideCondition(condition, data) {
418
418
  if (!condition.hide) {
@@ -454,12 +454,12 @@ class MarkdownRenderer {
454
454
  this._converter = new showdown.Converter();
455
455
  }
456
456
 
457
- /**
458
- * Render markdown to HTML.
459
- *
460
- * @param {string} markdown - The markdown to render
461
- *
462
- * @returns {string} HTML
457
+ /**
458
+ * Render markdown to HTML.
459
+ *
460
+ * @param {string} markdown - The markdown to render
461
+ *
462
+ * @returns {string} HTML
463
463
  */
464
464
  render(markdown) {
465
465
  return this._converter.makeHtml(markdown);
@@ -1115,23 +1115,23 @@ class FormFieldRegistry {
1115
1115
  }
1116
1116
  FormFieldRegistry.$inject = ['eventBus'];
1117
1117
 
1118
- /**
1119
- * @typedef { { id: String, components: Array<String> } } FormRow
1120
- * @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
1118
+ /**
1119
+ * @typedef { { id: String, components: Array<String> } } FormRow
1120
+ * @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
1121
1121
  */
1122
1122
 
1123
- /**
1124
- * Maintains the Form layout in a given structure, for example
1125
- *
1126
- * [
1127
- * {
1128
- * formFieldId: 'FormField_1',
1129
- * rows: [
1130
- * { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
1131
- * ]
1132
- * }
1133
- * ]
1134
- *
1123
+ /**
1124
+ * Maintains the Form layout in a given structure, for example
1125
+ *
1126
+ * [
1127
+ * {
1128
+ * formFieldId: 'FormField_1',
1129
+ * rows: [
1130
+ * { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
1131
+ * ]
1132
+ * }
1133
+ * ]
1134
+ *
1135
1135
  */
1136
1136
  class FormLayouter {
1137
1137
  constructor(eventBus) {
@@ -1141,8 +1141,8 @@ class FormLayouter {
1141
1141
  this._eventBus = eventBus;
1142
1142
  }
1143
1143
 
1144
- /**
1145
- * @param {FormRow} row
1144
+ /**
1145
+ * @param {FormRow} row
1146
1146
  */
1147
1147
  addRow(formFieldId, row) {
1148
1148
  let rowsPerComponent = this._rows.find(r => r.formFieldId === formFieldId);
@@ -1156,18 +1156,18 @@ class FormLayouter {
1156
1156
  rowsPerComponent.rows.push(row);
1157
1157
  }
1158
1158
 
1159
- /**
1160
- * @param {String} id
1161
- * @returns {FormRow}
1159
+ /**
1160
+ * @param {String} id
1161
+ * @returns {FormRow}
1162
1162
  */
1163
1163
  getRow(id) {
1164
1164
  const rows = allRows(this._rows);
1165
1165
  return rows.find(r => r.id === id);
1166
1166
  }
1167
1167
 
1168
- /**
1169
- * @param {any} formField
1170
- * @returns {FormRow}
1168
+ /**
1169
+ * @param {any} formField
1170
+ * @returns {FormRow}
1171
1171
  */
1172
1172
  getRowForField(formField) {
1173
1173
  return allRows(this._rows).find(r => {
@@ -1178,9 +1178,9 @@ class FormLayouter {
1178
1178
  });
1179
1179
  }
1180
1180
 
1181
- /**
1182
- * @param {String} formFieldId
1183
- * @returns { Array<FormRow> }
1181
+ /**
1182
+ * @param {String} formFieldId
1183
+ * @returns { Array<FormRow> }
1184
1184
  */
1185
1185
  getRows(formFieldId) {
1186
1186
  const rowsForField = this._rows.find(r => formFieldId === r.formFieldId);
@@ -1190,15 +1190,15 @@ class FormLayouter {
1190
1190
  return rowsForField.rows;
1191
1191
  }
1192
1192
 
1193
- /**
1194
- * @returns {string}
1193
+ /**
1194
+ * @returns {string}
1195
1195
  */
1196
1196
  nextRowId() {
1197
1197
  return this._ids.nextPrefixed('Row_');
1198
1198
  }
1199
1199
 
1200
- /**
1201
- * @param {any} formField
1200
+ /**
1201
+ * @param {any} formField
1202
1202
  */
1203
1203
  calculateLayout(formField) {
1204
1204
  const {
@@ -1252,9 +1252,9 @@ function groupByRow(components, ids) {
1252
1252
  });
1253
1253
  }
1254
1254
 
1255
- /**
1256
- * @param {Array<FormRows>} formRows
1257
- * @returns {Array<FormRow>}
1255
+ /**
1256
+ * @param {Array<FormRows>} formRows
1257
+ * @returns {Array<FormRow>}
1258
1258
  */
1259
1259
  function allRows(formRows) {
1260
1260
  return minDash.flatten(formRows.map(c => c.rows));
@@ -1331,10 +1331,10 @@ function createInjector(bootstrapModules) {
1331
1331
  return injector;
1332
1332
  }
1333
1333
 
1334
- /**
1335
- * @param {string?} prefix
1336
- *
1337
- * @returns Element
1334
+ /**
1335
+ * @param {string?} prefix
1336
+ *
1337
+ * @returns Element
1338
1338
  */
1339
1339
  function createFormContainer(prefix = 'fjs') {
1340
1340
  const container = document.createElement('div');
@@ -1380,22 +1380,22 @@ function generateIdForType(type) {
1380
1380
  return `${type}${generateIndexForType(type)}`;
1381
1381
  }
1382
1382
 
1383
- /**
1384
- * @template T
1385
- * @param {T} data
1386
- * @param {(this: any, key: string, value: any) => any} [replacer]
1387
- * @return {T}
1383
+ /**
1384
+ * @template T
1385
+ * @param {T} data
1386
+ * @param {(this: any, key: string, value: any) => any} [replacer]
1387
+ * @return {T}
1388
1388
  */
1389
1389
  function clone(data, replacer) {
1390
1390
  return JSON.parse(JSON.stringify(data, replacer));
1391
1391
  }
1392
1392
 
1393
- /**
1394
- * Parse the schema for input variables a form might make use of
1395
- *
1396
- * @param {any} schema
1397
- *
1398
- * @return {string[]}
1393
+ /**
1394
+ * Parse the schema for input variables a form might make use of
1395
+ *
1396
+ * @param {any} schema
1397
+ *
1398
+ * @return {string[]}
1399
1399
  */
1400
1400
  function getSchemaVariables(schema, expressionLanguage = new FeelExpressionLanguage(null), templating = new FeelersTemplating()) {
1401
1401
  if (!schema.components) {
@@ -1447,11 +1447,11 @@ function getSchemaVariables(schema, expressionLanguage = new FeelExpressionLangu
1447
1447
  }
1448
1448
 
1449
1449
  class Importer {
1450
- /**
1451
- * @constructor
1452
- * @param { import('../core').FormFieldRegistry } formFieldRegistry
1453
- * @param { import('../render/FormFields').default } formFields
1454
- * @param { import('../core').FormLayouter } formLayouter
1450
+ /**
1451
+ * @constructor
1452
+ * @param { import('../core').FormFieldRegistry } formFieldRegistry
1453
+ * @param { import('../render/FormFields').default } formFields
1454
+ * @param { import('../core').FormLayouter } formLayouter
1455
1455
  */
1456
1456
  constructor(formFieldRegistry, formFields, formLayouter) {
1457
1457
  this._formFieldRegistry = formFieldRegistry;
@@ -1459,15 +1459,15 @@ class Importer {
1459
1459
  this._formLayouter = formLayouter;
1460
1460
  }
1461
1461
 
1462
- /**
1463
- * Import schema adding `id`, `_parent` and `_path`
1464
- * information to each field and adding it to the
1465
- * form field registry.
1466
- *
1467
- * @param {any} schema
1468
- * @param {any} [data]
1469
- *
1470
- * @return { { warnings: Array<any>, schema: any, data: any } }
1462
+ /**
1463
+ * Import schema adding `id`, `_parent` and `_path`
1464
+ * information to each field and adding it to the
1465
+ * form field registry.
1466
+ *
1467
+ * @param {any} schema
1468
+ * @param {any} [data]
1469
+ *
1470
+ * @return { { warnings: Array<any>, schema: any, data: any } }
1471
1471
  */
1472
1472
  importSchema(schema, data = {}) {
1473
1473
  // TODO: Add warnings - https://github.com/bpmn-io/form-js/issues/289
@@ -1488,11 +1488,11 @@ class Importer {
1488
1488
  }
1489
1489
  }
1490
1490
 
1491
- /**
1492
- * @param {any} formField
1493
- * @param {string} [parentId]
1494
- *
1495
- * @return {any} importedField
1491
+ /**
1492
+ * @param {any} formField
1493
+ * @param {string} [parentId]
1494
+ *
1495
+ * @return {any} importedField
1496
1496
  */
1497
1497
  importFormField(formField, parentId) {
1498
1498
  const {
@@ -1543,10 +1543,10 @@ class Importer {
1543
1543
  });
1544
1544
  }
1545
1545
 
1546
- /**
1547
- * @param {Object} data
1548
- *
1549
- * @return {Object} initializedData
1546
+ /**
1547
+ * @param {Object} data
1548
+ *
1549
+ * @return {Object} initializedData
1550
1550
  */
1551
1551
  initializeFieldValues(data) {
1552
1552
  return this._formFieldRegistry.getAll().reduce((initializedData, formField) => {
@@ -1684,11 +1684,11 @@ const FormRenderContext = preact.createContext({
1684
1684
  });
1685
1685
  var FormRenderContext$1 = FormRenderContext;
1686
1686
 
1687
- /**
1688
- * @param {string} type
1689
- * @param {boolean} [strict]
1690
- *
1691
- * @returns {any}
1687
+ /**
1688
+ * @param {string} type
1689
+ * @param {boolean} [strict]
1690
+ *
1691
+ * @returns {any}
1692
1692
  */
1693
1693
  function getService(type, strict) {}
1694
1694
  const FormContext = preact.createContext({
@@ -1704,10 +1704,10 @@ function useService(type, strict) {
1704
1704
  return getService(type, strict);
1705
1705
  }
1706
1706
 
1707
- /**
1708
- * Returns the conditionally filtered data of a form reactively.
1709
- * Memoised to minimize re-renders
1710
- *
1707
+ /**
1708
+ * Returns the conditionally filtered data of a form reactively.
1709
+ * Memoised to minimize re-renders
1710
+ *
1711
1711
  */
1712
1712
  function useFilteredFormData() {
1713
1713
  const {
@@ -1724,12 +1724,12 @@ function useFilteredFormData() {
1724
1724
  }, [conditionChecker, data, initialData]);
1725
1725
  }
1726
1726
 
1727
- /**
1728
- * Evaluate if condition is met reactively based on the conditionChecker and form data.
1729
- *
1730
- * @param {string | undefined} condition
1731
- *
1732
- * @returns {boolean} true if condition is met or no condition or condition checker exists
1727
+ /**
1728
+ * Evaluate if condition is met reactively based on the conditionChecker and form data.
1729
+ *
1730
+ * @param {string | undefined} condition
1731
+ *
1732
+ * @returns {boolean} true if condition is met or no condition or condition checker exists
1733
1733
  */
1734
1734
  function useCondition(condition) {
1735
1735
  const conditionChecker = useService('conditionChecker', false);
@@ -1739,13 +1739,13 @@ function useCondition(condition) {
1739
1739
  }, [conditionChecker, condition, filteredData]);
1740
1740
  }
1741
1741
 
1742
- /**
1743
- * Evaluate a string reactively based on the expressionLanguage and form data.
1744
- * If the string is not an expression, it is returned as is.
1745
- * Memoised to minimize re-renders.
1746
- *
1747
- * @param {string} value
1748
- *
1742
+ /**
1743
+ * Evaluate a string reactively based on the expressionLanguage and form data.
1744
+ * If the string is not an expression, it is returned as is.
1745
+ * Memoised to minimize re-renders.
1746
+ *
1747
+ * @param {string} value
1748
+ *
1749
1749
  */
1750
1750
  function useExpressionEvaluation(value) {
1751
1751
  const formData = useFilteredFormData();
@@ -1774,16 +1774,16 @@ function useKeyDownAction(targetKey, action, listenerElement = window) {
1774
1774
  });
1775
1775
  }
1776
1776
 
1777
- /**
1778
- * Retrieve readonly value of a form field, given it can be an
1779
- * expression optionally or configured globally.
1780
- *
1781
- * @typedef { import('../../types').FormProperties } FormProperties
1782
- *
1783
- * @param {any} formField
1784
- * @param {FormProperties} properties
1785
- *
1786
- * @returns {boolean}
1777
+ /**
1778
+ * Retrieve readonly value of a form field, given it can be an
1779
+ * expression optionally or configured globally.
1780
+ *
1781
+ * @typedef { import('../../types').FormProperties } FormProperties
1782
+ *
1783
+ * @param {any} formField
1784
+ * @param {FormProperties} properties
1785
+ *
1786
+ * @returns {boolean}
1787
1787
  */
1788
1788
  function useReadonly(formField, properties = {}) {
1789
1789
  const expressionLanguage = useService('expressionLanguage');
@@ -1801,16 +1801,16 @@ function useReadonly(formField, properties = {}) {
1801
1801
  return readonly || false;
1802
1802
  }
1803
1803
 
1804
- /**
1805
- * Template a string reactively based on form data. If the string is not a template, it is returned as is.
1806
- * Memoised to minimize re-renders
1807
- *
1808
- * @param {string} value
1809
- * @param {Object} options
1810
- * @param {boolean} [options.debug = false]
1811
- * @param {boolean} [options.strict = false]
1812
- * @param {Function} [options.buildDebugString]
1813
- *
1804
+ /**
1805
+ * Template a string reactively based on form data. If the string is not a template, it is returned as is.
1806
+ * Memoised to minimize re-renders
1807
+ *
1808
+ * @param {string} value
1809
+ * @param {Object} options
1810
+ * @param {boolean} [options.debug = false]
1811
+ * @param {boolean} [options.strict = false]
1812
+ * @param {Function} [options.buildDebugString]
1813
+ *
1814
1814
  */
1815
1815
  function useTemplateEvaluation(value, options) {
1816
1816
  const filteredData = useFilteredFormData();
@@ -1823,17 +1823,17 @@ function useTemplateEvaluation(value, options) {
1823
1823
  }, [filteredData, templating, value, options]);
1824
1824
  }
1825
1825
 
1826
- /**
1827
- * Template a string reactively based on form data. If the string is not a template, it is returned as is.
1828
- * If the string contains multiple lines, only the first line is returned.
1829
- * Memoised to minimize re-renders
1830
- *
1831
- * @param {string} value
1832
- * @param {Object} [options]
1833
- * @param {boolean} [options.debug = false]
1834
- * @param {boolean} [options.strict = false]
1835
- * @param {Function} [options.buildDebugString]
1836
- *
1826
+ /**
1827
+ * Template a string reactively based on form data. If the string is not a template, it is returned as is.
1828
+ * If the string contains multiple lines, only the first line is returned.
1829
+ * Memoised to minimize re-renders
1830
+ *
1831
+ * @param {string} value
1832
+ * @param {Object} [options]
1833
+ * @param {boolean} [options.debug = false]
1834
+ * @param {boolean} [options.strict = false]
1835
+ * @param {Function} [options.buildDebugString]
1836
+ *
1837
1837
  */
1838
1838
  function useSingleLineTemplateEvaluation(value, options = {}) {
1839
1839
  const evaluatedTemplate = useTemplateEvaluation(value, options);
@@ -2020,8 +2020,8 @@ function _isValueSomething(value) {
2020
2020
  return value || value === 0 || value === false;
2021
2021
  }
2022
2022
 
2023
- /**
2024
- * @enum { String }
2023
+ /**
2024
+ * @enum { String }
2025
2025
  */
2026
2026
  const LOAD_STATES = {
2027
2027
  LOADING: 'loading',
@@ -2029,17 +2029,17 @@ const LOAD_STATES = {
2029
2029
  ERROR: 'error'
2030
2030
  };
2031
2031
 
2032
- /**
2033
- * @typedef {Object} ValuesGetter
2034
- * @property {Object[]} values - The values data
2035
- * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
2032
+ /**
2033
+ * @typedef {Object} ValuesGetter
2034
+ * @property {Object[]} values - The values data
2035
+ * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
2036
2036
  */
2037
2037
 
2038
- /**
2039
- * A hook to load values for single and multiselect components.
2040
- *
2041
- * @param {Object} field - The form field to handle values for
2042
- * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
2038
+ /**
2039
+ * A hook to load values for single and multiselect components.
2040
+ *
2041
+ * @param {Object} field - The form field to handle values for
2042
+ * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
2043
2043
  */
2044
2044
  function useValuesAsync (field) {
2045
2045
  const {
@@ -2517,8 +2517,8 @@ var CalendarIcon = (({
2517
2517
 
2518
2518
  function InputAdorner(props) {
2519
2519
  const {
2520
- pre = null,
2521
- post = null,
2520
+ pre,
2521
+ post,
2522
2522
  rootRef,
2523
2523
  inputRef,
2524
2524
  children,
@@ -2535,14 +2535,14 @@ function InputAdorner(props) {
2535
2535
  'hasErrors': hasErrors
2536
2536
  }),
2537
2537
  ref: rootRef,
2538
- children: [pre !== null && jsxRuntime.jsxs("span", {
2538
+ children: [pre && jsxRuntime.jsxs("span", {
2539
2539
  class: "fjs-input-adornment border-right border-radius-left",
2540
2540
  onClick: onAdornmentClick,
2541
2541
  children: [" ", minDash.isString(pre) ? jsxRuntime.jsx("span", {
2542
2542
  class: "fjs-input-adornment-text",
2543
2543
  children: pre
2544
2544
  }) : pre, " "]
2545
- }), children, post !== null && jsxRuntime.jsxs("span", {
2545
+ }), children, post && jsxRuntime.jsxs("span", {
2546
2546
  class: "fjs-input-adornment border-left border-radius-right",
2547
2547
  onClick: onAdornmentClick,
2548
2548
  children: [" ", minDash.isString(post) ? jsxRuntime.jsx("span", {
@@ -2823,9 +2823,16 @@ function Timepicker(props) {
2823
2823
  time,
2824
2824
  setTime
2825
2825
  } = props;
2826
+ const safeTimeInterval = hooks.useMemo(() => {
2827
+ const allowedIntervals = [1, 5, 10, 15, 30, 60];
2828
+ if (allowedIntervals.includes(timeInterval)) {
2829
+ return timeInterval;
2830
+ }
2831
+ return 15;
2832
+ }, [timeInterval]);
2826
2833
  const timeInputRef = hooks.useRef();
2827
2834
  const [dropdownIsOpen, setDropdownIsOpen] = hooks.useState(false);
2828
- const useDropdown = hooks.useMemo(() => timeInterval !== 1, [timeInterval]);
2835
+ const useDropdown = hooks.useMemo(() => safeTimeInterval !== 1, [safeTimeInterval]);
2829
2836
  const [rawValue, setRawValue] = hooks.useState('');
2830
2837
 
2831
2838
  // populates values from source
@@ -2834,12 +2841,12 @@ function Timepicker(props) {
2834
2841
  setRawValue('');
2835
2842
  return;
2836
2843
  }
2837
- const intervalAdjustedTime = time - time % timeInterval;
2844
+ const intervalAdjustedTime = time - time % safeTimeInterval;
2838
2845
  setRawValue(formatTime(use24h, intervalAdjustedTime));
2839
2846
  if (intervalAdjustedTime != time) {
2840
2847
  setTime(intervalAdjustedTime);
2841
2848
  }
2842
- }, [time, setTime, use24h, timeInterval]);
2849
+ }, [time, setTime, use24h, safeTimeInterval]);
2843
2850
  const propagateRawToMinute = hooks.useCallback(newRawValue => {
2844
2851
  const localRawValue = newRawValue || rawValue;
2845
2852
 
@@ -2858,34 +2865,34 @@ function Timepicker(props) {
2858
2865
  }
2859
2866
 
2860
2867
  // Enforce the minutes to match the timeInterval
2861
- const correctedMinutes = minutes - minutes % timeInterval;
2868
+ const correctedMinutes = minutes - minutes % safeTimeInterval;
2862
2869
 
2863
2870
  // Enforce the raw text to be formatted properly
2864
2871
  setRawValue(formatTime(use24h, correctedMinutes));
2865
2872
  setTime(correctedMinutes);
2866
- }, [rawValue, timeInterval, use24h, setTime]);
2873
+ }, [rawValue, safeTimeInterval, use24h, setTime]);
2867
2874
  const timeOptions = hooks.useMemo(() => {
2868
2875
  const minutesInDay = 24 * 60;
2869
- const intervalCount = Math.floor(minutesInDay / timeInterval);
2870
- return [...Array(intervalCount).keys()].map(intervalIndex => formatTime(use24h, intervalIndex * timeInterval));
2871
- }, [timeInterval, use24h]);
2876
+ const intervalCount = Math.floor(minutesInDay / safeTimeInterval);
2877
+ return [...Array(intervalCount).keys()].map(intervalIndex => formatTime(use24h, intervalIndex * safeTimeInterval));
2878
+ }, [safeTimeInterval, use24h]);
2872
2879
  const initialFocusIndex = hooks.useMemo(() => {
2873
2880
  // if there are no options, there will not be any focusing
2874
- if (!timeOptions || !timeInterval) return null;
2881
+ if (!timeOptions || !safeTimeInterval) return null;
2875
2882
 
2876
2883
  // if there is a set minute value, we focus it in the dropdown
2877
- if (time) return time / timeInterval;
2884
+ if (time) return time / safeTimeInterval;
2878
2885
  const cacheTime = parseInputTime(rawValue);
2879
2886
 
2880
2887
  // if there is a valid value in the input cache, we try and focus close to it
2881
2888
  if (cacheTime) {
2882
- const flooredCacheTime = cacheTime - cacheTime % timeInterval;
2883
- return flooredCacheTime / timeInterval;
2889
+ const flooredCacheTime = cacheTime - cacheTime % safeTimeInterval;
2890
+ return flooredCacheTime / safeTimeInterval;
2884
2891
  }
2885
2892
 
2886
2893
  // If there is no set value, simply focus the middle of the dropdown (12:00)
2887
2894
  return Math.floor(timeOptions.length / 2);
2888
- }, [rawValue, time, timeInterval, timeOptions]);
2895
+ }, [rawValue, time, safeTimeInterval, timeOptions]);
2889
2896
  const onInputKeyDown = e => {
2890
2897
  switch (e.key) {
2891
2898
  case 'ArrowUp':
@@ -3154,10 +3161,10 @@ Datetime.config = {
3154
3161
  }
3155
3162
  };
3156
3163
 
3157
- /**
3158
- * This file must not be changed or exchanged.
3159
- *
3160
- * @see http://bpmn.io/license for more information.
3164
+ /**
3165
+ * This file must not be changed or exchanged.
3166
+ *
3167
+ * @see http://bpmn.io/license for more information.
3161
3168
  */
3162
3169
  function Logo() {
3163
3170
  return jsxRuntime.jsxs("svg", {
@@ -3289,11 +3296,11 @@ const ATTR_WHITESPACE_PATTERN = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u
3289
3296
 
3290
3297
  const FORM_ELEMENT = document.createElement('form');
3291
3298
 
3292
- /**
3293
- * Sanitize a HTML string and return the cleaned, safe version.
3294
- *
3295
- * @param {string} html
3296
- * @return {string}
3299
+ /**
3300
+ * Sanitize a HTML string and return the cleaned, safe version.
3301
+ *
3302
+ * @param {string} html
3303
+ * @return {string}
3297
3304
  */
3298
3305
 
3299
3306
  // see https://github.com/developit/snarkdown/issues/70
@@ -3311,29 +3318,29 @@ function sanitizeHTML(html) {
3311
3318
  }
3312
3319
  }
3313
3320
 
3314
- /**
3315
- * Sanitizes an image source to ensure we only allow for data URI and links
3316
- * that start with http(s).
3317
- *
3318
- * Note: Most browsers anyway do not support script execution in <img> elements.
3319
- *
3320
- * @param {string} src
3321
- * @returns {string}
3321
+ /**
3322
+ * Sanitizes an image source to ensure we only allow for data URI and links
3323
+ * that start with http(s).
3324
+ *
3325
+ * Note: Most browsers anyway do not support script execution in <img> elements.
3326
+ *
3327
+ * @param {string} src
3328
+ * @returns {string}
3322
3329
  */
3323
3330
  function sanitizeImageSource(src) {
3324
3331
  const valid = ALLOWED_IMAGE_SRC_PATTERN.test(src);
3325
3332
  return valid ? src : '';
3326
3333
  }
3327
3334
 
3328
- /**
3329
- * Recursively sanitize a HTML node, potentially
3330
- * removing it, its children or attributes.
3331
- *
3332
- * Inspired by https://github.com/developit/snarkdown/issues/70
3333
- * and https://github.com/cure53/DOMPurify. Simplified
3334
- * for our use-case.
3335
- *
3336
- * @param {Element} node
3335
+ /**
3336
+ * Recursively sanitize a HTML node, potentially
3337
+ * removing it, its children or attributes.
3338
+ *
3339
+ * Inspired by https://github.com/developit/snarkdown/issues/70
3340
+ * and https://github.com/cure53/DOMPurify. Simplified
3341
+ * for our use-case.
3342
+ *
3343
+ * @param {Element} node
3337
3344
  */
3338
3345
  function sanitizeNode(node) {
3339
3346
  // allow text nodes
@@ -3377,13 +3384,13 @@ function sanitizeNode(node) {
3377
3384
  }
3378
3385
  }
3379
3386
 
3380
- /**
3381
- * Validates attributes for validity.
3382
- *
3383
- * @param {string} lcTag
3384
- * @param {string} lcName
3385
- * @param {string} value
3386
- * @return {boolean}
3387
+ /**
3388
+ * Validates attributes for validity.
3389
+ *
3390
+ * @param {string} lcTag
3391
+ * @param {string} lcName
3392
+ * @param {string} value
3393
+ * @return {boolean}
3387
3394
  */
3388
3395
  function isValidAttribute(lcTag, lcName, value) {
3389
3396
  // disallow most attributes based on whitelist