@bpmn-io/form-js-playground 0.14.0 → 0.14.1

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.
@@ -49251,30 +49251,178 @@
49251
49251
  return value;
49252
49252
  }
49253
49253
 
49254
+ const getFlavouredFeelVariableNames = (feelString, feelFlavour, options = {}) => {
49255
+ const {
49256
+ depth = 0,
49257
+ specialDepthAccessors = {}
49258
+ } = options;
49259
+ if (!['expression', 'unaryTest'].includes(feelFlavour)) return [];
49260
+ const tree = feelFlavour === 'expression' ? parseExpressions$1(feelString) : parseUnaryTests$1(feelString);
49261
+ const simpleExpressionTree = _buildSimpleFeelStructureTree(tree, feelString);
49262
+ return function _unfoldVariables(node) {
49263
+ if (node.name === 'PathExpression') {
49264
+ if (Object.keys(specialDepthAccessors).length === 0) {
49265
+ return depth === 0 ? [_getVariableNameAtPathIndex(node, 0)] : [];
49266
+ }
49267
+
49268
+ // if using special depth accessors, use a more complex extraction
49269
+ return Array.from(_smartExtractVariableNames(node, depth, specialDepthAccessors));
49270
+ }
49271
+ if (depth === 0 && node.name === 'VariableName') return [node.variableName];
49272
+
49273
+ // for any other kind of node, traverse its children and flatten the result
49274
+ if (node.children) {
49275
+ return node.children.reduce((acc, child) => {
49276
+ return acc.concat(_unfoldVariables(child));
49277
+ }, []);
49278
+ }
49279
+ return [];
49280
+ }(simpleExpressionTree);
49281
+ };
49282
+
49283
+ /**
49284
+ * Get the variable name at the specified index in a given path expression.
49285
+ *
49286
+ * @param {Object} root - The root node of the path expression tree.
49287
+ * @param {number} index - The index of the variable name to retrieve.
49288
+ * @returns {string|null} The variable name at the specified index or null if index is out of bounds.
49289
+ */
49290
+ const _getVariableNameAtPathIndex = (root, index) => {
49291
+ const accessors = _deconstructPathExpression(root);
49292
+ return accessors[index] || null;
49293
+ };
49294
+
49295
+ /**
49296
+ * Extracts the variables which are required of the external context for a given path expression.
49297
+ * This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
49298
+ *
49299
+ * @param {Object} node - The root node of the path expression tree.
49300
+ * @param {number} initialDepth - The depth at which the root node is located in the outer context.
49301
+ * @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
49302
+ * @returns {Set} - A set containing the extracted variable names.
49303
+ */
49304
+ const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) => {
49305
+ // depth info represents the previous (initialised as null) and current depth of the current accessor in the path expression
49306
+ // we track multiple of these to account for the fact that a path expression may be ambiguous due to special keywords
49307
+ let accessorDepthInfos = [{
49308
+ previous: null,
49309
+ current: initialDepth - 1
49310
+ }];
49311
+ const extractedVariables = new Set();
49312
+ const nodeAccessors = _deconstructPathExpression(node);
49313
+ for (let i = 0; i < nodeAccessors.length; i++) {
49314
+ const currentAccessor = nodeAccessors[i];
49315
+ if (currentAccessor in specialDepthAccessors) {
49316
+ const depthOffsets = specialDepthAccessors[currentAccessor];
49317
+
49318
+ // if the current accessor is a special keyword, we need to expand the current depth info set
49319
+ // this is done to account for the ambiguity of keywords like parent, which may be used to access
49320
+ // the parent of the current node, or a child variable of the same name
49321
+ accessorDepthInfos = depthOffsets.reduce((accumulator, offset) => {
49322
+ return [...accumulator, ...accessorDepthInfos.map(depthInfo => ({
49323
+ previous: depthInfo.current,
49324
+ current: depthInfo.current + offset
49325
+ }))];
49326
+ }, []).filter(depthInfo => depthInfo.current >= -1); // discard all depth infos which are out of bounds
49327
+ } else {
49328
+ // if the current accessor is not a special keyword, we know it's simply accessing a child
49329
+ // hence we are now one level deeper in the tree and simply increment
49330
+ accessorDepthInfos = accessorDepthInfos.map(depthInfo => ({
49331
+ previous: depthInfo.current,
49332
+ current: depthInfo.current + 1
49333
+ }));
49334
+ }
49335
+
49336
+ // finally, we check if for the current accessor, there is a scenario where:
49337
+ // previous it was at depth -1 (i.e. the root context), and is now at depth 0 (i.e. a variable)
49338
+ // these are the variables we need to request, so we add them to the set
49339
+ if (accessorDepthInfos.some(depthInfo => depthInfo.previous === -1 && depthInfo.current === 0)) {
49340
+ extractedVariables.add(currentAccessor);
49341
+ }
49342
+ }
49343
+
49344
+ // we return a set to avoid duplicates
49345
+ return new Set(extractedVariables);
49346
+ };
49347
+
49348
+ /**
49349
+ * Deconstructs a path expression tree into an array of components.
49350
+ *
49351
+ * @param {Object} root - The root node of the path expression tree.
49352
+ * @returns {Array<string>} An array of components in the path expression, in the correct order.
49353
+ */
49354
+ const _deconstructPathExpression = root => {
49355
+ let node = root;
49356
+ let parts = [];
49357
+
49358
+ // Traverse the tree and collect path components
49359
+ while (node.name === 'PathExpression') {
49360
+ parts.push(node.children[1].variableName);
49361
+ node = node.children[0];
49362
+ }
49363
+
49364
+ // Add the last component to the array
49365
+ parts.push(node.variableName);
49366
+
49367
+ // Reverse and return the array to get the correct order
49368
+ return parts.reverse();
49369
+ };
49370
+
49371
+ /**
49372
+ * Builds a simplified feel structure tree from the given parse tree and feel string.
49373
+ * The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
49374
+ *
49375
+ * @param {Object} parseTree - The parse tree generated by a parser.
49376
+ * @param {string} feelString - The feel string used for parsing.
49377
+ * @returns {Object} The simplified feel structure tree.
49378
+ */
49379
+ const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
49380
+ const stack = [{
49381
+ children: []
49382
+ }];
49383
+ parseTree.iterate({
49384
+ enter: node => {
49385
+ const nodeRepresentation = {
49386
+ name: node.type.name,
49387
+ children: []
49388
+ };
49389
+ if (node.type.name === 'VariableName') {
49390
+ nodeRepresentation.variableName = feelString.slice(node.from, node.to);
49391
+ }
49392
+ stack.push(nodeRepresentation);
49393
+ },
49394
+ leave: () => {
49395
+ const result = stack.pop();
49396
+ const parent = stack[stack.length - 1];
49397
+ parent.children.push(result);
49398
+ }
49399
+ });
49400
+ return stack[0].children[0];
49401
+ };
49254
49402
  class FeelExpressionLanguage {
49255
49403
  constructor(eventBus) {
49256
49404
  this._eventBus = eventBus;
49257
49405
  }
49258
49406
 
49259
- /**
49260
- * Determines if the given string is a FEEL expression.
49261
- *
49262
- * @param {string} value
49263
- * @returns {boolean}
49264
- *
49407
+ /**
49408
+ * Determines if the given value is a FEEL expression.
49409
+ *
49410
+ * @param {any} value
49411
+ * @returns {boolean}
49412
+ *
49265
49413
  */
49266
49414
  isExpression(value) {
49267
49415
  return isString$4(value) && value.startsWith('=');
49268
49416
  }
49269
49417
 
49270
- /**
49271
- * Retrieve variable names from a given FEEL expression.
49272
- *
49273
- * @param {string} expression
49274
- * @param {object} [options]
49275
- * @param {string} [options.type]
49276
- *
49277
- * @returns {string[]}
49418
+ /**
49419
+ * Retrieve variable names from a given FEEL expression.
49420
+ *
49421
+ * @param {string} expression
49422
+ * @param {object} [options]
49423
+ * @param {string} [options.type]
49424
+ *
49425
+ * @returns {string[]}
49278
49426
  */
49279
49427
  getVariableNames(expression, options = {}) {
49280
49428
  const {
@@ -49283,21 +49431,19 @@
49283
49431
  if (!this.isExpression(expression)) {
49284
49432
  return [];
49285
49433
  }
49286
- if (type === 'unaryTest') {
49287
- return this._getUnaryVariableNames(expression);
49288
- } else if (type === 'expression') {
49289
- return this._getExpressionVariableNames(expression);
49434
+ if (!['unaryTest', 'expression'].includes(type)) {
49435
+ throw new Error('Unknown expression type: ' + type);
49290
49436
  }
49291
- throw new Error('Unknown expression type: ' + options.type);
49437
+ return getFlavouredFeelVariableNames(expression, type);
49292
49438
  }
49293
49439
 
49294
- /**
49295
- * Evaluate an expression.
49296
- *
49297
- * @param {string} expression
49298
- * @param {import('../../types').Data} [data]
49299
- *
49300
- * @returns {any}
49440
+ /**
49441
+ * Evaluate an expression.
49442
+ *
49443
+ * @param {string} expression
49444
+ * @param {import('../../types').Data} [data]
49445
+ *
49446
+ * @returns {any}
49301
49447
  */
49302
49448
  evaluate(expression, data = {}) {
49303
49449
  if (!expression) {
@@ -49316,49 +49462,64 @@
49316
49462
  return null;
49317
49463
  }
49318
49464
  }
49319
- _getExpressionVariableNames(expression) {
49320
- const tree = parseExpressions$1(expression);
49321
- const cursor = tree.cursor();
49322
- const variables = new Set();
49323
- do {
49324
- const node = cursor.node;
49325
- if (node.type.name === 'VariableName') {
49326
- variables.add(expression.slice(node.from, node.to));
49327
- }
49328
- } while (cursor.next());
49329
- return Array.from(variables);
49330
- }
49331
- _getUnaryVariableNames(unaryTest) {
49332
- const tree = parseUnaryTests$1(unaryTest);
49333
- const cursor = tree.cursor();
49334
- const variables = new Set();
49335
- do {
49336
- const node = cursor.node;
49337
- if (node.type.name === 'VariableName') {
49338
- variables.add(unaryTest.slice(node.from, node.to));
49339
- }
49340
- } while (cursor.next());
49341
- return Array.from(variables);
49342
- }
49343
49465
  }
49344
49466
  FeelExpressionLanguage.$inject = ['eventBus'];
49345
49467
  class FeelersTemplating {
49346
49468
  constructor() {}
49469
+
49470
+ /**
49471
+ * Determines if the given value is a feelers template.
49472
+ *
49473
+ * @param {any} value
49474
+ * @returns {boolean}
49475
+ *
49476
+ */
49347
49477
  isTemplate(value) {
49348
- return isString$4(value) && (value.startsWith('=') || /{{/.test(value));
49478
+ return isString$4(value) && (value.startsWith('=') || /{{.*?}}/.test(value));
49349
49479
  }
49350
49480
 
49351
- /**
49352
- * Evaluate a template.
49353
- *
49354
- * @param {string} template
49355
- * @param {Object<string, any>} context
49356
- * @param {Object} options
49357
- * @param {boolean} [options.debug = false]
49358
- * @param {boolean} [options.strict = false]
49359
- * @param {Function} [options.buildDebugString]
49360
- *
49361
- * @returns
49481
+ /**
49482
+ * Retrieve variable names from a given feelers template.
49483
+ *
49484
+ * @param {string} template
49485
+ *
49486
+ * @returns {string[]}
49487
+ */
49488
+ getVariableNames(template) {
49489
+ if (!this.isTemplate(template)) {
49490
+ return [];
49491
+ }
49492
+ const expressions = this._extractExpressionsWithDepth(template);
49493
+
49494
+ // defines special accessors, and the change(s) in depth they could imply (e.g. parent can be used to access the parent context (depth - 1) or a child variable named parent (depth + 1)
49495
+ const specialDepthAccessors = {
49496
+ parent: [-1, 1],
49497
+ _parent_: [-1],
49498
+ this: [0, 1],
49499
+ _this_: [0]
49500
+ };
49501
+ return expressions.reduce((variables, {
49502
+ expression,
49503
+ depth
49504
+ }) => {
49505
+ return variables.concat(getFlavouredFeelVariableNames(expression, 'expression', {
49506
+ depth,
49507
+ specialDepthAccessors
49508
+ }));
49509
+ }, []);
49510
+ }
49511
+
49512
+ /**
49513
+ * Evaluate a template.
49514
+ *
49515
+ * @param {string} template
49516
+ * @param {Object<string, any>} context
49517
+ * @param {Object} options
49518
+ * @param {boolean} [options.debug = false]
49519
+ * @param {boolean} [options.strict = false]
49520
+ * @param {Function} [options.buildDebugString]
49521
+ *
49522
+ * @returns
49362
49523
  */
49363
49524
  evaluate(template, context = {}, options = {}) {
49364
49525
  const {
@@ -49372,12 +49533,56 @@
49372
49533
  buildDebugString
49373
49534
  });
49374
49535
  }
49536
+
49537
+ /**
49538
+ * @typedef {Object} ExpressionWithDepth
49539
+ * @property {number} depth - The depth of the expression in the syntax tree.
49540
+ * @property {string} expression - The extracted expression
49541
+ */
49542
+
49543
+ /**
49544
+ * Extracts all feel expressions in the template along with their depth in the syntax tree.
49545
+ * The depth is incremented for child expressions of loops to account for context drilling.
49546
+ * @name extractExpressionsWithDepth
49547
+ * @param {string} template - A feelers template string.
49548
+ * @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
49549
+ *
49550
+ * @example
49551
+ * const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
49552
+ * const extractedExpressions = _extractExpressionsWithDepth(template);
49553
+ */
49554
+ _extractExpressionsWithDepth(template) {
49555
+ // build simplified feelers syntax tree
49556
+ const parseTree = parser$1.parse(template);
49557
+ const tree = buildSimpleTree(parseTree, template);
49558
+ return function _traverse(n, depth = 0) {
49559
+ if (['Feel', 'FeelBlock'].includes(n.name)) {
49560
+ return [{
49561
+ depth,
49562
+ expression: n.content
49563
+ }];
49564
+ }
49565
+ if (n.name === 'LoopSpanner') {
49566
+ const loopExpression = n.children[0].content;
49567
+ const childResults = n.children.slice(1).reduce((acc, child) => {
49568
+ return acc.concat(_traverse(child, depth + 1));
49569
+ }, []);
49570
+ return [{
49571
+ depth,
49572
+ expression: loopExpression
49573
+ }, ...childResults];
49574
+ }
49575
+ return n.children.reduce((acc, child) => {
49576
+ return acc.concat(_traverse(child, depth));
49577
+ }, []);
49578
+ }(tree);
49579
+ }
49375
49580
  }
49376
49581
  FeelersTemplating.$inject = [];
49377
49582
 
49378
- /**
49379
- * @typedef {object} Condition
49380
- * @property {string} [hide]
49583
+ /**
49584
+ * @typedef {object} Condition
49585
+ * @property {string} [hide]
49381
49586
  */
49382
49587
 
49383
49588
  class ConditionChecker {
@@ -49386,11 +49591,11 @@
49386
49591
  this._eventBus = eventBus;
49387
49592
  }
49388
49593
 
49389
- /**
49390
- * For given data, remove properties based on condition.
49391
- *
49392
- * @param {Object<string, any>} properties
49393
- * @param {Object<string, any>} data
49594
+ /**
49595
+ * For given data, remove properties based on condition.
49596
+ *
49597
+ * @param {Object<string, any>} properties
49598
+ * @param {Object<string, any>} data
49394
49599
  */
49395
49600
  applyConditions(properties, data = {}) {
49396
49601
  const conditions = this._getConditions();
@@ -49409,13 +49614,13 @@
49409
49614
  return newProperties;
49410
49615
  }
49411
49616
 
49412
- /**
49413
- * Check if given condition is met. Returns null for invalid/missing conditions.
49414
- *
49415
- * @param {string} condition
49416
- * @param {import('../../types').Data} [data]
49417
- *
49418
- * @returns {boolean|null}
49617
+ /**
49618
+ * Check if given condition is met. Returns null for invalid/missing conditions.
49619
+ *
49620
+ * @param {string} condition
49621
+ * @param {import('../../types').Data} [data]
49622
+ *
49623
+ * @returns {boolean|null}
49419
49624
  */
49420
49625
  check(condition, data = {}) {
49421
49626
  if (!condition) {
@@ -49436,12 +49641,12 @@
49436
49641
  }
49437
49642
  }
49438
49643
 
49439
- /**
49440
- * Check if hide condition is met.
49441
- *
49442
- * @param {Condition} condition
49443
- * @param {Object<string, any>} data
49444
- * @returns {boolean}
49644
+ /**
49645
+ * Check if hide condition is met.
49646
+ *
49647
+ * @param {Condition} condition
49648
+ * @param {Object<string, any>} data
49649
+ * @returns {boolean}
49445
49650
  */
49446
49651
  _checkHideCondition(condition, data) {
49447
49652
  if (!condition.hide) {
@@ -49482,12 +49687,12 @@
49482
49687
  this._converter = new showdownExports.Converter();
49483
49688
  }
49484
49689
 
49485
- /**
49486
- * Render markdown to HTML.
49487
- *
49488
- * @param {string} markdown - The markdown to render
49489
- *
49490
- * @returns {string} HTML
49690
+ /**
49691
+ * Render markdown to HTML.
49692
+ *
49693
+ * @param {string} markdown - The markdown to render
49694
+ *
49695
+ * @returns {string} HTML
49491
49696
  */
49492
49697
  render(markdown) {
49493
49698
  return this._converter.makeHtml(markdown);
@@ -50071,23 +50276,23 @@
50071
50276
  };
50072
50277
  FormFieldRegistry$1.$inject = ['eventBus'];
50073
50278
 
50074
- /**
50075
- * @typedef { { id: String, components: Array<String> } } FormRow
50076
- * @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
50279
+ /**
50280
+ * @typedef { { id: String, components: Array<String> } } FormRow
50281
+ * @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
50077
50282
  */
50078
50283
 
50079
- /**
50080
- * Maintains the Form layout in a given structure, for example
50081
- *
50082
- * [
50083
- * {
50084
- * formFieldId: 'FormField_1',
50085
- * rows: [
50086
- * { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
50087
- * ]
50088
- * }
50089
- * ]
50090
- *
50284
+ /**
50285
+ * Maintains the Form layout in a given structure, for example
50286
+ *
50287
+ * [
50288
+ * {
50289
+ * formFieldId: 'FormField_1',
50290
+ * rows: [
50291
+ * { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
50292
+ * ]
50293
+ * }
50294
+ * ]
50295
+ *
50091
50296
  */
50092
50297
  class FormLayouter {
50093
50298
  constructor(eventBus) {
@@ -50097,8 +50302,8 @@
50097
50302
  this._eventBus = eventBus;
50098
50303
  }
50099
50304
 
50100
- /**
50101
- * @param {FormRow} row
50305
+ /**
50306
+ * @param {FormRow} row
50102
50307
  */
50103
50308
  addRow(formFieldId, row) {
50104
50309
  let rowsPerComponent = this._rows.find(r => r.formFieldId === formFieldId);
@@ -50112,18 +50317,18 @@
50112
50317
  rowsPerComponent.rows.push(row);
50113
50318
  }
50114
50319
 
50115
- /**
50116
- * @param {String} id
50117
- * @returns {FormRow}
50320
+ /**
50321
+ * @param {String} id
50322
+ * @returns {FormRow}
50118
50323
  */
50119
50324
  getRow(id) {
50120
50325
  const rows = allRows(this._rows);
50121
50326
  return rows.find(r => r.id === id);
50122
50327
  }
50123
50328
 
50124
- /**
50125
- * @param {any} formField
50126
- * @returns {FormRow}
50329
+ /**
50330
+ * @param {any} formField
50331
+ * @returns {FormRow}
50127
50332
  */
50128
50333
  getRowForField(formField) {
50129
50334
  return allRows(this._rows).find(r => {
@@ -50134,9 +50339,9 @@
50134
50339
  });
50135
50340
  }
50136
50341
 
50137
- /**
50138
- * @param {String} formFieldId
50139
- * @returns { Array<FormRow> }
50342
+ /**
50343
+ * @param {String} formFieldId
50344
+ * @returns { Array<FormRow> }
50140
50345
  */
50141
50346
  getRows(formFieldId) {
50142
50347
  const rowsForField = this._rows.find(r => formFieldId === r.formFieldId);
@@ -50146,15 +50351,15 @@
50146
50351
  return rowsForField.rows;
50147
50352
  }
50148
50353
 
50149
- /**
50150
- * @returns {string}
50354
+ /**
50355
+ * @returns {string}
50151
50356
  */
50152
50357
  nextRowId() {
50153
50358
  return this._ids.nextPrefixed('Row_');
50154
50359
  }
50155
50360
 
50156
- /**
50157
- * @param {any} formField
50361
+ /**
50362
+ * @param {any} formField
50158
50363
  */
50159
50364
  calculateLayout(formField) {
50160
50365
  const {
@@ -50208,9 +50413,9 @@
50208
50413
  });
50209
50414
  }
50210
50415
 
50211
- /**
50212
- * @param {Array<FormRows>} formRows
50213
- * @returns {Array<FormRow>}
50416
+ /**
50417
+ * @param {Array<FormRows>} formRows
50418
+ * @returns {Array<FormRow>}
50214
50419
  */
50215
50420
  function allRows(formRows) {
50216
50421
  return flatten$3(formRows.map(c => c.rows));
@@ -50286,10 +50491,10 @@
50286
50491
  return injector;
50287
50492
  }
50288
50493
 
50289
- /**
50290
- * @param {string?} prefix
50291
- *
50292
- * @returns Element
50494
+ /**
50495
+ * @param {string?} prefix
50496
+ *
50497
+ * @returns Element
50293
50498
  */
50294
50499
  function createFormContainer(prefix = 'fjs') {
50295
50500
  const container = document.createElement('div');
@@ -50297,6 +50502,7 @@
50297
50502
  return container;
50298
50503
  }
50299
50504
  const EXPRESSION_PROPERTIES = ['alt', 'source', 'text'];
50505
+ const TEMPLATE_PROPERTIES = ['text'];
50300
50506
  function findErrors(errors, path) {
50301
50507
  return errors[pathStringify(path)];
50302
50508
  }
@@ -50319,24 +50525,24 @@
50319
50525
  return `${type}${generateIndexForType(type)}`;
50320
50526
  }
50321
50527
 
50322
- /**
50323
- * @template T
50324
- * @param {T} data
50325
- * @param {(this: any, key: string, value: any) => any} [replacer]
50326
- * @return {T}
50528
+ /**
50529
+ * @template T
50530
+ * @param {T} data
50531
+ * @param {(this: any, key: string, value: any) => any} [replacer]
50532
+ * @return {T}
50327
50533
  */
50328
50534
  function clone(data, replacer) {
50329
50535
  return JSON.parse(JSON.stringify(data, replacer));
50330
50536
  }
50331
50537
 
50332
- /**
50333
- * Parse the schema for input variables a form might make use of
50334
- *
50335
- * @param {any} schema
50336
- *
50337
- * @return {string[]}
50538
+ /**
50539
+ * Parse the schema for input variables a form might make use of
50540
+ *
50541
+ * @param {any} schema
50542
+ *
50543
+ * @return {string[]}
50338
50544
  */
50339
- function getSchemaVariables(schema, expressionLanguage = new FeelExpressionLanguage(null)) {
50545
+ function getSchemaVariables(schema, expressionLanguage = new FeelExpressionLanguage(null), templating = new FeelersTemplating()) {
50340
50546
  if (!schema.components) {
50341
50547
  return [];
50342
50548
  }
@@ -50371,6 +50577,13 @@
50371
50577
  variables = [...variables, ...expressionVariables];
50372
50578
  }
50373
50579
  });
50580
+ TEMPLATE_PROPERTIES.forEach(prop => {
50581
+ const property = component[prop];
50582
+ if (property && !expressionLanguage.isExpression(property) && templating.isTemplate(property)) {
50583
+ const templateVariables = templating.getVariableNames(property);
50584
+ variables = [...variables, ...templateVariables];
50585
+ }
50586
+ });
50374
50587
  return variables;
50375
50588
  }, []);
