@bpmn-io/form-js-editor 0.14.0 → 0.15.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +116 -116
  3. package/dist/assets/form-js-editor-base.css +704 -489
  4. package/dist/assets/form-js-editor.css +229 -35
  5. package/dist/index.cjs +1049 -523
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.es.js +920 -394
  8. package/dist/index.es.js.map +1 -1
  9. package/dist/types/FormEditor.d.ts +9 -4
  10. package/dist/types/core/EventBus.d.ts +1 -1
  11. package/dist/types/core/FormLayoutValidator.d.ts +5 -1
  12. package/dist/types/core/index.d.ts +2 -1
  13. package/dist/types/features/dragging/Dragging.d.ts +3 -3
  14. package/dist/types/features/editor-actions/FormEditorActions.d.ts +2 -1
  15. package/dist/types/features/editor-actions/index.d.ts +1 -1
  16. package/dist/types/features/keyboard/index.d.ts +1 -1
  17. package/dist/types/features/modeling/FormLayoutUpdater.d.ts +2 -1
  18. package/dist/types/features/modeling/behavior/IdBehavior.d.ts +2 -1
  19. package/dist/types/features/modeling/behavior/KeyBehavior.d.ts +2 -1
  20. package/dist/types/features/modeling/behavior/ValidateBehavior.d.ts +2 -1
  21. package/dist/types/features/modeling/index.d.ts +6 -1
  22. package/dist/types/features/palette/PaletteRenderer.d.ts +1 -1
  23. package/dist/types/features/palette/components/Palette.d.ts +1 -1
  24. package/dist/types/features/properties-panel/PropertiesPanel.d.ts +1 -1
  25. package/dist/types/features/properties-panel/PropertiesPanelHeaderProvider.d.ts +1 -1
  26. package/dist/types/features/properties-panel/PropertiesPanelRenderer.d.ts +1 -1
  27. package/dist/types/features/properties-panel/entries/InputKeyValuesSourceEntry.d.ts +1 -1
  28. package/dist/types/render/Renderer.d.ts +1 -1
  29. package/dist/types/render/components/FieldDragPreview.d.ts +1 -1
  30. package/dist/types/render/components/FieldResizer.d.ts +1 -0
  31. package/dist/types/render/components/FormEditor.d.ts +1 -1
  32. package/dist/types/render/components/Util.d.ts +27 -1
  33. package/dist/types/render/components/editor-form-fields/EditorText.d.ts +2 -4
  34. package/dist/types/render/components/icons/index.d.ts +1 -1
  35. package/dist/types/types.d.ts +28 -28
  36. package/package.json +4 -3
  37. package/dist/types/features/properties-panel/icons/index.d.ts +0 -1
package/dist/index.cjs CHANGED
@@ -5,7 +5,7 @@ var Ids = require('ids');
5
5
  var minDash = require('min-dash');
6
6
  var classnames = require('classnames');
7
7
  var jsxRuntime = require('preact/jsx-runtime');
8
- var hooks$1 = require('preact/hooks');
8
+ var hooks = require('preact/hooks');
9
9
  var preact = require('preact');
10
10
  var React = require('preact/compat');
11
11
  var dragula = require('dragula');
@@ -19,6 +19,30 @@ var FN_REF = '__fn';
19
19
  var DEFAULT_PRIORITY$2 = 1000;
20
20
  var slice = Array.prototype.slice;
21
21
 
22
+ /**
23
+ * @typedef { {
24
+ * stopPropagation(): void;
25
+ * preventDefault(): void;
26
+ * cancelBubble: boolean;
27
+ * defaultPrevented: boolean;
28
+ * returnValue: any;
29
+ * } } Event
30
+ */
31
+
32
+ /**
33
+ * @template E
34
+ *
35
+ * @typedef { (event: E & Event, ...any) => any } EventBusEventCallback
36
+ */
37
+
38
+ /**
39
+ * @typedef { {
40
+ * priority: number;
41
+ * next: EventBusListener | null;
42
+ * callback: EventBusEventCallback<any>;
43
+ * } } EventBusListener
44
+ */
45
+
22
46
  /**
23
47
  * A general purpose event bus.
24
48
  *
@@ -103,6 +127,9 @@ var slice = Array.prototype.slice;
103
127
  * ```
104
128
  */
