@bpmn-io/form-js-playground 1.3.0-alpha.0 → 1.3.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.
@@ -19392,8 +19392,8 @@
19392
19392
  let sharedChunks = findSharedChunks(a, b, textDiff);
19393
19393
  let sideA = new SpanCursor(a, sharedChunks, minPointSize);
19394
19394
  let sideB = new SpanCursor(b, sharedChunks, minPointSize);
19395
- textDiff.iterGaps((fromA, fromB, length) => compare(sideA, fromA, sideB, fromB, length, comparator));
19396
- if (textDiff.empty && textDiff.length == 0) compare(sideA, 0, sideB, 0, 0, comparator);
19395
+ textDiff.iterGaps((fromA, fromB, length) => compare$1(sideA, fromA, sideB, fromB, length, comparator));
19396
+ if (textDiff.empty && textDiff.length == 0) compare$1(sideA, 0, sideB, 0, 0, comparator);
19397
19397
  }
19398
19398
  /**
19399
19399
  Compare the contents of two groups of range sets, returning true
@@ -19824,7 +19824,7 @@
19824
19824
  return open;
19825
19825
  }
19826
19826
  }
19827
- function compare(a, startA, b, startB, length, comparator) {
19827
+ function compare$1(a, startA, b, startB, length, comparator) {
19828
19828
  a.goto(startA);
19829
19829
  b.goto(startB);
19830
19830
  let endB = startB + length;
@@ -47571,26 +47571,26 @@
47571
47571
  return [...new Set(variables)];
47572
47572
  };
47573
47573
 
47574
- /**
47575
- * Get the variable name at the specified index in a given path expression.
47576
- *
47577
- * @param {Object} root - The root node of the path expression tree.
47578
- * @param {number} index - The index of the variable name to retrieve.
47579
- * @returns {string|null} The variable name at the specified index or null if index is out of bounds.
47574
+ /**
47575
+ * Get the variable name at the specified index in a given path expression.
47576
+ *
47577
+ * @param {Object} root - The root node of the path expression tree.
47578
+ * @param {number} index - The index of the variable name to retrieve.
47579
+ * @returns {string|null} The variable name at the specified index or null if index is out of bounds.
47580
47580
  */
47581
47581
  const _getVariableNameAtPathIndex = (root, index) => {
47582
47582
  const accessors = _deconstructPathExpression(root);
47583
47583
  return accessors[index] || null;
47584
47584
  };
47585
47585
 
47586
- /**
47587
- * Extracts the variables which are required of the external context for a given path expression.
47588
- * This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
47589
- *
47590
- * @param {Object} node - The root node of the path expression tree.
47591
- * @param {number} initialDepth - The depth at which the root node is located in the outer context.
47592
- * @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
47593
- * @returns {Set} - A set containing the extracted variable names.
47586
+ /**
47587
+ * Extracts the variables which are required of the external context for a given path expression.
47588
+ * This is done by traversing the path expression tree and keeping track of the current depth relative to the external context.
47589
+ *
47590
+ * @param {Object} node - The root node of the path expression tree.
47591
+ * @param {number} initialDepth - The depth at which the root node is located in the outer context.
47592
+ * @param {Object} specialDepthAccessors - Definitions of special keywords which represent more complex accesses of the outer context.
47593
+ * @returns {Set} - A set containing the extracted variable names.
47594
47594
  */
47595
47595
  const _smartExtractVariableNames = (node, initialDepth, specialDepthAccessors) => {
47596
47596
  // depth info represents the previous (initialised as null) and current depth of the current accessor in the path expression
@@ -47636,11 +47636,11 @@
47636
47636
  return new Set(extractedVariables);
47637
47637
  };
47638
47638
 
47639
- /**
47640
- * Deconstructs a path expression tree into an array of components.
47641
- *
47642
- * @param {Object} root - The root node of the path expression tree.
47643
- * @returns {Array<string>} An array of components in the path expression, in the correct order.
47639
+ /**
47640
+ * Deconstructs a path expression tree into an array of components.
47641
+ *
47642
+ * @param {Object} root - The root node of the path expression tree.
47643
+ * @returns {Array<string>} An array of components in the path expression, in the correct order.
47644
47644
  */
47645
47645
  const _deconstructPathExpression = root => {
47646
47646
  let node = root;
@@ -47659,13 +47659,13 @@
47659
47659
  return parts.reverse();
47660
47660
  };
47661
47661
 
47662
- /**
47663
- * Builds a simplified feel structure tree from the given parse tree and feel string.
47664
- * The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
47665
- *
47666
- * @param {Object} parseTree - The parse tree generated by a parser.
47667
- * @param {string} feelString - The feel string used for parsing.
47668
- * @returns {Object} The simplified feel structure tree.
47662
+ /**
47663
+ * Builds a simplified feel structure tree from the given parse tree and feel string.
47664
+ * The nodes follow this structure: `{ name: string, children: Array, variableName?: string }`
47665
+ *
47666
+ * @param {Object} parseTree - The parse tree generated by a parser.
47667
+ * @param {string} feelString - The feel string used for parsing.
47668
+ * @returns {Object} The simplified feel structure tree.
47669
47669
  */