50376
50589
 
@@ -50378,11 +50591,11 @@
50378
50591
  return Array.from(new Set(variables));
50379
50592
  }
50380
50593
  let Importer$1 = class Importer {
50381
- /**
50382
- * @constructor
50383
- * @param { import('../core').FormFieldRegistry } formFieldRegistry
50384
- * @param { import('../render/FormFields').default } formFields
50385
- * @param { import('../core').FormLayouter } formLayouter
50594
+ /**
50595
+ * @constructor
50596
+ * @param { import('../core').FormFieldRegistry } formFieldRegistry
50597
+ * @param { import('../render/FormFields').default } formFields
50598
+ * @param { import('../core').FormLayouter } formLayouter
50386
50599
  */
50387
50600
  constructor(formFieldRegistry, formFields, formLayouter) {
50388
50601
  this._formFieldRegistry = formFieldRegistry;
@@ -50390,15 +50603,15 @@
50390
50603
  this._formLayouter = formLayouter;
50391
50604
  }
50392
50605
 
50393
- /**
50394
- * Import schema adding `id`, `_parent` and `_path`
50395
- * information to each field and adding it to the
50396
- * form field registry.
50397
- *
50398
- * @param {any} schema
50399
- * @param {any} [data]
50400
- *
50401
- * @return { { warnings: Array<any>, schema: any, data: any } }
50606
+ /**
50607
+ * Import schema adding `id`, `_parent` and `_path`
50608
+ * information to each field and adding it to the
50609
+ * form field registry.
50610
+ *
50611
+ * @param {any} schema
50612
+ * @param {any} [data]
50613
+ *
50614
+ * @return { { warnings: Array<any>, schema: any, data: any } }
50402
50615
  */
50403
50616
  importSchema(schema, data = {}) {
50404
50617
  // TODO: Add warnings - https://github.com/bpmn-io/form-js/issues/289
@@ -50419,11 +50632,11 @@
50419
50632
  }
50420
50633
  }