105
129
  function EventBus() {
130
+ /**
131
+ * @type { Record<string, EventBusListener> }
132
+ */
106
133
  this._listeners = {};
107
134
 
108
135
  // cleanup on destroy on lowest priority to allow
@@ -122,10 +149,12 @@ function EventBus() {
122
149
  *
123
150
  * Returning anything but `undefined` from a listener will stop the listener propagation.
124
151
  *
125
- * @param {string|Array<string>} events
126
- * @param {number} [priority=1000] the priority in which this listener is called, larger is higher
127
- * @param {Function} callback
128
- * @param {Object} [that] Pass context (`this`) to the callback
152
+ * @template T
153
+ *
154
+ * @param {string|string[]} events to subscribe to
155
+ * @param {number} [priority=1000] listen priority
156
+ * @param {EventBusEventCallback<T>} callback
157
+ * @param {any} [that] callback context
129
158
  */
130
159
  EventBus.prototype.on = function (events, priority, callback, that) {
131
160
  events = minDash.isArray(events) ? events : [events];
@@ -157,14 +186,16 @@ EventBus.prototype.on = function (events, priority, callback, that) {
157
186
  };
158
187
 
159
188
  /**
160
- * Register an event listener that is executed only once.
189
+ * Register an event listener that is called only once.
190
+ *
191
+ * @template T
161
192
  *
162
- * @param {string} event the event name to register for
163
- * @param {number} [priority=1000] the priority in which this listener is called, larger is higher
164
- * @param {Function} callback the callback to execute
165
- * @param {Object} [that] Pass context (`this`) to the callback
193
+ * @param {string|string[]} events to subscribe to
194
+ * @param {number} [priority=1000] the listen priority
195
+ * @param {EventBusEventCallback<T>} callback
196
+ * @param {any} [that] callback context
166
197
  */
167
- EventBus.prototype.once = function (event, priority, callback, that) {
198
+ EventBus.prototype.once = function (events, priority, callback, that) {
168
199
  var self = this;
169
200
  if (minDash.isFunction(priority)) {
170
201
  that = callback;
@@ -177,7 +208,7 @@ EventBus.prototype.once = function (event, priority, callback, that) {
177
208
  function wrappedCallback() {
178
209
  wrappedCallback.__isTomb = true;
179
210
  var result = callback.apply(that, arguments);
180
- self.off(event, wrappedCallback);
211
+ self.off(events, wrappedCallback);
181
212
  return result;
182
213
  }
183
214
 
@@ -185,7 +216,7 @@ EventBus.prototype.once = function (event, priority, callback, that) {
185
216
  // bound callbacks via {@link #off} using the original
186
217
  // callback
187
218
  wrappedCallback[FN_REF] = callback;
188
- this.on(event, priority, wrappedCallback);
219
+ this.on(events, priority, wrappedCallback);
189
220
  };
190
221
 
191
222
  /**
@@ -193,8 +224,8 @@ EventBus.prototype.once = function (event, priority, callback, that) {
193
224
  *
194
225
  * If no callback is given, all listeners for a given event name are being removed.
195
226
  *
196
- * @param {string|Array<string>} events
197
- * @param {Function} [callback]
227
+ * @param {string|string[]} events
228
+ * @param {EventBusEventCallback} [callback]
198
229
  */
199
230
  EventBus.prototype.off = function (events, callback) {
200
231
  events = minDash.isArray(events) ? events : [events];
@@ -205,11 +236,11 @@ EventBus.prototype.off = function (events, callback) {
205
236
  };
206
237
 
207
238
  /**
208
- * Create an EventBus event.
239
+ * Create an event recognized be the event bus.
209
240
  *
210
- * @param {Object} data
241
+ * @param {Object} data Event data.
211
242
  *
212
- * @return {Object} event, recognized by the eventBus
243
+ * @return {Event} An event that will be recognized by the event bus.
213
244
  */
214
245
  EventBus.prototype.createEvent = function (data) {
215
246
  var event = new InternalEvent();
@@ -218,10 +249,11 @@ EventBus.prototype.createEvent = function (data) {
218
249
  };
219
250
 
220
251
  /**
221
- * Fires a named event.
252
+ * Fires an event.
222
253
  *
223
254
  * @example
224
255
  *
256
+ * ```javascript
225
257
  * // fire event by name
226
258
  * events.fire('foo');
227
259
  *
@@ -239,13 +271,13 @@ EventBus.prototype.createEvent = function (data) {
239
271
  * });
240
272
  *
241
273
  * events.fire({ type: 'foo' }, 'I am bar!');
274
+ * ```
242
275
  *
243
- * @param {string} [name] the optional event name
244
- * @param {Object} [event] the event object
245
- * @param {...Object} additional arguments to be passed to the callback functions
276
+ * @param {string} [type] event type
277
+ * @param {Object} [data] event or event data
278
+ * @param {...any} [args] additional arguments the callback will be called with.
246
279
  *
247
- * @return {boolean} the events return value, if specified or false if the
248
- * default action was prevented by listeners
280
+ * @return {any} The return value. Will be set to `false` if the default was prevented.
249
281
  */
250
282
  EventBus.prototype.fire = function (type, data) {
251
283
  var event, firstListener, returnValue, args;
@@ -297,6 +329,14 @@ EventBus.prototype.fire = function (type, data) {
297
329
  }
298
330
  return returnValue;
299
331
  };
332
+
333
+ /**
334
+ * Handle an error by firing an event.
335
+ *
336
+ * @param {Error} error The error to be handled.
337
+ *
338
+ * @return {boolean} Whether the error was handled.
339
+ */
300
340
  EventBus.prototype.handleError = function (error) {
301
341
  return this.fire('error', {
302
342
  error: error
@@ -305,6 +345,14 @@ EventBus.prototype.handleError = function (error) {
305
345
  EventBus.prototype._destroy = function () {
306
346
  this._listeners = {};
307
347
  };
348
+
349
+ /**
350
+ * @param {Event} event
351
+ * @param {any[]} args
352
+ * @param {EventBusListener} listener
353
+ *
354
+ * @return {any}
355
+ */
308
356
  EventBus.prototype._invokeListeners = function (event, args, listener) {
309
357
  var returnValue;
310
358
  while (listener) {
@@ -317,6 +365,14 @@ EventBus.prototype._invokeListeners = function (event, args, listener) {
317
365
  }
318
366
  return returnValue;
319
367
  };
368
+
369
+ /**
370
+ * @param {Event} event
371
+ * @param {any[]} args
372
+ * @param {EventBusListener} listener
373
+ *
374
+ * @return {any}
375
+ */
320
376
  EventBus.prototype._invokeListener = function (event, args, listener) {
321
377
  var returnValue;
322
378
  if (listener.callback.__isTomb) {
@@ -345,7 +401,7 @@ EventBus.prototype._invokeListener = function (event, args, listener) {
345
401
  return returnValue;
346
402
  };
347
403
 
348
- /*
404
+ /**
349
405
  * Add new listener with a certain priority to the list
350
406
  * of listeners (for the given event).
351
407
  *
@@ -359,7 +415,7 @@ EventBus.prototype._invokeListener = function (event, args, listener) {
359
415
  * * after: [ 1500, 1500, (new=1300), 1000, 1000, (new=1000) ]
360
416
  *
361
417
  * @param {string} event
362
- * @param {Object} listener { priority, callback }
418
+ * @param {EventBusListener} listener
363
419
  */
364
420
  EventBus.prototype._addListener = function (event, newListener) {
365
421
  var listener = this._getListeners(event),
@@ -390,9 +446,20 @@ EventBus.prototype._addListener = function (event, newListener) {
390
446
  // add new listener to back
391
447
  previousListener.next = newListener;
392
448
  };
449
+
450
+ /**
451
+ * @param {string} name
452
+ *
453
+ * @return {EventBusListener}
454
+ */
393
455
  EventBus.prototype._getListeners = function (name) {
394
456
  return this._listeners[name];
395
457
  };
458
+
459
+ /**
460
+ * @param {string} name
461
+ * @param {EventBusListener} listener
462
+ */
396
463
  EventBus.prototype._setListeners = function (name, listener) {
397
464
  this._listeners[name] = listener;
398
465
  };
@@ -440,18 +507,18 @@ InternalEvent.prototype.init = function (data) {
440
507
  * Invoke function. Be fast...
441
508
  *
442
509
  * @param {Function} fn
443
- * @param {Array<Object>} args
510
+ * @param {any[]} args
444
511
  *
445
- * @return {Any}
512
+ * @return {any}
446
513
  */
447
514
  function invokeFunction(fn, args) {
448
515
  return fn.apply(null, args);
449
516
  }
450
517
 
451
- /**
452
- * A factory to create a configurable debouncer.
453
- *
454
- * @param {number|boolean} [config=true]
518
+ /**
519
+ * A factory to create a configurable debouncer.
520
+ *
521
+ * @param {number|boolean} [config=true]
455
522
  */
456
523
  function DebounceFactory(config = true) {
457
524
  const timeout = typeof config === 'number' ? config : config ? 300 : 0;
@@ -464,11 +531,11 @@ function DebounceFactory(config = true) {
464
531
  DebounceFactory.$inject = ['config.debounce'];
465
532
 
466
533
  class FieldFactory {
467
- /**
468
- * @constructor
469
- *
470
- * @param { import('./FormFieldRegistry').default } formFieldRegistry
471
- * @param { import('@bpmn-io/form-js-viewer').FormFields } formFields
534
+ /**
535
+ * @constructor
536
+ *
537
+ * @param { import('./FormFieldRegistry').default } formFieldRegistry
538
+ * @param { import('@bpmn-io/form-js-viewer').FormFields } formFields
472
539
  */
473
540
  constructor(formFieldRegistry, formFields) {
474
541
  this._formFieldRegistry = formFieldRegistry;
@@ -484,21 +551,24 @@ class FieldFactory {
484
551
  if (!fieldDefinition) {
485
552
  throw new Error(`form field of type <${type}> not supported`);
486
553
  }
554
+ const {
555
+ config
556
+ } = fieldDefinition;
487
557
  if (id && this._formFieldRegistry._ids.assigned(id)) {
488
558
  throw new Error(`ID <${id}> already assigned`);
489
559
  }
490
560
  if (key && this._formFieldRegistry._keys.assigned(key)) {
491
561
  throw new Error(`key <${key}> already assigned`);
492
562
  }
493
- const labelAttrs = applyDefaults && fieldDefinition.label ? {
494
- label: fieldDefinition.label
563
+ const labelAttrs = applyDefaults && config.label ? {
564
+ label: config.label
495
565
  } : {};
496
- const field = fieldDefinition.create({
566
+ const field = config.create({
497
567
  ...labelAttrs,
498
568
  ...attrs
499
569
  });
500
570
  this._ensureId(field);
501
- if (fieldDefinition.keyed) {
571
+ if (config.keyed) {
502
572
  this._ensureKey(field, applyDefaults);
503
573
  }
504
574
  return field;
@@ -528,11 +598,11 @@ class FieldFactory {
528
598
  FieldFactory.$inject = ['formFieldRegistry', 'formFields'];
529
599
 
530
600
  class FormFieldRegistry extends formJsViewer.FormFieldRegistry {
531
- /**
532
- * Updates a form fields id.
533
- *
534
- * @param {Object} formField
535
- * @param {string} newId
601
+ /**
602
+ * Updates a form fields id.
603
+ *
604
+ * @param {Object} formField
605
+ * @param {string} newId
536
606
  */
537
607
  updateId(formField, newId) {
538
608
  this._validateId(newId);
@@ -553,13 +623,13 @@ class FormFieldRegistry extends formJsViewer.FormFieldRegistry {
553
623
  }
554
624
  }
555
625
 
556
- /**
557
- * Validate the suitability of the given id and signals a problem
558
- * with an exception.
559
- *
560
- * @param {string} id
561
- *
562
- * @throws {Error} if id is empty or already assigned
626
+ /**
627
+ * Validate the suitability of the given id and signals a problem
628
+ * with an exception.
629
+ *
630
+ * @param {string} id
631
+ *
632
+ * @throws {Error} if id is empty or already assigned
563
633
  */
564
634
  _validateId(id) {
565
635
  if (!id) {
@@ -571,12 +641,16 @@ class FormFieldRegistry extends formJsViewer.FormFieldRegistry {
571
641
  }
572
642
  }
573
643
 
644
+ const MAX_COLUMNS_PER_ROW = 16;
645
+ const MAX_COLUMNS = 16;
646
+ const MIN_COLUMNS = 2;
647
+ const MAX_FIELDS_PER_ROW = 4;
574
648
  class FormLayoutValidator {
575
- /**
576
- * @constructor
577
- *
578
- * @param { import('./FormLayouter').default } formLayouter
579
- * @param { import('./FormFieldRegistry').default } formFieldRegistry
649
+ /**
650
+ * @constructor
651
+ *
652
+ * @param { import('./FormLayouter').default } formLayouter
653
+ * @param { import('./FormFieldRegistry').default } formFieldRegistry
580
654
  */
581
655
  constructor(formLayouter, formFieldRegistry) {
582
656
  this._formLayouter = formLayouter;
@@ -584,15 +658,15 @@ class FormLayoutValidator {
584
658
  }
585
659
  validateField(field = {}, columns, row) {
586
660
  // allow empty (auto columns)
587
- if (columns) {
588
- // allow minimum 2 cols
589
- if (columns < 2) {
590
- return 'Minimum 2 columns are allowed';
661
+ if (Number.isInteger(columns)) {
662
+ // allow minimum cols
663
+ if (columns < MIN_COLUMNS) {
664
+ return `Minimum ${MIN_COLUMNS} columns are allowed`;
591
665
  }
592
666
 
593
- // allow maximum 16 cols
594
- if (columns > 16) {
595
- return 'Maximum 16 columns are allowed';
667
+ // allow maximum cols
668
+ if (columns > MAX_COLUMNS) {
669
+ return `Maximum ${MAX_COLUMNS} columns are allowed`;
596
670
  }
597
671
  }
598
672
  if (!row) {
@@ -617,23 +691,30 @@ class FormLayoutValidator {
617
691
  });
618
692
 
619
693
  // do not allow overflows
620
- if (sumColumns > 16 || sumColumns === 16 && sumAutoCols > 0 || columns === 16 && sumFields > 1) {
621
- return 'New value exceeds the maximum of 16 columns per row';
694
+ if (sumColumns > MAX_COLUMNS_PER_ROW || sumAutoCols > 0 && sumColumns > calculateMaxColumnsWithAuto(sumAutoCols) || columns === MAX_COLUMNS_PER_ROW && sumFields > 1) {
695
+ return `New value exceeds the maximum of ${MAX_COLUMNS_PER_ROW} columns per row`;
622
696
  }
623
- if (sumFields > 4) {
624
- return 'Maximum 4 fields per row are allowed';
697
+ if (sumFields > MAX_FIELDS_PER_ROW) {
698
+ return `Maximum ${MAX_FIELDS_PER_ROW} fields per row are allowed`;
625
699
  }
626
700
  return null;
627
701
  }
628
702
  }
629
703
  FormLayoutValidator.$inject = ['formLayouter', 'formFieldRegistry'];
630
704
 
705
+ // helper //////////////////////
706
+
707
+ // on normal screen sizes, auto columns take minimum 2 columns
708
+ function calculateMaxColumnsWithAuto(autoCols) {
709
+ return MAX_COLUMNS_PER_ROW - autoCols * 2;
710
+ }
711
+
631
712
  class Importer {
632
- /**
633
- * @constructor
634
- * @param { import('../core/FormFieldRegistry').default } formFieldRegistry
635
- * @param { import('../core/FieldFactory').default } fieldFactory
636
- * @param { import('../core/FormLayouter').default } formLayouter
713
+ /**
714
+ * @constructor
715
+ * @param { import('../core/FormFieldRegistry').default } formFieldRegistry
716
+ * @param { import('../core/FieldFactory').default } fieldFactory
717
+ * @param { import('../core/FormLayouter').default } formLayouter
637
718
  */
638
719
  constructor(formFieldRegistry, fieldFactory, formLayouter) {
639
720
  this._formFieldRegistry = formFieldRegistry;
@@ -641,21 +722,21 @@ class Importer {
641
722
  this._formLayouter = formLayouter;
642
723
  }
643
724
 
644
- /**
645
- * Import schema creating rows, fields, attaching additional
646
- * information to each field and adding fields to the
647
- * field registry.
648
- *
649
- * Additional information attached:
650
- *
651
- * * `id` (unless present)
652
- * * `_parent`
653
- * * `_path`
654
- *
655
- * @param {any} schema
656
- *
657
- * @typedef {{ warnings: Error[], schema: any }} ImportResult
658
- * @returns {ImportResult}
725
+ /**
726
+ * Import schema creating rows, fields, attaching additional
727
+ * information to each field and adding fields to the
728
+ * field registry.
729
+ *
730
+ * Additional information attached:
731
+ *
732
+ * * `id` (unless present)
733
+ * * `_parent`
734
+ * * `_path`
735
+ *
736
+ * @param {any} schema
737
+ *
738
+ * @typedef {{ warnings: Error[], schema: any }} ImportResult
739
+ * @returns {ImportResult}
659
740
  */
660
741
  importSchema(schema) {
661
742
  // TODO: Add warnings
@@ -673,12 +754,12 @@ class Importer {
673
754
  }
674
755
  }
675
756
 
676
- /**
677
- * @param {{[x: string]: any}} fieldAttrs
678
- * @param {String} [parentId]
679
- * @param {number} [index]
680
- *
681
- * @return {any} field
757
+ /**
758
+ * @param {{[x: string]: any}} fieldAttrs
759
+ * @param {String} [parentId]
760
+ * @param {number} [index]
761
+ *
762
+ * @return {any} field
682
763
  */
683
764
  importFormField(fieldAttrs, parentId, index) {
684
765
  const {
@@ -715,11 +796,11 @@ class Importer {
715
796
  return field;
716
797
  }
717
798
 
718
- /**
719
- * @param {Array<any>} components
720
- * @param {string} parentId
721
- *
722
- * @return {Array<any>} imported components
799
+ /**
800
+ * @param {Array<any>} components
801
+ * @param {string} parentId
802
+ *
803
+ * @return {Array<any>} imported components
723
804
  */
724
805
  importFormFields(components, parentId) {
725
806
  return components.map((component, index) => {
@@ -744,16 +825,101 @@ function editorFormFieldClasses(type, {
744
825
  });
745
826
  }
746
827
 
828
+ /**
829
+ * Add a dragger that calls back the passed function with
830
+ * { event, delta } on drag.
831
+ *
832
+ * @example
833
+ *
834
+ * function dragMove(event, delta) {
835
+ * // we are dragging (!!)
836
+ * }
837
+ *
838
+ * domElement.addEventListener('dragstart', dragger(dragMove));
839
+ *
840
+ * @param {Function} fn
841
+ * @param {Element} dragPreview
842
+ *
843
+ * @return {Function} drag start callback function
844
+ */
845
+ function createDragger(fn, dragPreview) {
846
+ let self;
847
+ let startX, startY;
848
+
849
+ /** drag start */
850
+ function onDragStart(event) {
851
+ self = this;
852
+ startX = event.clientX;
853
+ startY = event.clientY;
854
+
855
+ // (1) prevent preview image
856
+ if (event.dataTransfer) {
857
+ event.dataTransfer.setDragImage(dragPreview, 0, 0);
858
+ }
859
+
860
+ // (2) setup drag listeners
861
+
862
+ // attach drag + cleanup event
863
+ document.addEventListener('dragover', onDrag);
864
+ document.addEventListener('dragend', onEnd);
865
+ document.addEventListener('drop', preventDefault);
866
+ }
867
+ function onDrag(event) {
868
+ const delta = {
869
+ x: event.clientX - startX,
870
+ y: event.clientY - startY
871
+ };
872
+
873
+ // call provided fn with event, delta
874
+ return fn.call(self, event, delta);
875
+ }
876
+ function onEnd() {
877
+ document.removeEventListener('dragover', onDrag);
878
+ document.removeEventListener('dragend', onEnd);
879
+ document.removeEventListener('drop', preventDefault);
880
+ }
881
+ return onDragStart;
882
+ }
883
+
884
+ /**
885
+ * Throttle function call according UI update cycle.
886
+ *
887
+ * @param {Function} fn
888
+ *
889
+ * @return {Function} throttled fn
890
+ */
891
+ function throttle(fn) {
892
+ let active = false;
893
+ let lastArgs = [];
894
+ let lastThis = undefined;
895
+ return function (...args) {
896
+ lastArgs = args;
897
+ lastThis = this;
898
+ if (active) {
899
+ return;
900
+ }
901
+ active = true;
902
+ fn.apply(lastThis, lastArgs);
903
+ window.requestAnimationFrame(function () {
904
+ lastArgs = lastThis = active = undefined;
905
+ });
906
+ };
907
+ }
908
+ function preventDefault(event) {
909
+ event.preventDefault();
910
+ event.stopPropagation();
911
+ }
912
+
747
913
  const DragAndDropContext = preact.createContext({
748
914
  drake: null
749
915
  });
750
916
  var DragAndDropContext$1 = DragAndDropContext;
751
917
 
752
- /**
753
- * @param {string} type
754
- * @param {boolean} [strict]
755
- *
756
- * @returns {any}
918
+ /**
919
+ * @param {string} type
920
+ * @param {boolean} [strict]
921
+ *
922
+ * @returns {any}
757
923
  */
758
924
  function getService$1(type, strict) {}
759
925
  const FormEditorContext = preact.createContext({
@@ -764,7 +930,7 @@ var FormEditorContext$1 = FormEditorContext;
764
930
  function useService$1 (type, strict) {
765
931
  const {
766
932
  getService
767
- } = hooks$1.useContext(FormEditorContext$1);
933
+ } = hooks.useContext(FormEditorContext$1);
768
934
  return getService(type, strict);
769
935
  }
770
936
 
@@ -784,10 +950,42 @@ var CloseIcon = (({
784
950
  })));
785
951
 
786
952
  function _extends$2() { _extends$2 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$2.apply(this, arguments); }
787
- var DraggableIcon = (({
953
+ var DeleteIcon$1 = (({
788
954
  styles = {},
789
955
  ...props
790
956
  }) => /*#__PURE__*/React.createElement("svg", _extends$2({
957
+ xmlns: "http://www.w3.org/2000/svg",
958
+ width: "16",
959
+ height: "16",
960
+ fill: "none"
961
+ }, props), /*#__PURE__*/React.createElement("rect", {
962
+ width: "16",
963
+ height: "16",
964
+ x: ".536",
965
+ fill: "#fff",
966
+ rx: "3",
967
+ style: {
968
+ mixBlendMode: "multiply"
969
+ }
970
+ }), /*#__PURE__*/React.createElement("path", {
971
+ fill: "#fff",
972
+ d: "M.536 0h16v16h-16z",
973
+ style: {
974
+ mixBlendMode: "multiply"
975
+ }
976
+ }), /*#__PURE__*/React.createElement("path", {
977
+ fill: "currentcolor",
978
+ d: "M7.536 6h-1v6h1V6zm3 0h-1v6h1V6z"
979
+ }), /*#__PURE__*/React.createElement("path", {
980
+ fill: "currentcolor",
981
+ d: "M2.536 3v1h1v10a1 1 0 001 1h8a1 1 0 001-1V4h1V3h-12zm2 11V4h8v10h-8zm6-13h-4v1h4V1z"
982
+ })));
983
+
984
+ function _extends$1() { _extends$1 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
985
+ var DraggableIcon = (({
986
+ styles = {},
987
+ ...props
988
+ }) => /*#__PURE__*/React.createElement("svg", _extends$1({
791
989
  xmlns: "http://www.w3.org/2000/svg",
792
990
  width: "16",
793
991
  height: "16",
@@ -800,11 +998,11 @@ var DraggableIcon = (({
800
998
  fill: "none"
801
999
  })));
802
1000
 
803
- function _extends$1() { _extends$1 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
1001
+ function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
804
1002
  var SearchIcon = (({
805
1003
  styles = {},
806
1004
  ...props
807
- }) => /*#__PURE__*/React.createElement("svg", _extends$1({
1005
+ }) => /*#__PURE__*/React.createElement("svg", _extends({
808
1006
  width: "15",
809
1007
  height: "15",
810
1008
  fill: "none",
@@ -860,9 +1058,7 @@ function EditorText(props) {
860
1058
  disableLinks: true
861
1059
  });
862
1060
  }
863
- EditorText.create = formJsViewer.Text.create;
864
- EditorText.type = formJsViewer.Text.type;
865
- EditorText.keyed = formJsViewer.Text.keyed;
1061
+ EditorText.config = formJsViewer.Text.config;
866
1062
 
867
1063
  const editorFormFields = [EditorText];
868
1064
 
@@ -870,28 +1066,20 @@ class EditorFormFields extends formJsViewer.FormFields {
870
1066
  constructor() {
871
1067
  super();
872
1068
  editorFormFields.forEach(formField => {
873
- this.register(formField.type, formField);
1069
+ this.register(formField.config.type, formField);
874
1070
  });
875
1071
  }
876
1072
  }
877
1073
 
878
- function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
879
- var ListDeleteIcon = (({
880
- styles = {},
881
- ...props
882
- }) => /*#__PURE__*/React.createElement("svg", _extends({
883
- xmlns: "http://www.w3.org/2000/svg",
884
- width: "11",
885
- height: "14"
886
- }, props), /*#__PURE__*/React.createElement("path", {
887
- d: "M10 4v8c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V4h9zM8 6H3v4.8c0 .66.5 1.2 1.111 1.2H6.89C7.5 12 8 11.46 8 10.8V6zm3-5H8.5l-1-1h-4l-1 1H0v1.5h11V1z"
888
- })));
889
-
890
- const PALETTE_ENTRIES = formJsViewer.formFields.filter(f => f.type !== 'default').map(f => {
1074
+ const PALETTE_ENTRIES = formJsViewer.formFields.filter(({
1075
+ config: fieldConfig
1076
+ }) => fieldConfig.type !== 'default').map(({
1077
+ config: fieldConfig
1078
+ }) => {
891
1079
  return {
892
- label: f.label,
893
- type: f.type,
894
- group: f.group
1080
+ label: fieldConfig.label,
1081
+ type: fieldConfig.type,
1082
+ group: fieldConfig.group
895
1083
  };
896
1084
  });
897
1085
  const PALETTE_GROUPS = [{
@@ -908,27 +1096,32 @@ const PALETTE_GROUPS = [{
908
1096
  id: 'action'
909
1097
  }];
910
1098
  function Palette(props) {
911
- const [entries, setEntries] = hooks$1.useState(PALETTE_ENTRIES);
912
- const [searchTerm, setSearchTerm] = hooks$1.useState('');
913
- const inputRef = hooks$1.useRef();
1099
+ const [entries, setEntries] = hooks.useState(PALETTE_ENTRIES);
1100
+ const [searchTerm, setSearchTerm] = hooks.useState('');
1101
+ const inputRef = hooks.useRef();
914
1102
  const groups = groupEntries(entries);
1103
+ const simplifyString = hooks.useCallback(str => {
1104
+ return str.toLowerCase().replace(/\s+/g, '');
1105
+ }, []);
1106
+ const filter = hooks.useCallback(entry => {
1107
+ const simplifiedSearchTerm = simplifyString(searchTerm);
1108
+ if (!simplifiedSearchTerm) {
1109
+ return true;
1110
+ }
1111
+ const simplifiedEntryLabel = simplifyString(entry.label);
1112
+ const simplifiedEntryType = simplifyString(entry.type);
1113
+ return simplifiedEntryLabel.includes(simplifiedSearchTerm) || simplifiedEntryType.includes(simplifiedSearchTerm);
1114
+ }, [searchTerm, simplifyString]);
915
1115
 
916
1116
  // filter entries on search change
917
- hooks$1.useEffect(() => {
918
- const filter = entry => {
919
- if (!searchTerm) {
920
- return true;
921
- }
922
- const search = entry.label.toLowerCase();
923
- return searchTerm.toLowerCase().split(/\s/g).every(term => search.includes(term));
924
- };
1117
+ hooks.useEffect(() => {
925
1118
  const entries = PALETTE_ENTRIES.filter(filter);
926
1119
  setEntries(entries);
927
- }, [searchTerm]);
928
- const handleInput = hooks$1.useCallback(event => {
1120
+ }, [filter, searchTerm]);
1121
+ const handleInput = hooks.useCallback(event => {
929
1122
  setSearchTerm(() => event.target.value);
930
1123
  }, [setSearchTerm]);
931
- const handleClear = hooks$1.useCallback(event => {
1124
+ const handleClear = hooks.useCallback(event => {
932
1125
  setSearchTerm('');
933
1126
  inputRef.current.focus();
934
1127
  }, [inputRef, setSearchTerm]);
@@ -1046,19 +1239,19 @@ const DRAG_NO_DROP_CLS = 'fjs-no-drop';
1046
1239
  const DRAG_NO_MOVE_CLS = 'fjs-no-move';
1047
1240
  const ERROR_DROP_CLS = 'fjs-error-drop';
1048
1241
 
1049
- /**
1050
- * @typedef { { id: String, components: Array<any> } } FormRow
1242
+ /**
1243
+ * @typedef { { id: String, components: Array<any> } } FormRow
1051
1244
  */
1052
1245
 
1053
1246
  class Dragging {
1054
- /**
1055
- * @constructor
1056
- *
1057
- * @param { import('../../core/FormFieldRegistry').default } formFieldRegistry
1058
- * @param { import('../../core/FormLayouter').default } formLayouter
1059
- * @param { import('../../core/FormLayoutValidator').default } formLayoutValidator
1060
- * @param { import('../../core/EventBus').default } eventBus
1061
- * @param { import('../modeling/Modeling').default } modeling
1247
+ /**
1248
+ * @constructor
1249
+ *
1250
+ * @param { import('../../core/FormFieldRegistry').default } formFieldRegistry
1251
+ * @param { import('../../core/FormLayouter').default } formLayouter
1252
+ * @param { import('../../core/FormLayoutValidator').default } formLayoutValidator
1253
+ * @param { import('../../core/EventBus').default } eventBus
1254
+ * @param { import('../modeling/Modeling').default } modeling
1062
1255
  */
1063
1256
  constructor(formFieldRegistry, formLayouter, formLayoutValidator, eventBus, modeling) {
1064
1257
  this._formFieldRegistry = formFieldRegistry;
@@ -1068,13 +1261,13 @@ class Dragging {
1068
1261
  this._modeling = modeling;
1069
1262
  }
1070
1263
 
1071
- /**
1072
- * Calculcates position in form schema given the dropped place.
1073
- *
1074
- * @param { FormRow } targetRow
1075
- * @param { any } targetFormField
1076
- * @param { HTMLElement } sibling
1077
- * @returns { number }
1264
+ /**
1265
+ * Calculcates position in form schema given the dropped place.
1266
+ *
1267
+ * @param { FormRow } targetRow
1268
+ * @param { any } targetFormField
1269
+ * @param { HTMLElement } sibling
1270
+ * @returns { number }
1078
1271
  */
1079
1272
  getTargetIndex(targetRow, targetFormField, sibling) {
1080
1273
  /** @type HTMLElement */
@@ -1176,8 +1369,8 @@ class Dragging {
1176
1369
  }
1177
1370
  }
1178
1371
 
1179
- /**
1180
- * @param { { container: Array<string>, direction: string, mirrorContainer: string } } options
1372
+ /**
1373
+ * @param { { container: Array<string>, direction: string, mirrorContainer: string } } options
1181
1374
  */
1182
1375
  createDragulaInstance(options) {
1183
1376
  const {
@@ -1337,6 +1530,136 @@ function FieldDragPreview(props) {
1337
1530
  });
1338
1531
  }
1339
1532
 
1533
+ const COLUMNS_REGEX = /^cds--col(-lg)?/;
1534
+ const ELEMENT_RESIZING_CLS = 'fjs-element-resizing';
1535
+ const RESIZE_DRAG_PREVIEW_CLS = 'fjs-resize-drag-preview';
1536
+ const GRID_OFFSET_PX = 16;
1537
+ function FieldResizer(props) {
1538
+ const {
1539
+ field,
1540
+ position
1541
+ } = props;
1542
+ const ref = hooks.useRef(null);
1543
+ const formLayoutValidator = useService$1('formLayoutValidator');
1544
+ const modeling = useService$1('modeling');
1545
+
1546
+ // we can't use state as we need to
1547
+ // manipulate this inside dragging events
1548
+ const context = hooks.useRef({
1549
+ startColumns: 0,
1550
+ newColumns: 0
1551
+ });
1552
+ const onResize = throttle((_, delta) => {
1553
+ const {
1554
+ x: dx
1555
+ } = delta;
1556
+ const {
1557
+ layout = {}
1558
+ } = field;
1559
+ const newColumns = calculateNewColumns(ref.current, layout.columns || context.current.startColumns, dx, position);
1560
+ const errorMessage = formLayoutValidator.validateField(field, newColumns);
1561
+ if (!errorMessage) {
1562
+ context.current.newColumns = newColumns;
1563
+
1564
+ // make visual updates to preview change
1565
+ const columnNode = ref.current.closest('.fjs-layout-column');
1566
+ removeMatching(columnNode, COLUMNS_REGEX);
1567
+ columnNode.classList.add(`cds--col-lg-${newColumns}`);
1568
+ }
1569
+ });
1570
+ const onResizeStart = event => {
1571
+ const target = getElementNode(field);
1572
+ const parent = getParent(target);
1573
+
1574
+ // create a blank element to use as drag preview
1575
+ // ensure it was only created once
1576
+ let blankPreview = getDragPreviewImage(parent);
1577
+ if (!blankPreview) {
1578
+ blankPreview = document.createElement('div');
1579
+ blankPreview.classList.add(RESIZE_DRAG_PREVIEW_CLS);
1580
+ parent.appendChild(blankPreview);
1581
+ }
1582
+
1583
+ // initialize drag handler
1584
+ const onDragStart = createDragger(onResize, blankPreview);
1585
+ onDragStart(event);
1586
+
1587
+ // mitigate auto columns on the grid that
1588
+ // has a offset of 16px (1rem) to both side
1589
+ const columnNode = getColumnNode(target);
1590
+ const startWidth = columnNode.getBoundingClientRect().width + GRID_OFFSET_PX;
1591
+ context.current.startColumns = asColumns(startWidth, parent);
1592
+ setResizing(target, position);
1593
+ };
1594
+ const onResizeEnd = () => {
1595
+ const {
1596
+ layout = {}
1597
+ } = field;
1598
+ if (context.current.newColumns) {
1599
+ modeling.editFormField(field, 'layout', {
1600
+ ...layout,
1601
+ columns: context.current.newColumns
1602
+ });
1603
+ }
1604
+ const target = getElementNode(field);
1605
+ unsetResizing(target, position);
1606
+ context.current.newColumns = null;
1607
+
1608
+ // remove blank preview
1609
+ const blankPreview = getDragPreviewImage(getParent(target));
1610
+ blankPreview.remove();
1611
+ };
1612
+ if (field.type === 'default') {
1613
+ return null;
1614
+ }
1615
+ return jsxRuntime.jsx("div", {
1616
+ ref: ref,
1617
+ class: classnames('fjs-field-resize-handle', 'fjs-field-resize-handle-' + position, DRAG_NO_MOVE_CLS),
1618
+ draggable: true,
1619
+ onDragStart: onResizeStart,
1620
+ onDragEnd: onResizeEnd
1621
+ });
1622
+ }
1623
+
1624
+ // helper //////
1625
+
1626
+ function asColumns(width, parent) {
1627
+ const totalWidth = parent.getBoundingClientRect().width;
1628
+ const oneColumn = 1 / 16 * totalWidth;
1629
+ return Math.round(width / oneColumn);
1630
+ }
1631
+ function calculateNewColumns(node, currentColumns, deltaX, position) {
1632
+ const parent = getParent(node);
1633
+
1634
+ // invert delta if we are resizing from the left
1635
+ if (position === 'left') {
1636
+ deltaX = deltaX * -1;
1637
+ }
1638
+ const deltaColumns = asColumns(deltaX, parent);
1639
+ return currentColumns + deltaColumns;
1640
+ }
1641
+ function getParent(node) {
1642
+ return node.closest('.fjs-layout-row');
1643
+ }
1644
+ function removeMatching(node, regex) {
1645
+ return minDom.classes(node).removeMatching(regex);
1646
+ }
1647
+ function getColumnNode(node) {
1648
+ return node.closest('.fjs-layout-column');
1649
+ }
1650
+ function getElementNode(field) {
1651
+ return minDom.query('.fjs-element[data-id="' + field.id + '"]');
1652
+ }
1653
+ function getDragPreviewImage(node) {
1654
+ return minDom.query('.fjs-resize-drag-preview', node);
1655
+ }
1656
+ function setResizing(node, position) {
1657
+ minDom.classes(node).add(ELEMENT_RESIZING_CLS + '-' + position);
1658
+ }
1659
+ function unsetResizing(node, position) {
1660
+ minDom.classes(node).remove(ELEMENT_RESIZING_CLS + '-' + position);
1661
+ }
1662
+
1340
1663
  function ContextPad(props) {
1341
1664
  if (!props.children) {
1342
1665
  return null;
@@ -1362,7 +1685,7 @@ function Element(props) {
1362
1685
  id,
1363
1686
  type
1364
1687
  } = field;
1365
- const ref = hooks$1.useRef();
1688
+ const ref = hooks.useRef();
1366
1689
  function scrollIntoView({
1367
1690
  selection
1368
1691
  }) {
@@ -1375,7 +1698,7 @@ function Element(props) {
1375
1698
  ref.current.scrollIntoView();
1376
1699
  }
1377
1700
  }
1378
- hooks$1.useEffect(() => {
1701
+ hooks.useEffect(() => {
1379
1702
  eventBus.on('selection.changed', scrollIntoView);
1380
1703
  return () => eventBus.off('selection.changed', scrollIntoView);
1381
1704
  }, [id]);
@@ -1408,9 +1731,15 @@ function Element(props) {
1408
1731
  children: selection.isSelected(field) && field.type !== 'default' ? jsxRuntime.jsx("button", {
1409
1732
  class: "fjs-context-pad-item",
1410
1733
  onClick: onRemove,
1411
- children: jsxRuntime.jsx(ListDeleteIcon, {})
1734
+ children: jsxRuntime.jsx(DeleteIcon$1, {})
1412
1735
  }) : null
1413
- }), props.children]
1736
+ }), props.children, jsxRuntime.jsx(FieldResizer, {
1737
+ position: "left",
1738
+ field: field
1739
+ }), jsxRuntime.jsx(FieldResizer, {
1740
+ position: "right",
1741
+ field: field
1742
+ })]
1414
1743
  });
1415
1744
  }
1416
1745
  function DebugColumns(props) {
@@ -1422,7 +1751,7 @@ function DebugColumns(props) {
1422
1751
  return null;
1423
1752
  }
1424
1753
  return jsxRuntime.jsx("div", {
1425
- 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;",
1754
+ 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;",
1426
1755
  class: "fjs-debug-columns",
1427
1756
  children: (field.layout || {}).columns || 'auto'
1428
1757
  });
@@ -1495,13 +1824,17 @@ function FormEditor$1(props) {
1495
1824
  propertiesPanel = useService$1('propertiesPanel'),
1496
1825
  propertiesPanelConfig = useService$1('config.propertiesPanel');
1497
1826
  const {
1498
- schema
1827
+ schema,
1828
+ properties
1499
1829
  } = formEditor._getState();
1500
- const formContainerRef = hooks$1.useRef(null);
1501
- const paletteRef = hooks$1.useRef(null);
1502
- const propertiesPanelRef = hooks$1.useRef(null);
1503
- const [, setSelection] = hooks$1.useState(schema);
1504
- hooks$1.useEffect(() => {
1830
+ const {
1831
+ ariaLabel
1832
+ } = properties;
1833
+ const formContainerRef = hooks.useRef(null);
1834
+ const paletteRef = hooks.useRef(null);
1835
+ const propertiesPanelRef = hooks.useRef(null);
1836
+ const [, setSelection] = hooks.useState(schema);
1837
+ hooks.useEffect(() => {
1505
1838
  function handleSelectionChanged(event) {
1506
1839
  setSelection(event.selection || schema);
1507
1840
  }
@@ -1511,11 +1844,11 @@ function FormEditor$1(props) {
1511
1844
  eventBus.off('selection.changed', handleSelectionChanged);
1512
1845
  };
1513
1846
  }, [schema, selection]);
1514
- const [drake, setDrake] = hooks$1.useState(null);
1847
+ const [drake, setDrake] = hooks.useState(null);
1515
1848
  const dragAndDropContext = {
1516
1849
  drake
1517
1850
  };
1518
- hooks$1.useEffect(() => {
1851
+ hooks.useEffect(() => {
1519
1852
  let dragulaInstance = dragging.createDragulaInstance({
1520
1853
  container: [DRAG_CONTAINER_CLS, DROP_CONTAINER_VERTICAL_CLS, DROP_CONTAINER_HORIZONTAL_CLS],
1521
1854
  direction: 'vertical',
@@ -1562,7 +1895,7 @@ function FormEditor$1(props) {
1562
1895
  }, []);
1563
1896
 
1564
1897
  // fire event after render to notify interested parties
1565
- hooks$1.useEffect(() => {
1898
+ hooks.useEffect(() => {
1566
1899
  eventBus.fire('formEditor.rendered');
1567
1900
  }, []);
1568
1901
  const formRenderContext = {
@@ -1582,6 +1915,7 @@ function FormEditor$1(props) {
1582
1915
  data: {},
1583
1916
  errors: {},
1584
1917
  properties: {
1918
+ ariaLabel,
1585
1919
  readOnly: true
1586
1920
  },
1587
1921
  schema
@@ -1593,12 +1927,12 @@ function FormEditor$1(props) {
1593
1927
  },
1594
1928
  formId: formEditor._id
1595
1929
  };
1596
- const onSubmit = hooks$1.useCallback(() => {}, []);
1597
- const onReset = hooks$1.useCallback(() => {}, []);
1930
+ const onSubmit = hooks.useCallback(() => {}, []);
1931
+ const onReset = hooks.useCallback(() => {}, []);
1598
1932
 
1599
1933
  // attach default palette
1600
1934
  const hasDefaultPalette = defaultPalette(paletteConfig);
1601
- hooks$1.useEffect(() => {
1935
+ hooks.useEffect(() => {
1602
1936
  if (hasDefaultPalette) {
1603
1937
  palette.attachTo(paletteRef.current);
1604
1938
  }
@@ -1606,7 +1940,7 @@ function FormEditor$1(props) {
1606
1940
 
1607
1941
  // attach default properties panel
1608
1942
  const hasDefaultPropertiesPanel = defaultPropertiesPanel(propertiesPanelConfig);
1609
- hooks$1.useEffect(() => {
1943
+ hooks.useEffect(() => {
1610
1944
  if (hasDefaultPropertiesPanel) {
1611
1945
  propertiesPanel.attachTo(propertiesPanelRef.current);
1612
1946
  }
@@ -1652,7 +1986,7 @@ function getFormFieldIndex(parent, formField) {
1652
1986
  function CreatePreview(props) {
1653
1987
  const {
1654
1988
  drake
1655
- } = hooks$1.useContext(DragAndDropContext$1);
1989
+ } = hooks.useContext(DragAndDropContext$1);
1656
1990
  function handleCloned(clone, original, type) {
1657
1991
  const fieldType = clone.dataset.fieldType;
1658
1992
 
@@ -1690,7 +2024,7 @@ function CreatePreview(props) {
1690
2024
  clone.classList.add('cds--grid--condensed');
1691
2025
  }
1692
2026
  }
1693
- hooks$1.useEffect(() => {
2027
+ hooks.useEffect(() => {
1694
2028
  if (!drake) {
1695
2029
  return;
1696
2030
  }
@@ -1719,7 +2053,7 @@ class Renderer {
1719
2053
  compact = false
1720
2054
  } = renderConfig;
1721
2055
  const App = () => {
1722
- const [state, setState] = hooks$1.useState(formEditor._getState());
2056
+ const [state, setState] = hooks.useState(formEditor._getState());
1723
2057
  const formEditorContext = {
1724
2058
  getService(type, strict = true) {
1725
2059
  return injector.get(type, strict);
@@ -1768,6 +2102,12 @@ var core = {
1768
2102
  fieldFactory: ['type', FieldFactory]
1769
2103
  };
1770
2104
 
2105
+ /**
2106
+ * @typedef {import('didi').Injector} Injector
2107
+ *
2108
+ * @typedef {import('../../core/EventBus').default} EventBus
2109
+ */
2110
+
1771
2111
  var NOT_REGISTERED_ERROR = 'is not a registered action',
1772
2112
  IS_REGISTERED_ERROR = 'is already registered';
1773
2113
 
@@ -1897,10 +2237,10 @@ EditorActions.prototype._registerDefaultActions = function (injector) {
1897
2237
  /**
1898
2238
  * Triggers a registered action
1899
2239
  *
1900
- * @param {string} action
1901
- * @param {Object} opts
2240
+ * @param {string} action
2241
+ * @param {Object} opts
1902
2242
  *
1903
- * @return {Unknown} Returns what the registered listener returns
2243
+ * @return {unknown} Returns what the registered listener returns
1904
2244
  */
1905
2245
  EditorActions.prototype.trigger = function (action, opts) {
1906
2246
  if (!this._actions[action]) {
@@ -1929,7 +2269,7 @@ EditorActions.prototype.trigger = function (action, opts) {
1929
2269
  * editorActions.isRegistered('spaceTool'); // true
1930
2270
  * ´´´
1931
2271
  *
1932
- * @param {Object} actions
2272
+ * @param {Object} actions
1933
2273
  */
1934
2274
  EditorActions.prototype.register = function (actions, listener) {
1935
2275
  var self = this;
@@ -1944,8 +2284,8 @@ EditorActions.prototype.register = function (actions, listener) {
1944
2284
  /**
1945
2285
  * Registers a listener to an action key
1946
2286
  *
1947
- * @param {string} action
1948
- * @param {Function} listener
2287
+ * @param {string} action
2288
+ * @param {Function} listener
1949
2289
  */
1950
2290
  EditorActions.prototype._registerAction = function (action, listener) {
1951
2291
  if (this.isRegistered(action)) {
@@ -1989,6 +2329,9 @@ function error(action, message) {
1989
2329
  return new Error(action + ' ' + message);
1990
2330
  }
1991
2331
 
2332
+ /**
2333
+ * @type { import('didi').ModuleDeclaration }
2334
+ */
1992
2335
  var EditorActionsModule$1 = {
1993
2336
  __init__: ['editorActions'],
1994
2337
  editorActions: ['type', EditorActions]
@@ -2048,10 +2391,10 @@ var DraggingModule = {
2048
2391
  dragging: ['type', Dragging]
2049
2392
  };
2050
2393
 
2051
- var KEYS_COPY = ['c', 'C', 'KeyC'];
2052
- var KEYS_PASTE = ['v', 'V', 'KeyV'];
2053
- var KEYS_REDO$1 = ['y', 'Y', 'KeyY'];
2054
- var KEYS_UNDO$1 = ['z', 'Z', 'KeyZ'];
2394
+ var KEYS_COPY = ['c', 'C'];
2395
+ var KEYS_PASTE = ['v', 'V'];
2396
+ var KEYS_REDO = ['y', 'Y'];
2397
+ var KEYS_UNDO = ['z', 'Z'];
2055
2398
 
2056
2399
  /**
2057
2400
  * Returns true if event was triggered with any modifier
@@ -2076,7 +2419,7 @@ function isCmd(event) {
2076
2419
  /**
2077
2420
  * Checks if key pressed is one of provided keys.
2078
2421
  *
2079
- * @param {string|Array<string>} keys
2422
+ * @param {string|string[]} keys
2080
2423
  * @param {KeyboardEvent} event
2081
2424
  */
2082
2425
  function isKey(keys, event) {
@@ -2097,12 +2440,16 @@ function isPaste(event) {
2097
2440
  return isCmd(event) && isKey(KEYS_PASTE, event);
2098
2441
  }
2099
2442
  function isUndo(event) {
2100
- return isCmd(event) && !isShift(event) && isKey(KEYS_UNDO$1, event);
2443
+ return isCmd(event) && !isShift(event) && isKey(KEYS_UNDO, event);
2101
2444
  }
2102
2445
  function isRedo(event) {
2103
- return isCmd(event) && (isKey(KEYS_REDO$1, event) || isKey(KEYS_UNDO$1, event) && isShift(event));
2446
+ return isCmd(event) && (isKey(KEYS_REDO, event) || isKey(KEYS_UNDO, event) && isShift(event));
2104
2447
  }
2105
2448
 
2449
+ /**
2450
+ * @typedef {import('../../core/EventBus').default} EventBus
2451
+ */
2452
+
2106
2453
  var KEYDOWN_EVENT = 'keyboard.keydown',
2107
2454
  KEYUP_EVENT = 'keyboard.keyup';
2108
2455
  var HANDLE_MODIFIER_ATTRIBUTE = 'input-handle-modified-keys';
@@ -2129,7 +2476,7 @@ var DEFAULT_PRIORITY$1 = 1000;
2129
2476
  * A default binding for the keyboard may be specified via the
2130
2477
  * `keyboard.bindTo` configuration option.
2131
2478
  *
2132
- * @param {Config} config
2479
+ * @param {Object} config
2133
2480
  * @param {EventBus} eventBus
2134
2481
  */
2135
2482
  function Keyboard(config, eventBus) {
@@ -2258,8 +2605,6 @@ function isInput(target) {
2258
2605
  }
2259
2606
 
2260
2607
  var LOW_PRIORITY$1 = 500;
2261
- var KEYS_REDO = ['y', 'Y', 'KeyY'];
2262
- var KEYS_UNDO = ['z', 'Z', 'KeyZ'];
2263
2608
 
2264
2609
  /**
2265
2610
  * Adds default keyboard bindings.
@@ -2390,6 +2735,9 @@ KeyboardBindings.prototype.registerBindings = function (keyboard, editorActions)
2390
2735
  });
2391
2736
  };
2392
2737
 
2738
+ /**
2739
+ * @type { import('didi').ModuleDeclaration }
2740
+ */
2393
2741
  var KeyboardModule$1 = {
2394
2742
  __init__: ['keyboard', 'keyboardBindings'],
2395
2743
  keyboard: ['type', Keyboard],
@@ -2469,10 +2817,10 @@ function updateRow(formField, rowId) {
2469
2817
  }
2470
2818
 
2471
2819
  class AddFormFieldHandler {
2472
- /**
2473
- * @constructor
2474
- * @param { import('../../../FormEditor').default } formEditor
2475
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
2820
+ /**
2821
+ * @constructor
2822
+ * @param { import('../../../FormEditor').default } formEditor
2823
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
2476
2824
  */
2477
2825
  constructor(formEditor, formFieldRegistry) {
2478
2826
  this._formEditor = formEditor;
@@ -2533,10 +2881,10 @@ class AddFormFieldHandler {
2533
2881
  AddFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
2534
2882
 
2535
2883
  class EditFormFieldHandler {
2536
- /**
2537
- * @constructor
2538
- * @param { import('../../../FormEditor').default } formEditor
2539
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
2884
+ /**
2885
+ * @constructor
2886
+ * @param { import('../../../FormEditor').default } formEditor
2887
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
2540
2888
  */
2541
2889
  constructor(formEditor, formFieldRegistry) {
2542
2890
  this._formEditor = formEditor;
@@ -2599,10 +2947,10 @@ class EditFormFieldHandler {
2599
2947
  EditFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
2600
2948
 
2601
2949
  class MoveFormFieldHandler {
2602
- /**
2603
- * @constructor
2604
- * @param { import('../../../FormEditor').default } formEditor
2605
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
2950
+ /**
2951
+ * @constructor
2952
+ * @param { import('../../../FormEditor').default } formEditor
2953
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
2606
2954
  */
2607
2955
  constructor(formEditor, formFieldRegistry) {
2608
2956
  this._formEditor = formEditor;
@@ -2691,10 +3039,10 @@ class MoveFormFieldHandler {
2691
3039
  MoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
2692
3040
 
2693
3041
  class RemoveFormFieldHandler {
2694
- /**
2695
- * @constructor
2696
- * @param { import('../../../FormEditor').default } formEditor
2697
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3042
+ /**
3043
+ * @constructor
3044
+ * @param { import('../../../FormEditor').default } formEditor
3045
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
2698
3046
  */
2699
3047
  constructor(formEditor, formFieldRegistry) {
2700
3048
  this._formEditor = formEditor;
@@ -2754,9 +3102,9 @@ class RemoveFormFieldHandler {
2754
3102
  RemoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
2755
3103
 
2756
3104
  class UpdateIdClaimHandler {
2757
- /**
2758
- * @constructor
2759
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3105
+ /**
3106
+ * @constructor
3107
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
2760
3108
  */
2761
3109
  constructor(formFieldRegistry) {
2762
3110
  this._formFieldRegistry = formFieldRegistry;
@@ -2789,9 +3137,9 @@ class UpdateIdClaimHandler {
2789
3137
  UpdateIdClaimHandler.$inject = ['formFieldRegistry'];
2790
3138
 
2791
3139
  class UpdateKeyClaimHandler {
2792
- /**
2793
- * @constructor
2794
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3140
+ /**
3141
+ * @constructor
3142
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
2795
3143
  */
2796
3144
  constructor(formFieldRegistry) {
2797
3145
  this._formFieldRegistry = formFieldRegistry;
@@ -2925,32 +3273,46 @@ class Modeling {
2925
3273
  }
2926
3274
  Modeling.$inject = ['commandStack', 'eventBus', 'formEditor', 'formFieldRegistry', 'fieldFactory'];
2927
3275
 
3276
+ /**
3277
+ * @typedef {import('../core/Types').ElementLike} ElementLike
3278
+ * @typedef {import('../core/EventBus').default} EventBus
3279
+ * @typedef {import('./CommandStack').CommandContext} CommandContext
3280
+ *
3281
+ * @typedef {string|string[]} Events
3282
+ * @typedef { (context: CommandContext) => ElementLike[] | void } HandlerFunction
3283
+ * @typedef { (context: CommandContext) => void } ComposeHandlerFunction
3284
+ */
3285
+
2928
3286
  var DEFAULT_PRIORITY = 1000;
2929
3287
 
2930
3288
  /**
2931
- * A utility that can be used to plug-in into the command execution for
3289
+ * A utility that can be used to plug into the command execution for
2932
3290
  * extension and/or validation.
2933
3291
  *
2934
- * @param {EventBus} eventBus
3292
+ * @class
3293
+ * @constructor
2935
3294
  *
2936
3295
  * @example
2937
3296
  *
2938
- * import inherits from 'inherits-browser';
2939
- *
3297
+ * ```javascript
2940
3298
  * import CommandInterceptor from 'diagram-js/lib/command/CommandInterceptor';
2941
3299
  *
2942
- * function CommandLogger(eventBus) {
2943
- * CommandInterceptor.call(this, eventBus);
3300
+ * class CommandLogger extends CommandInterceptor {
3301
+ * constructor(eventBus) {
3302
+ * super(eventBus);
2944
3303
  *
2945
- * this.preExecute(function(event) {
2946
- * console.log('command pre-execute', event);
3304
+ * this.preExecute('shape.create', (event) => {
3305
+ * console.log('commandStack.shape-create.preExecute', event);
2947
3306
  * });
2948
3307
  * }
3308
+ * ```
2949
3309
  *
2950
- * inherits(CommandLogger, CommandInterceptor);
2951
- *
3310
+ * @param {EventBus} eventBus
2952
3311
  */
2953
3312
  function CommandInterceptor(eventBus) {
3313
+ /**
3314
+ * @type {EventBus}
3315
+ */
2954
3316
  this._eventBus = eventBus;
2955
3317
  }
2956
3318
  CommandInterceptor.$inject = ['eventBus'];
@@ -2961,15 +3323,14 @@ function unwrapEvent(fn, that) {
2961
3323
  }
2962
3324
 
2963
3325
  /**
2964
- * Register an interceptor for a command execution
2965
- *
2966
- * @param {string|Array<string>} [events] list of commands to register on
2967
- * @param {string} [hook] command hook, i.e. preExecute, executed to listen on
2968
- * @param {number} [priority] the priority on which to hook into the execution
2969
- * @param {Function} handlerFn interceptor to be invoked with (event)
2970
- * @param {boolean} unwrap if true, unwrap the event and pass (context, command, event) to the
2971
- * listener instead
2972
- * @param {Object} [that] Pass context (`this`) to the handler function
3326
+ * Intercept a command during one of the phases.
3327
+ *
3328
+ * @param {Events} [events] command(s) to intercept
3329
+ * @param {string} [hook] phase to intercept
3330
+ * @param {number} [priority]
3331
+ * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
3332
+ * @param {boolean} [unwrap] whether the event should be unwrapped
3333
+ * @param {any} [that]
2973
3334
  */
2974
3335
  CommandInterceptor.prototype.on = function (events, hook, priority, handlerFn, unwrap, that) {
2975
3336
  if (minDash.isFunction(hook) || minDash.isNumber(hook)) {
@@ -3004,28 +3365,130 @@ CommandInterceptor.prototype.on = function (events, hook, priority, handlerFn, u
3004
3365
  eventBus.on(fullEvent, priority, unwrap ? unwrapEvent(handlerFn, that) : handlerFn, that);
3005
3366
  });
3006
3367
  };
3007
- var hooks = ['canExecute', 'preExecute', 'preExecuted', 'execute', 'executed', 'postExecute', 'postExecuted', 'revert', 'reverted'];
3368
+
3369
+ /**
3370
+ * Add a <canExecute> phase of command interceptor.
3371
+ *
3372
+ * @param {Events} [events] command(s) to intercept
3373
+ * @param {number} [priority]
3374
+ * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
3375
+ * @param {boolean} [unwrap] whether the event should be unwrapped
3376
+ * @param {any} [that]
3377
+ */
3378
+ CommandInterceptor.prototype.canExecute = createHook('canExecute');
3379
+
3380
+ /**
3381
+ * Add a <preExecute> phase of command interceptor.
3382
+ *
3383
+ * @param {Events} [events] command(s) to intercept
3384
+ * @param {number} [priority]
3385
+ * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
3386
+ * @param {boolean} [unwrap] whether the event should be unwrapped
3387
+ * @param {any} [that]
3388
+ */
3389
+ CommandInterceptor.prototype.preExecute = createHook('preExecute');
3390
+
3391
+ /**
3392
+ * Add a <preExecuted> phase of command interceptor.
3393
+ *
3394
+ * @param {Events} [events] command(s) to intercept
3395
+ * @param {number} [priority]
3396
+ * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
3397
+ * @param {boolean} [unwrap] whether the event should be unwrapped
3398
+ * @param {any} [that]
3399
+ */
3400
+ CommandInterceptor.prototype.preExecuted = createHook('preExecuted');
3401
+
3402
+ /**
3403
+ * Add a <execute> phase of command interceptor.
3404
+ *
3405
+ * @param {Events} [events] command(s) to intercept
3406
+ * @param {number} [priority]
3407
+ * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
3408
+ * @param {boolean} [unwrap] whether the event should be unwrapped
3409
+ * @param {any} [that]
3410
+ */
3411
+ CommandInterceptor.prototype.execute = createHook('execute');
3412
+
3413
+ /**
3414
+ * Add a <executed> phase of command interceptor.
3415
+ *
3416
+ * @param {Events} [events] command(s) to intercept
3417
+ * @param {number} [priority]
3418
+ * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
3419
+ * @param {boolean} [unwrap] whether the event should be unwrapped
3420
+ * @param {any} [that]
3421
+ */
3422
+ CommandInterceptor.prototype.executed = createHook('executed');
3423
+
3424
+ /**
3425
+ * Add a <postExecute> phase of command interceptor.
3426
+ *
3427
+ * @param {Events} [events] command(s) to intercept
3428
+ * @param {number} [priority]
3429
+ * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
3430
+ * @param {boolean} [unwrap] whether the event should be unwrapped
3431
+ * @param {any} [that]
3432
+ */
3433
+ CommandInterceptor.prototype.postExecute = createHook('postExecute');
3434
+
3435
+ /**
3436
+ * Add a <postExecuted> phase of command interceptor.
3437
+ *
3438
+ * @param {Events} [events] command(s) to intercept
3439
+ * @param {number} [priority]
3440
+ * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
3441
+ * @param {boolean} [unwrap] whether the event should be unwrapped
3442
+ * @param {any} [that]
3443
+ */
3444
+ CommandInterceptor.prototype.postExecuted = createHook('postExecuted');
3445
+
3446
+ /**
3447
+ * Add a <revert> phase of command interceptor.
3448
+ *
3449
+ * @param {Events} [events] command(s) to intercept
3450
+ * @param {number} [priority]
3451
+ * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
3452
+ * @param {boolean} [unwrap] whether the event should be unwrapped
3453
+ * @param {any} [that]
3454
+ */
3455
+ CommandInterceptor.prototype.revert = createHook('revert');
3456
+
3457
+ /**
3458
+ * Add a <reverted> phase of command interceptor.
3459
+ *
3460
+ * @param {Events} [events] command(s) to intercept
3461
+ * @param {number} [priority]
3462
+ * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
3463
+ * @param {boolean} [unwrap] whether the event should be unwrapped
3464
+ * @param {any} [that]
3465
+ */
3466
+ CommandInterceptor.prototype.reverted = createHook('reverted');
3008
3467
 
3009
3468
  /*
3010
- * Install hook shortcuts
3469
+ * Add prototype methods for each phase of command execution (e.g. execute,
3470
+ * revert).
3011
3471
  *
3012
- * This will generate the CommandInterceptor#(preExecute|...|reverted) methods
3013
- * which will in term forward to CommandInterceptor#on.
3472
+ * @param {string} hook
3473
+ *
3474
+ * @return { (
3475
+ * events?: Events,
3476
+ * priority?: number,
3477
+ * handlerFn: ComposeHandlerFunction|HandlerFunction,
3478
+ * unwrap?: boolean
3479
+ * ) => any }
3014
3480
  */
3015
- minDash.forEach(hooks, function (hook) {
3481
+ function createHook(hook) {
3016
3482
  /**
3017
- * {canExecute|preExecute|preExecuted|execute|executed|postExecute|postExecuted|revert|reverted}
3018
- *
3019
- * A named hook for plugging into the command execution
3483
+ * @this {CommandInterceptor}
3020
3484
  *
3021
- * @param {string|Array<string>} [events] list of commands to register on
3022
- * @param {number} [priority] the priority on which to hook into the execution
3023
- * @param {Function} handlerFn interceptor to be invoked with (event)
3024
- * @param {boolean} [unwrap=false] if true, unwrap the event and pass (context, command, event) to the
3025
- * listener instead
3026
- * @param {Object} [that] Pass context (`this`) to the handler function
3485
+ * @param {Events} [events]
3486
+ * @param {number} [priority]
3487
+ * @param {ComposeHandlerFunction|HandlerFunction} handlerFn
3488
+ * @param {boolean} [unwrap]
3489
+ * @param {any} [that]
3027
3490
  */
3028
- CommandInterceptor.prototype[hook] = function (events, priority, handlerFn, unwrap, that) {
3491
+ const hookFn = function (events, priority, handlerFn, unwrap, that) {
3029
3492
  if (minDash.isFunction(events) || minDash.isNumber(events)) {
3030
3493
  that = unwrap;
3031
3494
  unwrap = handlerFn;
@@ -3035,7 +3498,8 @@ minDash.forEach(hooks, function (hook) {
3035
3498
  }
3036
3499
  this.on(events, hook, priority, handlerFn, unwrap, that);
3037
3500
  };
3038
- });
3501
+ return hookFn;
3502
+ }
3039
3503
 
3040
3504
  class FormLayoutUpdater extends CommandInterceptor {
3041
3505
  constructor(eventBus, formLayouter, modeling, formEditor) {
@@ -3141,8 +3605,8 @@ class ValidateBehavior extends CommandInterceptor {
3141
3605
  constructor(eventBus) {
3142
3606
  super(eventBus);
3143
3607
 
3144
- /**
3145
- * Remove custom validation if <validationType> is about to be added.
3608
+ /**
3609
+ * Remove custom validation if <validationType> is about to be added.
3146
3610
  */
3147
3611
  // @ts-ignore-next-line
3148
3612
  this.preExecute('formField.edit', function (context) {
@@ -3173,6 +3637,34 @@ var behaviorModule = {
3173
3637
  validateBehavior: ['type', ValidateBehavior]
3174
3638
  };
3175
3639
 
3640
+ /**
3641
+ * @typedef {import('didi').Injector} Injector
3642
+ *
3643
+ * @typedef {import('../core/Types').ElementLike} ElementLike
3644
+ *
3645
+ * @typedef {import('../core/EventBus').default} EventBus
3646
+ * @typedef {import('./CommandHandler').default} CommandHandler
3647
+ *
3648
+ * @typedef { any } CommandContext
3649
+ * @typedef { {
3650
+ * new (...args: any[]) : CommandHandler
3651
+ * } } CommandHandlerConstructor
3652
+ * @typedef { {
3653
+ * [key: string]: CommandHandler;
3654
+ * } } CommandHandlerMap
3655
+ * @typedef { {
3656
+ * command: string;
3657
+ * context: any;
3658
+ * id?: any;
3659
+ * } } CommandStackAction
3660
+ * @typedef { {
3661
+ * actions: CommandStackAction[];
3662
+ * dirty: ElementLike[];
3663
+ * trigger: 'execute' | 'undo' | 'redo' | 'clear' | null;
3664
+ * atomic?: boolean;
3665
+ * } } CurrentExecution
3666
+ */
3667
+
3176
3668
  /**
3177
3669
  * A service that offers un- and redoable execution of commands.
3178
3670
  *
@@ -3223,7 +3715,7 @@ var behaviorModule = {
3223
3715
  * got changed during the `execute` and `revert` operations.
3224
3716
  *
3225
3717
  * Command handlers may execute other modeling operations (and thus
3226
- * commands) in their `preExecute` and `postExecute` phases. The command
3718
+ * commands) in their `preExecute(d)` and `postExecute(d)` phases. The command
3227
3719
  * stack will properly group all commands together into a logical unit
3228
3720
  * that may be re- and undone atomically.
3229
3721
  *
@@ -3253,14 +3745,14 @@ function CommandStack(eventBus, injector) {
3253
3745
  /**
3254
3746
  * A map of all registered command handlers.
3255
3747
  *
3256
- * @type {Object}
3748
+ * @type {CommandHandlerMap}
3257
3749
  */
3258
3750
  this._handlerMap = {};
3259
3751
 
3260
3752
  /**
3261
3753
  * A stack containing all re/undoable actions on the diagram
3262
3754
  *
3263
- * @type {Array<Object>}
3755
+ * @type {CommandStackAction[]}
3264
3756
  */
3265
3757
  this._stack = [];
3266
3758
 
@@ -3274,18 +3766,27 @@ function CommandStack(eventBus, injector) {
3274
3766
  /**
3275
3767
  * Current active commandStack execution
3276
3768
  *
3277
- * @type {Object}
3278
- * @property {Object[]} actions
3279
- * @property {Object[]} dirty
3280
- * @property { 'undo' | 'redo' | 'clear' | 'execute' | null } trigger the cause of the current excecution
3769
+ * @type {CurrentExecution}
3281
3770
  */
3282
3771
  this._currentExecution = {
3283
3772
  actions: [],
3284
3773
  dirty: [],
3285
3774
  trigger: null
3286
3775
  };
3776
+
3777
+ /**
3778
+ * @type {Injector}
3779
+ */
3287
3780
  this._injector = injector;
3781
+
3782
+ /**
3783
+ * @type EventBus
3784
+ */
3288
3785
  this._eventBus = eventBus;
3786
+
3787
+ /**
3788
+ * @type { number }
3789
+ */
3289
3790
  this._uid = 1;
3290
3791
  eventBus.on(['diagram.destroy', 'diagram.clear'], function () {
3291
3792
  this.clear(false);
@@ -3294,10 +3795,10 @@ function CommandStack(eventBus, injector) {
3294
3795
  CommandStack.$inject = ['eventBus', 'injector'];
3295
3796
 
3296
3797
  /**
3297
- * Execute a command
3798
+ * Execute a command.
3298
3799
  *
3299
- * @param {string} command the command to execute
3300
- * @param {Object} context the environment to execute the command in
3800
+ * @param {string} command The command to execute.
3801
+ * @param {CommandContext} context The context with which to execute the command.
3301
3802
  */
3302
3803
  CommandStack.prototype.execute = function (command, context) {
3303
3804
  if (!command) {
@@ -3310,11 +3811,11 @@ CommandStack.prototype.execute = function (command, context) {
3310
3811
  };
3311
3812
  this._pushAction(action);
3312
3813
  this._internalExecute(action);
3313
- this._popAction(action);
3814
+ this._popAction();
3314
3815
  };
3315
3816
 
3316
3817
  /**
3317
- * Ask whether a given command can be executed.
3818
+ * Check whether a command can be executed.
3318
3819
  *
3319
3820
  * Implementors may hook into the mechanism on two ways:
3320
3821
  *
@@ -3328,10 +3829,10 @@ CommandStack.prototype.execute = function (command, context) {
3328
3829
  * If the method {@link CommandHandler#canExecute} is implemented in a handler
3329
3830
  * it will be called to figure out whether the execution is allowed.
3330
3831
  *
3331
- * @param {string} command the command to execute
3332
- * @param {Object} context the environment to execute the command in
3832
+ * @param {string} command The command to execute.
3833
+ * @param {CommandContext} context The context with which to execute the command.
3333
3834
  *
3334
- * @return {boolean} true if the command can be executed
3835
+ * @return {boolean} Whether the command can be executed with the given context.
3335
3836
  */
3336
3837
  CommandStack.prototype.canExecute = function (command, context) {
3337
3838
  const action = {
@@ -3355,7 +3856,9 @@ CommandStack.prototype.canExecute = function (command, context) {
3355
3856
  };
3356
3857
 
3357
3858
  /**
3358
- * Clear the command stack, erasing all undo / redo history
3859
+ * Clear the command stack, erasing all undo / redo history.
3860
+ *
3861
+ * @param {boolean} [emit=true] Whether to fire an event. Defaults to `true`.
3359
3862
  */
3360
3863
  CommandStack.prototype.clear = function (emit) {
3361
3864
  this._stack.length = 0;
@@ -3410,21 +3913,21 @@ CommandStack.prototype.redo = function () {
3410
3913
  };
3411
3914
 
3412
3915
  /**
3413
- * Register a handler instance with the command stack
3916
+ * Register a handler instance with the command stack.
3414
3917
  *
3415
- * @param {string} command
3416
- * @param {CommandHandler} handler
3918
+ * @param {string} command Command to be executed.
3919
+ * @param {CommandHandler} handler Handler to execute the command.
3417
3920
  */
3418
3921
  CommandStack.prototype.register = function (command, handler) {
3419
3922
  this._setHandler(command, handler);
3420
3923
  };
3421
3924
 
3422
3925
  /**
3423
- * Register a handler type with the command stack
3424
- * by instantiating it and injecting its dependencies.
3926
+ * Register a handler type with the command stack by instantiating it and
3927
+ * injecting its dependencies.
3425
3928
  *
3426
- * @param {string} command
3427
- * @param {Function} a constructor for a {@link CommandHandler}
3929
+ * @param {string} command Command to be executed.
3930
+ * @param {CommandHandlerConstructor} handlerCls Constructor to instantiate a {@link CommandHandler}.
3428
3931
  */
3429
3932
  CommandStack.prototype.registerHandler = function (command, handlerCls) {
3430
3933
  if (!command || !handlerCls) {
@@ -3433,9 +3936,17 @@ CommandStack.prototype.registerHandler = function (command, handlerCls) {
3433
3936
  const handler = this._injector.instantiate(handlerCls);
3434
3937
  this.register(command, handler);
3435
3938
  };
3939
+
3940
+ /**
3941
+ * @return {boolean}
3942
+ */
3436
3943
  CommandStack.prototype.canUndo = function () {
3437
3944
  return !!this._getUndoAction();
3438
3945
  };
3946
+
3947
+ /**
3948
+ * @return {boolean}
3949
+ */
3439
3950
  CommandStack.prototype.canRedo = function () {
3440
3951
  return !!this._getRedoAction();
3441
3952
  };
@@ -3529,7 +4040,7 @@ CommandStack.prototype._internalExecute = function (action, redo) {
3529
4040
  }
3530
4041
  this._fire(command, 'postExecuted', action);
3531
4042
  }
3532
- this._popAction(action);
4043
+ this._popAction();
3533
4044
  };
3534
4045
  CommandStack.prototype._pushAction = function (action) {
3535
4046
  const execution = this._currentExecution,
@@ -3590,6 +4101,9 @@ CommandStack.prototype._setHandler = function (command, handler) {
3590
4101
  this._handlerMap[command] = handler;
3591
4102
  };
3592
4103
 
4104
+ /**
4105
+ * @type { import('didi').ModuleDeclaration }
4106
+ */
3593
4107
  var commandModule = {
3594
4108
  commandStack: ['type', CommandStack]
3595
4109
  };
@@ -3687,10 +4201,10 @@ class PaletteRenderer {
3687
4201
  });
3688
4202
  }
3689
4203
 
3690
- /**
3691
- * Attach the palette to a parent node.
3692
- *
3693
- * @param {HTMLElement} container
4204
+ /**
4205
+ * Attach the palette to a parent node.
4206
+ *
4207
+ * @param {HTMLElement} container
3694
4208
  */
3695
4209
  attachTo(container) {
3696
4210
  if (!container) {
@@ -3710,8 +4224,8 @@ class PaletteRenderer {
3710
4224
  this._eventBus.fire('palette.attach');
3711
4225
  }
3712
4226
 
3713
- /**
3714
- * Detach the palette from its parent node.
4227
+ /**
4228
+ * Detach the palette from its parent node.
3715
4229
  */
3716
4230
  detach() {
3717
4231
  const parentNode = this._container.parentNode;
@@ -3935,13 +4449,13 @@ const LayoutContext = preact.createContext({
3935
4449
  function useDescriptionContext(id, element) {
3936
4450
  const {
3937
4451
  getDescriptionForId
3938
- } = hooks$1.useContext(DescriptionContext);
4452
+ } = hooks.useContext(DescriptionContext);
3939
4453
  return getDescriptionForId(id, element);
3940
4454
  }
3941
4455
  function useError(id) {
3942
4456
  const {
3943
4457
  errors
3944
- } = hooks$1.useContext(ErrorsContext);
4458
+ } = hooks.useContext(ErrorsContext);
3945
4459
  return errors[id];
3946
4460
  }
3947
4461
 
@@ -3952,13 +4466,13 @@ function useError(id) {
3952
4466
  * @param {Function} callback
3953
4467
  */
3954
4468
  function useEvent(event, callback, eventBus) {
3955
- const eventContext = hooks$1.useContext(EventContext);
4469
+ const eventContext = hooks.useContext(EventContext);
3956
4470
  if (!eventBus) {
3957
4471
  ({
3958
4472
  eventBus
3959
4473
  } = eventContext);
3960
4474
  }
3961
- const didMount = hooks$1.useRef(false);
4475
+ const didMount = hooks.useRef(false);
3962
4476
 
3963
4477
  // (1) subscribe immediately
3964
4478
  if (eventBus && !didMount.current) {
@@ -3966,7 +4480,7 @@ function useEvent(event, callback, eventBus) {
3966
4480
  }
3967
4481
 
3968
4482
  // (2) update subscription after inputs changed
3969
- hooks$1.useEffect(() => {
4483
+ hooks.useEffect(() => {
3970
4484
  if (eventBus && didMount.current) {
3971
4485
  eventBus.on(event, callback);
3972
4486
  }
@@ -3998,9 +4512,9 @@ function useLayoutState(path, defaultValue) {
3998
4512
  const {
3999
4513
  getLayoutForKey,
4000
4514
  setLayoutForKey
4001
- } = hooks$1.useContext(LayoutContext);
4515
+ } = hooks.useContext(LayoutContext);
4002
4516
  const layoutForKey = getLayoutForKey(path, defaultValue);
4003
- const setState = hooks$1.useCallback(newValue => {
4517
+ const setState = hooks.useCallback(newValue => {
4004
4518
  setLayoutForKey(path, newValue);
4005
4519
  }, [setLayoutForKey]);
4006
4520
  return [layoutForKey, setState];
@@ -4014,8 +4528,8 @@ function useLayoutState(path, defaultValue) {
4014
4528
  */
4015
4529
 
4016
4530
  function usePrevious(value) {
4017
- const ref = hooks$1.useRef();
4018
- hooks$1.useEffect(() => {
4531
+ const ref = hooks.useRef();
4532
+ hooks.useEffect(() => {
4019
4533
  ref.current = value;
4020
4534
  });
4021
4535
  return ref.current;
@@ -4031,10 +4545,10 @@ function usePrevious(value) {
4031
4545
  function useShowEntryEvent(id) {
4032
4546
  const {
4033
4547
  onShow
4034
- } = hooks$1.useContext(LayoutContext);
4035
- const ref = hooks$1.useRef();
4036
- const focus = hooks$1.useRef(false);
4037
- const onShowEntry = hooks$1.useCallback(event => {
4548
+ } = hooks.useContext(LayoutContext);
4549
+ const ref = hooks.useRef();
4550
+ const focus = hooks.useRef(false);
4551
+ const onShowEntry = hooks.useCallback(event => {
4038
4552
  if (event.id === id) {
4039
4553
  onShow();
4040
4554
  if (!focus.current) {
@@ -4042,7 +4556,7 @@ function useShowEntryEvent(id) {
4042
4556
  }
4043
4557
  }
4044
4558
  }, [id]);
4045
- hooks$1.useEffect(() => {
4559
+ hooks.useEffect(() => {
4046
4560
  if (focus.current && ref.current) {
4047
4561
  if (minDash.isFunction(ref.current.focus)) {
4048
4562
  ref.current.focus();
@@ -4073,7 +4587,7 @@ function useShowEntryEvent(id) {
4073
4587
  * @param {setSticky} setSticky
4074
4588
  */
4075
4589
  function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky) {
4076
- hooks$1.useEffect(() => {
4590
+ hooks.useEffect(() => {
4077
4591
  const Observer = IntersectionObserver;
4078
4592
 
4079
4593
  // return early if IntersectionObserver is not available
@@ -4124,9 +4638,9 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
4124
4638
  * @returns {Function} static function reference
4125
4639
  */
4126
4640
  function useStaticCallback(callback) {
4127
- const callbackRef = hooks$1.useRef(callback);
4641
+ const callbackRef = hooks.useRef(callback);
4128
4642
  callbackRef.current = callback;
4129
- return hooks$1.useCallback((...args) => callbackRef.current(...args), []);
4643
+ return hooks.useCallback((...args) => callbackRef.current(...args), []);
4130
4644
  }
4131
4645
  function Group(props) {
4132
4646
  const {
@@ -4136,15 +4650,15 @@ function Group(props) {
4136
4650
  label,
4137
4651
  shouldOpen = false
4138
4652
  } = props;
4139
- const groupRef = hooks$1.useRef(null);
4653
+ const groupRef = hooks.useRef(null);
4140
4654
  const [open, setOpen] = useLayoutState(['groups', id, 'open'], shouldOpen);
4141
- const onShow = hooks$1.useCallback(() => setOpen(true), [setOpen]);
4655
+ const onShow = hooks.useCallback(() => setOpen(true), [setOpen]);
4142
4656
  const toggleOpen = () => setOpen(!open);
4143
- const [edited, setEdited] = hooks$1.useState(false);
4144
- const [sticky, setSticky] = hooks$1.useState(false);
4657
+ const [edited, setEdited] = hooks.useState(false);
4658
+ const [sticky, setSticky] = hooks.useState(false);
4145
4659
 
4146
4660
  // set edited state depending on all entries
4147
- hooks$1.useEffect(() => {
4661
+ hooks.useEffect(() => {
4148
4662
  const hasOneEditedEntry = entries.find(entry => {
4149
4663
  const {
4150
4664
  id,
@@ -4163,7 +4677,7 @@ function Group(props) {
4163
4677
  // set css class when group is sticky to top
4164
4678
  useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
4165
4679
  const propertiesPanelContext = {
4166
- ...hooks$1.useContext(LayoutContext),
4680
+ ...hooks.useContext(LayoutContext),
4167
4681
  onShow
4168
4682
  };
4169
4683
  return jsxRuntime.jsxs("div", {
@@ -4325,14 +4839,14 @@ function PropertiesPanel(props) {
4325
4839
  } = props;
4326
4840
 
4327
4841
  // set-up layout context
4328
- const [layout, setLayout] = hooks$1.useState(createLayout(layoutConfig));
4842
+ const [layout, setLayout] = hooks.useState(createLayout(layoutConfig));
4329
4843
 
4330
4844
  // react to external changes in the layout config
4331
4845
  useUpdateEffect(() => {
4332
4846
  const newLayout = createLayout(layoutConfig);
4333
4847
  setLayout(newLayout);
4334
4848
  }, [layoutConfig]);
4335
- hooks$1.useEffect(() => {
4849
+ hooks.useEffect(() => {
4336
4850
  if (typeof layoutChanged === 'function') {
4337
4851
  layoutChanged(layout);
4338
4852
  }
@@ -4353,8 +4867,8 @@ function PropertiesPanel(props) {
4353
4867
  };
4354
4868
 
4355
4869
  // set-up description context
4356
- const description = hooks$1.useMemo(() => createDescriptionContext(descriptionConfig), [descriptionConfig]);
4357
- hooks$1.useEffect(() => {
4870
+ const description = hooks.useMemo(() => createDescriptionContext(descriptionConfig), [descriptionConfig]);
4871
+ hooks.useEffect(() => {
4358
4872
  if (typeof descriptionLoaded === 'function') {
4359
4873
  descriptionLoaded(description);
4360
4874
  }
@@ -4366,7 +4880,7 @@ function PropertiesPanel(props) {
4366
4880
  description,
4367
4881
  getDescriptionForId
4368
4882
  };
4369
- const [errors, setErrors] = hooks$1.useState({});
4883
+ const [errors, setErrors] = hooks.useState({});
4370
4884
  const onSetErrors = ({
4371
4885
  errors
4372
4886
  }) => setErrors(errors);
@@ -4455,8 +4969,8 @@ function createDescriptionContext(overrides = {}) {
4455
4969
  * @param {Array} deps
4456
4970
  */
4457
4971
  function useUpdateEffect(effect, deps) {
4458
- const isMounted = hooks$1.useRef(false);
4459
- hooks$1.useEffect(() => {
4972
+ const isMounted = hooks.useRef(false);
4973
+ hooks.useEffect(() => {
4460
4974
  if (isMounted.current) {
4461
4975
  return effect();
4462
4976
  } else {
@@ -4473,14 +4987,14 @@ function CollapsibleEntry(props) {
4473
4987
  open: shouldOpen,
4474
4988
  remove
4475
4989
  } = props;
4476
- const [open, setOpen] = hooks$1.useState(shouldOpen);
4990
+ const [open, setOpen] = hooks.useState(shouldOpen);
4477
4991
  const toggleOpen = () => setOpen(!open);
4478
4992
  const {
4479
4993
  onShow
4480
- } = hooks$1.useContext(LayoutContext);
4994
+ } = hooks.useContext(LayoutContext);
4481
4995
  const propertiesPanelContext = {
4482
- ...hooks$1.useContext(LayoutContext),
4483
- onShow: hooks$1.useCallback(() => {
4996
+ ...hooks.useContext(LayoutContext),
4997
+ onShow: hooks.useCallback(() => {
4484
4998
  setOpen(true);
4485
4999
  if (minDash.isFunction(onShow)) {
4486
5000
  onShow();
@@ -4538,7 +5052,7 @@ function ListItem(props) {
4538
5052
  } = props;
4539
5053
 
4540
5054
  // focus specified entry on auto open
4541
- hooks$1.useEffect(() => {
5055
+ hooks.useEffect(() => {
4542
5056
  if (autoOpen && autoFocusEntry) {
4543
5057
  const entry = minDom.query(`[data-entry-id="${autoFocusEntry}"]`);
4544
5058
  const focusableInput = minDom.query('.bio-properties-panel-input', entry);
@@ -4574,15 +5088,15 @@ function ListGroup(props) {
4574
5088
  shouldOpen = true,
4575
5089
  shouldSort = true
4576
5090
  } = props;
4577
- const groupRef = hooks$1.useRef(null);
5091
+ const groupRef = hooks.useRef(null);
4578
5092
  const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
4579
- const [sticky, setSticky] = hooks$1.useState(false);
4580
- const onShow = hooks$1.useCallback(() => setOpen(true), [setOpen]);
4581
- const [ordering, setOrdering] = hooks$1.useState([]);
4582
- const [newItemAdded, setNewItemAdded] = hooks$1.useState(false);
5093
+ const [sticky, setSticky] = hooks.useState(false);
5094
+ const onShow = hooks.useCallback(() => setOpen(true), [setOpen]);
5095
+ const [ordering, setOrdering] = hooks.useState([]);
5096
+ const [newItemAdded, setNewItemAdded] = hooks.useState(false);
4583
5097
 
4584
5098
  // Flag to mark that add button was clicked in the last render cycle
4585
- const [addTriggered, setAddTriggered] = hooks$1.useState(false);
5099
+ const [addTriggered, setAddTriggered] = hooks.useState(false);
4586
5100
  const prevItems = usePrevious(items);
4587
5101
  const prevElement = usePrevious(element);
4588
5102
  const elementChanged = element !== prevElement;
@@ -4596,14 +5110,14 @@ function ListGroup(props) {
4596
5110
  // keep ordering in sync to items - and open changes
4597
5111
 
4598
5112
  // (0) set initial ordering from given items
4599
- hooks$1.useEffect(() => {
5113
+ hooks.useEffect(() => {
4600
5114
  if (!prevItems || !shouldSort) {
4601
5115
  setOrdering(createOrdering(items));
4602
5116
  }
4603
5117
  }, [items, element]);
4604
5118
 
4605
5119
  // (1) items were added
4606
- hooks$1.useEffect(() => {
5120
+ hooks.useEffect(() => {
4607
5121
  // reset addTriggered flag
4608
5122
  setAddTriggered(false);
4609
5123
  if (shouldHandleEffects && prevItems && items.length > prevItems.length) {
@@ -4644,14 +5158,14 @@ function ListGroup(props) {
4644
5158
  }, [items, open, shouldHandleEffects, addTriggered]);
4645
5159
 
4646
5160
  // (2) sort items on open if shouldSort is set
4647
- hooks$1.useEffect(() => {
5161
+ hooks.useEffect(() => {
4648
5162
  if (shouldSort && open && !newItemAdded) {
4649
5163
  setOrdering(createOrdering(sortItems(items)));
4650
5164
  }
4651
5165
  }, [open, shouldSort]);
4652
5166
 
4653
5167
  // (3) items were deleted
4654
- hooks$1.useEffect(() => {
5168
+ hooks.useEffect(() => {
4655
5169
  if (shouldHandleEffects && prevItems && items.length < prevItems.length) {
4656
5170
  let keep = [];
4657
5171
  ordering.forEach(o => {
@@ -4668,7 +5182,7 @@ function ListGroup(props) {
4668
5182
  const toggleOpen = () => setOpen(!open);
4669
5183
  const hasItems = !!items.length;
4670
5184
  const propertiesPanelContext = {
4671
- ...hooks$1.useContext(LayoutContext),
5185
+ ...hooks.useContext(LayoutContext),
4672
5186
  onShow
4673
5187
  };
4674
5188
  const handleAddClick = e => {
@@ -4776,7 +5290,7 @@ function Checkbox(props) {
4776
5290
  onFocus,
4777
5291
  onBlur
4778
5292
  } = props;
4779
- const [localValue, setLocalValue] = hooks$1.useState(value);
5293
+ const [localValue, setLocalValue] = hooks.useState(value);
4780
5294
  const handleChangeCallback = ({
4781
5295
  target
4782
5296
  }) => {
@@ -4786,7 +5300,7 @@ function Checkbox(props) {
4786
5300
  handleChangeCallback(e);
4787
5301
  setLocalValue(e.target.value);
4788
5302
  };
4789
- hooks$1.useEffect(() => {
5303
+ hooks.useEffect(() => {
4790
5304
  if (value === localValue) {
4791
5305
  return;
4792
5306
  }
@@ -4871,8 +5385,8 @@ function prefixId$7(id) {
4871
5385
  return `bio-properties-panel-${id}`;
4872
5386
  }
4873
5387
  const useBufferedFocus$1 = function (editor, ref) {
4874
- const [buffer, setBuffer] = hooks$1.useState(undefined);
4875
- ref.current = hooks$1.useMemo(() => ({
5388
+ const [buffer, setBuffer] = hooks.useState(undefined);
5389
+ ref.current = hooks.useMemo(() => ({
4876
5390
  focus: offset => {
4877
5391
  if (editor) {
4878
5392
  editor.focus(offset);
@@ -4884,7 +5398,7 @@ const useBufferedFocus$1 = function (editor, ref) {
4884
5398
  }
4885
5399
  }
4886
5400
  }), [editor]);
4887
- hooks$1.useEffect(() => {
5401
+ hooks.useEffect(() => {
4888
5402
  if (typeof buffer !== 'undefined' && editor) {
4889
5403
  editor.focus(buffer);
4890
5404
  setBuffer(false);
@@ -4903,15 +5417,15 @@ const CodeEditor$1 = React.forwardRef((props, ref) => {
4903
5417
  hostLanguage = null,
4904
5418
  singleLine = false
4905
5419
  } = props;
4906
- const inputRef = hooks$1.useRef();
4907
- const [editor, setEditor] = hooks$1.useState();
4908
- const [localValue, setLocalValue] = hooks$1.useState(value || '');
5420
+ const inputRef = hooks.useRef();
5421
+ const [editor, setEditor] = hooks.useState();
5422
+ const [localValue, setLocalValue] = hooks.useState(value || '');
4909
5423
  useBufferedFocus$1(editor, ref);
4910
5424
  const handleInput = useStaticCallback(newValue => {
4911
5425
  onInput(newValue);
4912
5426
  setLocalValue(newValue);
4913
5427
  });
4914
- hooks$1.useEffect(() => {
5428
+ hooks.useEffect(() => {
4915
5429
  let editor;
4916
5430
  editor = new feelers.FeelersEditor({
4917
5431
  container: inputRef.current,
@@ -4931,7 +5445,7 @@ const CodeEditor$1 = React.forwardRef((props, ref) => {
4931
5445
  setEditor(null);
4932
5446
  };
4933
5447
  }, []);
4934
- hooks$1.useEffect(() => {
5448
+ hooks.useEffect(() => {
4935
5449
  if (!editor) {
4936
5450
  return;
4937
5451
  }
@@ -4952,8 +5466,8 @@ const CodeEditor$1 = React.forwardRef((props, ref) => {
4952
5466
  });
4953
5467
  });
4954
5468
  const useBufferedFocus = function (editor, ref) {
4955
- const [buffer, setBuffer] = hooks$1.useState(undefined);
4956
- ref.current = hooks$1.useMemo(() => ({
5469
+ const [buffer, setBuffer] = hooks.useState(undefined);
5470
+ ref.current = hooks.useMemo(() => ({
4957
5471
  focus: offset => {
4958
5472
  if (editor) {
4959
5473
  editor.focus(offset);
@@ -4965,7 +5479,7 @@ const useBufferedFocus = function (editor, ref) {
4965
5479
  }
4966
5480
  }
4967
5481
  }), [editor]);
4968
- hooks$1.useEffect(() => {
5482
+ hooks.useEffect(() => {
4969
5483
  if (typeof buffer !== 'undefined' && editor) {
4970
5484
  editor.focus(buffer);
4971
5485
  setBuffer(false);
@@ -4982,15 +5496,15 @@ const CodeEditor = React.forwardRef((props, ref) => {
4982
5496
  tooltipContainer,
4983
5497
  variables
4984
5498
  } = props;
4985
- const inputRef = hooks$1.useRef();
4986
- const [editor, setEditor] = hooks$1.useState();
4987
- const [localValue, setLocalValue] = hooks$1.useState(value || '');
5499
+ const inputRef = hooks.useRef();
5500
+ const [editor, setEditor] = hooks.useState();
5501
+ const [localValue, setLocalValue] = hooks.useState(value || '');
4988
5502
  useBufferedFocus(editor, ref);
4989
5503
  const handleInput = useStaticCallback(newValue => {
4990
5504
  onInput(newValue);
4991
5505
  setLocalValue(newValue);
4992
5506
  });
4993
- hooks$1.useEffect(() => {
5507
+ hooks.useEffect(() => {
4994
5508
  let editor;
4995
5509
 
4996
5510
  /* Trigger FEEL toggle when
@@ -5024,7 +5538,7 @@ const CodeEditor = React.forwardRef((props, ref) => {
5024
5538
  setEditor(null);
5025
5539
  };
5026
5540
  }, []);
5027
- hooks$1.useEffect(() => {
5541
+ hooks.useEffect(() => {
5028
5542
  if (!editor) {
5029
5543
  return;
5030
5544
  }
@@ -5034,7 +5548,7 @@ const CodeEditor = React.forwardRef((props, ref) => {
5034
5548
  editor.setValue(value);
5035
5549
  setLocalValue(value);
5036
5550
  }, [value]);
5037
- hooks$1.useEffect(() => {
5551
+ hooks.useEffect(() => {
5038
5552
  if (!editor) {
5039
5553
  return;
5040
5554
  }
@@ -5113,12 +5627,12 @@ function FeelTextfield(props) {
5113
5627
  tooltipContainer,
5114
5628
  OptionalComponent = OptionalFeelInput
5115
5629
  } = props;
5116
- const [localValue, _setLocalValue] = hooks$1.useState(value);
5630
+ const [localValue, _setLocalValue] = hooks.useState(value);
5117
5631
  const editorRef = useShowEntryEvent(id);
5118
- const containerRef = hooks$1.useRef();
5632
+ const containerRef = hooks.useRef();
5119
5633
  const feelActive = localValue.startsWith('=') || feel === 'required';
5120
5634
  const feelOnlyValue = localValue.startsWith('=') ? localValue.substring(1) : localValue;
5121
- const [focus, _setFocus] = hooks$1.useState(undefined);
5635
+ const [focus, _setFocus] = hooks.useState(undefined);
5122
5636
  const setFocus = (offset = 0) => {
5123
5637
  const hasFocus = containerRef.current.contains(document.activeElement);
5124
5638
 
@@ -5126,7 +5640,7 @@ function FeelTextfield(props) {
5126
5640
  const position = hasFocus ? document.activeElement.selectionStart : Infinity;
5127
5641
  _setFocus(position + offset);
5128
5642
  };
5129
- const handleInputCallback = hooks$1.useMemo(() => {
5643
+ const handleInputCallback = hooks.useMemo(() => {
5130
5644
  return debounce(newValue => {
5131
5645
  onInput(newValue);
5132
5646
  });
@@ -5171,13 +5685,13 @@ function FeelTextfield(props) {
5171
5685
  const message = `${error.source}: ${error.message}`;
5172
5686
  onError(message);
5173
5687
  });
5174
- hooks$1.useEffect(() => {
5688
+ hooks.useEffect(() => {
5175
5689
  if (typeof focus !== 'undefined') {
5176
5690
  editorRef.current.focus(focus);
5177
5691
  _setFocus(undefined);
5178
5692
  }
5179
5693
  }, [focus]);
5180
- hooks$1.useEffect(() => {
5694
+ hooks.useEffect(() => {
5181
5695
  if (value === localValue) {
5182
5696
  return;
5183
5697
  }
@@ -5191,7 +5705,7 @@ function FeelTextfield(props) {
5191
5705
  }, [value]);
5192
5706
 
5193
5707
  // copy-paste integration
5194
- hooks$1.useEffect(() => {
5708
+ hooks.useEffect(() => {
5195
5709
  const copyHandler = event => {
5196
5710
  if (!feelActive) {
5197
5711
  return;
@@ -5273,7 +5787,7 @@ const OptionalFeelInput = React.forwardRef((props, ref) => {
5273
5787
  onFocus,
5274
5788
  onBlur
5275
5789
  } = props;
5276
- const inputRef = hooks$1.useRef();
5790
+ const inputRef = hooks.useRef();
5277
5791
 
5278
5792
  // To be consistent with the FEEL editor, set focus at start of input
5279
5793
  // this ensures clean editing experience when switching with the keyboard
@@ -5316,7 +5830,7 @@ React.forwardRef((props, ref) => {
5316
5830
  onFocus,
5317
5831
  onBlur
5318
5832
  } = props;
5319
- const inputRef = hooks$1.useRef();
5833
+ const inputRef = hooks.useRef();
5320
5834
 
5321
5835
  // To be consistent with the FEEL editor, set focus at start of input
5322
5836
  // this ensures clean editing experience when switching with the keyboard
@@ -5387,12 +5901,12 @@ function FeelEntry(props) {
5387
5901
  onFocus,
5388
5902
  onBlur
5389
5903
  } = props;
5390
- const [cachedInvalidValue, setCachedInvalidValue] = hooks$1.useState(null);
5391
- const [validationError, setValidationError] = hooks$1.useState(null);
5392
- const [localError, setLocalError] = hooks$1.useState(null);
5904
+ const [cachedInvalidValue, setCachedInvalidValue] = hooks.useState(null);
5905
+ const [validationError, setValidationError] = hooks.useState(null);
5906
+ const [localError, setLocalError] = hooks.useState(null);
5393
5907
  let value = getValue(element);
5394
5908
  const previousValue = usePrevious(value);
5395
- hooks$1.useEffect(() => {
5909
+ hooks.useEffect(() => {
5396
5910
  if (minDash.isFunction(validate)) {
5397
5911
  const newValidationError = validate(value) || null;
5398
5912
  setValidationError(newValidationError);
@@ -5413,7 +5927,7 @@ function FeelEntry(props) {
5413
5927
  }
5414
5928
  setValidationError(newValidationError);
5415
5929
  });
5416
- const onError = hooks$1.useCallback(err => {
5930
+ const onError = hooks.useCallback(err => {
5417
5931
  setLocalError(err);
5418
5932
  }, []);
5419
5933
  if (previousValue === value && validationError) {
@@ -5504,8 +6018,8 @@ function NumberField(props) {
5504
6018
  onFocus,
5505
6019
  onBlur
5506
6020
  } = props;
5507
- const [localValue, setLocalValue] = hooks$1.useState(value);
5508
- const handleInputCallback = hooks$1.useMemo(() => {
6021
+ const [localValue, setLocalValue] = hooks.useState(value);
6022
+ const handleInputCallback = hooks.useMemo(() => {
5509
6023
  return debounce(event => {
5510
6024
  const {
5511
6025
  validity,
@@ -5520,7 +6034,7 @@ function NumberField(props) {
5520
6034
  handleInputCallback(e);
5521
6035
  setLocalValue(e.target.value);
5522
6036
  };
5523
- hooks$1.useEffect(() => {
6037
+ hooks.useEffect(() => {
5524
6038
  if (value === localValue) {
5525
6039
  return;
5526
6040
  }
@@ -5585,12 +6099,12 @@ function NumberFieldEntry(props) {
5585
6099
  onBlur,
5586
6100
  validate
5587
6101
  } = props;
5588
- const [cachedInvalidValue, setCachedInvalidValue] = hooks$1.useState(null);
6102
+ const [cachedInvalidValue, setCachedInvalidValue] = hooks.useState(null);
5589
6103
  const globalError = useError(id);
5590
- const [localError, setLocalError] = hooks$1.useState(null);
6104
+ const [localError, setLocalError] = hooks.useState(null);
5591
6105
  let value = getValue(element);
5592
6106
  const previousValue = usePrevious(value);
5593
- hooks$1.useEffect(() => {
6107
+ hooks.useEffect(() => {
5594
6108
  if (minDash.isFunction(validate)) {
5595
6109
  const newValidationError = validate(value) || null;
5596
6110
  setLocalError(newValidationError);
@@ -5658,7 +6172,7 @@ function Select(props) {
5658
6172
  onBlur
5659
6173
  } = props;
5660
6174
  const ref = useShowEntryEvent(id);
5661
- const [localValue, setLocalValue] = hooks$1.useState(value);
6175
+ const [localValue, setLocalValue] = hooks.useState(value);
5662
6176
  const handleChangeCallback = ({
5663
6177
  target
5664
6178
  }) => {
@@ -5668,7 +6182,7 @@ function Select(props) {
5668
6182
  handleChangeCallback(e);
5669
6183
  setLocalValue(e.target.value);
5670
6184
  };
5671
- hooks$1.useEffect(() => {
6185
+ hooks.useEffect(() => {
5672
6186
  if (value === localValue) {
5673
6187
  return;
5674
6188
  }
@@ -5740,12 +6254,12 @@ function SelectEntry(props) {
5740
6254
  validate
5741
6255
  } = props;
5742
6256
  const options = getOptions(element);
5743
- const [cachedInvalidValue, setCachedInvalidValue] = hooks$1.useState(null);
6257
+ const [cachedInvalidValue, setCachedInvalidValue] = hooks.useState(null);
5744
6258
  const globalError = useError(id);
5745
- const [localError, setLocalError] = hooks$1.useState(null);
6259
+ const [localError, setLocalError] = hooks.useState(null);
5746
6260
  let value = getValue(element);
5747
6261
  const previousValue = usePrevious(value);
5748
- hooks$1.useEffect(() => {
6262
+ hooks.useEffect(() => {
5749
6263
  if (minDash.isFunction(validate)) {
5750
6264
  const newValidationError = validate(value) || null;
5751
6265
  setLocalError(newValidationError);
@@ -5819,9 +6333,9 @@ function TextArea(props) {
5819
6333
  autoResize,
5820
6334
  rows = autoResize ? 1 : 2
5821
6335
  } = props;
5822
- const [localValue, setLocalValue] = hooks$1.useState(value);
6336
+ const [localValue, setLocalValue] = hooks.useState(value);
5823
6337
  const ref = useShowEntryEvent(id);
5824
- const handleInputCallback = hooks$1.useMemo(() => {
6338
+ const handleInputCallback = hooks.useMemo(() => {
5825
6339
  return debounce(({
5826
6340
  target
5827
6341
  }) => onInput(target.value.length ? target.value : undefined));
@@ -5831,10 +6345,10 @@ function TextArea(props) {
5831
6345
  autoResize && resizeToContents(e.target);
5832
6346
  setLocalValue(e.target.value);
5833
6347
  };
5834
- hooks$1.useLayoutEffect(() => {
6348
+ hooks.useLayoutEffect(() => {
5835
6349
  autoResize && resizeToContents(ref.current);
5836
6350
  }, []);
5837
- hooks$1.useEffect(() => {
6351
+ hooks.useEffect(() => {
5838
6352
  if (value === localValue) {
5839
6353
  return;
5840
6354
  }
@@ -5941,9 +6455,9 @@ function Textfield(props) {
5941
6455
  onBlur,
5942
6456
  value = ''
5943
6457
  } = props;
5944
- const [localValue, setLocalValue] = hooks$1.useState(value || '');
6458
+ const [localValue, setLocalValue] = hooks.useState(value || '');
5945
6459
  const ref = useShowEntryEvent(id);
5946
- const handleInputCallback = hooks$1.useMemo(() => {
6460
+ const handleInputCallback = hooks.useMemo(() => {
5947
6461
  return debounce(({
5948
6462
  target
5949
6463
  }) => onInput(target.value.length ? target.value : undefined));
@@ -5952,7 +6466,7 @@ function Textfield(props) {
5952
6466
  handleInputCallback(e);
5953
6467
  setLocalValue(e.target.value);
5954
6468
  };
5955
- hooks$1.useEffect(() => {
6469
+ hooks.useEffect(() => {
5956
6470
  if (value === localValue) {
5957
6471
  return;
5958
6472
  }
@@ -6009,12 +6523,12 @@ function TextfieldEntry(props) {
6009
6523
  onFocus,
6010
6524
  onBlur
6011
6525
  } = props;
6012
- const [cachedInvalidValue, setCachedInvalidValue] = hooks$1.useState(null);
6526
+ const [cachedInvalidValue, setCachedInvalidValue] = hooks.useState(null);
6013
6527
  const globalError = useError(id);
6014
- const [localError, setLocalError] = hooks$1.useState(null);
6528
+ const [localError, setLocalError] = hooks.useState(null);
6015
6529
  let value = getValue(element);
6016
6530
  const previousValue = usePrevious(value);
6017
- hooks$1.useEffect(() => {
6531
+ hooks.useEffect(() => {
6018
6532
  if (minDash.isFunction(validate)) {
6019
6533
  const newValidationError = validate(value) || null;
6020
6534
  setLocalError(newValidationError);
@@ -6068,11 +6582,11 @@ function prefixId$1(id) {
6068
6582
  return `bio-properties-panel-${id}`;
6069
6583
  }
6070
6584
 
6071
- /**
6072
- * @param {string} type
6073
- * @param {boolean} [strict]
6074
- *
6075
- * @returns {any}
6585
+ /**
6586
+ * @param {string} type
6587
+ * @param {boolean} [strict]
6588
+ *
6589
+ * @returns {any}
6076
6590
  */
6077
6591
  function getService(type, strict) {}
6078
6592
  const PropertiesPanelContext = preact.createContext({
@@ -6161,8 +6675,8 @@ const PropertiesPanelHeaderProvider = {
6161
6675
  }
6162
6676
  };
6163
6677
 
6164
- /**
6165
- * Provide placeholders for empty and multiple state.
6678
+ /**
6679
+ * Provide placeholders for empty and multiple state.
6166
6680
  */
6167
6681
  const PropertiesPanelPlaceholderProvider = {
6168
6682
  getEmpty: () => {
@@ -6230,14 +6744,14 @@ function Action(props) {
6230
6744
  function useService (type, strict) {
6231
6745
  const {
6232
6746
  getService
6233
- } = hooks$1.useContext(FormPropertiesPanelContext);
6747
+ } = hooks.useContext(FormPropertiesPanelContext);
6234
6748
  return getService(type, strict);
6235
6749
  }
6236
6750
 
6237
- /**
6238
- * Retrieve list of variables from the form schema.
6239
- *
6240
- * @returns { string[] } list of variables used in form schema
6751
+ /**
6752
+ * Retrieve list of variables from the form schema.
6753
+ *
6754
+ * @returns { string[] } list of variables used in form schema
6241
6755
  */
6242
6756
  function useVariables() {
6243
6757
  const form = useService('formEditor');
@@ -6335,7 +6849,7 @@ function Columns(props) {
6335
6849
  },
6336
6850
  // todo(pinussilvestrus): make options dependant on field type
6337
6851
  // cf. https://github.com/bpmn-io/form-js/issues/575
6338
- ...[2, 4, 6, 8, 10, 12, 14, 16].map(asOption)];
6852
+ ...asArray(16).filter(i => i >= MIN_COLUMNS).map(asOption)];
6339
6853
  };
6340
6854
  return SelectEntry({
6341
6855
  debounce,
@@ -6357,6 +6871,11 @@ function asOption(number) {
6357
6871
  label: number.toString()
6358
6872
  };
6359
6873
  }
6874
+ function asArray(length) {
6875
+ return Array.from({
6876
+ length
6877
+ }).map((_, i) => i + 1);
6878
+ }
6360
6879
 
6361
6880
  function DescriptionEntry(props) {
6362
6881
  const {
@@ -7042,7 +7561,7 @@ function Text(props) {
7042
7561
  const setValue = value => {
7043
7562
  return editField(field, path, value);
7044
7563
  };
7045
- const description = hooks$1.useMemo(() => jsxRuntime.jsxs(jsxRuntime.Fragment, {
7564
+ const description = hooks.useMemo(() => jsxRuntime.jsxs(jsxRuntime.Fragment, {
7046
7565
  children: ["Supports markdown and templating. ", jsxRuntime.jsx("a", {
7047
7566
  href: "https://docs.camunda.io/docs/components/modeler/forms/form-element-library/forms-element-library-text/",
7048
7567
  target: "_blank",
@@ -7514,7 +8033,7 @@ function Label(props) {
7514
8033
  id,
7515
8034
  label: 'Label',
7516
8035
  setValue,
7517
- validate: validateFactory(getValue())
8036
+ validate: validateFactory(getValue(), entry => entry.label)
7518
8037
  });
7519
8038
  }
7520
8039
  function Value$1(props) {
@@ -7540,7 +8059,7 @@ function Value$1(props) {
7540
8059
  id,
7541
8060
  label: 'Value',
7542
8061
  setValue,
7543
- validate: validateFactory(getValue())
8062
+ validate: validateFactory(getValue(), entry => entry.value)
7544
8063
  });
7545
8064
  }
7546
8065
 
@@ -7630,14 +8149,14 @@ function Value(props) {
7630
8149
 
7631
8150
  // helpers //////////
7632
8151
 
7633
- /**
7634
- * Returns copy of object with updated value.
7635
- *
7636
- * @param {Object} properties
7637
- * @param {string} key
7638
- * @param {string} value
7639
- *
7640
- * @returns {Object}
8152
+ /**
8153
+ * Returns copy of object with updated value.
8154
+ *
8155
+ * @param {Object} properties
8156
+ * @param {string} key
8157
+ * @param {string} value
8158
+ *
8159
+ * @returns {Object}
7641
8160
  */
7642
8161
  function updateValue(properties, key, value) {
7643
8162
  return {
@@ -7646,14 +8165,14 @@ function updateValue(properties, key, value) {
7646
8165
  };
7647
8166
  }
7648
8167
 
7649
- /**
7650
- * Returns copy of object with updated key.
7651
- *
7652
- * @param {Object} properties
7653
- * @param {string} oldKey
7654
- * @param {string} newKey
7655
- *
7656
- * @returns {Object}
8168
+ /**
8169
+ * Returns copy of object with updated key.
8170
+ *
8171
+ * @param {Object} properties
8172
+ * @param {string} oldKey
8173
+ * @param {string} newKey
8174
+ *
8175
+ * @returns {Object}
7657
8176
  */
7658
8177
  function updateKey(properties, oldKey, newKey) {
7659
8178
  return Object.entries(properties).reduce((newProperties, entry) => {
@@ -7782,13 +8301,13 @@ function StaticValuesSourceEntry(props) {
7782
8301
  const addEntry = e => {
7783
8302
  e.stopPropagation();
7784
8303
  const index = values.length + 1;
7785
- const entry = getIndexedEntry(index);
8304
+ const entry = getIndexedEntry(index, values);
7786
8305
  editField(field, formJsViewer.VALUES_SOURCES_PATHS[formJsViewer.VALUES_SOURCES.STATIC], arrayAdd(values, values.length, entry));
7787
8306
  };
7788
8307
  const removeEntry = entry => {
7789
8308
  editField(field, formJsViewer.VALUES_SOURCES_PATHS[formJsViewer.VALUES_SOURCES.STATIC], minDash.without(values, entry));
7790
8309
  };
7791
- const validateFactory = key => {
8310
+ const validateFactory = (key, getValue) => {
7792
8311
  return value => {
7793
8312
  if (value === key) {
7794
8313
  return;
@@ -7796,7 +8315,7 @@ function StaticValuesSourceEntry(props) {
7796
8315
  if (minDash.isUndefined(value) || !value.length) {
7797
8316
  return 'Must not be empty.';
7798
8317
  }
7799
- const isValueAssigned = values.find(entry => entry.value === value);
8318
+ const isValueAssigned = values.find(entry => getValue(entry) === value);
7800
8319
  if (isValueAssigned) {
7801
8320
  return 'Must be unique.';
7802
8321
  }
@@ -7827,17 +8346,23 @@ function StaticValuesSourceEntry(props) {
7827
8346
 
7828
8347
  // helper
7829
8348
 
7830
- function getIndexedEntry(index) {
8349
+ function getIndexedEntry(index, values) {
7831
8350
  const entry = {
7832
8351
  label: 'Value',
7833
8352
  value: 'value'
7834
8353
  };
8354
+ while (labelOrValueIsAlreadyAssignedForIndex(index, values)) {
8355
+ index++;
8356
+ }
7835
8357
  if (index > 1) {
7836
8358
  entry.label += ` ${index}`;
7837
8359
  entry.value += `${index}`;
7838
8360
  }
7839
8361
  return entry;
7840
8362
  }
8363
+ function labelOrValueIsAlreadyAssignedForIndex(index, values) {
8364
+ return values.some(existingEntry => existingEntry.label === `Value ${index}` || existingEntry.value === `value${index}`);
8365
+ }
7841
8366
 
7842
8367
  function AdornerEntry(props) {
7843
8368
  const {
@@ -8289,8 +8814,8 @@ function ValuesGroups(field, editField) {
8289
8814
  };
8290
8815
  const valuesSourceId = `${fieldId}-valuesSource`;
8291
8816
 
8292
- /**
8293
- * @type {Array<Group|ListGroup>}
8817
+ /**
8818
+ * @type {Array<Group|ListGroup>}
8294
8819
  */
8295
8820
  const groups = [{
8296
8821
  id: valuesSourceId,
@@ -8338,12 +8863,13 @@ function CustomValuesGroup(field, editField) {
8338
8863
  }
8339
8864
  const addEntry = event => {
8340
8865
  event.stopPropagation();
8341
- const index = Object.keys(properties).length + 1;
8342
- const key = `key${index}`,
8343
- value = 'value';
8866
+ let index = Object.keys(properties).length + 1;
8867
+ while (`key${index}` in properties) {
8868
+ index++;
8869
+ }
8344
8870
  editField(field, ['properties'], {
8345
8871
  ...properties,
8346
- [key]: value
8872
+ [`key${index}`]: 'value'
8347
8873
  });
8348
8874
  };
8349
8875
  const validateFactory = key => {
@@ -8391,13 +8917,13 @@ function CustomValuesGroup(field, editField) {
8391
8917
 
8392
8918
  // helpers //////////
8393
8919
 
8394
- /**
8395
- * Returns copy of object without key.
8396
- *
8397
- * @param {Object} properties
8398
- * @param {string} oldKey
8399
- *
8400
- * @returns {Object}
8920
+ /**
8921
+ * Returns copy of object without key.
8922
+ *
8923
+ * @param {Object} properties
8924
+ * @param {string} oldKey
8925
+ *
8926
+ * @returns {Object}
8401
8927
  */
8402
8928
  function removeKey(properties, oldKey) {
8403
8929
  return Object.entries(properties).reduce((newProperties, entry) => {
@@ -8486,7 +9012,7 @@ function FormPropertiesPanel(props) {
8486
9012
  const {
8487
9013
  schema
8488
9014
  } = formEditor._getState();
8489
- const [state, setState] = hooks$1.useState({
9015
+ const [state, setState] = hooks.useState({
8490
9016
  selectedFormField: selection.get() || schema
8491
9017
  });
8492
9018
  const _update = field => {
@@ -8500,7 +9026,7 @@ function FormPropertiesPanel(props) {
8500
9026
  formField: field
8501
9027
  });
8502
9028
  };
8503
- hooks$1.useLayoutEffect(() => {
9029
+ hooks.useLayoutEffect(() => {
8504
9030
  function onSelectionChange(event) {
8505
9031
  _update(event.selection || schema);
8506
9032
  }
@@ -8509,11 +9035,11 @@ function FormPropertiesPanel(props) {
8509
9035
  eventBus.off('selection.changed', onSelectionChange);
8510
9036
  };
8511
9037
  }, []);
8512
- hooks$1.useLayoutEffect(() => {
9038
+ hooks.useLayoutEffect(() => {
8513
9039
  const onFieldChanged = () => {
8514
- /**
8515
- * TODO(pinussilvestrus): update with actual updated element,
8516
- * once we have a proper updater/change support
9040
+ /**
9041
+ * TODO(pinussilvestrus): update with actual updated element,
9042
+ * once we have a proper updater/change support
8517
9043
  */
8518
9044
  _update(selection.get() || schema);
8519
9045
  };
@@ -8529,7 +9055,7 @@ function FormPropertiesPanel(props) {
8529
9055
  };
8530
9056
  const onFocus = () => eventBus.fire('propertiesPanel.focusin');
8531
9057
  const onBlur = () => eventBus.fire('propertiesPanel.focusout');
8532
- const editField = hooks$1.useCallback((formField, key, value) => modeling.editFormField(formField, key, value), [modeling]);
9058
+ const editField = hooks.useCallback((formField, key, value) => modeling.editFormField(formField, key, value), [modeling]);
8533
9059
  return jsxRuntime.jsx("div", {
8534
9060
  class: "fjs-properties-panel",
8535
9061
  "data-field": selectedFormField && selectedFormField.id,
@@ -8564,10 +9090,10 @@ class PropertiesPanelRenderer {
8564
9090
  });
8565
9091
  }
8566
9092
 
8567
- /**
8568
- * Attach the properties panel to a parent node.
8569
- *
8570
- * @param {HTMLElement} container
9093
+ /**
9094
+ * Attach the properties panel to a parent node.
9095
+ *
9096
+ * @param {HTMLElement} container
8571
9097
  */
8572
9098
  attachTo(container) {
8573
9099
  if (!container) {
@@ -8587,8 +9113,8 @@ class PropertiesPanelRenderer {
8587
9113
  this._eventBus.fire('propertiesPanel.attach');
8588
9114
  }
8589
9115
 
8590
- /**
8591
- * Detach the properties panel from its parent node.
9116
+ /**
9117
+ * Detach the properties panel from its parent node.
8592
9118
  */
8593
9119
  detach() {
8594
9120
  const parentNode = this._container.parentNode;
@@ -8626,48 +9152,48 @@ var ExpressionLanguageModule = {
8626
9152
 
8627
9153
  const ids = new Ids([32, 36, 1]);
8628
9154
 
8629
- /**
8630
- * @typedef { import('./types').Injector } Injector
8631
- * @typedef { import('./types').Module } Module
8632
- * @typedef { import('./types').Schema } Schema
8633
- *
8634
- * @typedef { import('./types').FormEditorOptions } FormEditorOptions
8635
- * @typedef { import('./types').FormEditorProperties } FormEditorProperties
8636
- *
8637
- * @typedef { {
8638
- * properties: FormEditorProperties,
8639
- * schema: Schema
8640
- * } } State
8641
- *
8642
- * @typedef { (type:string, priority:number, handler:Function) => void } OnEventWithPriority
8643
- * @typedef { (type:string, handler:Function) => void } OnEventWithOutPriority
8644
- * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
9155
+ /**
9156
+ * @typedef { import('./types').Injector } Injector
9157
+ * @typedef { import('./types').Module } Module
9158
+ * @typedef { import('./types').Schema } Schema
9159
+ *
9160
+ * @typedef { import('./types').FormEditorOptions } FormEditorOptions
9161
+ * @typedef { import('./types').FormEditorProperties } FormEditorProperties
9162
+ *
9163
+ * @typedef { {
9164
+ * properties: FormEditorProperties,
9165
+ * schema: Schema
9166
+ * } } State
9167
+ *
9168
+ * @typedef { (type:string, priority:number, handler:Function) => void } OnEventWithPriority
9169
+ * @typedef { (type:string, handler:Function) => void } OnEventWithOutPriority
9170
+ * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
8645
9171
  */
8646
9172
 
8647
- /**
8648
- * The form editor.
9173
+ /**
9174
+ * The form editor.
8649
9175
  */
8650
9176
  class FormEditor {
8651
- /**
8652
- * @constructor
8653
- * @param {FormEditorOptions} options
9177
+ /**
9178
+ * @constructor
9179
+ * @param {FormEditorOptions} options
8654
9180
  */
8655
9181
  constructor(options = {}) {
8656
- /**
8657
- * @public
8658
- * @type {OnEventType}
9182
+ /**
9183
+ * @public
9184
+ * @type {OnEventType}
8659
9185
  */
8660
9186
  this.on = this._onEvent;
8661
9187
 
8662
- /**
8663
- * @public
8664
- * @type {String}
9188
+ /**
9189
+ * @public
9190
+ * @type {String}
8665
9191
  */
8666
9192
  this._id = ids.next();
8667
9193
 
8668
- /**
8669
- * @private
8670
- * @type {Element}
9194
+ /**
9195
+ * @private
9196
+ * @type {Element}
8671
9197
  */
8672
9198
  this._container = formJsViewer.createFormContainer();
8673
9199
  this._container.setAttribute('input-handle-modified-keys', 'z,y');
@@ -8678,15 +9204,15 @@ class FormEditor {
8678
9204
  properties = {}
8679
9205
  } = options;
8680
9206
 
8681
- /**
8682
- * @private
8683
- * @type {any}
9207
+ /**
9208
+ * @private
9209
+ * @type {any}
8684
9210
  */
8685
9211
  this.exporter = exporter;
8686
9212
 
8687
- /**
8688
- * @private
8689
- * @type {State}
9213
+ /**
9214
+ * @private
9215
+ * @type {State}
8690
9216
  */
8691
9217
  this._state = {
8692
9218
  properties,
@@ -8715,10 +9241,10 @@ class FormEditor {
8715
9241
  this._detach(false);
8716
9242
  }
8717
9243
 
8718
- /**
8719
- * @param {Schema} schema
8720
- *
8721
- * @return {Promise<{ warnings: Array<any> }>}
9244
+ /**
9245
+ * @param {Schema} schema
9246
+ *
9247
+ * @return {Promise<{ warnings: Array<any> }>}
8722
9248
  */
8723
9249
  importSchema(schema) {
8724
9250
  return new Promise((resolve, reject) => {
@@ -8747,15 +9273,15 @@ class FormEditor {
8747
9273
  });
8748
9274
  }
8749
9275
 
8750
- /**
8751
- * @returns {Schema}
9276
+ /**
9277
+ * @returns {Schema}
8752
9278
  */
8753
9279
  saveSchema() {
8754
9280
  return this.getSchema();
8755
9281
  }
8756
9282
 
8757
- /**
8758
- * @returns {Schema}
9283
+ /**
9284
+ * @returns {Schema}
8759
9285
  */
8760
9286
  getSchema() {
8761
9287
  const {
@@ -8764,8 +9290,8 @@ class FormEditor {
8764
9290
  return exportSchema(schema, this.exporter, formJsViewer.schemaVersion);
8765
9291
  }
8766
9292
 
8767
- /**
8768
- * @param {Element|string} parentNode
9293
+ /**
9294
+ * @param {Element|string} parentNode
8769
9295
  */
8770
9296
  attachTo(parentNode) {
8771
9297
  if (!parentNode) {
@@ -8783,10 +9309,10 @@ class FormEditor {
8783
9309
  this._detach();
8784
9310
  }
8785
9311
 
8786
- /**
8787
- * @internal
8788
- *
8789
- * @param {boolean} [emit]
9312
+ /**
9313
+ * @internal
9314
+ *
9315
+ * @param {boolean} [emit]
8790
9316
  */
8791
9317
  _detach(emit = true) {
8792
9318
  const container = this._container,
@@ -8800,9 +9326,9 @@ class FormEditor {
8800
9326
  parentNode.removeChild(container);
8801
9327
  }
8802
9328
 
8803
- /**
8804
- * @param {any} property
8805
- * @param {any} value
9329
+ /**
9330
+ * @param {any} property
9331
+ * @param {any} value
8806
9332
  */
8807
9333
  setProperty(property, value) {
8808
9334
  const properties = minDash.set(this._getState().properties, [property], value);
@@ -8811,21 +9337,21 @@ class FormEditor {
8811
9337
  });
8812
9338
  }
8813
9339
 
8814
- /**
8815
- * @param {string} type
8816
- * @param {Function} handler
9340
+ /**
9341
+ * @param {string} type
9342
+ * @param {Function} handler
8817
9343
  */
8818
9344
  off(type, handler) {
8819
9345
  this.get('eventBus').off(type, handler);
8820
9346
  }
8821
9347
 
8822
- /**
8823
- * @internal
8824
- *
8825
- * @param {FormEditorOptions} options
8826
- * @param {Element} container
8827
- *
8828
- * @returns {Injector}
9348
+ /**
9349
+ * @internal
9350
+ *
9351
+ * @param {FormEditorOptions} options
9352
+ * @param {Element} container
9353
+ *
9354
+ * @returns {Injector}
8829
9355
  */
8830
9356
  _createInjector(options, container) {
8831
9357
  const {
@@ -8847,22 +9373,22 @@ class FormEditor {
8847
9373
  }, core, ...modules, ...additionalModules]);
8848
9374
  }
8849
9375
 
8850
- /**
8851
- * @internal
9376
+ /**
9377
+ * @internal
8852
9378
  */
8853
9379
  _emit(type, data) {
8854
9380
  this.get('eventBus').fire(type, data);
8855
9381
  }
8856
9382
 
8857
- /**
8858
- * @internal
9383
+ /**
9384
+ * @internal
8859
9385
  */
8860
9386
  _getState() {
8861
9387
  return this._state;
8862
9388
  }
8863
9389
 
8864
- /**
8865
- * @internal
9390
+ /**
9391
+ * @internal
8866
9392
  */
8867
9393
  _setState(state) {
8868
9394
  this._state = {
@@ -8872,15 +9398,15 @@ class FormEditor {
8872
9398
  this._emit('changed', this._getState());
8873
9399
  }
8874
9400
 
8875
- /**
8876
- * @internal
9401
+ /**
9402
+ * @internal
8877
9403
  */
8878
9404
  _getModules() {
8879
9405
  return [ModelingModule, EditorActionsModule, DraggingModule, KeyboardModule, SelectionModule, PaletteModule, ExpressionLanguageModule, formJsViewer.MarkdownModule, PropertiesPanelModule];
8880
9406
  }
8881
9407
 
8882
- /**
8883
- * @internal
9408
+ /**
9409
+ * @internal
8884
9410
  */
8885
9411
  _onEvent(type, priority, handler) {
8886
9412
  this.get('eventBus').on(type, priority, handler);