47670
47670
  const _buildSimpleFeelStructureTree = (parseTree, feelString) => {
47671
47671
  const stack = [{
@@ -47691,9 +47691,9 @@
47691
47691
  return _extractFilterExpressions(stack[0].children[0]);
47692
47692
  };
47693
47693
 
47694
- /**
47695
- * Restructure the tree in such a way to bring filters (which create new contexts) to the root of the tree.
47696
- * This is done to simplify the extraction of variables and match the context hierarchy.
47694
+ /**
47695
+ * Restructure the tree in such a way to bring filters (which create new contexts) to the root of the tree.
47696
+ * This is done to simplify the extraction of variables and match the context hierarchy.
47697
47697
  */
47698
47698
  const _extractFilterExpressions = tree => {
47699
47699
  const flattenedExpressionTree = {
@@ -47733,25 +47733,25 @@
47733
47733
  this._eventBus = eventBus;
47734
47734
  }
47735
47735
 
47736
- /**
47737
- * Determines if the given value is a FEEL expression.
47738
- *
47739
- * @param {any} value
47740
- * @returns {boolean}
47741
- *
47736
+ /**
47737
+ * Determines if the given value is a FEEL expression.
47738
+ *
47739
+ * @param {any} value
47740
+ * @returns {boolean}
47741
+ *
47742
47742
  */
47743
47743
  isExpression(value) {
47744
47744
  return isString$3(value) && value.startsWith('=');
47745
47745
  }
47746
47746
 
47747
- /**
47748
- * Retrieve variable names from a given FEEL expression.
47749
- *
47750
- * @param {string} expression
47751
- * @param {object} [options]
47752
- * @param {string} [options.type]
47753
- *
47754
- * @returns {string[]}
47747
+ /**
47748
+ * Retrieve variable names from a given FEEL expression.
47749
+ *
47750
+ * @param {string} expression
47751
+ * @param {object} [options]
47752
+ * @param {string} [options.type]
47753
+ *
47754
+ * @returns {string[]}
47755
47755
  */
47756
47756
  getVariableNames(expression, options = {}) {
47757
47757
  const {
@@ -47766,13 +47766,13 @@
47766
47766
  return getFlavouredFeelVariableNames(expression, type);
47767
47767
  }
47768
47768
 
47769
- /**
47770
- * Evaluate an expression.
47771
- *
47772
- * @param {string} expression
47773
- * @param {import('../../types').Data} [data]
47774
- *
47775
- * @returns {any}
47769
+ /**
47770
+ * Evaluate an expression.
47771
+ *
47772
+ * @param {string} expression
47773
+ * @param {import('../../types').Data} [data]
47774
+ *
47775
+ * @returns {any}
47776
47776
  */
47777
47777
  evaluate(expression, data = {}) {
47778
47778
  if (!expression) {
@@ -47796,23 +47796,23 @@
47796
47796
  class FeelersTemplating {
47797
47797
  constructor() {}
47798
47798
 
47799
- /**
47800
- * Determines if the given value is a feelers template.
47801
- *
47802
- * @param {any} value
47803
- * @returns {boolean}
47804
- *
47799
+ /**
47800
+ * Determines if the given value is a feelers template.
47801
+ *
47802
+ * @param {any} value
47803
+ * @returns {boolean}
47804
+ *
47805
47805
  */
47806
47806
  isTemplate(value) {
47807
47807
  return isString$3(value) && (value.startsWith('=') || /{{.*?}}/.test(value));
47808
47808
  }
47809
47809
 
47810
- /**
47811
- * Retrieve variable names from a given feelers template.
47812
- *
47813
- * @param {string} template
47814
- *
47815
- * @returns {string[]}
47810
+ /**
47811
+ * Retrieve variable names from a given feelers template.
47812
+ *
47813
+ * @param {string} template
47814
+ *
47815
+ * @returns {string[]}
47816
47816
  */
47817
47817
  getVariableNames(template) {
47818
47818
  if (!this.isTemplate(template)) {
@@ -47838,17 +47838,17 @@
47838
47838
  }, []);
47839
47839
  }
47840
47840
 
47841
- /**
47842
- * Evaluate a template.
47843
- *
47844
- * @param {string} template
47845
- * @param {Object<string, any>} context
47846
- * @param {Object} options
47847
- * @param {boolean} [options.debug = false]
47848
- * @param {boolean} [options.strict = false]
47849
- * @param {Function} [options.buildDebugString]
47850
- *
47851
- * @returns
47841
+ /**
47842
+ * Evaluate a template.
47843
+ *
47844
+ * @param {string} template
47845
+ * @param {Object<string, any>} context
47846
+ * @param {Object} options
47847
+ * @param {boolean} [options.debug = false]
47848
+ * @param {boolean} [options.strict = false]
47849
+ * @param {Function} [options.buildDebugString]
47850
+ *
47851
+ * @returns
47852
47852
  */
47853
47853
  evaluate(template, context = {}, options = {}) {
47854
47854
  const {
@@ -47863,22 +47863,22 @@
47863
47863
  });
47864
47864
  }
47865
47865
 
47866
- /**
47867
- * @typedef {Object} ExpressionWithDepth
47868
- * @property {number} depth - The depth of the expression in the syntax tree.
47869
- * @property {string} expression - The extracted expression
47866
+ /**
47867
+ * @typedef {Object} ExpressionWithDepth
47868
+ * @property {number} depth - The depth of the expression in the syntax tree.
47869
+ * @property {string} expression - The extracted expression
47870
47870
  */
47871
47871
 
47872
- /**
47873
- * Extracts all feel expressions in the template along with their depth in the syntax tree.
47874
- * The depth is incremented for child expressions of loops to account for context drilling.
47875
- * @name extractExpressionsWithDepth
47876
- * @param {string} template - A feelers template string.
47877
- * @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
47878
- *
47879
- * @example
47880
- * const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
47881
- * const extractedExpressions = _extractExpressionsWithDepth(template);
47872
+ /**
47873
+ * Extracts all feel expressions in the template along with their depth in the syntax tree.
47874
+ * The depth is incremented for child expressions of loops to account for context drilling.
47875
+ * @name extractExpressionsWithDepth
47876
+ * @param {string} template - A feelers template string.
47877
+ * @returns {Array<ExpressionWithDepth>} An array of objects, each containing the depth and the extracted expression.
47878
+ *
47879
+ * @example
47880
+ * const template = "Hello {{user}}, you have:{{#loop items}}\n- {{amount}} {{name}}{{/loop}}.";
47881
+ * const extractedExpressions = _extractExpressionsWithDepth(template);
47882
47882
  */
47883
47883
  _extractExpressionsWithDepth(template) {
47884
47884
  // build simplified feelers syntax tree
@@ -47983,10 +47983,10 @@
47983
47983
  return injector;
47984
47984
  }
47985
47985
 
47986
- /**
47987
- * @param {string?} prefix
47988
- *
47989
- * @returns Element
47986
+ /**
47987
+ * @param {string?} prefix
47988
+ *
47989
+ * @returns Element
47990
47990
  */
47991
47991
  function createFormContainer(prefix = 'fjs') {
47992
47992
  const container = document.createElement('div');
@@ -47996,22 +47996,22 @@
47996
47996
  const EXPRESSION_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'conditional.hide', 'description', 'label', 'source', 'readonly', 'text', 'validate.min', 'validate.max', 'validate.minLength', 'validate.maxLength', 'valuesExpression'];
47997
47997
  const TEMPLATE_PROPERTIES = ['alt', 'appearance.prefixAdorner', 'appearance.suffixAdorner', 'description', 'label', 'source', 'text'];
47998
47998
 
47999
- /**
48000
- * @template T
48001
- * @param {T} data
48002
- * @param {(this: any, key: string, value: any) => any} [replacer]
48003
- * @return {T}
47999
+ /**
48000
+ * @template T
48001
+ * @param {T} data
48002
+ * @param {(this: any, key: string, value: any) => any} [replacer]
48003
+ * @return {T}
48004
48004
  */
48005
48005
  function clone(data, replacer) {
48006
48006
  return JSON.parse(JSON.stringify(data, replacer));
48007
48007
  }
48008
48008
 
48009
- /**
48010
- * Parse the schema for input variables a form might make use of
48011
- *
48012
- * @param {any} schema
48013
- *
48014
- * @return {string[]}
48009
+ /**
48010
+ * Parse the schema for input variables a form might make use of
48011
+ *
48012
+ * @param {any} schema
48013
+ *
48014
+ * @return {string[]}
48015
48015
  */
48016
48016
  function getSchemaVariables(schema, options = {}) {
48017
48017
  const {
@@ -48096,9 +48096,9 @@
48096
48096
  fn(formField);
48097
48097
  }
48098
48098
 
48099
- /**
48100
- * @typedef {object} Condition
48101
- * @property {string} [hide]
48099
+ /**
48100
+ * @typedef {object} Condition
48101
+ * @property {string} [hide]
48102
48102
  */
48103
48103
 
48104
48104
  class ConditionChecker {
@@ -48108,11 +48108,11 @@
48108
48108
  this._eventBus = eventBus;
48109
48109
  }
48110
48110
 
48111
- /**
48112
- * For given data, remove properties based on condition.
48113
- *
48114
- * @param {Object<string, any>} properties
48115
- * @param {Object<string, any>} data
48111
+ /**
48112
+ * For given data, remove properties based on condition.
48113
+ *
48114
+ * @param {Object<string, any>} properties
48115
+ * @param {Object<string, any>} data
48116
48116
  */
48117
48117
  applyConditions(properties, data = {}) {
48118
48118
  const newProperties = clone(properties);
@@ -48139,13 +48139,13 @@
48139
48139
  return newProperties;
48140
48140
  }
48141
48141
 
48142
- /**
48143
- * Check if given condition is met. Returns null for invalid/missing conditions.
48144
- *
48145
- * @param {string} condition
48146
- * @param {import('../../types').Data} [data]
48147
- *
48148
- * @returns {boolean|null}
48142
+ /**
48143
+ * Check if given condition is met. Returns null for invalid/missing conditions.
48144
+ *
48145
+ * @param {string} condition
48146
+ * @param {import('../../types').Data} [data]
48147
+ *
48148
+ * @returns {boolean|null}
48149
48149
  */
48150
48150
  check(condition, data = {}) {
48151
48151
  if (!condition) {
@@ -48166,12 +48166,12 @@
48166
48166
  }
48167
48167
  }
48168
48168
 
48169
- /**
48170
- * Check if hide condition is met.
48171
- *
48172
- * @param {Condition} condition
48173
- * @param {Object<string, any>} data
48174
- * @returns {boolean}
48169
+ /**
48170
+ * Check if hide condition is met.
48171
+ *
48172
+ * @param {Condition} condition
48173
+ * @param {Object<string, any>} data
48174
+ * @returns {boolean}
48175
48175
  */
48176
48176
  _checkHideCondition(condition, data) {
48177
48177
  if (!condition.hide) {
@@ -48206,12 +48206,12 @@
48206
48206
  this._converter = new showdown.Converter();
48207
48207
  }
48208
48208
 
48209
- /**
48210
- * Render markdown to HTML.
48211
- *
48212
- * @param {string} markdown - The markdown to render
48213
- *
48214
- * @returns {string} HTML
48209
+ /**
48210
+ * Render markdown to HTML.
48211
+ *
48212
+ * @param {string} markdown - The markdown to render
48213
+ *
48214
+ * @returns {string} HTML
48215
48215
  */
48216
48216
  render(markdown) {
48217
48217
  return this._converter.makeHtml(markdown);
@@ -49352,8 +49352,8 @@
49352
49352
 
49353
49353
  // helpers //////////
49354
49354
 
49355
- /**
49356
- * Helper function to evaluate optional FEEL validation values.
49355
+ /**
49356
+ * Helper function to evaluate optional FEEL validation values.
49357
49357
  */
49358
49358
  function evaluateFEELValues(validate, expressionLanguage, conditionChecker, form) {
49359
49359
  const evaluatedValidate = {
@@ -49386,12 +49386,12 @@
49386
49386
  return evaluatedValidate;
49387
49387
  }
49388
49388
  class Importer {
49389
- /**
49390
- * @constructor
49391
- * @param { import('./FormFieldRegistry').default } formFieldRegistry
49392
- * @param { import('./PathRegistry').default } pathRegistry
49393
- * @param { import('./FieldFactory').default } fieldFactory
49394
- * @param { import('./FormLayouter').default } formLayouter
49389
+ /**
49390
+ * @constructor
49391
+ * @param { import('./FormFieldRegistry').default } formFieldRegistry
49392
+ * @param { import('./PathRegistry').default } pathRegistry
49393
+ * @param { import('./FieldFactory').default } fieldFactory
49394
+ * @param { import('./FormLayouter').default } formLayouter
49395
49395
  */
49396
49396
  constructor(formFieldRegistry, pathRegistry, fieldFactory, formLayouter) {
49397
49397
  this._formFieldRegistry = formFieldRegistry;
@@ -49400,21 +49400,21 @@
49400
49400
  this._formLayouter = formLayouter;
49401
49401
  }
49402
49402
 
49403
- /**
49404
- * Import schema creating rows, fields, attaching additional
49405
- * information to each field and adding fields to the
49406
- * field registry.
49407
- *
49408
- * Additional information attached:
49409
- *
49410
- * * `id` (unless present)
49411
- * * `_parent`
49412
- * * `_path`
49413
- *
49414
- * @param {any} schema
49415
- *
49416
- * @typedef {{ warnings: Error[], schema: any }} ImportResult
49417
- * @returns {ImportResult}
49403
+ /**
49404
+ * Import schema creating rows, fields, attaching additional
49405
+ * information to each field and adding fields to the
49406
+ * field registry.
49407
+ *
49408
+ * Additional information attached:
49409
+ *
49410
+ * * `id` (unless present)
49411
+ * * `_parent`
49412
+ * * `_path`
49413
+ *
49414
+ * @param {any} schema
49415
+ *
49416
+ * @typedef {{ warnings: Error[], schema: any }} ImportResult
49417
+ * @returns {ImportResult}
49418
49418
  */
49419
49419
  importSchema(schema) {
49420
49420
  // TODO: Add warnings
@@ -49439,12 +49439,12 @@
49439
49439
  this._pathRegistry.clear();
49440
49440
  }
49441
49441
 
49442
- /**
49443
- * @param {{[x: string]: any}} fieldAttrs
49444
- * @param {String} [parentId]
49445
- * @param {number} [index]
49446
- *
49447
- * @return {any} field
49442
+ /**
49443
+ * @param {{[x: string]: any}} fieldAttrs
49444
+ * @param {String} [parentId]
49445
+ * @param {number} [index]
49446
+ *
49447
+ * @return {any} field
49448
49448
  */
49449
49449
  importFormField(fieldAttrs, parentId, index) {
49450
49450
  const {
@@ -49469,11 +49469,11 @@
49469
49469
  return field;
49470
49470
  }
49471
49471
 
49472
- /**
49473
- * @param {Array<any>} components
49474
- * @param {string} parentId
49475
- *
49476
- * @return {Array<any>} imported components
49472
+ /**
49473
+ * @param {Array<any>} components
49474
+ * @param {string} parentId
49475
+ *
49476
+ * @return {Array<any>} imported components
49477
49477
  */
49478
49478
  importFormFields(components, parentId) {
49479
49479
  return components.map((component, index) => {
@@ -49483,11 +49483,11 @@
49483
49483
  }
49484
49484
  Importer.$inject = ['formFieldRegistry', 'pathRegistry', 'fieldFactory', 'formLayouter'];
49485
49485
  class FieldFactory {
49486
- /**
49487
- * @constructor
49488
- *
49489
- * @param formFieldRegistry
49490
- * @param formFields
49486
+ /**
49487
+ * @constructor
49488
+ *
49489
+ * @param formFieldRegistry
49490
+ * @param formFields
49491
49491
  */
49492
49492
  constructor(formFieldRegistry, pathRegistry, formFields) {
49493
49493
  this._formFieldRegistry = formFieldRegistry;
@@ -49569,36 +49569,36 @@
49569
49569
  }
49570
49570
  FieldFactory.$inject = ['formFieldRegistry', 'pathRegistry', 'formFields'];
49571
49571
 
49572
- /**
49573
- * The PathRegistry class manages a hierarchical structure of paths associated with form fields.
49574
- * It enables claiming, unclaiming, and validating paths within this structure.
49575
- *
49576
- * Example Tree Structure:
49577
- *
49578
- * [
49579
- * {
49580
- * segment: 'root',
49581
- * claimCount: 1,
49582
- * children: [
49583
- * {
49584
- * segment: 'child1',
49585
- * claimCount: 2,
49586
- * children: null // A leaf node (closed path)
49587
- * },
49588
- * {
49589
- * segment: 'child2',
49590
- * claimCount: 1,
49591
- * children: [
49592
- * {
49593
- * segment: 'subChild1',
49594
- * claimCount: 1,
49595
- * children: [] // An open node (open path)
49596
- * }
49597
- * ]
49598
- * }
49599
- * ]
49600
- * }
49601
- * ]
49572
+ /**
49573
+ * The PathRegistry class manages a hierarchical structure of paths associated with form fields.
49574
+ * It enables claiming, unclaiming, and validating paths within this structure.
49575
+ *
49576
+ * Example Tree Structure:
49577
+ *
49578
+ * [
49579
+ * {
49580
+ * segment: 'root',
49581
+ * claimCount: 1,
49582
+ * children: [
49583
+ * {
49584
+ * segment: 'child1',
49585
+ * claimCount: 2,
49586
+ * children: null // A leaf node (closed path)
49587
+ * },
49588
+ * {
49589
+ * segment: 'child2',
49590
+ * claimCount: 1,
49591
+ * children: [
49592
+ * {
49593
+ * segment: 'subChild1',
49594
+ * claimCount: 1,
49595
+ * children: [] // An open node (open path)
49596
+ * }
49597
+ * ]
49598
+ * }
49599
+ * ]
49600
+ * }
49601
+ * ]
49602
49602
  */
49603
49603
  class PathRegistry {
49604
49604
  constructor(formFieldRegistry, formFields) {
@@ -49681,16 +49681,16 @@
49681
49681
  }
49682
49682
  }
49683
49683
 
49684
- /**
49685
- * Applies a function (fn) recursively on a given field and its children.
49686
- *
49687
- * - `field`: Starting field object.
49688
- * - `fn`: Function to apply.
49689
- * - `context`: Optional object for passing data between calls.
49690
- *
49691
- * Stops early if `fn` returns `false`. Useful for traversing the form field tree.
49692
- *
49693
- * @returns {boolean} Success status based on function execution.
49684
+ /**
49685
+ * Applies a function (fn) recursively on a given field and its children.
49686
+ *
49687
+ * - `field`: Starting field object.
49688
+ * - `fn`: Function to apply.
49689
+ * - `context`: Optional object for passing data between calls.
49690
+ *
49691
+ * Stops early if `fn` returns `false`. Useful for traversing the form field tree.
49692
+ *
49693
+ * @returns {boolean} Success status based on function execution.
49694
49694
  */
49695
49695
  executeRecursivelyOnFields(field, fn, context = {}) {
49696
49696
  let result = true;
@@ -49724,15 +49724,15 @@
49724
49724
  return result;
49725
49725
  }
49726
49726
 
49727
- /**
49728
- * Generates an array representing the binding path to an underlying data object for a form field.
49729
- *
49730
- * @param {Object} field - The field object with properties: `key`, `path`, `id`, and optionally `_parent`.
49731
- * @param {Object} [options={}] - Configuration options.
49732
- * @param {Object} [options.replacements={}] - A map of field IDs to alternative path arrays.
49733
- * @param {Object} [options.cutoffNode] - The ID of the parent field at which to stop generating the path.
49734
- *
49735
- * @returns {(Array<string>|undefined)} An array of strings representing the binding path, or undefined if not determinable.
49727
+ /**
49728
+ * Generates an array representing the binding path to an underlying data object for a form field.
49729
+ *
49730
+ * @param {Object} field - The field object with properties: `key`, `path`, `id`, and optionally `_parent`.
49731
+ * @param {Object} [options={}] - Configuration options.
49732
+ * @param {Object} [options.replacements={}] - A map of field IDs to alternative path arrays.
49733
+ * @param {Object} [options.cutoffNode] - The ID of the parent field at which to stop generating the path.
49734
+ *
49735
+ * @returns {(Array<string>|undefined)} An array of strings representing the binding path, or undefined if not determinable.
49736
49736
  */
49737
49737
  getValuePath(field, options = {}) {
49738
49738
  const {
@@ -49776,23 +49776,23 @@
49776
49776
  };
49777
49777
  PathRegistry.$inject = ['formFieldRegistry', 'formFields'];
49778
49778
 
49779
- /**
49780
- * @typedef { { id: String, components: Array<String> } } FormRow
49781
- * @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
49779
+ /**
49780
+ * @typedef { { id: String, components: Array<String> } } FormRow
49781
+ * @typedef { { formFieldId: String, rows: Array<FormRow> } } FormRows
49782
49782
  */
49783
49783
 
49784
- /**
49785
- * Maintains the Form layout in a given structure, for example
49786
- *
49787
- * [
49788
- * {
49789
- * formFieldId: 'FormField_1',
49790
- * rows: [
49791
- * { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
49792
- * ]
49793
- * }
49794
- * ]
49795
- *
49784
+ /**
49785
+ * Maintains the Form layout in a given structure, for example
49786
+ *
49787
+ * [
49788
+ * {
49789
+ * formFieldId: 'FormField_1',
49790
+ * rows: [
49791
+ * { id: 'Row_1', components: [ 'Text_1', 'Textdield_1', ... ] }
49792
+ * ]
49793
+ * }
49794
+ * ]
49795
+ *
49796
49796
  */
49797
49797
  class FormLayouter {
49798
49798
  constructor(eventBus) {
@@ -49802,8 +49802,8 @@
49802
49802
  this._eventBus = eventBus;
49803
49803
  }
49804
49804
 
49805
- /**
49806
- * @param {FormRow} row
49805
+ /**
49806
+ * @param {FormRow} row
49807
49807
  */
49808
49808
  addRow(formFieldId, row) {
49809
49809
  let rowsPerComponent = this._rows.find(r => r.formFieldId === formFieldId);
@@ -49817,18 +49817,18 @@
49817
49817
  rowsPerComponent.rows.push(row);
49818
49818
  }
49819
49819
 
49820
- /**
49821
- * @param {String} id
49822
- * @returns {FormRow}
49820
+ /**
49821
+ * @param {String} id
49822
+ * @returns {FormRow}
49823
49823
  */
49824
49824
  getRow(id) {
49825
49825
  const rows = allRows(this._rows);
49826
49826
  return rows.find(r => r.id === id);
49827
49827
  }
49828
49828
 
49829
- /**
49830
- * @param {any} formField
49831
- * @returns {FormRow}
49829
+ /**
49830
+ * @param {any} formField
49831
+ * @returns {FormRow}
49832
49832
  */
49833
49833
  getRowForField(formField) {
49834
49834
  return allRows(this._rows).find(r => {
@@ -49839,9 +49839,9 @@
49839
49839
  });
49840
49840
  }
49841
49841
 
49842
- /**
49843
- * @param {String} formFieldId
49844
- * @returns { Array<FormRow> }
49842
+ /**
49843
+ * @param {String} formFieldId
49844
+ * @returns { Array<FormRow> }
49845
49845
  */
49846
49846
  getRows(formFieldId) {
49847
49847
  const rowsForField = this._rows.find(r => formFieldId === r.formFieldId);
@@ -49851,15 +49851,15 @@
49851
49851
  return rowsForField.rows;
49852
49852
  }
49853
49853
 
49854
- /**
49855
- * @returns {string}
49854
+ /**
49855
+ * @returns {string}
49856
49856
  */
49857
49857
  nextRowId() {
49858
49858
  return this._ids.nextPrefixed('Row_');
49859
49859
  }
49860
49860
 
49861
- /**
49862
- * @param {any} formField
49861
+ /**
49862
+ * @param {any} formField
49863
49863
  */
49864
49864
  calculateLayout(formField) {
49865
49865
  const {
@@ -49913,9 +49913,9 @@
49913
49913
  });
49914
49914
  }
49915
49915
 
49916
- /**
49917
- * @param {Array<FormRows>} formRows
49918
- * @returns {Array<FormRow>}
49916
+ /**
49917
+ * @param {Array<FormRows>} formRows
49918
+ * @returns {Array<FormRow>}
49919
49919
  */
49920
49920
  function allRows(formRows) {
49921
49921
  return flatten$2(formRows.map(c => c.rows));
@@ -50067,11 +50067,11 @@
50067
50067
  });
50068
50068
  var FormRenderContext$1 = FormRenderContext;
50069
50069
 
50070
- /**
50071
- * @param {string} type
50072
- * @param {boolean} [strict]
50073
- *
50074
- * @returns {any}
50070
+ /**
50071
+ * @param {string} type
50072
+ * @param {boolean} [strict]
50073
+ *
50074
+ * @returns {any}
50075
50075
  */
50076
50076
  function getService$2(type, strict) {}
50077
50077
  const FormContext = D$2({
@@ -50086,10 +50086,10 @@
50086
50086
  return getService(type, strict);
50087
50087
  }
50088
50088
 
50089
- /**
50090
- * Returns the conditionally filtered data of a form reactively.
50091
- * Memoised to minimize re-renders
50092
- *
50089
+ /**
50090
+ * Returns the conditionally filtered data of a form reactively.
50091
+ * Memoised to minimize re-renders
50092
+ *
50093
50093
  */
50094
50094
  function useFilteredFormData() {
50095
50095
  const {
@@ -50106,12 +50106,12 @@
50106
50106
  }, [conditionChecker, data, initialData]);
50107
50107
  }
50108
50108
 
50109
- /**
50110
- * Evaluate if condition is met reactively based on the conditionChecker and form data.
50111
- *
50112
- * @param {string | undefined} condition
50113
- *
50114
- * @returns {boolean} true if condition is met or no condition or condition checker exists
50109
+ /**
50110
+ * Evaluate if condition is met reactively based on the conditionChecker and form data.
50111
+ *
50112
+ * @param {string | undefined} condition
50113
+ *
50114
+ * @returns {boolean} true if condition is met or no condition or condition checker exists
50115
50115
  */
50116
50116
  function useCondition(condition) {
50117
50117
  const conditionChecker = useService$2('conditionChecker', false);
@@ -50121,13 +50121,13 @@
50121
50121
  }, [conditionChecker, condition, filteredData]);
50122
50122
  }
50123
50123
 
50124
- /**
50125
- * Evaluate a string reactively based on the expressionLanguage and form data.
50126
- * If the string is not an expression, it is returned as is.
50127
- * Memoised to minimize re-renders.
50128
- *
50129
- * @param {string} value
50130
- *
50124
+ /**
50125
+ * Evaluate a string reactively based on the expressionLanguage and form data.
50126
+ * If the string is not an expression, it is returned as is.
50127
+ * Memoised to minimize re-renders.
50128
+ *
50129
+ * @param {string} value
50130
+ *
50131
50131
  */
50132
50132
  function useExpressionEvaluation(value) {
50133
50133
  const formData = useFilteredFormData();
@@ -50155,16 +50155,16 @@
50155
50155
  });
50156
50156
  }
50157
50157
 
50158
- /**
50159
- * Retrieve readonly value of a form field, given it can be an
50160
- * expression optionally or configured globally.
50161
- *
50162
- * @typedef { import('../../types').FormProperties } FormProperties
50163
- *
50164
- * @param {any} formField
50165
- * @param {FormProperties} properties
50166
- *
50167
- * @returns {boolean}
50158
+ /**
50159
+ * Retrieve readonly value of a form field, given it can be an
50160
+ * expression optionally or configured globally.
50161
+ *
50162
+ * @typedef { import('../../types').FormProperties } FormProperties
50163
+ *
50164
+ * @param {any} formField
50165
+ * @param {FormProperties} properties
50166
+ *
50167
+ * @returns {boolean}
50168
50168
  */
50169
50169
  function useReadonly(formField, properties = {}) {
50170
50170
  const expressionLanguage = useService$2('expressionLanguage');
@@ -50181,17 +50181,47 @@
50181
50181
  }
50182
50182
  return readonly || false;
50183
50183
  }
50184
+ function usePrevious$1(value, defaultValue, dependencies) {
50185
+ const ref = s$1(defaultValue);
50186
+ y(() => ref.current = value, dependencies);
50187
+ return ref.current;
50188
+ }
50184
50189
 
50185
- /**
50186
- * Template a string reactively based on form data. If the string is not a template, it is returned as is.
50187
- * Memoised to minimize re-renders
50188
- *
50189
- * @param {string} value
50190
- * @param {Object} options
50191
- * @param {boolean} [options.debug = false]
50192
- * @param {boolean} [options.strict = false]
50193
- * @param {Function} [options.buildDebugString]
50194
- *
50190
+ /**
50191
+ * A custom hook to manage state changes with deep comparison.
50192
+ *
50193
+ * @param {any} value - The current value to manage.
50194
+ * @param {any} defaultValue - The initial default value for the state.
50195
+ * @returns {any} - Returns the current state.
50196
+ */
50197
+ function useDeepCompareState(value, defaultValue) {
50198
+ const [state, setState] = l$2(defaultValue);
50199
+ const previous = usePrevious$1(value, defaultValue, [value]);
50200
+ const changed = !compare(previous, value);
50201
+ y(() => {
50202
+ if (changed) {
50203
+ setState(value);
50204
+ }
50205
+ }, [changed, value]);
50206
+ return state;
50207
+ }
50208
+
50209
+ // helpers //////////////////////////
50210
+
50211
+ function compare(a, b) {
50212
+ return JSON.stringify(a) === JSON.stringify(b);
50213
+ }
50214
+
50215
+ /**
50216
+ * Template a string reactively based on form data. If the string is not a template, it is returned as is.
50217
+ * Memoised to minimize re-renders
50218
+ *
50219
+ * @param {string} value
50220
+ * @param {Object} options
50221
+ * @param {boolean} [options.debug = false]
50222
+ * @param {boolean} [options.strict = false]
50223
+ * @param {Function} [options.buildDebugString]
50224
+ *
50195
50225
  */
50196
50226
  function useTemplateEvaluation(value, options) {
50197
50227
  const filteredData = useFilteredFormData();
@@ -50204,17 +50234,17 @@
50204
50234
  }, [filteredData, templating, value, options]);
50205
50235
  }
50206
50236
 
50207
- /**
50208
- * Template a string reactively based on form data. If the string is not a template, it is returned as is.
50209
- * If the string contains multiple lines, only the first line is returned.
50210
- * Memoised to minimize re-renders
50211
- *
50212
- * @param {string} value
50213
- * @param {Object} [options]
50214
- * @param {boolean} [options.debug = false]
50215
- * @param {boolean} [options.strict = false]
50216
- * @param {Function} [options.buildDebugString]
50217
- *
50237
+ /**
50238
+ * Template a string reactively based on form data. If the string is not a template, it is returned as is.
50239
+ * If the string contains multiple lines, only the first line is returned.
50240
+ * Memoised to minimize re-renders
50241
+ *
50242
+ * @param {string} value
50243
+ * @param {Object} [options]
50244
+ * @param {boolean} [options.debug = false]
50245
+ * @param {boolean} [options.strict = false]
50246
+ * @param {Function} [options.buildDebugString]
50247
+ *
50218
50248
  */
50219
50249
  function useSingleLineTemplateEvaluation(value, options = {}) {
50220
50250
  const evaluatedTemplate = useTemplateEvaluation(value, options);
@@ -50414,8 +50444,8 @@
50414
50444
  };
50415
50445
  }
50416
50446
 
50417
- /**
50418
- * @enum { String }
50447
+ /**
50448
+ * @enum { String }
50419
50449
  */
50420
50450
  const LOAD_STATES = {
50421
50451
  LOADING: 'loading',
@@ -50423,17 +50453,17 @@
50423
50453
  ERROR: 'error'
50424
50454
  };
50425
50455
 
50426
- /**
50427
- * @typedef {Object} ValuesGetter
50428
- * @property {Object[]} values - The values data
50429
- * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
50456
+ /**
50457
+ * @typedef {Object} ValuesGetter
50458
+ * @property {Object[]} values - The values data
50459
+ * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
50430
50460
  */
50431
50461
 
50432
- /**
50433
- * A hook to load values for single and multiselect components.
50434
- *
50435
- * @param {Object} field - The form field to handle values for
50436
- * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
50462
+ /**
50463
+ * A hook to load values for single and multiselect components.
50464
+ *
50465
+ * @param {Object} field - The form field to handle values for
50466
+ * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
50437
50467
  */
50438
50468
  function useValuesAsync(field) {
50439
50469
  const {
@@ -50447,11 +50477,8 @@
50447
50477
  state: LOAD_STATES.LOADING
50448
50478
  });
50449
50479
  const initialData = useService$2('form')._getState().initialData;
50450
- const evaluatedValues = d(() => {
50451
- if (valuesExpression) {
50452
- return useExpressionEvaluation(valuesExpression);
50453
- }
50454
- }, [valuesExpression]);
50480
+ const expressionEvaluation = useExpressionEvaluation(valuesExpression);
50481
+ const evaluatedValues = useDeepCompareState(expressionEvaluation || [], []);
50455
50482
  y(() => {
50456
50483
  let values = [];
50457
50484
 
@@ -50467,8 +50494,10 @@
50467
50494
  values = Array.isArray(staticValues) ? staticValues : [];
50468
50495
 
50469
50496
  // expression
50470
- } else if (evaluatedValues && Array.isArray(evaluatedValues)) {
50471
- values = evaluatedValues;
50497
+ } else if (valuesExpression) {
50498
+ if (evaluatedValues && Array.isArray(evaluatedValues)) {
50499
+ values = evaluatedValues;
50500
+ }
50472
50501
  } else {
50473
50502
  setValuesGetter(buildErrorState('No values source defined in the form definition'));
50474
50503
  return;
@@ -50477,7 +50506,7 @@
50477
50506
  // normalize data to support primitives and partially defined objects
50478
50507
  values = normalizeValuesData(values);
50479
50508
  setValuesGetter(buildLoadedState(values));
50480
- }, [valuesKey, staticValues, initialData]);
50509
+ }, [valuesKey, staticValues, initialData, valuesExpression, evaluatedValues]);
50481
50510
  return valuesGetter;
50482
50511
  }
50483
50512
  const buildErrorState = error => ({
@@ -50949,12 +50978,12 @@
50949
50978
  };
50950
50979
  var CalendarIcon = SvgCalendar;
50951
50980
 
50952
- /**
50953
- * Returns date format for the provided locale.
50954
- * If the locale is not provided, uses the browser's locale.
50955
- *
50956
- * @param {string} [locale] - The locale to get date format for.
50957
- * @returns {string} The date format for the locale.
50981
+ /**
50982
+ * Returns date format for the provided locale.
50983
+ * If the locale is not provided, uses the browser's locale.
50984
+ *
50985
+ * @param {string} [locale] - The locale to get date format for.
50986
+ * @returns {string} The date format for the locale.
50958
50987
  */
50959
50988
  function getLocaleDateFormat(locale = 'default') {
50960
50989
  const parts = new Intl.DateTimeFormat(locale).formatToParts(new Date(Date.UTC(2020, 5, 5)));
@@ -50973,12 +51002,12 @@
50973
51002
  }).join('');
50974
51003
  }
50975
51004
 
50976
- /**
50977
- * Returns readable date format for the provided locale.
50978
- * If the locale is not provided, uses the browser's locale.
50979
- *
50980
- * @param {string} [locale] - The locale to get readable date format for.
50981
- * @returns {string} The readable date format for the locale.
51005
+ /**
51006
+ * Returns readable date format for the provided locale.
51007
+ * If the locale is not provided, uses the browser's locale.
51008
+ *
51009
+ * @param {string} [locale] - The locale to get readable date format for.
51010
+ * @returns {string} The readable date format for the locale.
50982
51011
  */
50983
51012
  function getLocaleReadableDateFormat(locale) {
50984
51013
  let format = getLocaleDateFormat(locale).toLowerCase();
@@ -50995,12 +51024,12 @@
50995
51024
  return format;
50996
51025
  }
50997
51026
 
50998
- /**
50999
- * Returns flatpickr config for the provided locale.
51000
- * If the locale is not provided, uses the browser's locale.
51001
- *
51002
- * @param {string} [locale] - The locale to get flatpickr config for.
51003
- * @returns {object} The flatpickr config for the locale.
51027
+ /**
51028
+ * Returns flatpickr config for the provided locale.
51029
+ * If the locale is not provided, uses the browser's locale.
51030
+ *
51031
+ * @param {string} [locale] - The locale to get flatpickr config for.
51032
+ * @returns {object} The flatpickr config for the locale.
51004
51033
  */
51005
51034
  function getLocaleDateFlatpickrConfig(locale) {
51006
51035
  return flatpickerizeDateFormat(getLocaleDateFormat(locale));
@@ -51277,7 +51306,8 @@
51277
51306
  y(() => {
51278
51307
  const individualEntries = dropdownContainer.current.children;
51279
51308
  if (individualEntries.length && !mouseControl) {
51280
- individualEntries[focusedValueIndex].scrollIntoView({
51309
+ const focusedEntry = individualEntries[focusedValueIndex];
51310
+ focusedEntry && focusedEntry.scrollIntoView({
51281
51311
  block: 'nearest',
51282
51312
  inline: 'nearest'
51283
51313
  });
@@ -51687,10 +51717,10 @@
51687
51717
  }
51688
51718
  };
51689
51719
 
51690
- /**
51691
- * This file must not be changed or exchanged.
51692
- *
51693
- * @see http://bpmn.io/license for more information.
51720
+ /**
51721
+ * This file must not be changed or exchanged.
51722
+ *
51723
+ * @see http://bpmn.io/license for more information.
51694
51724
  */
51695
51725
  function Logo() {
51696
51726
  return e$1("svg", {
@@ -51865,11 +51895,11 @@
51865
51895
 
51866
51896
  const FORM_ELEMENT = document.createElement('form');
51867
51897
 
51868
- /**
51869
- * Sanitize a HTML string and return the cleaned, safe version.
51870
- *
51871
- * @param {string} html
51872
- * @return {string}
51898
+ /**
51899
+ * Sanitize a HTML string and return the cleaned, safe version.
51900
+ *
51901
+ * @param {string} html
51902
+ * @return {string}
51873
51903
  */
51874
51904
 
51875
51905
  // see https://github.com/developit/snarkdown/issues/70
@@ -51887,29 +51917,29 @@
51887
51917
  }
51888
51918
  }
51889
51919
 
51890
- /**
51891
- * Sanitizes an image source to ensure we only allow for data URI and links
51892
- * that start with http(s).
51893
- *
51894
- * Note: Most browsers anyway do not support script execution in <img> elements.
51895
- *
51896
- * @param {string} src
51897
- * @returns {string}
51920
+ /**
51921
+ * Sanitizes an image source to ensure we only allow for data URI and links
51922
+ * that start with http(s).
51923
+ *
51924
+ * Note: Most browsers anyway do not support script execution in <img> elements.
51925
+ *
51926
+ * @param {string} src
51927
+ * @returns {string}
51898
51928
  */
51899
51929
  function sanitizeImageSource(src) {
51900
51930
  const valid = ALLOWED_IMAGE_SRC_PATTERN.test(src);
51901
51931
  return valid ? src : '';
51902
51932
  }
51903
51933
 
51904
- /**
51905
- * Recursively sanitize a HTML node, potentially
51906
- * removing it, its children or attributes.
51907
- *
51908
- * Inspired by https://github.com/developit/snarkdown/issues/70
51909
- * and https://github.com/cure53/DOMPurify. Simplified
51910
- * for our use-case.
51911
- *
51912
- * @param {Element} node
51934
+ /**
51935
+ * Recursively sanitize a HTML node, potentially
51936
+ * removing it, its children or attributes.
51937
+ *
51938
+ * Inspired by https://github.com/developit/snarkdown/issues/70
51939
+ * and https://github.com/cure53/DOMPurify. Simplified
51940
+ * for our use-case.
51941
+ *
51942
+ * @param {Element} node
51913
51943
  */
51914
51944
  function sanitizeNode(node) {
51915
51945
  // allow text nodes
@@ -51953,13 +51983,13 @@
51953
51983
  }
51954
51984
  }
51955
51985
 
51956
- /**
51957
- * Validates attributes for validity.
51958
- *
51959
- * @param {string} lcTag
51960
- * @param {string} lcName
51961
- * @param {string} value
51962
- * @return {boolean}
51986
+ /**
51987
+ * Validates attributes for validity.
51988
+ *
51989
+ * @param {string} lcTag
51990
+ * @param {string} lcName
51991
+ * @param {string} value
51992
+ * @return {boolean}
51963
51993
  */
51964
51994
  function isValidAttribute(lcTag, lcName, value) {
51965
51995
  // disallow most attributes based on whitelist
@@ -53898,55 +53928,55 @@
53898
53928
  validator: ['type', Validator]
53899
53929
  };
53900
53930
 
53901
- /**
53902
- * @typedef { import('./types').Injector } Injector
53903
- * @typedef { import('./types').Data } Data
53904
- * @typedef { import('./types').Errors } Errors
53905
- * @typedef { import('./types').Schema } Schema
53906
- * @typedef { import('./types').FormProperties } FormProperties
53907
- * @typedef { import('./types').FormProperty } FormProperty
53908
- * @typedef { import('./types').FormEvent } FormEvent
53909
- * @typedef { import('./types').FormOptions } FormOptions
53910
- *
53911
- * @typedef { {
53912
- * data: Data,
53913
- * initialData: Data,
53914
- * errors: Errors,
53915
- * properties: FormProperties,
53916
- * schema: Schema
53917
- * } } State
53918
- *
53919
- * @typedef { (type:FormEvent, priority:number, handler:Function) => void } OnEventWithPriority
53920
- * @typedef { (type:FormEvent, handler:Function) => void } OnEventWithOutPriority
53921
- * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
53931
+ /**
53932
+ * @typedef { import('./types').Injector } Injector
53933
+ * @typedef { import('./types').Data } Data
53934
+ * @typedef { import('./types').Errors } Errors
53935
+ * @typedef { import('./types').Schema } Schema
53936
+ * @typedef { import('./types').FormProperties } FormProperties
53937
+ * @typedef { import('./types').FormProperty } FormProperty
53938
+ * @typedef { import('./types').FormEvent } FormEvent
53939
+ * @typedef { import('./types').FormOptions } FormOptions
53940
+ *
53941
+ * @typedef { {
53942
+ * data: Data,
53943
+ * initialData: Data,
53944
+ * errors: Errors,
53945
+ * properties: FormProperties,
53946
+ * schema: Schema
53947
+ * } } State
53948
+ *
53949
+ * @typedef { (type:FormEvent, priority:number, handler:Function) => void } OnEventWithPriority
53950
+ * @typedef { (type:FormEvent, handler:Function) => void } OnEventWithOutPriority
53951
+ * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
53922
53952
  */
53923
53953
 
53924
53954
  const ids$1 = new Ids([32, 36, 1]);
53925
53955
 
53926
- /**
53927
- * The form.
53956
+ /**
53957
+ * The form.
53928
53958
  */
53929
53959
  class Form {
53930
- /**
53931
- * @constructor
53932
- * @param {FormOptions} options
53960
+ /**
53961
+ * @constructor
53962
+ * @param {FormOptions} options
53933
53963
  */
53934
53964
  constructor(options = {}) {
53935
- /**
53936
- * @public
53937
- * @type {OnEventType}
53965
+ /**
53966
+ * @public
53967
+ * @type {OnEventType}
53938
53968
  */
53939
53969
  this.on = this._onEvent;
53940
53970
 
53941
- /**
53942
- * @public
53943
- * @type {String}
53971
+ /**
53972
+ * @public
53973
+ * @type {String}
53944
53974
  */
53945
53975
  this._id = ids$1.next();
53946
53976
 
53947
- /**
53948
- * @private
53949
- * @type {Element}
53977
+ /**
53978
+ * @private
53979
+ * @type {Element}
53950
53980
  */
53951
53981
  this._container = createFormContainer();
53952
53982
  const {
@@ -53955,9 +53985,9 @@
53955
53985
  properties = {}
53956
53986
  } = options;
53957
53987
 
53958
- /**
53959
- * @private
53960
- * @type {State}
53988
+ /**
53989
+ * @private
53990
+ * @type {State}
53961
53991
  */
53962
53992
  this._state = {
53963
53993
  initialData: null,
@@ -53981,9 +54011,9 @@
53981
54011
  this._emit('form.clear');
53982
54012
  }
53983
54013
 
53984
- /**
53985
- * Destroy the form, removing it from DOM,
53986
- * if attached.
54014
+ /**
54015
+ * Destroy the form, removing it from DOM,
54016
+ * if attached.
53987
54017
  */
53988
54018
  destroy() {
53989
54019
  // destroy form services
@@ -53994,13 +54024,13 @@
53994
54024
  this._detach(false);
53995
54025
  }
53996
54026
 
53997
- /**
53998
- * Open a form schema with the given initial data.
53999
- *
54000
- * @param {Schema} schema
54001
- * @param {Data} [data]
54002
- *
54003
- * @return Promise<{ warnings: Array<any> }>
54027
+ /**
54028
+ * Open a form schema with the given initial data.
54029
+ *
54030
+ * @param {Schema} schema
54031
+ * @param {Data} [data]
54032
+ *
54033
+ * @return Promise<{ warnings: Array<any> }>
54004
54034
  */
54005
54035
  importSchema(schema, data = {}) {
54006
54036
  return new Promise((resolve, reject) => {
@@ -54033,10 +54063,10 @@
54033
54063
  });
54034
54064
  }
54035
54065
 
54036
- /**
54037
- * Submit the form, triggering all field validations.
54038
- *
54039
- * @returns { { data: Data, errors: Errors } }
54066
+ /**
54067
+ * Submit the form, triggering all field validations.
54068
+ *
54069
+ * @returns { { data: Data, errors: Errors } }
54040
54070
  */
54041
54071
  submit() {
54042
54072
  const {
@@ -54063,8 +54093,8 @@
54063
54093
  });
54064
54094
  }
54065
54095
 
54066
- /**
54067
- * @returns {Errors}
54096
+ /**
54097
+ * @returns {Errors}
54068
54098
  */
54069
54099
  validate() {
54070
54100
  const formFieldRegistry = this.get('formFieldRegistry'),
@@ -54090,8 +54120,8 @@
54090
54120
  return errors;
54091
54121
  }
54092
54122
 
54093
- /**
54094
- * @param {Element|string} parentNode
54123
+ /**
54124
+ * @param {Element|string} parentNode
54095
54125
  */
54096
54126
  attachTo(parentNode) {
54097
54127
  if (!parentNode) {
@@ -54109,10 +54139,10 @@
54109
54139
  this._detach();
54110
54140
  }
54111
54141
 
54112
- /**
54113
- * @private
54114
- *
54115
- * @param {boolean} [emit]
54142
+ /**
54143
+ * @private
54144
+ *
54145
+ * @param {boolean} [emit]
54116
54146
  */
54117
54147
  _detach(emit = true) {
54118
54148
  const container = this._container,
@@ -54126,9 +54156,9 @@
54126
54156
  parentNode.removeChild(container);
54127
54157
  }
54128
54158
 
54129
- /**
54130
- * @param {FormProperty} property
54131
- * @param {any} value
54159
+ /**
54160
+ * @param {FormProperty} property
54161
+ * @param {any} value
54132
54162
  */
54133
54163
  setProperty(property, value) {
54134
54164
  const properties = set$3(this._getState().properties, [property], value);
@@ -54137,21 +54167,21 @@
54137
54167
  });
54138
54168
  }
54139
54169
 
54140
- /**
54141
- * @param {FormEvent} type
54142
- * @param {Function} handler
54170
+ /**
54171
+ * @param {FormEvent} type
54172
+ * @param {Function} handler
54143
54173
  */
54144
54174
  off(type, handler) {
54145
54175
  this.get('eventBus').off(type, handler);
54146
54176
  }
54147
54177
 
54148
- /**
54149
- * @private
54150
- *
54151
- * @param {FormOptions} options
54152
- * @param {Element} container
54153
- *
54154
- * @returns {Injector}
54178
+ /**
54179
+ * @private
54180
+ *
54181
+ * @param {FormOptions} options
54182
+ * @param {Element} container
54183
+ *
54184
+ * @returns {Injector}
54155
54185
  */
54156
54186
  _createInjector(options, container) {
54157
54187
  const {
@@ -54170,17 +54200,17 @@
54170
54200
  }, core$1, ...modules, ...additionalModules]);
54171
54201
  }
54172
54202
 
54173
- /**
54174
- * @private
54203
+ /**
54204
+ * @private
54175
54205
  */
54176
54206
  _emit(type, data) {
54177
54207
  this.get('eventBus').fire(type, data);
54178
54208
  }
54179
54209
 
54180
- /**
54181
- * @internal
54182
- *
54183
- * @param { { add?: boolean, field: any, remove?: number, value?: any } } update
54210
+ /**
54211
+ * @internal
54212
+ *
54213
+ * @param { { add?: boolean, field: any, remove?: number, value?: any } } update
54184
54214
  */
54185
54215
  _update(update) {
54186
54216
  const {
@@ -54202,15 +54232,15 @@
54202
54232
  });
54203
54233
  }
54204
54234
 
54205
- /**
54206
- * @internal
54235
+ /**
54236
+ * @internal
54207
54237
  */
54208
54238
  _getState() {
54209
54239
  return this._state;
54210
54240
  }
54211
54241
 
54212
- /**
54213
- * @internal
54242
+ /**
54243
+ * @internal
54214
54244
  */
54215
54245
  _setState(state) {
54216
54246
  this._state = {
@@ -54220,22 +54250,22 @@
54220
54250
  this._emit('changed', this._getState());
54221
54251
  }
54222
54252
 
54223
- /**
54224
- * @internal
54253
+ /**
54254
+ * @internal
54225
54255
  */
54226
54256
  _getModules() {
54227
54257
  return [ExpressionLanguageModule$1, MarkdownModule, ViewerCommandsModule];
54228
54258
  }
54229
54259
 
54230
- /**
54231
- * @internal
54260
+ /**
54261
+ * @internal
54232
54262
  */
54233
54263
  _onEvent(type, priority, handler) {
54234
54264
  this.get('eventBus').on(type, priority, handler);
54235
54265
  }
54236
54266
 
54237
- /**
54238
- * @internal
54267
+ /**
54268
+ * @internal
54239
54269
  */
54240
54270
  _getSubmitData() {
54241
54271
  const formFieldRegistry = this.get('formFieldRegistry'),
@@ -54263,16 +54293,16 @@
54263
54293
  return filteredSubmitData;
54264
54294
  }
54265
54295
 
54266
- /**
54267
- * @internal
54296
+ /**
54297
+ * @internal
54268
54298
  */
54269
54299
  _applyConditions(toFilter, data) {
54270
54300
  const conditionChecker = this.get('conditionChecker');
54271
54301
  return conditionChecker.applyConditions(toFilter, data);
54272
54302
  }
54273
54303
 
54274
- /**
54275
- * @internal
54304
+ /**
54305
+ * @internal
54276
54306
  */
54277
54307
  _initializeFieldData(data) {
54278
54308
  const formFieldRegistry = this.get('formFieldRegistry'),
@@ -54586,29 +54616,6 @@
54586
54616
  return callback;
54587
54617
  }
54588
54618
 
54589
- /**
54590
- * Throttle fn, calling at most once
54591
- * in the given interval.
54592
- *
54593
- * @param {Function} fn
54594
- * @param {Number} interval
54595
- *
54596
- * @return {Function} throttled function
54597
- */
54598
- function throttle$1(fn, interval) {
54599
- let throttling = false;
54600
- return function (...args) {
54601
- if (throttling) {
54602
- return;
54603
- }
54604
- fn(...args);
54605
- throttling = true;
54606
- setTimeout(() => {
54607
- throttling = false;
54608
- }, interval);
54609
- };
54610
- }
54611
-
54612
54619
  /**
54613
54620
  * Bind function against target <this>.
54614
54621
  *
@@ -60268,10 +60275,10 @@
60268
60275
  return fn.apply(null, args);
60269
60276
  }
60270
60277
 
60271
- /**
60272
- * A factory to create a configurable debouncer.
60273
- *
60274
- * @param {number|boolean} [config=true]
60278
+ /**
60279
+ * A factory to create a configurable debouncer.
60280
+ *
60281
+ * @param {number|boolean} [config=true]
60275
60282
  */
60276
60283
  function DebounceFactory(config = true) {
60277
60284
  const timeout = typeof config === 'number' ? config : config ? 300 : 0;
@@ -60283,11 +60290,11 @@
60283
60290
  }
60284
60291
  DebounceFactory.$inject = ['config.debounce'];
60285
60292
  class FormFieldRegistry extends FormFieldRegistry$1 {
60286
- /**
60287
- * Updates a form fields id.
60288
- *
60289
- * @param {Object} formField
60290
- * @param {string} newId
60293
+ /**
60294
+ * Updates a form fields id.
60295
+ *
60296
+ * @param {Object} formField
60297
+ * @param {string} newId
60291
60298
  */
60292
60299
  updateId(formField, newId) {
60293
60300
  this._validateId(newId);
@@ -60308,13 +60315,13 @@
60308
60315
  }
60309
60316
  }
60310
60317
 
60311
- /**
60312
- * Validate the suitability of the given id and signals a problem
60313
- * with an exception.
60314
- *
60315
- * @param {string} id
60316
- *
60317
- * @throws {Error} if id is empty or already assigned
60318
+ /**
60319
+ * Validate the suitability of the given id and signals a problem
60320
+ * with an exception.
60321
+ *
60322
+ * @param {string} id
60323
+ *
60324
+ * @throws {Error} if id is empty or already assigned
60318
60325
  */
60319
60326
  _validateId(id) {
60320
60327
  if (!id) {
@@ -60330,11 +60337,11 @@
60330
60337
  const MIN_COLUMNS = 2;
60331
60338
  const MAX_FIELDS_PER_ROW = 4;
60332
60339
  class FormLayoutValidator {
60333
- /**
60334
- * @constructor
60335
- *
60336
- * @param { import('./FormLayouter').default } formLayouter
60337
- * @param { import('./FormFieldRegistry').default } formFieldRegistry
60340
+ /**
60341
+ * @constructor
60342
+ *
60343
+ * @param { import('./FormLayouter').default } formLayouter
60344
+ * @param { import('./FormFieldRegistry').default } formFieldRegistry
60338
60345
  */
60339
60346
  constructor(formLayouter, formFieldRegistry) {
60340
60347
  this._formLayouter = formLayouter;
@@ -60404,21 +60411,21 @@
60404
60411
  });
60405
60412
  }
60406
60413
 
60407
- /**
60408
- * Add a dragger that calls back the passed function with
60409
- * { event, delta } on drag.
60410
- *
60411
- * @example
60412
- *
60413
- * function dragMove(event, delta) {
60414
- * // we are dragging (!!)
60415
- * }
60416
- *
60417
- * domElement.addEventListener('dragstart', dragger(dragMove));
60418
- *
60419
- * @param {Function} fn
60420
- *
60421
- * @return {Function} drag start callback function
60414
+ /**
60415
+ * Add a dragger that calls back the passed function with
60416
+ * { event, delta } on drag.
60417
+ *
60418
+ * @example
60419
+ *
60420
+ * function dragMove(event, delta) {
60421
+ * // we are dragging (!!)
60422
+ * }
60423
+ *
60424
+ * domElement.addEventListener('dragstart', dragger(dragMove));
60425
+ *
60426
+ * @param {Function} fn
60427
+ *
60428
+ * @return {Function} drag start callback function
60422
60429
  */
60423
60430
  function createDragger$1(fn) {
60424
60431
  let self;
@@ -60459,12 +60466,12 @@
60459
60466
  return onDragStart;
60460
60467
  }
60461
60468
 
60462
- /**
60463
- * Throttle function call according UI update cycle.
60464
- *
60465
- * @param {Function} fn
60466
- *
60467
- * @return {Function} throttled fn
60469
+ /**
60470
+ * Throttle function call according UI update cycle.
60471
+ *
60472
+ * @param {Function} fn
60473
+ *
60474
+ * @return {Function} throttled fn
60468
60475
  */
60469
60476
  function throttle(fn) {
60470
60477
  let active = false;
@@ -60497,11 +60504,11 @@
60497
60504
  });
60498
60505
  var DragAndDropContext$1 = DragAndDropContext;
60499
60506
 
60500
- /**
60501
- * @param {string} type
60502
- * @param {boolean} [strict]
60503
- *
60504
- * @returns {any}
60507
+ /**
60508
+ * @param {string} type
60509
+ * @param {boolean} [strict]
60510
+ *
60511
+ * @returns {any}
60505
60512
  */
60506
60513
  function getService$1(type, strict) {}
60507
60514
  const FormEditorContext = D$2({
@@ -60902,23 +60909,23 @@
60902
60909
  return fillsAndSeparators;
60903
60910
  };
60904
60911
 
60905
- /**
60906
- * Creates a Fragment for a fill.
60907
- *
60908
- * @param {Object} fill Fill to be rendered
60909
- * @returns {Object} Preact Fragment containing fill's children
60912
+ /**
60913
+ * Creates a Fragment for a fill.
60914
+ *
60915
+ * @param {Object} fill Fill to be rendered
60916
+ * @returns {Object} Preact Fragment containing fill's children
60910
60917
  */
60911
60918
  const FillFragment = fill => e$1(d$1, {
60912
60919
  children: fill.children
60913
60920
  }, fill.id);
60914
60921
 
60915
- /**
60916
- * Creates an array of fills, with separators inserted between groups.
60917
- *
60918
- * @param {Array} groups Groups of fills
60919
- * @param {Function} fillRenderer Function to create a fill
60920
- * @param {Function} separatorRenderer Function to create a separator
60921
- * @returns {Array} Array of fills and separators
60922
+ /**
60923
+ * Creates an array of fills, with separators inserted between groups.
60924
+ *
60925
+ * @param {Array} groups Groups of fills
60926
+ * @param {Function} fillRenderer Function to create a fill
60927
+ * @param {Function} separatorRenderer Function to create a separator
60928
+ * @returns {Array} Array of fills and separators
60922
60929
  */
60923
60930
  const buildFills = (groups, fillRenderer, separatorRenderer) => {
60924
60931
  const result = [];
@@ -60936,8 +60943,8 @@
60936
60943
  return result;
60937
60944
  };
60938
60945
 
60939
- /**
60940
- * Groups fills by group name property.
60946
+ /**
60947
+ * Groups fills by group name property.
60941
60948
  */
60942
60949
  const _groupByGroupName = fills => {
60943
60950
  const groups = [];
@@ -60957,8 +60964,8 @@
60957
60964
  return Object.keys(groupsById).sort().map(id => groupsById[id]);
60958
60965
  };
60959
60966
 
60960
- /**
60961
- * Compares fills by priority.
60967
+ /**
60968
+ * Compares fills by priority.
60962
60969
  */
60963
60970
  const _comparePriority = (a, b) => {
60964
60971
  return (b.priority || 0) - (a.priority || 0);
@@ -61181,20 +61188,20 @@
61181
61188
  const DRAG_NO_MOVE_CLS = 'fjs-no-move';
61182
61189
  const ERROR_DROP_CLS = 'fjs-error-drop';
61183
61190
 
61184
- /**
61185
- * @typedef { { id: String, components: Array<any> } } FormRow
61191
+ /**
61192
+ * @typedef { { id: String, components: Array<any> } } FormRow
61186
61193
  */
61187
61194
 
61188
61195
  class Dragging {
61189
- /**
61190
- * @constructor
61191
- *
61192
- * @param { import('../../core/FormFieldRegistry').default } formFieldRegistry
61193
- * @param { import('../../core/FormLayouter').default } formLayouter
61194
- * @param { import('../../core/FormLayoutValidator').default } formLayoutValidator
61195
- * @param { import('../../core/EventBus').default } eventBus
61196
- * @param { import('../modeling/Modeling').default } modeling
61197
- * @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
61196
+ /**
61197
+ * @constructor
61198
+ *
61199
+ * @param { import('../../core/FormFieldRegistry').default } formFieldRegistry
61200
+ * @param { import('../../core/FormLayouter').default } formLayouter
61201
+ * @param { import('../../core/FormLayoutValidator').default } formLayoutValidator
61202
+ * @param { import('../../core/EventBus').default } eventBus
61203
+ * @param { import('../modeling/Modeling').default } modeling
61204
+ * @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
61198
61205
  */
61199
61206
  constructor(formFieldRegistry, formLayouter, formLayoutValidator, eventBus, modeling, pathRegistry) {
61200
61207
  this._formFieldRegistry = formFieldRegistry;
@@ -61205,13 +61212,13 @@
61205
61212
  this._pathRegistry = pathRegistry;
61206
61213
  }
61207
61214
 
61208
- /**
61209
- * Calculcates position in form schema given the dropped place.
61210
- *
61211
- * @param { FormRow } targetRow
61212
- * @param { any } targetFormField
61213
- * @param { HTMLElement } sibling
61214
- * @returns { number }
61215
+ /**
61216
+ * Calculcates position in form schema given the dropped place.
61217
+ *
61218
+ * @param { FormRow } targetRow
61219
+ * @param { any } targetFormField
61220
+ * @param { HTMLElement } sibling
61221
+ * @returns { number }
61215
61222
  */
61216
61223
  getTargetIndex(targetRow, targetFormField, sibling) {
61217
61224
  /** @type HTMLElement */
@@ -61352,8 +61359,8 @@
61352
61359
  }
61353
61360
  }
61354
61361
 
61355
- /**
61356
- * @param { { container: Array<string>, direction: string, mirrorContainer: string } } options
61362
+ /**
61363
+ * @param { { container: Array<string>, direction: string, mirrorContainer: string } } options
61357
61364
  */
61358
61365
  createDragulaInstance(options) {
61359
61366
  const {
@@ -61764,7 +61771,7 @@
61764
61771
  return null;
61765
61772
  }
61766
61773
  return e$1("div", {
61767
- 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;",
61774
+ 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;",
61768
61775
  class: "fjs-debug-columns",
61769
61776
  children: (field.layout || {}).columns || 'auto'
61770
61777
  });
@@ -62823,10 +62830,10 @@
62823
62830
  return formField;
62824
62831
  }
62825
62832
  class AddFormFieldHandler {
62826
- /**
62827
- * @constructor
62828
- * @param { import('../../../FormEditor').default } formEditor
62829
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
62833
+ /**
62834
+ * @constructor
62835
+ * @param { import('../../../FormEditor').default } formEditor
62836
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
62830
62837
  */
62831
62838
  constructor(formEditor, formFieldRegistry) {
62832
62839
  this._formEditor = formEditor;
@@ -62886,10 +62893,10 @@
62886
62893
  }
62887
62894
  AddFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
62888
62895
  class EditFormFieldHandler {
62889
- /**
62890
- * @constructor
62891
- * @param { import('../../../FormEditor').default } formEditor
62892
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
62896
+ /**
62897
+ * @constructor
62898
+ * @param { import('../../../FormEditor').default } formEditor
62899
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
62893
62900
  */
62894
62901
  constructor(formEditor, formFieldRegistry) {
62895
62902
  this._formEditor = formEditor;
@@ -62951,11 +62958,11 @@
62951
62958
  }
62952
62959
  EditFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
62953
62960
  class MoveFormFieldHandler {
62954
- /**
62955
- * @constructor
62956
- * @param { import('../../../FormEditor').default } formEditor
62957
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
62958
- * @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
62961
+ /**
62962
+ * @constructor
62963
+ * @param { import('../../../FormEditor').default } formEditor
62964
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
62965
+ * @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
62959
62966
  */
62960
62967
  constructor(formEditor, formFieldRegistry, pathRegistry) {
62961
62968
  this._formEditor = formEditor;
@@ -63059,10 +63066,10 @@
63059
63066
  }
63060
63067
  MoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry', 'pathRegistry'];
63061
63068
  class RemoveFormFieldHandler {
63062
- /**
63063
- * @constructor
63064
- * @param { import('../../../FormEditor').default } formEditor
63065
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
63069
+ /**
63070
+ * @constructor
63071
+ * @param { import('../../../FormEditor').default } formEditor
63072
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
63066
63073
  */
63067
63074
  constructor(formEditor, formFieldRegistry) {
63068
63075
  this._formEditor = formEditor;
@@ -63121,9 +63128,9 @@
63121
63128
  }
63122
63129
  RemoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
63123
63130
  class UpdateIdClaimHandler {
63124
- /**
63125
- * @constructor
63126
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
63131
+ /**
63132
+ * @constructor
63133
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
63127
63134
  */
63128
63135
  constructor(formFieldRegistry) {
63129
63136
  this._formFieldRegistry = formFieldRegistry;
@@ -63155,9 +63162,9 @@
63155
63162
  }
63156
63163
  UpdateIdClaimHandler.$inject = ['formFieldRegistry'];
63157
63164
  class UpdateKeyClaimHandler {
63158
- /**
63159
- * @constructor
63160
- * @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
63165
+ /**
63166
+ * @constructor
63167
+ * @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
63161
63168
  */
63162
63169
  constructor(pathRegistry) {
63163
63170
  this._pathRegistry = pathRegistry;
@@ -63197,9 +63204,9 @@
63197
63204
  }
63198
63205
  UpdateKeyClaimHandler.$inject = ['pathRegistry'];
63199
63206
  class UpdatePathClaimHandler {
63200
- /**
63201
- * @constructor
63202
- * @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
63207
+ /**
63208
+ * @constructor
63209
+ * @param { import('@bpmn-io/form-js-viewer').PathRegistry } pathRegistry
63203
63210
  */
63204
63211
  constructor(pathRegistry) {
63205
63212
  this._pathRegistry = pathRegistry;
@@ -63755,8 +63762,8 @@
63755
63762
  constructor(eventBus) {
63756
63763
  super(eventBus);
63757
63764
 
63758
- /**
63759
- * Remove custom validation if <validationType> is about to be added.
63765
+ /**
63766
+ * Remove custom validation if <validationType> is about to be added.
63760
63767
  */
63761
63768
  this.preExecute('formField.edit', function (context) {
63762
63769
  const {
@@ -64331,22 +64338,22 @@
64331
64338
  selectionBehavior: ['type', SelectionBehavior]
64332
64339
  };
64333
64340
 
64334
- /**
64335
- * Base class for sectionable UI modules.
64336
- *
64337
- * @property {EventBus} _eventBus - EventBus instance used for event handling.
64338
- * @property {string} managerType - Type of the render manager. Used to form event names.
64339
- *
64340
- * @class SectionModuleBase
64341
+ /**
64342
+ * Base class for sectionable UI modules.
64343
+ *
64344
+ * @property {EventBus} _eventBus - EventBus instance used for event handling.
64345
+ * @property {string} managerType - Type of the render manager. Used to form event names.
64346
+ *
64347
+ * @class SectionModuleBase
64341
64348
  */
64342
64349
  class SectionModuleBase {
64343
- /**
64344
- * Create a SectionModuleBase instance.
64345
- *
64346
- * @param {any} eventBus - The EventBus instance used for event handling.
64347
- * @param {string} sectionKey - The type of render manager. Used to form event names.
64348
- *
64349
- * @constructor
64350
+ /**
64351
+ * Create a SectionModuleBase instance.
64352
+ *
64353
+ * @param {any} eventBus - The EventBus instance used for event handling.
64354
+ * @param {string} sectionKey - The type of render manager. Used to form event names.
64355
+ *
64356
+ * @constructor
64350
64357
  */
64351
64358
  constructor(eventBus, sectionKey) {
64352
64359
  this._eventBus = eventBus;
@@ -64359,10 +64366,10 @@
64359
64366
  });
64360
64367
  }
64361
64368
 
64362
- /**
64363
- * Attach the managed section to a parent node.
64364
- *
64365
- * @param {HTMLElement} container - The parent node to attach to.
64369
+ /**
64370
+ * Attach the managed section to a parent node.
64371
+ *
64372
+ * @param {HTMLElement} container - The parent node to attach to.
64366
64373
  */
64367
64374
  attachTo(container) {
64368
64375
  this._onceSectionRendered(() => this._eventBus.fire(`${this._sectionKey}.attach`, {
@@ -64370,22 +64377,22 @@
64370
64377
  }));
64371
64378
  }
64372
64379
 
64373
- /**
64374
- * Detach the managed section from its parent node.
64380
+ /**
64381
+ * Detach the managed section from its parent node.
64375
64382
  */
64376
64383
  detach() {
64377
64384
  this._onceSectionRendered(() => this._eventBus.fire(`${this._sectionKey}.detach`));
64378
64385
  }
64379
64386
 
64380
- /**
64381
- * Reset the managed section to its initial state.
64387
+ /**
64388
+ * Reset the managed section to its initial state.
64382
64389
  */
64383
64390
  reset() {
64384
64391
  this._onceSectionRendered(() => this._eventBus.fire(`${this._sectionKey}.reset`));
64385
64392
  }
64386
64393
 
64387
- /**
64388
- * Circumvents timing issues.
64394
+ /**
64395
+ * Circumvents timing issues.
64389
64396
  */
64390
64397
  _onceSectionRendered(callback) {
64391
64398
  if (this.isSectionRendered) {
@@ -64633,18 +64640,25 @@
64633
64640
  parent
64634
64641
  } = props;
64635
64642
  const [visible, setShow] = l$2(false);
64643
+ const [focusedViaKeyboard, setFocusedViaKeyboard] = l$2(false);
64636
64644
  let timeout = null;
64637
64645
  const wrapperRef = s$1(null);
64638
64646
  const tooltipRef = s$1(null);
64639
64647
  const showTooltip = async event => {
64640
- const show = () => !visible && setShow(true);
64641
- if (event instanceof MouseEvent) {
64642
- timeout = setTimeout(show, 200);
64643
- } else {
64644
- show();
64648
+ const show = () => setShow(true);
64649
+ if (!visible && !timeout) {
64650
+ if (event instanceof MouseEvent) {
64651
+ timeout = setTimeout(show, 200);
64652
+ } else {
64653
+ show();
64654
+ setFocusedViaKeyboard(true);
64655
+ }
64645
64656
  }
64646
64657
  };
64647
- const hideTooltip = () => setShow(false);
64658
+ const hideTooltip = () => {
64659
+ setShow(false);
64660
+ setFocusedViaKeyboard(false);
64661
+ };
64648
64662
  const hideTooltipViaEscape = e => {
64649
64663
  e.code === 'Escape' && hideTooltip();
64650
64664
  };
@@ -64668,7 +64682,7 @@
64668
64682
  if (visible && !isTooltipHovered({
64669
64683
  x: e.x,
64670
64684
  y: e.y
64671
- }) && !isFocused) {
64685
+ }) && !(isFocused && focusedViaKeyboard)) {
64672
64686
  hideTooltip();
64673
64687
  }
64674
64688
  };
@@ -64676,8 +64690,8 @@
64676
64690
  const {
64677
64691
  relatedTarget
64678
64692
  } = e;
64679
- const isTooltipChild = el => el && !!el.closest('.bio-properties-panel-tooltip');
64680
- if (visible && !isHovered(wrapperRef.current) && !isTooltipChild(relatedTarget)) {
64693
+ const isTooltipChild = el => !!el.closest('.bio-properties-panel-tooltip');
64694
+ if (visible && !isHovered(wrapperRef.current) && relatedTarget && !isTooltipChild(relatedTarget)) {
64681
64695
  hideTooltip();
64682
64696
  }
64683
64697
  };
@@ -64689,7 +64703,7 @@
64689
64703
  document.removeEventListener('mousemove', hideHoveredTooltip);
64690
64704
  document.removeEventListener('focusout', hideFocusedTooltip);
64691
64705
  };
64692
- }, [wrapperRef.current, visible]);
64706
+ }, [wrapperRef.current, visible, focusedViaKeyboard]);
64693
64707
  const renderTooltip = () => {
64694
64708
  return e$1("div", {
64695
64709
  class: "bio-properties-panel-tooltip",
@@ -64712,12 +64726,12 @@
64712
64726
  tabIndex: "0",
64713
64727
  ref: wrapperRef,
64714
64728
  onMouseEnter: showTooltip,
64715
- onMouseLeave: () => clearTimeout(timeout),
64729
+ onMouseLeave: () => {
64730
+ clearTimeout(timeout);
64731
+ timeout = null;
64732
+ },
64716
64733
  onFocus: showTooltip,
64717
64734
  onKeyDown: hideTooltipViaEscape,
64718
- onMouseDown: e => {
64719
- e.preventDefault();
64720
- },
64721
64735
  children: [props.children, visible ? parent ? W(renderTooltip(), parent.current) : renderTooltip() : null]
64722
64736
  });
64723
64737
  }
@@ -64994,20 +65008,24 @@
64994
65008
 
64995
65009
  // set edited state depending on all entries
64996
65010
  y(() => {
64997
- const hasOneEditedEntry = entries.find(entry => {
64998
- const {
64999
- id,
65000
- isEdited
65001
- } = entry;
65002
- const entryNode = query(`[data-entry-id="${id}"]`);
65003
- if (!isFunction(isEdited) || !entryNode) {
65004
- return false;
65005
- }
65006
- const inputNode = query('.bio-properties-panel-input', entryNode);
65007
- return isEdited(inputNode);
65011
+ // TODO(@barmac): replace with CSS when `:has()` is supported in all major browsers, or rewrite as in https://github.com/camunda/camunda-modeler/issues/3815#issuecomment-1733038161
65012
+ const scheduled = requestAnimationFrame(() => {
65013
+ const hasOneEditedEntry = entries.find(entry => {
65014
+ const {
65015
+ id,
65016
+ isEdited
65017
+ } = entry;
65018
+ const entryNode = query(`[data-entry-id="${id}"]`);
65019
+ if (!isFunction(isEdited) || !entryNode) {
65020
+ return false;
65021
+ }
65022
+ const inputNode = query('.bio-properties-panel-input', entryNode);
65023
+ return isEdited(inputNode);
65024
+ });
65025
+ setEdited(hasOneEditedEntry);
65008
65026
  });
65009
- setEdited(hasOneEditedEntry);
65010
- }, [entries]);
65027
+ return () => cancelAnimationFrame(scheduled);
65028
+ }, [entries, setEdited]);
65011
65029
 
65012
65030
  // set error state depending on all entries
65013
65031
  const allErrors = useErrors();
@@ -65027,7 +65045,8 @@
65027
65045
  class: classNames('bio-properties-panel-group-header', edited ? '' : 'empty', open ? 'open' : '', sticky && open ? 'sticky' : ''),
65028
65046
  onClick: toggleOpen,
65029
65047
  children: [e$1("div", {
65030
- title: label,
65048
+ title: props.tooltip ? null : label,
65049
+ "data-title": label,
65031
65050
  class: "bio-properties-panel-group-header-title",
65032
65051
  children: e$1(TooltipWrapper, {
65033
65052
  value: props.tooltip,
@@ -65434,7 +65453,11 @@
65434
65453
  // (2) setup drag listeners
65435
65454
 
65436
65455
  // attach drag + cleanup event
65437
- document.addEventListener('dragover', onDrag);
65456
+ // we need to do this to make sure we track cursor
65457
+ // movements before we reach other drag event handlers,
65458
+ // e.g. in child containers.
65459
+ document.addEventListener('dragover', onDrag, true);
65460
+ document.addEventListener('dragenter', preventDefault, true);
65438
65461
  document.addEventListener('dragend', onEnd);
65439
65462
  document.addEventListener('drop', preventDefault);
65440
65463
  }
@@ -65448,7 +65471,8 @@
65448
65471
  return fn.call(self, event, delta);
65449
65472
  }
65450
65473
  function onEnd() {
65451
- document.removeEventListener('dragover', onDrag);
65474
+ document.removeEventListener('dragover', onDrag, true);
65475
+ document.removeEventListener('dragenter', preventDefault, true);
65452
65476
  document.removeEventListener('dragend', onEnd);
65453
65477
  document.removeEventListener('drop', preventDefault);
65454
65478
  }
@@ -65469,6 +65493,7 @@
65469
65493
  * @param {Object} props
65470
65494
  * @param {HTMLElement} [props.container]
65471
65495
  * @param {string} [props.className]
65496
+ * @param {boolean} [props.delayInitialFocus]
65472
65497
  * @param {{x: number, y: number}} [props.position]
65473
65498
  * @param {number} [props.width]
65474
65499
  * @param {number} [props.height]
@@ -65476,12 +65501,15 @@
65476
65501
  * @param {Function} [props.onPostActivate]
65477
65502
  * @param {Function} [props.onPostDeactivate]
65478
65503
  * @param {boolean} [props.returnFocus]
65504
+ * @param {boolean} [props.closeOnEscape]
65479
65505
  * @param {string} props.title
65506
+ * @param {Ref} [ref]
65480
65507
  */
65481
- function Popup(props) {
65508
+ function PopupComponent(props, globalRef) {
65482
65509
  const {
65483
65510
  container,
65484
65511
  className,
65512
+ delayInitialFocus,
65485
65513
  position,
65486
65514
  width,
65487
65515
  height,
@@ -65489,12 +65517,16 @@
65489
65517
  onPostActivate = noop$3,
65490
65518
  onPostDeactivate = noop$3,
65491
65519
  returnFocus = true,
65520
+ closeOnEscape = true,
65492
65521
  title
65493
65522
  } = props;
65494
65523
  const focusTrapRef = s$1(null);
65495
- const popupRef = s$1(null);
65496
- const handleKeyPress = event => {
65497
- if (event.key === 'Escape') {
65524
+ const localRef = s$1(null);
65525
+ const popupRef = globalRef || localRef;
65526
+ const handleKeydown = event => {
65527
+ // do not allow keyboard events to bubble
65528
+ event.stopPropagation();
65529
+ if (closeOnEscape && event.key === 'Escape') {
65498
65530
  onClose();
65499
65531
  }
65500
65532
  };
@@ -65519,14 +65551,6 @@
65519
65551
  if (height) {
65520
65552
  style.height = height + 'px';
65521
65553
  }
65522
- y(() => {
65523
- if (popupRef.current) {
65524
- popupRef.current.addEventListener('keydown', handleKeyPress);
65525
- }
65526
- return () => {
65527
- popupRef.current.removeEventListener('keydown', handleKeyPress);
65528
- };
65529
- }, [popupRef]);
65530
65554
  y(() => {
65531
65555
  if (popupRef.current) {
65532
65556
  popupRef.current.addEventListener('focusin', handleFocus);
@@ -65539,6 +65563,7 @@
65539
65563
  if (popupRef.current) {
65540
65564
  focusTrapRef.current = createFocusTrap(popupRef.current, {
65541
65565
  clickOutsideDeactivates: true,
65566
+ delayInitialFocus,
65542
65567
  fallbackFocus: popupRef.current,
65543
65568
  onPostActivate,
65544
65569
  onPostDeactivate,
@@ -65552,12 +65577,14 @@
65552
65577
  "aria-label": title,
65553
65578
  tabIndex: -1,
65554
65579
  ref: popupRef,
65580
+ onKeyDown: handleKeydown,
65555
65581
  role: "dialog",
65556
65582
  class: classNames('bio-properties-panel-popup', className),
65557
65583
  style: style,
65558
65584
  children: props.children
65559
65585
  }), container || document.body);
65560
65586
  }
65587
+ const Popup = x$1(PopupComponent);
65561
65588
  Popup.Title = Title;
65562
65589
  Popup.Body = Body;
65563
65590
  Popup.Footer = Footer;
@@ -65566,6 +65593,7 @@
65566
65593
  children,
65567
65594
  className,
65568
65595
  draggable,
65596
+ emit = () => {},
65569
65597
  title,
65570
65598
  ...rest
65571
65599
  } = props;
@@ -65578,7 +65606,8 @@
65578
65606
  });
65579
65607
  const dragPreviewRef = s$1();
65580
65608
  const titleRef = s$1();
65581
- const onMove = throttle$1((_, delta) => {
65609
+ const onMove = (event, delta) => {
65610
+ cancel(event);
65582
65611
  const {
65583
65612
  x: dx,
65584
65613
  y: dy
@@ -65590,20 +65619,33 @@
65590
65619
  const popupParent = getPopupParent(titleRef.current);
65591
65620
  popupParent.style.top = newPosition.y + 'px';
65592
65621
  popupParent.style.left = newPosition.x + 'px';
65593
- });
65622
+
65623
+ // notify interested parties
65624
+ emit('dragover', {
65625
+ newPosition,
65626
+ delta
65627
+ });
65628
+ };
65594
65629
  const onMoveStart = event => {
65595
65630
  // initialize drag handler
65596
65631
  const onDragStart = createDragger(onMove, dragPreviewRef.current);
65597
65632
  onDragStart(event);
65633
+ event.stopPropagation();
65598
65634
  const popupParent = getPopupParent(titleRef.current);
65599
65635
  const bounds = popupParent.getBoundingClientRect();
65600
65636
  context.current.startPosition = {
65601
65637
  x: bounds.left,
65602
65638
  y: bounds.top
65603
65639
  };
65640
+
65641
+ // notify interested parties
65642
+ emit('dragstart');
65604
65643
  };
65605
65644
  const onMoveEnd = () => {
65606
65645
  context.current.newPosition = null;
65646
+
65647
+ // notify interested parties
65648
+ emit('dragend');
65607
65649
  };
65608
65650
  return e$1("div", {
65609
65651
  class: classNames('bio-properties-panel-popup__header', draggable && 'draggable', className),
@@ -65656,26 +65698,52 @@
65656
65698
  function getPopupParent(node) {
65657
65699
  return node.closest('.bio-properties-panel-popup');
65658
65700
  }
65701
+ function cancel(event) {
65702
+ event.preventDefault();
65703
+ event.stopPropagation();
65704
+ }
65659
65705
  const FEEL_POPUP_WIDTH = 700;
65660
65706
  const FEEL_POPUP_HEIGHT = 250;
65661
65707
 
65662
65708
  /**
65663
- * FEEL popup component, built as a singleton.
65709
+ * FEEL popup component, built as a singleton. Emits lifecycle events as follows:
65710
+ * - `feelPopup.open` - fired before the popup is mounted
65711
+ * - `feelPopup.opened` - fired after the popup is mounted. Event context contains the DOM node of the popup
65712
+ * - `feelPopup.close` - fired before the popup is unmounted. Event context contains the DOM node of the popup
65713
+ * - `feelPopup.closed` - fired after the popup is unmounted
65664
65714
  */
65665
65715
  function FEELPopupRoot(props) {
65666
65716
  const {
65667
- element
65717
+ element,
65718
+ eventBus = {
65719
+ fire() {},
65720
+ on() {},
65721
+ off() {}
65722
+ },
65723
+ popupContainer
65668
65724
  } = props;
65669
65725
  const prevElement = usePrevious(element);
65670
65726
  const [popupConfig, setPopupConfig] = l$2({});
65671
65727
  const [open, setOpen] = l$2(false);
65672
65728
  const [source, setSource] = l$2(null);
65673
65729
  const [sourceElement, setSourceElement] = l$2(null);
65674
- const handleOpen = (key, config, _sourceElement) => {
65675
- setSource(key);
65730
+ const emit = (type, context) => {
65731
+ eventBus.fire('feelPopup.' + type, context);
65732
+ };
65733
+ const isOpen = A$1(() => {
65734
+ return !!open;
65735
+ }, [open]);
65736
+ useUpdateEffect(() => {
65737
+ if (!open) {
65738
+ emit('closed');
65739
+ }
65740
+ }, [open]);
65741
+ const handleOpen = (entryId, config, _sourceElement) => {
65742
+ setSource(entryId);
65676
65743
  setPopupConfig(config);
65677
65744
  setOpen(true);
65678
65745
  setSourceElement(_sourceElement);
65746
+ emit('open');
65679
65747
  };
65680
65748
  const handleClose = () => {
65681
65749
  setOpen(false);
@@ -65689,21 +65757,47 @@
65689
65757
 
65690
65758
  // close popup on element change, cf. https://github.com/bpmn-io/properties-panel/issues/270
65691
65759
  y(() => {
65692
- if (element && element !== prevElement) {
65760
+ if (element && prevElement && element !== prevElement) {
65693
65761
  handleClose();
65694
65762
  }
65695
65763
  }, [element]);
65764
+
65765
+ // allow close and open via events
65766
+ y(() => {
65767
+ const handlePopupOpen = context => {
65768
+ const {
65769
+ entryId,
65770
+ popupConfig,
65771
+ sourceElement
65772
+ } = context;
65773
+ handleOpen(entryId, popupConfig, sourceElement);
65774
+ };
65775
+ const handleIsOpen = () => {
65776
+ return isOpen();
65777
+ };
65778
+ eventBus.on('feelPopup._close', handleClose);
65779
+ eventBus.on('feelPopup._open', handlePopupOpen);
65780
+ eventBus.on('feelPopup._isOpen', handleIsOpen);
65781
+ return () => {
65782
+ eventBus.off('feelPopup._close', handleClose);
65783
+ eventBus.off('feelPopup._open', handleOpen);
65784
+ eventBus.off('feelPopup._isOpen', handleIsOpen);
65785
+ };
65786
+ }, [eventBus, isOpen]);
65696
65787
  return e$1(FeelPopupContext.Provider, {
65697
65788
  value: feelPopupContext,
65698
65789
  children: [open && e$1(FeelPopupComponent, {
65699
65790
  onClose: handleClose,
65791
+ container: popupContainer,
65700
65792
  sourceElement: sourceElement,
65793
+ emit: emit,
65701
65794
  ...popupConfig
65702
65795
  }), props.children]
65703
65796
  });
65704
65797
  }
65705
65798
  function FeelPopupComponent(props) {
65706
65799
  const {
65800
+ container,
65707
65801
  id,
65708
65802
  hostLanguage,
65709
65803
  onInput,
@@ -65715,20 +65809,45 @@
65715
65809
  tooltipContainer,
65716
65810
  type,
65717
65811
  value,
65718
- variables
65812
+ variables,
65813
+ emit
65719
65814
  } = props;
65720
65815
  const editorRef = s$1();
65816
+ const popupRef = s$1();
65817
+ const isAutoCompletionOpen = s$1(false);
65721
65818
  const handleSetReturnFocus = () => {
65722
65819
  sourceElement && sourceElement.focus();
65723
65820
  };
65724
- y(() => {
65725
- const editor = editorRef.current;
65726
- if (editor) {
65727
- editor.focus();
65821
+ const onKeyDownCapture = event => {
65822
+ // we use capture here to make sure we handle the event before the editor does
65823
+ if (event.key === 'Escape') {
65824
+ isAutoCompletionOpen.current = autoCompletionOpen(event.target);
65825
+ }
65826
+ };
65827
+ const onKeyDown = event => {
65828
+ if (event.key === 'Escape') {
65829
+ // close popup only if auto completion is not open
65830
+ // we need to do check this because the editor is not
65831
+ // stop propagating the keydown event
65832
+ // cf. https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322/5
65833
+ if (!isAutoCompletionOpen.current) {
65834
+ onClose();
65835
+ isAutoCompletionOpen.current = false;
65836
+ }
65728
65837
  }
65729
- }, [editorRef, id]);
65838
+ };
65839
+ y(() => {
65840
+ emit('opened', {
65841
+ domNode: popupRef.current
65842
+ });
65843
+ return () => emit('close', {
65844
+ domNode: popupRef.current
65845
+ });
65846
+ }, []);
65730
65847
  return e$1(Popup, {
65848
+ container: container,
65731
65849
  className: "bio-properties-panel-feel-popup",
65850
+ emit: emit,
65732
65851
  position: position,
65733
65852
  title: title,
65734
65853
  onClose: onClose
@@ -65737,14 +65856,20 @@
65737
65856
  ,
65738
65857
 
65739
65858
  returnFocus: false,
65859
+ closeOnEscape: false,
65860
+ delayInitialFocus: false,
65740
65861
  onPostDeactivate: handleSetReturnFocus,
65741
65862
  height: FEEL_POPUP_HEIGHT,
65742
65863
  width: FEEL_POPUP_WIDTH,
65864
+ ref: popupRef,
65743
65865
  children: [e$1(Popup.Title, {
65744
65866
  title: title,
65867
+ emit: emit,
65745
65868
  draggable: true
65746
65869
  }), e$1(Popup.Body, {
65747
65870
  children: e$1("div", {
65871
+ onKeyDownCapture: onKeyDownCapture,
65872
+ onKeyDown: onKeyDown,
65748
65873
  class: "bio-properties-panel-feel-popup__body",
65749
65874
  children: [type === 'feel' && e$1(CodeEditor, {
65750
65875
  enableGutters: true,
@@ -65786,6 +65911,26 @@
65786
65911
  function prefixId$8(id) {
65787
65912
  return `bio-properties-panel-${id}`;
65788
65913
  }
65914
+ function autoCompletionOpen(element) {
65915
+ return element.closest('.cm-editor').querySelector('.cm-tooltip-autocomplete');
65916
+ }
65917
+
65918
+ /**
65919
+ * This hook behaves like useEffect, but does not trigger on the first render.
65920
+ *
65921
+ * @param {Function} effect
65922
+ * @param {Array} deps
65923
+ */
65924
+ function useUpdateEffect(effect, deps) {
65925
+ const isMounted = s$1(false);
65926
+ y(() => {
65927
+ if (isMounted.current) {
65928
+ return effect();
65929
+ } else {
65930
+ isMounted.current = true;
65931
+ }
65932
+ }, deps);
65933
+ }
65789
65934
  function ToggleSwitch(props) {
65790
65935
  const {
65791
65936
  id,
@@ -66532,7 +66677,7 @@
66532
66677
  setLocalError(err);
66533
66678
  }, []);
66534
66679
  const temporaryError = useError(id);
66535
- const error = localError || temporaryError || validationError;
66680
+ const error = temporaryError || localError || validationError;
66536
66681
  return e$1("div", {
66537
66682
  class: classNames(props.class, 'bio-properties-panel-entry', error ? 'has-error' : ''),
66538
66683
  "data-entry-id": id,
@@ -66681,7 +66826,7 @@
66681
66826
 
66682
66827
  // todo(pinussilvestrus): make this configurable in the future
66683
66828
  function getPopupTitle(element, label) {
66684
- let popupTitle;
66829
+ let popupTitle = '';
66685
66830
  if (element && element.type) {
66686
66831
  popupTitle = `${element.type} / `;
66687
66832
  }
@@ -66768,6 +66913,7 @@
66768
66913
  * @param {Function} [props.descriptionLoaded]
66769
66914
  * @param {TooltipConfig} [props.tooltipConfig]
66770
66915
  * @param {Function} [props.tooltipLoaded]
66916
+ * @param {HTMLElement} [props.feelPopupContainer]
66771
66917
  * @param {Object} [props.eventBus]
66772
66918
  */
66773
66919
  function PropertiesPanel(props) {
@@ -66782,6 +66928,7 @@
66782
66928
  descriptionLoaded,
66783
66929
  tooltipConfig,
66784
66930
  tooltipLoaded,
66931
+ feelPopupContainer,
66785
66932
  eventBus
66786
66933
  } = props;
66787
66934
 
@@ -66884,6 +67031,8 @@
66884
67031
  value: eventContext,
66885
67032
  children: e$1(FEELPopupRoot, {
66886
67033
  element: element,
67034
+ eventBus: eventBus,
67035
+ popupContainer: feelPopupContainer,
66887
67036
  children: e$1("div", {
66888
67037
  class: "bio-properties-panel",
66889
67038
  children: [e$1(Header, {
@@ -67183,7 +67332,8 @@
67183
67332
  class: classNames('bio-properties-panel-group-header', hasItems ? '' : 'empty', hasItems && open ? 'open' : '', sticky && open ? 'sticky' : ''),
67184
67333
  onClick: hasItems ? toggleOpen : noop$1,
67185
67334
  children: [e$1("div", {
67186
- title: label,
67335
+ title: props.tooltip ? null : label,
67336
+ "data-title": label,
67187
67337
  class: "bio-properties-panel-group-header-title",
67188
67338
  children: e$1(TooltipWrapper, {
67189
67339
  value: props.tooltip,
@@ -67821,12 +67971,51 @@
67821
67971
  function prefixId(id) {
67822
67972
  return `bio-properties-panel-${id}`;
67823
67973
  }
67974
+ class FeelPopupModule {
67975
+ constructor(eventBus) {
67976
+ this._eventBus = eventBus;
67977
+ }
67824
67978
 
67825
- /**
67826
- * @param {string} type
67827
- * @param {boolean} [strict]
67828
- *
67829
- * @returns {any}
67979
+ /**
67980
+ * Check if the FEEL popup is open.
67981
+ * @return {Boolean}
67982
+ */
67983
+ isOpen() {
67984
+ return this._eventBus.fire('feelPopup._isOpen');
67985
+ }
67986
+
67987
+ /**
67988
+ * Open the FEEL popup.
67989
+ *
67990
+ * @param {String} entryId
67991
+ * @param {Object} popupConfig
67992
+ * @param {HTMLElement} sourceElement
67993
+ */
67994
+ open(entryId, popupConfig, sourceElement) {
67995
+ return this._eventBus.fire('feelPopup._open', {
67996
+ entryId,
67997
+ popupConfig,
67998
+ sourceElement
67999
+ });
68000
+ }
68001
+
68002
+ /**
68003
+ * Close the FEEL popup.
68004
+ */
68005
+ close() {
68006
+ return this._eventBus.fire('feelPopup._close');
68007
+ }
68008
+ }
68009
+ FeelPopupModule.$inject = ['eventBus'];
68010
+ var index = {
68011
+ feelPopup: ['type', FeelPopupModule]
68012
+ };
68013
+
68014
+ /**
68015
+ * @param {string} type
68016
+ * @param {boolean} [strict]
68017
+ *
68018
+ * @returns {any}
67830
68019
  */
67831
68020
  function getService(type, strict) {}
67832
68021
  const PropertiesPanelContext = D$2({
@@ -67921,8 +68110,8 @@
67921
68110
  }
67922
68111
  };
67923
68112
 
67924
- /**
67925
- * Provide placeholders for empty and multiple state.
68113
+ /**
68114
+ * Provide placeholders for empty and multiple state.
67926
68115
  */
67927
68116
  const PropertiesPanelPlaceholderProvider = {
67928
68117
  getEmpty: () => {
@@ -67992,10 +68181,10 @@
67992
68181
  return getService(type, strict);
67993
68182
  }
67994
68183
 
67995
- /**
67996
- * Retrieve list of variables from the form schema.
67997
- *
67998
- * @returns { string[] } list of variables used in form schema
68184
+ /**
68185
+ * Retrieve list of variables from the form schema.
68186
+ *
68187
+ * @returns { string[] } list of variables used in form schema
67999
68188
  */
68000
68189
  function useVariables() {
68001
68190
  const form = useService('formEditor');
@@ -69624,14 +69813,14 @@
69624
69813
 
69625
69814
  // helpers //////////
69626
69815
 
69627
- /**
69628
- * Returns copy of object with updated value.
69629
- *
69630
- * @param {Object} properties
69631
- * @param {string} key
69632
- * @param {string} value
69633
- *
69634
- * @returns {Object}
69816
+ /**
69817
+ * Returns copy of object with updated value.
69818
+ *
69819
+ * @param {Object} properties
69820
+ * @param {string} key
69821
+ * @param {string} value
69822
+ *
69823
+ * @returns {Object}
69635
69824
  */
69636
69825
  function updateValue(properties, key, value) {
69637
69826
  return {
@@ -69640,14 +69829,14 @@
69640
69829
  };
69641
69830
  }
69642
69831
 
69643
- /**
69644
- * Returns copy of object with updated key.
69645
- *
69646
- * @param {Object} properties
69647
- * @param {string} oldKey
69648
- * @param {string} newKey
69649
- *
69650
- * @returns {Object}
69832
+ /**
69833
+ * Returns copy of object with updated key.
69834
+ *
69835
+ * @param {Object} properties
69836
+ * @param {string} oldKey
69837
+ * @param {string} newKey
69838
+ *
69839
+ * @returns {Object}
69651
69840
  */
69652
69841
  function updateKey(properties, oldKey, newKey) {
69653
69842
  return Object.entries(properties).reduce((newProperties, entry) => {
@@ -70449,7 +70638,8 @@
70449
70638
  id,
70450
70639
  label: 'Validation pattern',
70451
70640
  setValue,
70452
- getOptions: () => Object.values(VALIDATION_TYPE_OPTIONS)
70641
+ getOptions: () => Object.values(VALIDATION_TYPE_OPTIONS),
70642
+ tooltip: getValue('validationType')() === VALIDATION_TYPE_OPTIONS.phone.value ? 'The built-in phone validation pattern is based on the E.164 standard with no spaces. Ex: +491234567890' : undefined
70453
70643
  });
70454
70644
  }
70455
70645
  function ValuesGroups(field, editField) {
@@ -70466,13 +70656,13 @@
70466
70656
  };
70467
70657
  const valuesSourceId = `${fieldId}-valuesSource`;
70468
70658
 
70469
- /**
70470
- * @type {Array<Group|ListGroup>}
70659
+ /**
70660
+ * @type {Array<Group|ListGroup>}
70471
70661
  */
70472
70662
  const groups = [{
70473
70663
  id: valuesSourceId,
70474
70664
  label: 'Options source',
70475
- tooltip: '"Static" defines a constant, predefined set of form options.\n"Dynamic" defines options that are populated dynamically, adjusting based on variable data for flexible responses to different conditions or inputs.',
70665
+ tooltip: getValuesTooltip(),
70476
70666
  component: Group,
70477
70667
  entries: ValuesSourceSelectEntry({
70478
70668
  ...context,
@@ -70516,6 +70706,12 @@
70516
70706
  }
70517
70707
  return groups;
70518
70708
  }
70709
+
70710
+ // helpers //////////
70711
+
70712
+ function getValuesTooltip() {
70713
+ return '"Static" defines a constant, predefined set of form options.\n\n' + '"Input data" defines options that are populated dynamically, adjusting based on variable data for flexible responses to different conditions or inputs.\n\n' + '"Expression" defines options that are populated from a FEEL expression.';
70714
+ }
70519
70715
  function CustomPropertiesGroup(field, editField) {
70520
70716
  const {
70521
70717
  properties = {},
@@ -70581,13 +70777,13 @@
70581
70777
 
70582
70778
  // helpers //////////
70583
70779
 
70584
- /**
70585
- * Returns copy of object without key.
70586
- *
70587
- * @param {Object} properties
70588
- * @param {string} oldKey
70589
- *
70590
- * @returns {Object}
70780
+ /**
70781
+ * Returns copy of object without key.
70782
+ *
70783
+ * @param {Object} properties
70784
+ * @param {string} oldKey
70785
+ *
70786
+ * @returns {Object}
70591
70787
  */
70592
70788
  function removeKey(properties, oldKey) {
70593
70789
  return Object.entries(properties).reduce((newProperties, entry) => {
@@ -70669,6 +70865,10 @@
70669
70865
  const formEditor = injector.get('formEditor');
70670
70866
  const modeling = injector.get('modeling');
70671
70867
  const selectionModule = injector.get('selection');
70868
+ const propertiesPanelConfig = injector.get('config.propertiesPanel') || {};
70869
+ const {
70870
+ feelPopupContainer
70871
+ } = propertiesPanelConfig;
70672
70872
  const [state, setState] = l$2({
70673
70873
  selectedFormField: selectionModule.get() || formEditor._getState().schema
70674
70874
  });
@@ -70686,9 +70886,9 @@
70686
70886
  });
70687
70887
  }, [eventBus, formEditor, selectionModule]);
70688
70888
  h$1(() => {
70689
- /**
70690
- * TODO(pinussilvestrus): update with actual updated element,
70691
- * once we have a proper updater/change support
70889
+ /**
70890
+ * TODO(pinussilvestrus): update with actual updated element,
70891
+ * once we have a proper updater/change support
70692
70892
  */
70693
70893
  eventBus.on('changed', refresh);
70694
70894
  eventBus.on('import.done', refresh);
@@ -70718,7 +70918,8 @@
70718
70918
  eventBus: eventBus,
70719
70919
  groups: getGroups(selectedFormField, editField, getService),
70720
70920
  headerProvider: PropertiesPanelHeaderProvider,
70721
- placeholderProvider: PropertiesPanelPlaceholderProvider
70921
+ placeholderProvider: PropertiesPanelPlaceholderProvider,
70922
+ feelPopupContainer: feelPopupContainer
70722
70923
  })
70723
70924
  })
70724
70925
  });
@@ -70739,10 +70940,10 @@
70739
70940
  });
70740
70941
  }
70741
70942
 
70742
- /**
70743
- * Attach the properties panel to a parent node.
70744
- *
70745
- * @param {HTMLElement} container
70943
+ /**
70944
+ * Attach the properties panel to a parent node.
70945
+ *
70946
+ * @param {HTMLElement} container
70746
70947
  */
70747
70948
  attachTo(container) {
70748
70949
  if (!container) {
@@ -70762,8 +70963,8 @@
70762
70963
  this._eventBus.fire('propertiesPanel.attach');
70763
70964
  }
70764
70965
 
70765
- /**
70766
- * Detach the properties panel from its parent node.
70966
+ /**
70967
+ * Detach the properties panel from its parent node.
70767
70968
  */
70768
70969
  detach() {
70769
70970
  const parentNode = this._container.parentNode;
@@ -70788,14 +70989,15 @@
70788
70989
  }
70789
70990
  PropertiesPanelRenderer.$inject = ['config.propertiesPanel', 'injector', 'eventBus'];
70790
70991
  var PropertiesPanelModule = {
70992
+ __depends__: [index],
70791
70993
  __init__: ['propertiesPanel'],
70792
70994
  propertiesPanel: ['type', PropertiesPanelRenderer]
70793
70995
  };
70794
70996
 
70795
- /**
70796
- * Manages the rendering of visual plugins.
70797
- * @constructor
70798
- * @param {Object} eventBus - Event bus for the application.
70997
+ /**
70998
+ * Manages the rendering of visual plugins.
70999
+ * @constructor
71000
+ * @param {Object} eventBus - Event bus for the application.
70799
71001
  */
70800
71002
  class RenderInjector extends SectionModuleBase {
70801
71003
  constructor(eventBus) {
@@ -70804,10 +71006,10 @@
70804
71006
  this.registeredRenderers = [];
70805
71007
  }
70806
71008
 
70807
- /**
70808
- * Inject a new renderer into the injector.
70809
- * @param {string} identifier - Identifier for the renderer.
70810
- * @param {Function} Renderer - The renderer function.
71009
+ /**
71010
+ * Inject a new renderer into the injector.
71011
+ * @param {string} identifier - Identifier for the renderer.
71012
+ * @param {Function} Renderer - The renderer function.
70811
71013
  */
70812
71014
  attachRenderer(identifier, Renderer) {
70813
71015
  this.registeredRenderers = [...this.registeredRenderers, {
@@ -70816,17 +71018,17 @@
70816
71018
  }];
70817
71019
  }
70818
71020
 
70819
- /**
70820
- * Detach a renderer from the by key injector.
70821
- * @param {string} identifier - Identifier for the renderer.
71021
+ /**
71022
+ * Detach a renderer from the by key injector.
71023
+ * @param {string} identifier - Identifier for the renderer.
70822
71024
  */
70823
71025
  detachRenderer(identifier) {
70824
71026
  this.registeredRenderers = this.registeredRenderers.filter(r => r.identifier !== identifier);
70825
71027
  }
70826
71028
 
70827
- /**
70828
- * Returns the registered renderers.
70829
- * @returns {Array} Array of registered renderers.
71029
+ /**
71030
+ * Returns the registered renderers.
71031
+ * @returns {Array} Array of registered renderers.
70830
71032
  */
70831
71033
  fetchRenderers() {
70832
71034
  return this.registeredRenderers;
@@ -70856,48 +71058,48 @@
70856
71058
  };
70857
71059
  const ids = new Ids([32, 36, 1]);
70858
71060
 
70859
- /**
70860
- * @typedef { import('./types').Injector } Injector
70861
- * @typedef { import('./types').Module } Module
70862
- * @typedef { import('./types').Schema } Schema
70863
- *
70864
- * @typedef { import('./types').FormEditorOptions } FormEditorOptions
70865
- * @typedef { import('./types').FormEditorProperties } FormEditorProperties
70866
- *
70867
- * @typedef { {
70868
- * properties: FormEditorProperties,
70869
- * schema: Schema
70870
- * } } State
70871
- *
70872
- * @typedef { (type:string, priority:number, handler:Function) => void } OnEventWithPriority
70873
- * @typedef { (type:string, handler:Function) => void } OnEventWithOutPriority
70874
- * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
71061
+ /**
71062
+ * @typedef { import('./types').Injector } Injector
71063
+ * @typedef { import('./types').Module } Module
71064
+ * @typedef { import('./types').Schema } Schema
71065
+ *
71066
+ * @typedef { import('./types').FormEditorOptions } FormEditorOptions
71067
+ * @typedef { import('./types').FormEditorProperties } FormEditorProperties
71068
+ *
71069
+ * @typedef { {
71070
+ * properties: FormEditorProperties,
71071
+ * schema: Schema
71072
+ * } } State
71073
+ *
71074
+ * @typedef { (type:string, priority:number, handler:Function) => void } OnEventWithPriority
71075
+ * @typedef { (type:string, handler:Function) => void } OnEventWithOutPriority
71076
+ * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
70875
71077
  */
70876
71078
 
70877
- /**
70878
- * The form editor.
71079
+ /**
71080
+ * The form editor.
70879
71081
  */
70880
71082
  class FormEditor {
70881
- /**
70882
- * @constructor
70883
- * @param {FormEditorOptions} options
71083
+ /**
71084
+ * @constructor
71085
+ * @param {FormEditorOptions} options
70884
71086
  */
70885
71087
  constructor(options = {}) {
70886
- /**
70887
- * @public
70888
- * @type {OnEventType}
71088
+ /**
71089
+ * @public
71090
+ * @type {OnEventType}
70889
71091
  */
70890
71092
  this.on = this._onEvent;
70891
71093
 
70892
- /**
70893
- * @public
70894
- * @type {String}
71094
+ /**
71095
+ * @public
71096
+ * @type {String}
70895
71097
  */
70896
71098
  this._id = ids.next();
70897
71099
 
70898
- /**
70899
- * @private
70900
- * @type {Element}
71100
+ /**
71101
+ * @private
71102
+ * @type {Element}
70901
71103
  */
70902
71104
  this._container = createFormContainer();
70903
71105
  this._container.setAttribute('input-handle-modified-keys', 'z,y');
@@ -70908,15 +71110,15 @@
70908
71110
  properties = {}
70909
71111
  } = options;
70910
71112
 
70911
- /**
70912
- * @private
70913
- * @type {any}
71113
+ /**
71114
+ * @private
71115
+ * @type {any}
70914
71116
  */
70915
71117
  this.exporter = exporter;
70916
71118
 
70917
- /**
70918
- * @private
70919
- * @type {State}
71119
+ /**
71120
+ * @private
71121
+ * @type {State}
70920
71122
  */
70921
71123
  this._state = {
70922
71124
  properties,
@@ -70945,10 +71147,10 @@
70945
71147
  this._detach(false);
70946
71148
  }
70947
71149
 
70948
- /**
70949
- * @param {Schema} schema
70950
- *
70951
- * @return {Promise<{ warnings: Array<any> }>}
71150
+ /**
71151
+ * @param {Schema} schema
71152
+ *
71153
+ * @return {Promise<{ warnings: Array<any> }>}
70952
71154
  */
70953
71155
  importSchema(schema) {
70954
71156
  return new Promise((resolve, reject) => {
@@ -70977,15 +71179,15 @@
70977
71179
  });
70978
71180
  }
70979
71181
 
70980
- /**
70981
- * @returns {Schema}
71182
+ /**
71183
+ * @returns {Schema}
70982
71184
  */
70983
71185
  saveSchema() {
70984
71186
  return this.getSchema();
70985
71187
  }
70986
71188
 
70987
- /**
70988
- * @returns {Schema}
71189
+ /**
71190
+ * @returns {Schema}
70989
71191
  */
70990
71192
  getSchema() {
70991
71193
  const {
@@ -70994,8 +71196,8 @@
70994
71196
  return exportSchema(schema, this.exporter, schemaVersion);
70995
71197
  }
70996
71198
 
70997
- /**
70998
- * @param {Element|string} parentNode
71199
+ /**
71200
+ * @param {Element|string} parentNode
70999
71201
  */
71000
71202
  attachTo(parentNode) {
71001
71203
  if (!parentNode) {
@@ -71013,10 +71215,10 @@
71013
71215
  this._detach();
71014
71216
  }
71015
71217
 
71016
- /**
71017
- * @internal
71018
- *
71019
- * @param {boolean} [emit]
71218
+ /**
71219
+ * @internal
71220
+ *
71221
+ * @param {boolean} [emit]
71020
71222
  */
71021
71223
  _detach(emit = true) {
71022
71224
  const container = this._container,
@@ -71030,9 +71232,9 @@
71030
71232
  parentNode.removeChild(container);
71031
71233
  }
71032
71234
 
71033
- /**
71034
- * @param {any} property
71035
- * @param {any} value
71235
+ /**
71236
+ * @param {any} property
71237
+ * @param {any} value
71036
71238
  */
71037
71239
  setProperty(property, value) {
71038
71240
  const properties = set$2(this._getState().properties, [property], value);
@@ -71041,21 +71243,21 @@
71041
71243
  });
71042
71244
  }
71043
71245
 
71044
- /**
71045
- * @param {string} type
71046
- * @param {Function} handler
71246
+ /**
71247
+ * @param {string} type
71248
+ * @param {Function} handler
71047
71249
  */
71048
71250
  off(type, handler) {
71049
71251
  this.get('eventBus').off(type, handler);
71050
71252
  }
71051
71253
 
71052
- /**
71053
- * @internal
71054
- *
71055
- * @param {FormEditorOptions} options
71056
- * @param {Element} container
71057
- *
71058
- * @returns {Injector}
71254
+ /**
71255
+ * @internal
71256
+ *
71257
+ * @param {FormEditorOptions} options
71258
+ * @param {Element} container
71259
+ *
71260
+ * @returns {Injector}
71059
71261
  */
71060
71262
  _createInjector(options, container) {
71061
71263
  const {
@@ -71077,22 +71279,22 @@
71077
71279
  }, core, ...modules, ...additionalModules]);
71078
71280
  }
71079
71281
 
71080
- /**
71081
- * @internal
71282
+ /**
71283
+ * @internal
71082
71284
  */
71083
71285
  _emit(type, data) {
71084
71286
  this.get('eventBus').fire(type, data);
71085
71287
  }
71086
71288
 
71087
- /**
71088
- * @internal
71289
+ /**
71290
+ * @internal
71089
71291
  */
71090
71292
  _getState() {
71091
71293
  return this._state;
71092
71294
  }
71093
71295
 
71094
- /**
71095
- * @internal
71296
+ /**
71297
+ * @internal
71096
71298
  */
71097
71299
  _setState(state) {
71098
71300
  this._state = {
@@ -71102,15 +71304,15 @@
71102
71304
  this._emit('changed', this._getState());
71103
71305
  }
71104
71306
 
71105
- /**
71106
- * @internal
71307
+ /**
71308
+ * @internal
71107
71309
  */
71108
71310
  _getModules() {
71109
71311
  return [ModelingModule, EditorActionsModule, DraggingModule, KeyboardModule, SelectionModule, PaletteModule, ExpressionLanguageModule, MarkdownModule, PropertiesPanelModule, RenderInjectionModule];
71110
71312
  }
71111
71313
 
71112
- /**
71113
- * @internal
71314
+ /**
71315
+ * @internal
71114
71316
  */
71115
71317
  _onEvent(type, priority, handler) {
71116
71318
  this.get('eventBus').on(type, priority, handler);
@@ -72613,8 +72815,8 @@
72613
72815
  return new LanguageSupport(jsonLanguage);
72614
72816
  }
72615
72817
 
72616
- /**
72617
- * @type {Facet<import('..').Variables>} Variables
72818
+ /**
72819
+ * @type {Facet<import('..').Variables>} Variables
72618
72820
  */
72619
72821
  const variablesFacet = Facet.define();
72620
72822
 
@@ -72791,11 +72993,11 @@
72791
72993
 
72792
72994
  const NO_LINT_CLS = 'fjs-no-json-lint';
72793
72995
 
72794
- /**
72795
- * @param {object} options
72796
- * @param {boolean} [options.readonly]
72797
- * @param {object} [options.contentAttributes]
72798
- * @param {string | HTMLElement} [options.placeholder]
72996
+ /**
72997
+ * @param {object} options
72998
+ * @param {boolean} [options.readonly]
72999
+ * @param {object} [options.contentAttributes]
73000
+ * @param {string | HTMLElement} [options.placeholder]
72799
73001
  */
72800
73002
  function JSONEditor(options = {}) {
72801
73003
  const {
@@ -72808,8 +73010,8 @@
72808
73010
  let tabSize = new Compartment().of(EditorState.tabSize.of(2));
72809
73011
  let container = null;
72810
73012
 
72811
- /**
72812
- * @typedef {Array<string>} Variables
73013
+ /**
73014
+ * @typedef {Array<string>} Variables
72813
73015
  */
72814
73016
 
72815
73017
  const autocompletionConf = new Compartment();
@@ -72860,8 +73062,8 @@
72860
73062
  return view.state.doc.toString();
72861
73063
  };
72862
73064
 
72863
- /**
72864
- * @param {Variables} variables
73065
+ /**
73066
+ * @param {Variables} variables
72865
73067
  */
72866
73068
  this.setVariables = function (variables) {
72867
73069
  view.setVariables(variables);
@@ -72931,7 +73133,8 @@
72931
73133
  viewerProperties = {},
72932
73134
  editorProperties = {},
72933
73135
  viewerAdditionalModules = [],
72934
- editorAdditionalModules = []
73136
+ editorAdditionalModules = [],
73137
+ propertiesPanel: propertiesPanelConfig = {}
72935
73138
  } = props;
72936
73139
  const {
72937
73140
  display: displayActions = true
@@ -73007,7 +73210,8 @@
73007
73210
  parent: paletteContainerRef.current
73008
73211
  },
73009
73212
  propertiesPanel: {
73010
- parent: propertiesPanelContainerRef.current
73213
+ parent: propertiesPanelContainerRef.current,
73214
+ ...propertiesPanelConfig
73011
73215
  },
73012
73216
  exporter: exporterConfig,
73013
73217
  properties: {