50421
50634
 
50422
- /**
50423
- * @param {any} formField
50424
- * @param {string} [parentId]
50425
- *
50426
- * @return {any} importedField
50635
+ /**
50636
+ * @param {any} formField
50637
+ * @param {string} [parentId]
50638
+ *
50639
+ * @return {any} importedField
50427
50640
  */
50428
50641
  importFormField(formField, parentId) {
50429
50642
  const {
@@ -50474,10 +50687,10 @@
50474
50687
  });
50475
50688
  }
50476
50689
 
50477
- /**
50478
- * @param {Object} data
50479
- *
50480
- * @return {Object} initializedData
50690
+ /**
50691
+ * @param {Object} data
50692
+ *
50693
+ * @return {Object} initializedData
50481
50694
  */
50482
50695
  initializeFieldValues(data) {
50483
50696
  return this._formFieldRegistry.getAll().reduce((initializedData, formField) => {
@@ -50605,11 +50818,11 @@
50605
50818
  });
50606
50819
  var FormRenderContext$1 = FormRenderContext;
50607
50820
 
50608
- /**
50609
- * @param {string} type
50610
- * @param {boolean} [strict]
50611
- *
50612
- * @returns {any}
50821
+ /**
50822
+ * @param {string} type
50823
+ * @param {boolean} [strict]
50824
+ *
50825
+ * @returns {any}
50613
50826
  */
50614
50827
  function getService$2(type, strict) {}
50615
50828
  const FormContext = D$1({
@@ -50783,8 +50996,8 @@
50783
50996
  return getService(type, strict);
50784
50997
  }
50785
50998
 
50786
- /**
50787
- * @enum { String }
50999
+ /**
51000
+ * @enum { String }
50788
51001
  */
50789
51002
  const LOAD_STATES = {
50790
51003
  LOADING: 'loading',
@@ -50792,17 +51005,17 @@
50792
51005
  ERROR: 'error'
50793
51006
  };
50794
51007
 
50795
- /**
50796
- * @typedef {Object} ValuesGetter
50797
- * @property {Object[]} values - The values data
50798
- * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
51008
+ /**
51009
+ * @typedef {Object} ValuesGetter
51010
+ * @property {Object[]} values - The values data
51011
+ * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
50799
51012
  */
50800
51013
 
50801
- /**
50802
- * A hook to load values for single and multiselect components.
50803
- *
50804
- * @param {Object} field - The form field to handle values for
50805
- * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
51014
+ /**
51015
+ * A hook to load values for single and multiselect components.
51016
+ *
51017
+ * @param {Object} field - The form field to handle values for
51018
+ * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
50806
51019
  */
50807
51020
  function useValuesAsync(field) {
50808
51021
  const {
@@ -51145,10 +51358,10 @@
51145
51358
  Checklist.sanitizeValue = sanitizeMultiSelectValue;
51146
51359
  Checklist.group = 'selection';
51147
51360
 
51148
- /**
51149
- * Returns the conditionally filtered data of a form reactively.
51150
- * Memoised to minimize re-renders
51151
- *
51361
+ /**
51362
+ * Returns the conditionally filtered data of a form reactively.
51363
+ * Memoised to minimize re-renders
51364
+ *
51152
51365
  */
51153
51366
  function useFilteredFormData() {
51154
51367
  const {
@@ -51165,12 +51378,12 @@
51165
51378
  }, [conditionChecker, data, initialData]);
51166
51379
  }
51167
51380
 
51168
- /**
51169
- * Evaluate if condition is met reactively based on the conditionChecker and form data.
51170
- *
51171
- * @param {string | undefined} condition
51172
- *
51173
- * @returns {boolean} true if condition is met or no condition or condition checker exists
51381
+ /**
51382
+ * Evaluate if condition is met reactively based on the conditionChecker and form data.
51383
+ *
51384
+ * @param {string | undefined} condition
51385
+ *
51386
+ * @returns {boolean} true if condition is met or no condition or condition checker exists
51174
51387
  */
51175
51388
  function useCondition(condition) {
51176
51389
  const conditionChecker = useService$2('conditionChecker', false);
@@ -51180,13 +51393,13 @@
51180
51393
  }, [conditionChecker, condition, filteredData]);
51181
51394
  }
51182
51395
 
51183
- /**
51184
- * Evaluate a string reactively based on the expressionLanguage and form data.
51185
- * If the string is not an expression, it is returned as is.
51186
- * Memoised to minimize re-renders.
51187
- *
51188
- * @param {string} value
51189
- *
51396
+ /**
51397
+ * Evaluate a string reactively based on the expressionLanguage and form data.
51398
+ * If the string is not an expression, it is returned as is.
51399
+ * Memoised to minimize re-renders.
51400
+ *
51401
+ * @param {string} value
51402
+ *
51190
51403
  */
51191
51404
  function useExpressionEvaluation(value) {
51192
51405
  const formData = useFilteredFormData();
@@ -51214,16 +51427,16 @@
51214
51427
  });
51215
51428
  }
51216
51429
 
51217
- /**
51218
- * Template a string reactively based on form data. If the string is not a template, it is returned as is.
51219
- * Memoised to minimize re-renders
51220
- *
51221
- * @param {string} value
51222
- * @param {Object} options
51223
- * @param {boolean} [options.debug = false]
51224
- * @param {boolean} [options.strict = false]
51225
- * @param {Function} [options.buildDebugString]
51226
- *
51430
+ /**
51431
+ * Template a string reactively based on form data. If the string is not a template, it is returned as is.
51432
+ * Memoised to minimize re-renders
51433
+ *
51434
+ * @param {string} value
51435
+ * @param {Object} options
51436
+ * @param {boolean} [options.debug = false]
51437
+ * @param {boolean} [options.strict = false]
51438
+ * @param {Function} [options.buildDebugString]
51439
+ *
51227
51440
  */
51228
51441
  function useTemplateEvaluation(value, options) {
51229
51442
  const filteredData = useFilteredFormData();
@@ -51992,10 +52205,10 @@
51992
52205
  Datetime.label = 'Date time';
51993
52206
  Datetime.group = 'basic-input';
51994
52207
 
51995
- /**
51996
- * This file must not be changed or exchanged.
51997
- *
51998
- * @see http://bpmn.io/license for more information.
52208
+ /**
52209
+ * This file must not be changed or exchanged.
52210
+ *
52211
+ * @see http://bpmn.io/license for more information.
51999
52212
  */
52000
52213
  function Logo() {
52001
52214
  return e$1("svg", {
@@ -52120,11 +52333,11 @@
52120
52333
 
52121
52334
  const FORM_ELEMENT = document.createElement('form');
52122
52335
 
52123
- /**
52124
- * Sanitize a HTML string and return the cleaned, safe version.
52125
- *
52126
- * @param {string} html
52127
- * @return {string}
52336
+ /**
52337
+ * Sanitize a HTML string and return the cleaned, safe version.
52338
+ *
52339
+ * @param {string} html
52340
+ * @return {string}
52128
52341
  */
52129
52342
 
52130
52343
  // see https://github.com/developit/snarkdown/issues/70
@@ -52142,29 +52355,29 @@
52142
52355
  }
52143
52356
  }
52144
52357
 
52145
- /**
52146
- * Sanitizes an image source to ensure we only allow for data URI and links
52147
- * that start with http(s).
52148
- *
52149
- * Note: Most browsers anyway do not support script execution in <img> elements.
52150
- *
52151
- * @param {string} src
52152
- * @returns {string}
52358
+ /**
52359
+ * Sanitizes an image source to ensure we only allow for data URI and links
52360
+ * that start with http(s).
52361
+ *
52362
+ * Note: Most browsers anyway do not support script execution in <img> elements.
52363
+ *
52364
+ * @param {string} src
52365
+ * @returns {string}
52153
52366
  */
52154
52367
  function sanitizeImageSource(src) {
52155
52368
  const valid = ALLOWED_IMAGE_SRC_PATTERN.test(src);
52156
52369
  return valid ? src : '';
52157
52370
  }
52158
52371
 
52159
- /**
52160
- * Recursively sanitize a HTML node, potentially
52161
- * removing it, its children or attributes.
52162
- *
52163
- * Inspired by https://github.com/developit/snarkdown/issues/70
52164
- * and https://github.com/cure53/DOMPurify. Simplified
52165
- * for our use-case.
52166
- *
52167
- * @param {Element} node
52372
+ /**
52373
+ * Recursively sanitize a HTML node, potentially
52374
+ * removing it, its children or attributes.
52375
+ *
52376
+ * Inspired by https://github.com/developit/snarkdown/issues/70
52377
+ * and https://github.com/cure53/DOMPurify. Simplified
52378
+ * for our use-case.
52379
+ *
52380
+ * @param {Element} node
52168
52381
  */
52169
52382
  function sanitizeNode(node) {
52170
52383
  // allow text nodes
@@ -52208,13 +52421,13 @@
52208
52421
  }
52209
52422
  }
52210
52423
 
52211
- /**
52212
- * Validates attributes for validity.
52213
- *
52214
- * @param {string} lcTag
52215
- * @param {string} lcName
52216
- * @param {string} value
52217
- * @return {boolean}
52424
+ /**
52425
+ * Validates attributes for validity.
52426
+ *
52427
+ * @param {string} lcTag
52428
+ * @param {string} lcName
52429
+ * @param {string} value
52430
+ * @return {boolean}
52218
52431
  */
52219
52432
  function isValidAttribute(lcTag, lcName, value) {
52220
52433
  // disallow most attributes based on whitelist
@@ -52978,6 +53191,12 @@
52978
53191
  errors,
52979
53192
  disabled
52980
53193
  }),
53194
+ onKeyDown: event => {
53195
+ if (event.key === 'Enter') {
53196
+ event.preventDefault();
53197
+ event.stopPropagation();
53198
+ }
53199
+ },
52981
53200
  children: [e$1(Label$1, {
52982
53201
  id: prefixId(id, formId),
52983
53202
  label: label,
@@ -53127,6 +53346,12 @@
53127
53346
  errors,
53128
53347
  disabled
53129
53348
  }),
53349
+ onKeyDown: event => {
53350
+ if (event.key === 'Enter') {
53351
+ event.stopPropagation();
53352
+ event.preventDefault();
53353
+ }
53354
+ },
53130
53355
  children: [e$1(Label$1, {
53131
53356
  label: label,
53132
53357
  required: required,
@@ -58083,10 +58308,10 @@
58083
58308
  return fn.apply(null, args);
58084
58309
  }
58085
58310
 
58086
- /**
58087
- * A factory to create a configurable debouncer.
58088
- *
58089
- * @param {number|boolean} [config=true]
58311
+ /**
58312
+ * A factory to create a configurable debouncer.
58313
+ *
58314
+ * @param {number|boolean} [config=true]
58090
58315
  */
58091
58316
  function DebounceFactory(config = true) {
58092
58317
  const timeout = typeof config === 'number' ? config : config ? 300 : 0;
@@ -58098,11 +58323,11 @@
58098
58323
  }
58099
58324
  DebounceFactory.$inject = ['config.debounce'];
58100
58325
  class FieldFactory {
58101
- /**
58102
- * @constructor
58103
- *
58104
- * @param { import('./FormFieldRegistry').default } formFieldRegistry
58105
- * @param { import('@bpmn-io/form-js-viewer').FormFields } formFields
58326
+ /**
58327
+ * @constructor
58328
+ *
58329
+ * @param { import('./FormFieldRegistry').default } formFieldRegistry
58330
+ * @param { import('@bpmn-io/form-js-viewer').FormFields } formFields
58106
58331
  */
58107
58332
  constructor(formFieldRegistry, formFields) {
58108
58333
  this._formFieldRegistry = formFieldRegistry;
@@ -58161,11 +58386,11 @@
58161
58386
  }
58162
58387
  FieldFactory.$inject = ['formFieldRegistry', 'formFields'];
58163
58388
  class FormFieldRegistry extends FormFieldRegistry$1 {
58164
- /**
58165
- * Updates a form fields id.
58166
- *
58167
- * @param {Object} formField
58168
- * @param {string} newId
58389
+ /**
58390
+ * Updates a form fields id.
58391
+ *
58392
+ * @param {Object} formField
58393
+ * @param {string} newId
58169
58394
  */
58170
58395
  updateId(formField, newId) {
58171
58396
  this._validateId(newId);
@@ -58186,13 +58411,13 @@
58186
58411
  }
58187
58412
  }
58188
58413
 
58189
- /**
58190
- * Validate the suitability of the given id and signals a problem
58191
- * with an exception.
58192
- *
58193
- * @param {string} id
58194
- *
58195
- * @throws {Error} if id is empty or already assigned
58414
+ /**
58415
+ * Validate the suitability of the given id and signals a problem
58416
+ * with an exception.
58417
+ *
58418
+ * @param {string} id
58419
+ *
58420
+ * @throws {Error} if id is empty or already assigned
58196
58421
  */
58197
58422
  _validateId(id) {
58198
58423
  if (!id) {
@@ -58204,11 +58429,11 @@
58204
58429
  }
58205
58430
  }
58206
58431
  class FormLayoutValidator {
58207
- /**
58208
- * @constructor
58209
- *
58210
- * @param { import('./FormLayouter').default } formLayouter
58211
- * @param { import('./FormFieldRegistry').default } formFieldRegistry
58432
+ /**
58433
+ * @constructor
58434
+ *
58435
+ * @param { import('./FormLayouter').default } formLayouter
58436
+ * @param { import('./FormFieldRegistry').default } formFieldRegistry
58212
58437
  */
58213
58438
  constructor(formLayouter, formFieldRegistry) {
58214
58439
  this._formLayouter = formLayouter;
@@ -58260,11 +58485,11 @@
58260
58485
  }
58261
58486
  FormLayoutValidator.$inject = ['formLayouter', 'formFieldRegistry'];
58262
58487
  class Importer {
58263
- /**
58264
- * @constructor
58265
- * @param { import('../core/FormFieldRegistry').default } formFieldRegistry
58266
- * @param { import('../core/FieldFactory').default } fieldFactory
58267
- * @param { import('../core/FormLayouter').default } formLayouter
58488
+ /**
58489
+ * @constructor
58490
+ * @param { import('../core/FormFieldRegistry').default } formFieldRegistry
58491
+ * @param { import('../core/FieldFactory').default } fieldFactory
58492
+ * @param { import('../core/FormLayouter').default } formLayouter
58268
58493
  */
58269
58494
  constructor(formFieldRegistry, fieldFactory, formLayouter) {
58270
58495
  this._formFieldRegistry = formFieldRegistry;
@@ -58272,21 +58497,21 @@
58272
58497
  this._formLayouter = formLayouter;
58273
58498
  }
58274
58499
 
58275
- /**
58276
- * Import schema creating rows, fields, attaching additional
58277
- * information to each field and adding fields to the
58278
- * field registry.
58279
- *
58280
- * Additional information attached:
58281
- *
58282
- * * `id` (unless present)
58283
- * * `_parent`
58284
- * * `_path`
58285
- *
58286
- * @param {any} schema
58287
- *
58288
- * @typedef {{ warnings: Error[], schema: any }} ImportResult
58289
- * @returns {ImportResult}
58500
+ /**
58501
+ * Import schema creating rows, fields, attaching additional
58502
+ * information to each field and adding fields to the
58503
+ * field registry.
58504
+ *
58505
+ * Additional information attached:
58506
+ *
58507
+ * * `id` (unless present)
58508
+ * * `_parent`
58509
+ * * `_path`
58510
+ *
58511
+ * @param {any} schema
58512
+ *
58513
+ * @typedef {{ warnings: Error[], schema: any }} ImportResult
58514
+ * @returns {ImportResult}
58290
58515
  */
58291
58516
  importSchema(schema) {
58292
58517
  // TODO: Add warnings
@@ -58304,12 +58529,12 @@
58304
58529
  }
58305
58530
  }
58306
58531
 
58307
- /**
58308
- * @param {{[x: string]: any}} fieldAttrs
58309
- * @param {String} [parentId]
58310
- * @param {number} [index]
58311
- *
58312
- * @return {any} field
58532
+ /**
58533
+ * @param {{[x: string]: any}} fieldAttrs
58534
+ * @param {String} [parentId]
58535
+ * @param {number} [index]
58536
+ *
58537
+ * @return {any} field
58313
58538
  */
58314
58539
  importFormField(fieldAttrs, parentId, index) {
58315
58540
  const {
@@ -58346,11 +58571,11 @@
58346
58571
  return field;
58347
58572
  }
58348
58573
 
58349
- /**
58350
- * @param {Array<any>} components
58351
- * @param {string} parentId
58352
- *
58353
- * @return {Array<any>} imported components
58574
+ /**
58575
+ * @param {Array<any>} components
58576
+ * @param {string} parentId
58577
+ *
58578
+ * @return {Array<any>} imported components
58354
58579
  */
58355
58580
  importFormFields(components, parentId) {
58356
58581
  return components.map((component, index) => {
@@ -58377,11 +58602,11 @@
58377
58602
  });
58378
58603
  var DragAndDropContext$1 = DragAndDropContext;
58379
58604
 
58380
- /**
58381
- * @param {string} type
58382
- * @param {boolean} [strict]
58383
- *
58384
- * @returns {any}
58605
+ /**
58606
+ * @param {string} type
58607
+ * @param {boolean} [strict]
58608
+ *
58609
+ * @returns {any}
58385
58610
  */
58386
58611
  function getService$1(type, strict) {}
58387
58612
  const FormEditorContext = D$1({
@@ -58715,19 +58940,19 @@
58715
58940
  const DRAG_NO_MOVE_CLS = 'fjs-no-move';
58716
58941
  const ERROR_DROP_CLS = 'fjs-error-drop';
58717
58942
 
58718
- /**
58719
- * @typedef { { id: String, components: Array<any> } } FormRow
58943
+ /**
58944
+ * @typedef { { id: String, components: Array<any> } } FormRow
58720
58945
  */
58721
58946
 
58722
58947
  class Dragging {
58723
- /**
58724
- * @constructor
58725
- *
58726
- * @param { import('../../core/FormFieldRegistry').default } formFieldRegistry
58727
- * @param { import('../../core/FormLayouter').default } formLayouter
58728
- * @param { import('../../core/FormLayoutValidator').default } formLayoutValidator
58729
- * @param { import('../../core/EventBus').default } eventBus
58730
- * @param { import('../modeling/Modeling').default } modeling
58948
+ /**
58949
+ * @constructor
58950
+ *
58951
+ * @param { import('../../core/FormFieldRegistry').default } formFieldRegistry
58952
+ * @param { import('../../core/FormLayouter').default } formLayouter
58953
+ * @param { import('../../core/FormLayoutValidator').default } formLayoutValidator
58954
+ * @param { import('../../core/EventBus').default } eventBus
58955
+ * @param { import('../modeling/Modeling').default } modeling
58731
58956
  */
58732
58957
  constructor(formFieldRegistry, formLayouter, formLayoutValidator, eventBus, modeling) {
58733
58958
  this._formFieldRegistry = formFieldRegistry;
@@ -58737,13 +58962,13 @@
58737
58962
  this._modeling = modeling;
58738
58963
  }
58739
58964
 
58740
- /**
58741
- * Calculcates position in form schema given the dropped place.
58742
- *
58743
- * @param { FormRow } targetRow
58744
- * @param { any } targetFormField
58745
- * @param { HTMLElement } sibling
58746
- * @returns { number }
58965
+ /**
58966
+ * Calculcates position in form schema given the dropped place.
58967
+ *
58968
+ * @param { FormRow } targetRow
58969
+ * @param { any } targetFormField
58970
+ * @param { HTMLElement } sibling
58971
+ * @returns { number }
58747
58972
  */
58748
58973
  getTargetIndex(targetRow, targetFormField, sibling) {
58749
58974
  /** @type HTMLElement */
@@ -58845,8 +59070,8 @@
58845
59070
  }
58846
59071
  }
58847
59072
 
58848
- /**
58849
- * @param { { container: Array<string>, direction: string, mirrorContainer: string } } options
59073
+ /**
59074
+ * @param { { container: Array<string>, direction: string, mirrorContainer: string } } options
58850
59075
  */
58851
59076
  createDragulaInstance(options) {
58852
59077
  const {
@@ -59089,7 +59314,7 @@
59089
59314
  return null;
59090
59315
  }
59091
59316
  return e$1("div", {
59092
- style: "width: fit-content;\r padding: 2px 6px;\r height: 16px;\r background: var(--color-blue-205-100-95);\r display: flex;\r justify-content: center;\r align-items: center;\r position: absolute;\r bottom: -2px;\r z-index: 2;\r font-size: 10px;\r right: 3px;",
59317
+ style: "width: fit-content; padding: 2px 6px; height: 16px; background: var(--color-blue-205-100-95); display: flex; justify-content: center; align-items: center; position: absolute; bottom: -2px; z-index: 2; font-size: 10px; right: 3px;",
59093
59318
  class: "fjs-debug-columns",
59094
59319
  children: (field.layout || {}).columns || 'auto'
59095
59320
  });
@@ -60120,10 +60345,10 @@
60120
60345
  return formField;
60121
60346
  }
60122
60347
  class AddFormFieldHandler {
60123
- /**
60124
- * @constructor
60125
- * @param { import('../../../FormEditor').default } formEditor
60126
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60348
+ /**
60349
+ * @constructor
60350
+ * @param { import('../../../FormEditor').default } formEditor
60351
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60127
60352
  */
60128
60353
  constructor(formEditor, formFieldRegistry) {
60129
60354
  this._formEditor = formEditor;
@@ -60183,10 +60408,10 @@
60183
60408
  }
60184
60409
  AddFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
60185
60410
  class EditFormFieldHandler {
60186
- /**
60187
- * @constructor
60188
- * @param { import('../../../FormEditor').default } formEditor
60189
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60411
+ /**
60412
+ * @constructor
60413
+ * @param { import('../../../FormEditor').default } formEditor
60414
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60190
60415
  */
60191
60416
  constructor(formEditor, formFieldRegistry) {
60192
60417
  this._formEditor = formEditor;
@@ -60248,10 +60473,10 @@
60248
60473
  }
60249
60474
  EditFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
60250
60475
  class MoveFormFieldHandler {
60251
- /**
60252
- * @constructor
60253
- * @param { import('../../../FormEditor').default } formEditor
60254
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60476
+ /**
60477
+ * @constructor
60478
+ * @param { import('../../../FormEditor').default } formEditor
60479
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60255
60480
  */
60256
60481
  constructor(formEditor, formFieldRegistry) {
60257
60482
  this._formEditor = formEditor;
@@ -60339,10 +60564,10 @@
60339
60564
  }
60340
60565
  MoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
60341
60566
  class RemoveFormFieldHandler {
60342
- /**
60343
- * @constructor
60344
- * @param { import('../../../FormEditor').default } formEditor
60345
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60567
+ /**
60568
+ * @constructor
60569
+ * @param { import('../../../FormEditor').default } formEditor
60570
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60346
60571
  */
60347
60572
  constructor(formEditor, formFieldRegistry) {
60348
60573
  this._formEditor = formEditor;
@@ -60401,9 +60626,9 @@
60401
60626
  }
60402
60627
  RemoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
60403
60628
  class UpdateIdClaimHandler {
60404
- /**
60405
- * @constructor
60406
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60629
+ /**
60630
+ * @constructor
60631
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60407
60632
  */
60408
60633
  constructor(formFieldRegistry) {
60409
60634
  this._formFieldRegistry = formFieldRegistry;
@@ -60435,9 +60660,9 @@
60435
60660
  }
60436
60661
  UpdateIdClaimHandler.$inject = ['formFieldRegistry'];
60437
60662
  class UpdateKeyClaimHandler {
60438
- /**
60439
- * @constructor
60440
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60663
+ /**
60664
+ * @constructor
60665
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
60441
60666
  */
60442
60667
  constructor(formFieldRegistry) {
60443
60668
  this._formFieldRegistry = formFieldRegistry;
@@ -60781,8 +61006,8 @@
60781
61006
  constructor(eventBus) {
60782
61007
  super(eventBus);
60783
61008
 
60784
- /**
60785
- * Remove custom validation if <validationType> is about to be added.
61009
+ /**
61010
+ * Remove custom validation if <validationType> is about to be added.
60786
61011
  */
60787
61012
  // @ts-ignore-next-line
60788
61013
  this.preExecute('formField.edit', function (context) {
@@ -61320,10 +61545,10 @@
61320
61545
  });
61321
61546
  }
61322
61547
 
61323
- /**
61324
- * Attach the palette to a parent node.
61325
- *
61326
- * @param {HTMLElement} container
61548
+ /**
61549
+ * Attach the palette to a parent node.
61550
+ *
61551
+ * @param {HTMLElement} container
61327
61552
  */
61328
61553
  attachTo(container) {
61329
61554
  if (!container) {
@@ -61343,8 +61568,8 @@
61343
61568
  this._eventBus.fire('palette.attach');
61344
61569
  }
61345
61570
 
61346
- /**
61347
- * Detach the palette from its parent node.
61571
+ /**
61572
+ * Detach the palette from its parent node.
61348
61573
  */
61349
61574
  detach() {
61350
61575
  const parentNode = this._container.parentNode;
@@ -63699,11 +63924,11 @@
63699
63924
  return `bio-properties-panel-${id}`;
63700
63925
  }
63701
63926
 
63702
- /**
63703
- * @param {string} type
63704
- * @param {boolean} [strict]
63705
- *
63706
- * @returns {any}
63927
+ /**
63928
+ * @param {string} type
63929
+ * @param {boolean} [strict]
63930
+ *
63931
+ * @returns {any}
63707
63932
  */
63708
63933
  function getService(type, strict) {}
63709
63934
  const PropertiesPanelContext = D$1({
@@ -63790,8 +64015,8 @@
63790
64015
  }
63791
64016
  };
63792
64017
 
63793
- /**
63794
- * Provide placeholders for empty and multiple state.
64018
+ /**
64019
+ * Provide placeholders for empty and multiple state.
63795
64020
  */
63796
64021
  const PropertiesPanelPlaceholderProvider = {
63797
64022
  getEmpty: () => {
@@ -63861,10 +64086,10 @@
63861
64086
  return getService(type, strict);
63862
64087
  }
63863
64088
 
63864
- /**
63865
- * Retrieve list of variables from the form schema.
63866
- *
63867
- * @returns { string[] } list of variables used in form schema
64089
+ /**
64090
+ * Retrieve list of variables from the form schema.
64091
+ *
64092
+ * @returns { string[] } list of variables used in form schema
63868
64093
  */
63869
64094
  function useVariables() {
63870
64095
  const form = useService('formEditor');
@@ -65122,7 +65347,7 @@
65122
65347
  id,
65123
65348
  label: 'Label',
65124
65349
  setValue,
65125
- validate: validateFactory(getValue())
65350
+ validate: validateFactory(getValue(), entry => entry.label)
65126
65351
  });
65127
65352
  }
65128
65353
  function Value$1(props) {
@@ -65148,7 +65373,7 @@
65148
65373
  id,
65149
65374
  label: 'Value',
65150
65375
  setValue,
65151
- validate: validateFactory(getValue())
65376
+ validate: validateFactory(getValue(), entry => entry.value)
65152
65377
  });
65153
65378
  }
65154
65379
  function CustomValueEntry(props) {
@@ -65237,14 +65462,14 @@
65237
65462
 
65238
65463
  // helpers //////////
65239
65464
 
65240
- /**
65241
- * Returns copy of object with updated value.
65242
- *
65243
- * @param {Object} properties
65244
- * @param {string} key
65245
- * @param {string} value
65246
- *
65247
- * @returns {Object}
65465
+ /**
65466
+ * Returns copy of object with updated value.
65467
+ *
65468
+ * @param {Object} properties
65469
+ * @param {string} key
65470
+ * @param {string} value
65471
+ *
65472
+ * @returns {Object}
65248
65473
  */
65249
65474
  function updateValue(properties, key, value) {
65250
65475
  return {
@@ -65253,14 +65478,14 @@
65253
65478
  };
65254
65479
  }
65255
65480
 
65256
- /**
65257
- * Returns copy of object with updated key.
65258
- *
65259
- * @param {Object} properties
65260
- * @param {string} oldKey
65261
- * @param {string} newKey
65262
- *
65263
- * @returns {Object}
65481
+ /**
65482
+ * Returns copy of object with updated key.
65483
+ *
65484
+ * @param {Object} properties
65485
+ * @param {string} oldKey
65486
+ * @param {string} newKey
65487
+ *
65488
+ * @returns {Object}
65264
65489
  */
65265
65490
  function updateKey(properties, oldKey, newKey) {
65266
65491
  return Object.entries(properties).reduce((newProperties, entry) => {
@@ -65386,13 +65611,13 @@
65386
65611
  const addEntry = e => {
65387
65612
  e.stopPropagation();
65388
65613
  const index = values.length + 1;
65389
- const entry = getIndexedEntry(index);
65614
+ const entry = getIndexedEntry(index, values);
65390
65615
  editField(field, VALUES_SOURCES_PATHS[VALUES_SOURCES.STATIC], arrayAdd(values, values.length, entry));
65391
65616
  };
65392
65617
  const removeEntry = entry => {
65393
65618
  editField(field, VALUES_SOURCES_PATHS[VALUES_SOURCES.STATIC], without(values, entry));
65394
65619
  };
65395
- const validateFactory = key => {
65620
+ const validateFactory = (key, getValue) => {
65396
65621
  return value => {
65397
65622
  if (value === key) {
65398
65623
  return;
@@ -65400,7 +65625,7 @@
65400
65625
  if (isUndefined(value) || !value.length) {
65401
65626
  return 'Must not be empty.';
65402
65627
  }
65403
- const isValueAssigned = values.find(entry => entry.value === value);
65628
+ const isValueAssigned = values.find(entry => getValue(entry) === value);
65404
65629
  if (isValueAssigned) {
65405
65630
  return 'Must be unique.';
65406
65631
  }
@@ -65431,17 +65656,23 @@
65431
65656
 
65432
65657
  // helper
65433
65658
 
65434
- function getIndexedEntry(index) {
65659
+ function getIndexedEntry(index, values) {
65435
65660
  const entry = {
65436
65661
  label: 'Value',
65437
65662
  value: 'value'
65438
65663
  };
65664
+ while (labelOrValueIsAlreadyAssignedForIndex(index, values)) {
65665
+ index++;
65666
+ }
65439
65667
  if (index > 1) {
65440
65668
  entry.label += ` ${index}`;
65441
65669
  entry.value += `${index}`;
65442
65670
  }
65443
65671
  return entry;
65444
65672
  }
65673
+ function labelOrValueIsAlreadyAssignedForIndex(index, values) {
65674
+ return values.some(existingEntry => existingEntry.label === `Value ${index}` || existingEntry.value === `value${index}`);
65675
+ }
65445
65676
  function AdornerEntry(props) {
65446
65677
  const {
65447
65678
  editField,
@@ -65886,8 +66117,8 @@
65886
66117
  };
65887
66118
  const valuesSourceId = `${fieldId}-valuesSource`;
65888
66119
 
65889
- /**
65890
- * @type {Array<Group|ListGroup>}
66120
+ /**
66121
+ * @type {Array<Group|ListGroup>}
65891
66122
  */
65892
66123
  const groups = [{
65893
66124
  id: valuesSourceId,
@@ -65934,12 +66165,13 @@
65934
66165
  }
65935
66166
  const addEntry = event => {
65936
66167
  event.stopPropagation();
65937
- const index = Object.keys(properties).length + 1;
65938
- const key = `key${index}`,
65939
- value = 'value';
66168
+ let index = Object.keys(properties).length + 1;
66169
+ while (`key${index}` in properties) {
66170
+ index++;
66171
+ }
65940
66172
  editField(field, ['properties'], {
65941
66173
  ...properties,
65942
- [key]: value
66174
+ [`key${index}`]: 'value'
65943
66175
  });
65944
66176
  };
65945
66177
  const validateFactory = key => {
@@ -65987,13 +66219,13 @@
65987
66219
 
65988
66220
  // helpers //////////
65989
66221
 
65990
- /**
65991
- * Returns copy of object without key.
65992
- *
65993
- * @param {Object} properties
65994
- * @param {string} oldKey
65995
- *
65996
- * @returns {Object}
66222
+ /**
66223
+ * Returns copy of object without key.
66224
+ *
66225
+ * @param {Object} properties
66226
+ * @param {string} oldKey
66227
+ *
66228
+ * @returns {Object}
65997
66229
  */
65998
66230
  function removeKey(properties, oldKey) {
65999
66231
  return Object.entries(properties).reduce((newProperties, entry) => {
@@ -66103,9 +66335,9 @@
66103
66335
  }, []);
66104
66336
  h(() => {
66105
66337
  const onFieldChanged = () => {
66106
- /**
66107
- * TODO(pinussilvestrus): update with actual updated element,
66108
- * once we have a proper updater/change support
66338
+ /**
66339
+ * TODO(pinussilvestrus): update with actual updated element,
66340
+ * once we have a proper updater/change support
66109
66341
  */
66110
66342
  _update(selection.get() || schema);
66111
66343
  };
@@ -66155,10 +66387,10 @@
66155
66387
  });
66156
66388
  }
66157
66389
 
66158
- /**
66159
- * Attach the properties panel to a parent node.
66160
- *
66161
- * @param {HTMLElement} container
66390
+ /**
66391
+ * Attach the properties panel to a parent node.
66392
+ *
66393
+ * @param {HTMLElement} container
66162
66394
  */
66163
66395
  attachTo(container) {
66164
66396
  if (!container) {
@@ -66178,8 +66410,8 @@
66178
66410
  this._eventBus.fire('propertiesPanel.attach');
66179
66411
  }
66180
66412
 
66181
- /**
66182
- * Detach the properties panel from its parent node.
66413
+ /**
66414
+ * Detach the properties panel from its parent node.
66183
66415
  */
66184
66416
  detach() {
66185
66417
  const parentNode = this._container.parentNode;
@@ -66214,48 +66446,48 @@
66214
66446
  };
66215
66447
  const ids = new Ids([32, 36, 1]);
66216
66448
 
66217
- /**
66218
- * @typedef { import('./types').Injector } Injector
66219
- * @typedef { import('./types').Module } Module
66220
- * @typedef { import('./types').Schema } Schema
66221
- *
66222
- * @typedef { import('./types').FormEditorOptions } FormEditorOptions
66223
- * @typedef { import('./types').FormEditorProperties } FormEditorProperties
66224
- *
66225
- * @typedef { {
66226
- * properties: FormEditorProperties,
66227
- * schema: Schema
66228
- * } } State
66229
- *
66230
- * @typedef { (type:string, priority:number, handler:Function) => void } OnEventWithPriority
66231
- * @typedef { (type:string, handler:Function) => void } OnEventWithOutPriority
66232
- * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
66449
+ /**
66450
+ * @typedef { import('./types').Injector } Injector
66451
+ * @typedef { import('./types').Module } Module
66452
+ * @typedef { import('./types').Schema } Schema
66453
+ *
66454
+ * @typedef { import('./types').FormEditorOptions } FormEditorOptions
66455
+ * @typedef { import('./types').FormEditorProperties } FormEditorProperties
66456
+ *
66457
+ * @typedef { {
66458
+ * properties: FormEditorProperties,
66459
+ * schema: Schema
66460
+ * } } State
66461
+ *
66462
+ * @typedef { (type:string, priority:number, handler:Function) => void } OnEventWithPriority
66463
+ * @typedef { (type:string, handler:Function) => void } OnEventWithOutPriority
66464
+ * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
66233
66465
  */
66234
66466
 
66235
- /**
66236
- * The form editor.
66467
+ /**
66468
+ * The form editor.
66237
66469
  */
66238
66470
  class FormEditor {
66239
- /**
66240
- * @constructor
66241
- * @param {FormEditorOptions} options
66471
+ /**
66472
+ * @constructor
66473
+ * @param {FormEditorOptions} options
66242
66474
  */
66243
66475
  constructor(options = {}) {
66244
- /**
66245
- * @public
66246
- * @type {OnEventType}
66476
+ /**
66477
+ * @public
66478
+ * @type {OnEventType}
66247
66479
  */
66248
66480
  this.on = this._onEvent;
66249
66481
 
66250
- /**
66251
- * @public
66252
- * @type {String}
66482
+ /**
66483
+ * @public
66484
+ * @type {String}
66253
66485
  */
66254
66486
  this._id = ids.next();
66255
66487
 
66256
- /**
66257
- * @private
66258
- * @type {Element}
66488
+ /**
66489
+ * @private
66490
+ * @type {Element}
66259
66491
  */
66260
66492
  this._container = createFormContainer();
66261
66493
  this._container.setAttribute('input-handle-modified-keys', 'z,y');
@@ -66266,15 +66498,15 @@
66266
66498
  properties = {}
66267
66499
  } = options;
66268
66500
 
66269
- /**
66270
- * @private
66271
- * @type {any}
66501
+ /**
66502
+ * @private
66503
+ * @type {any}
66272
66504
  */
66273
66505
  this.exporter = exporter;
66274
66506
 
66275
- /**
66276
- * @private
66277
- * @type {State}
66507
+ /**
66508
+ * @private
66509
+ * @type {State}
66278
66510
  */
66279
66511
  this._state = {
66280
66512
  properties,
@@ -66303,10 +66535,10 @@
66303
66535
  this._detach(false);
66304
66536
  }
66305
66537
 
66306
- /**
66307
- * @param {Schema} schema
66308
- *
66309
- * @return {Promise<{ warnings: Array<any> }>}
66538
+ /**
66539
+ * @param {Schema} schema
66540
+ *
66541
+ * @return {Promise<{ warnings: Array<any> }>}
66310
66542
  */
66311
66543
  importSchema(schema) {
66312
66544
  return new Promise((resolve, reject) => {
@@ -66335,15 +66567,15 @@
66335
66567
  });
66336
66568
  }
66337
66569
 
66338
- /**
66339
- * @returns {Schema}
66570
+ /**
66571
+ * @returns {Schema}
66340
66572
  */
66341
66573
  saveSchema() {
66342
66574
  return this.getSchema();
66343
66575
  }
66344
66576
 
66345
- /**
66346
- * @returns {Schema}
66577
+ /**
66578
+ * @returns {Schema}
66347
66579
  */
66348
66580
  getSchema() {
66349
66581
  const {
@@ -66352,8 +66584,8 @@
66352
66584
  return exportSchema(schema, this.exporter, schemaVersion);
66353
66585
  }
66354
66586
 
66355
- /**
66356
- * @param {Element|string} parentNode
66587
+ /**
66588
+ * @param {Element|string} parentNode
66357
66589
  */
66358
66590
  attachTo(parentNode) {
66359
66591
  if (!parentNode) {
@@ -66371,10 +66603,10 @@
66371
66603
  this._detach();
66372
66604
  }
66373
66605
 
66374
- /**
66375
- * @internal
66376
- *
66377
- * @param {boolean} [emit]
66606
+ /**
66607
+ * @internal
66608
+ *
66609
+ * @param {boolean} [emit]
66378
66610
  */
66379
66611
  _detach(emit = true) {
66380
66612
  const container = this._container,
@@ -66388,9 +66620,9 @@
66388
66620
  parentNode.removeChild(container);
66389
66621
  }
66390
66622
 
66391
- /**
66392
- * @param {any} property
66393
- * @param {any} value
66623
+ /**
66624
+ * @param {any} property
66625
+ * @param {any} value
66394
66626
  */
66395
66627
  setProperty(property, value) {
66396
66628
  const properties = set$1(this._getState().properties, [property], value);
@@ -66399,21 +66631,21 @@
66399
66631
  });
66400
66632
  }
66401
66633
 
66402
- /**
66403
- * @param {string} type
66404
- * @param {Function} handler
66634
+ /**
66635
+ * @param {string} type
66636
+ * @param {Function} handler
66405
66637
  */
66406
66638
  off(type, handler) {
66407
66639
  this.get('eventBus').off(type, handler);
66408
66640
  }
66409
66641
 
66410
- /**
66411
- * @internal
66412
- *
66413
- * @param {FormEditorOptions} options
66414
- * @param {Element} container
66415
- *
66416
- * @returns {Injector}
66642
+ /**
66643
+ * @internal
66644
+ *
66645
+ * @param {FormEditorOptions} options
66646
+ * @param {Element} container
66647
+ *
66648
+ * @returns {Injector}
66417
66649
  */
66418
66650
  _createInjector(options, container) {
66419
66651
  const {
@@ -66435,22 +66667,22 @@
66435
66667
  }, core, ...modules, ...additionalModules]);
66436
66668
  }
66437
66669
 
66438
- /**
66439
- * @internal
66670
+ /**
66671
+ * @internal
66440
66672
  */
66441
66673
  _emit(type, data) {
66442
66674
  this.get('eventBus').fire(type, data);
66443
66675
  }
66444
66676
 
66445
- /**
66446
- * @internal
66677
+ /**
66678
+ * @internal
66447
66679
  */
66448
66680
  _getState() {
66449
66681
  return this._state;
66450
66682
  }
66451
66683
 
66452
- /**
66453
- * @internal
66684
+ /**
66685
+ * @internal
66454
66686
  */
66455
66687
  _setState(state) {
66456
66688
  this._state = {
@@ -66460,15 +66692,15 @@
66460
66692
  this._emit('changed', this._getState());
66461
66693
  }
66462
66694
 
66463
- /**
66464
- * @internal
66695
+ /**
66696
+ * @internal
66465
66697
  */
66466
66698
  _getModules() {
66467
66699
  return [ModelingModule, EditorActionsModule, DraggingModule, KeyboardModule, SelectionModule, PaletteModule, ExpressionLanguageModule, MarkdownModule, PropertiesPanelModule];
66468
66700
  }
66469
66701
 
66470
- /**
66471
- * @internal
66702
+ /**
66703
+ * @internal
66472
66704
  */
66473
66705
  _onEvent(type, priority, handler) {
66474
66706
  this.get('eventBus').on(type, priority, handler);
@@ -67971,8 +68203,8 @@
67971
68203
  return new LanguageSupport(jsonLanguage);
67972
68204
  }
67973
68205
 
67974
- /**
67975
- * @type {Facet<import('..').Variables>} Variables
68206
+ /**
68207
+ * @type {Facet<import('..').Variables>} Variables
67976
68208
  */
67977
68209
  const variablesFacet = Facet.define();
67978
68210
 
@@ -68011,8 +68243,8 @@
68011
68243
  let language = new Compartment().of(json());
68012
68244
  let tabSize = new Compartment().of(EditorState.tabSize.of(2));
68013
68245
 
68014
- /**
68015
- * @typedef {Array<string>} Variables
68246
+ /**
68247
+ * @typedef {Array<string>} Variables
68016
68248
  */
68017
68249
 
68018
68250
  const autocompletionConf = new Compartment();
@@ -68051,8 +68283,8 @@
68051
68283
  return view.state.doc.toString();
68052
68284
  };
68053
68285
 
68054
- /**
68055
- * @param {Variables} variables
68286
+ /**
68287
+ * @param {Variables} variables
68056
68288
  */
68057
68289
  this.setVariables = function (variables) {
68058
68290
  view.setVariables(variables);