@bpmn-io/form-js-editor 1.11.3 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1202,7 +1202,37 @@ EditorExpressionField.config = {
1202
1202
  escapeGridRender: false
1203
1203
  };
1204
1204
 
1205
- const editorFormFields = [EditorIFrame, EditorText, EditorHtml, EditorTable, EditorExpressionField];
1205
+ function EditorDocumentPreview(props) {
1206
+ const {
1207
+ field,
1208
+ domId
1209
+ } = props;
1210
+ const {
1211
+ label
1212
+ } = field;
1213
+ const Icon = formJsViewer.iconsByType(field.type);
1214
+ return jsxRuntime.jsxs("div", {
1215
+ class: editorFormFieldClasses(field.type),
1216
+ children: [jsxRuntime.jsx(formJsViewer.Label, {
1217
+ id: domId,
1218
+ label: label
1219
+ }), jsxRuntime.jsx("div", {
1220
+ class: "fjs-documentPreview-placeholder",
1221
+ id: domId,
1222
+ children: jsxRuntime.jsxs("p", {
1223
+ class: "fjs-documentPreview-placeholder-text",
1224
+ children: [jsxRuntime.jsx(Icon, {
1225
+ width: "32",
1226
+ height: "24",
1227
+ viewBox: "0 0 56 56"
1228
+ }), "Document preview"]
1229
+ })
1230
+ })]
1231
+ });
1232
+ }
1233
+ EditorDocumentPreview.config = formJsViewer.DocumentPreview.config;
1234
+
1235
+ const editorFormFields = [EditorIFrame, EditorText, EditorHtml, EditorTable, EditorExpressionField, EditorDocumentPreview];
1206
1236
 
1207
1237
  class EditorFormFields extends formJsViewer.FormFields {
1208
1238
  constructor() {
@@ -2293,13 +2323,17 @@ function Element$1(props) {
2293
2323
  ref.current.focus();
2294
2324
  }
2295
2325
  }, [selection, field]);
2296
- function onClick(event) {
2297
- event.stopPropagation();
2298
- selection.toggle(field);
2299
-
2300
- // properly focus on field
2301
- ref.current.focus();
2302
- }
2326
+ const onClick = hooks.useCallback(event => {
2327
+ // TODO(nikku): refactor this to use proper DOM delegation
2328
+ const fieldEl = event.target.closest('[data-id]');
2329
+ if (!fieldEl) {
2330
+ return;
2331
+ }
2332
+ const id = fieldEl.dataset.id;
2333
+ if (id === field.id) {
2334
+ selection.toggle(field);
2335
+ }
2336
+ }, [field, selection]);
2303
2337
  const isSelected = selection.isSelected(field);
2304
2338
  const classString = hooks.useMemo(() => {
2305
2339
  const classes = [];
@@ -2691,6 +2725,34 @@ class Renderer {
2691
2725
  container,
2692
2726
  compact = false
2693
2727
  } = renderConfig;
2728
+ eventBus.on('form.init', function () {
2729
+ // emit <canvas.init> so dependent components can hook in
2730
+ // this is required to register keyboard bindings
2731
+ eventBus.fire('canvas.init', {
2732
+ svg: container,
2733
+ viewport: null
2734
+ });
2735
+ });
2736
+
2737
+ // focus container on over if no selection
2738
+ container.addEventListener('mouseover', function () {
2739
+ if (document.activeElement === document.body) {
2740
+ container.focus({
2741
+ preventScroll: true
2742
+ });
2743
+ }
2744
+ });
2745
+
2746
+ // ensure we focus the container if the users clicks
2747
+ // inside; this follows input focus handling closely
2748
+ container.addEventListener('click', function (event) {
2749
+ // force focus when clicking container
2750
+ if (!container.contains(document.activeElement)) {
2751
+ container.focus({
2752
+ preventScroll: true
2753
+ });
2754
+ }
2755
+ });
2694
2756
  const App = () => {
2695
2757
  const [state, setState] = hooks.useState(formEditor._getState());
2696
2758
  const formEditorContext = {
@@ -3128,8 +3190,8 @@ function isRedo(event) {
3128
3190
 
3129
3191
  var KEYDOWN_EVENT = 'keyboard.keydown',
3130
3192
  KEYUP_EVENT = 'keyboard.keyup';
3131
- var HANDLE_MODIFIER_ATTRIBUTE = 'input-handle-modified-keys';
3132
3193
  var DEFAULT_PRIORITY$2 = 1000;
3194
+ var compatMessage = 'Keyboard binding is now implicit; explicit binding to an element got removed. For more information, see https://github.com/bpmn-io/diagram-js/issues/661';
3133
3195
 
3134
3196
  /**
3135
3197
  * A keyboard abstraction that may be activated and
@@ -3149,16 +3211,16 @@ var DEFAULT_PRIORITY$2 = 1000;
3149
3211
  *
3150
3212
  * All events contain one field which is node.
3151
3213
  *
3152
- * A default binding for the keyboard may be specified via the
3153
- * `keyboard.bindTo` configuration option.
3214
+ * Specify the initial keyboard binding state via the
3215
+ * `keyboard.bind=true|false` configuration option.
3154
3216
  *
3155
3217
  * @param {Object} config
3156
- * @param {EventTarget} [config.bindTo]
3218
+ * @param {boolean} [config.bind]
3157
3219
  * @param {EventBus} eventBus
3158
3220
  */
3159
3221
  function Keyboard(config, eventBus) {
3160
3222
  var self = this;
3161
- this._config = config || {};
3223
+ this._config = config = config || {};
3162
3224
  this._eventBus = eventBus;
3163
3225
  this._keydownHandler = this._keydownHandler.bind(this);
3164
3226
  this._keyupHandler = this._keyupHandler.bind(this);
@@ -3168,16 +3230,16 @@ function Keyboard(config, eventBus) {
3168
3230
  self._fire('destroy');
3169
3231
  self.unbind();
3170
3232
  });
3171
- eventBus.on('diagram.init', function () {
3172
- self._fire('init');
3173
- });
3174
- eventBus.on('attach', function () {
3175
- if (config && config.bindTo) {
3176
- self.bind(config.bindTo);
3233
+ if (config.bindTo) {
3234
+ console.error('unsupported configuration <keyboard.bindTo>', new Error(compatMessage));
3235
+ }
3236
+ var bind = config && config.bind !== false;
3237
+ eventBus.on('canvas.init', function (event) {
3238
+ self._target = event.svg;
3239
+ if (bind) {
3240
+ self.bind();
3177
3241
  }
3178
- });
3179
- eventBus.on('detach', function () {
3180
- self.unbind();
3242
+ self._fire('init');
3181
3243
  });
3182
3244
  }
3183
3245
  Keyboard.$inject = ['config.keyboard', 'eventBus'];
@@ -3201,35 +3263,29 @@ Keyboard.prototype._keyHandler = function (event, type) {
3201
3263
  }
3202
3264
  };
3203
3265
  Keyboard.prototype._isEventIgnored = function (event) {
3204
- if (event.defaultPrevented) {
3205
- return true;
3206
- }
3207
- return (isInput(event.target) || isButton(event.target) && isKey([' ', 'Enter'], event)) && this._isModifiedKeyIgnored(event);
3208
- };
3209
- Keyboard.prototype._isModifiedKeyIgnored = function (event) {
3210
- if (!isCmd(event)) {
3211
- return true;
3212
- }
3213
- var allowedModifiers = this._getAllowedModifiers(event.target);
3214
- return allowedModifiers.indexOf(event.key) === -1;
3215
- };
3216
- Keyboard.prototype._getAllowedModifiers = function (element) {
3217
- var modifierContainer = minDom.closest(element, '[' + HANDLE_MODIFIER_ATTRIBUTE + ']', true);
3218
- if (!modifierContainer || this._node && !this._node.contains(modifierContainer)) {
3219
- return [];
3220
- }
3221
- return modifierContainer.getAttribute(HANDLE_MODIFIER_ATTRIBUTE).split(',');
3266
+ return false;
3222
3267
  };
3223
3268
 
3224
3269
  /**
3225
3270
  * Bind keyboard events to the given DOM node.
3226
3271
  *
3272
+ * @overlord
3273
+ * @deprecated No longer in use since version 15.0.0.
3274
+ *
3227
3275
  * @param {EventTarget} node
3228
3276
  */
3277
+ /**
3278
+ * Bind keyboard events to the canvas node.
3279
+ */
3229
3280
  Keyboard.prototype.bind = function (node) {
3281
+ // legacy <node> argument provided
3282
+ if (node) {
3283
+ console.error('unsupported argument <node>', new Error(compatMessage));
3284
+ }
3285
+
3230
3286
  // make sure that the keyboard is only bound once to the DOM
3231
3287
  this.unbind();
3232
- this._node = node;
3288
+ node = this._node = this._target;
3233
3289
 
3234
3290
  // bind key events
3235
3291
  minDom.event.bind(node, 'keydown', this._keydownHandler);
@@ -3296,15 +3352,6 @@ Keyboard.prototype.isCmd = isCmd;
3296
3352
  Keyboard.prototype.isShift = isShift;
3297
3353
  Keyboard.prototype.isKey = isKey;
3298
3354
 
3299
- // helpers ///////
3300
-
3301
- function isInput(target) {
3302
- return target && (minDom.matches(target, 'input, textarea') || target.contentEditable === 'true');
3303
- }
3304
- function isButton(target) {
3305
- return target && minDom.matches(target, 'button, input[type=submit], input[type=button], a[href], [aria-role=button]');
3306
- }
3307
-
3308
3355
  var LOW_PRIORITY$1 = 500;
3309
3356
 
3310
3357
  /**
@@ -3468,7 +3515,7 @@ class FormEditorKeyboardBindings {
3468
3515
  const {
3469
3516
  keyEvent
3470
3517
  } = context;
3471
- if (isCmd(keyEvent) && !isShift(keyEvent) && isKey(KEYS_UNDO, keyEvent)) {
3518
+ if (isUndo(keyEvent)) {
3472
3519
  editorActions.trigger('undo');
3473
3520
  return true;
3474
3521
  }
@@ -3481,7 +3528,7 @@ class FormEditorKeyboardBindings {
3481
3528
  const {
3482
3529
  keyEvent
3483
3530
  } = context;
3484
- if (isCmd(keyEvent) && (isKey(KEYS_REDO, keyEvent) || isKey(KEYS_UNDO, keyEvent) && isShift(keyEvent))) {
3531
+ if (isRedo(keyEvent)) {
3485
3532
  editorActions.trigger('redo');
3486
3533
  return true;
3487
3534
  }
@@ -5296,6 +5343,21 @@ ArrowIcon.defaultProps = {
5296
5343
  width: "16",
5297
5344
  height: "16"
5298
5345
  };
5346
+ var CloseIcon = function CloseIcon(props) {
5347
+ return jsxRuntime.jsx("svg", {
5348
+ ...props,
5349
+ children: jsxRuntime.jsx("path", {
5350
+ fillRule: "evenodd",
5351
+ d: "m12 4.7-.7-.7L8 7.3 4.7 4l-.7.7L7.3 8 4 11.3l.7.7L8 8.7l3.3 3.3.7-.7L8.7 8 12 4.7Z",
5352
+ fill: "currentColor"
5353
+ })
5354
+ });
5355
+ };
5356
+ CloseIcon.defaultProps = {
5357
+ xmlns: "http://www.w3.org/2000/svg",
5358
+ width: "16",
5359
+ height: "16"
5360
+ };
5299
5361
  var CreateIcon = function CreateIcon(props) {
5300
5362
  return jsxRuntime.jsx("svg", {
5301
5363
  ...props,
@@ -5383,26 +5445,17 @@ FeelIcon$1.defaultProps = {
5383
5445
  fill: "none",
5384
5446
  xmlns: "http://www.w3.org/2000/svg"
5385
5447
  };
5386
- var HelpIcon = function HelpIcon(props) {
5448
+ var LaunchIcon = function LaunchIcon(props) {
5387
5449
  return jsxRuntime.jsxs("svg", {
5388
5450
  ...props,
5389
5451
  children: [jsxRuntime.jsx("path", {
5390
- d: "M16 2a14 14 0 1 0 14 14A14 14 0 0 0 16 2Zm0 26a12 12 0 1 1 12-12 12 12 0 0 1-12 12Z"
5391
- }), jsxRuntime.jsx("circle", {
5392
- cx: "16",
5393
- cy: "23.5",
5394
- r: "1.5"
5452
+ d: "M26 28H6a2.003 2.003 0 0 1-2-2V6a2.003 2.003 0 0 1 2-2h10v2H6v20h20V16h2v10a2.003 2.003 0 0 1-2 2Z"
5395
5453
  }), jsxRuntime.jsx("path", {
5396
- d: "M17 8h-1.5a4.49 4.49 0 0 0-4.5 4.5v.5h2v-.5a2.5 2.5 0 0 1 2.5-2.5H17a2.5 2.5 0 0 1 0 5h-2v4.5h2V17a4.5 4.5 0 0 0 0-9Z"
5397
- }), jsxRuntime.jsx("path", {
5398
- style: {
5399
- fill: "none"
5400
- },
5401
- d: "M0 0h32v32H0z"
5454
+ d: "M20 2v2h6.586L18 12.586 19.414 14 28 5.414V12h2V2H20z"
5402
5455
  })]
5403
5456
  });
5404
5457
  };
5405
- HelpIcon.defaultProps = {
5458
+ LaunchIcon.defaultProps = {
5406
5459
  xmlns: "http://www.w3.org/2000/svg",
5407
5460
  viewBox: "0 0 32 32"
5408
5461
  };
@@ -5424,21 +5477,6 @@ PopupIcon.defaultProps = {
5424
5477
  height: "16",
5425
5478
  viewBox: "0 0 32 32"
5426
5479
  };
5427
- var CloseIcon = function CloseIcon(props) {
5428
- return jsxRuntime.jsx("svg", {
5429
- ...props,
5430
- children: jsxRuntime.jsx("path", {
5431
- fillRule: "evenodd",
5432
- d: "m12 4.7-.7-.7L8 7.3 4.7 4l-.7.7L7.3 8 4 11.3l.7.7L8 8.7l3.3 3.3.7-.7L8.7 8 12 4.7Z",
5433
- fill: "currentColor"
5434
- })
5435
- });
5436
- };
5437
- CloseIcon.defaultProps = {
5438
- xmlns: "http://www.w3.org/2000/svg",
5439
- width: "16",
5440
- height: "16"
5441
- };
5442
5480
  function Header(props) {
5443
5481
  const {
5444
5482
  element,
@@ -5477,7 +5515,7 @@ function Header(props) {
5477
5515
  }), jsxRuntime.jsx("div", {
5478
5516
  class: "bio-properties-panel-header-actions",
5479
5517
  children: documentationRef ? jsxRuntime.jsx("a", {
5480
- rel: "noopener",
5518
+ rel: "noreferrer",
5481
5519
  class: "bio-properties-panel-header-link",
5482
5520
  href: documentationRef,
5483
5521
  title: "Open documentation",
@@ -5495,19 +5533,19 @@ const ErrorsContext = preact.createContext({
5495
5533
  errors: {}
5496
5534
  });
5497
5535
 
5498
- /**
5499
- * @typedef {Function} <propertiesPanel.showEntry> callback
5500
- *
5501
- * @example
5502
- *
5503
- * useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
5504
- * // ...
5505
- * });
5506
- *
5507
- * @param {Object} context
5508
- * @param {boolean} [context.focus]
5509
- *
5510
- * @returns void
5536
+ /**
5537
+ * @typedef {Function} <propertiesPanel.showEntry> callback
5538
+ *
5539
+ * @example
5540
+ *
5541
+ * useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
5542
+ * // ...
5543
+ * });
5544
+ *
5545
+ * @param {Object} context
5546
+ * @param {boolean} [context.focus]
5547
+ *
5548
+ * @returns void
5511
5549
  */
5512
5550
 
5513
5551
  const EventContext = preact.createContext({
@@ -5524,20 +5562,20 @@ const TooltipContext = preact.createContext({
5524
5562
  getTooltipForId: () => {}
5525
5563
  });
5526
5564
 
5527
- /**
5528
- * Accesses the global TooltipContext and returns a tooltip for a given id and element.
5529
- *
5530
- * @example
5531
- * ```jsx
5532
- * function TextField(props) {
5533
- * const tooltip = useTooltipContext('input1', element);
5534
- * }
5535
- * ```
5536
- *
5537
- * @param {string} id
5538
- * @param {object} element
5539
- *
5540
- * @returns {string}
5565
+ /**
5566
+ * Accesses the global TooltipContext and returns a tooltip for a given id and element.
5567
+ *
5568
+ * @example
5569
+ * ```jsx
5570
+ * function TextField(props) {
5571
+ * const tooltip = useTooltipContext('input1', element);
5572
+ * }
5573
+ * ```
5574
+ *
5575
+ * @param {string} id
5576
+ * @param {object} element
5577
+ *
5578
+ * @returns {string}
5541
5579
  */
5542
5580
  function useTooltipContext(id, element) {
5543
5581
  const {
@@ -5689,20 +5727,20 @@ function prefixId$9(id) {
5689
5727
  return `bio-properties-panel-${id}`;
5690
5728
  }
5691
5729
 
5692
- /**
5693
- * Accesses the global DescriptionContext and returns a description for a given id and element.
5694
- *
5695
- * @example
5696
- * ```jsx
5697
- * function TextField(props) {
5698
- * const description = useDescriptionContext('input1', element);
5699
- * }
5700
- * ```
5701
- *
5702
- * @param {string} id
5703
- * @param {object} element
5704
- *
5705
- * @returns {string}
5730
+ /**
5731
+ * Accesses the global DescriptionContext and returns a description for a given id and element.
5732
+ *
5733
+ * @example
5734
+ * ```jsx
5735
+ * function TextField(props) {
5736
+ * const description = useDescriptionContext('input1', element);
5737
+ * }
5738
+ * ```
5739
+ *
5740
+ * @param {string} id
5741
+ * @param {object} element
5742
+ *
5743
+ * @returns {string}
5706
5744
  */
5707
5745
  function useDescriptionContext(id, element) {
5708
5746
  const {
@@ -5723,11 +5761,11 @@ function useErrors() {
5723
5761
  return errors;
5724
5762
  }
5725
5763
 
5726
- /**
5727
- * Subscribe to an event immediately. Update subscription after inputs changed.
5728
- *
5729
- * @param {string} event
5730
- * @param {Function} callback
5764
+ /**
5765
+ * Subscribe to an event immediately. Update subscription after inputs changed.
5766
+ *
5767
+ * @param {string} event
5768
+ * @param {Function} callback
5731
5769
  */
5732
5770
  function useEvent(event, callback, eventBus) {
5733
5771
  const eventContext = hooks.useContext(EventContext);
@@ -5757,20 +5795,20 @@ function useEvent(event, callback, eventBus) {
5757
5795
  }, [callback, event, eventBus]);
5758
5796
  }
5759
5797
 
5760
- /**
5761
- * Creates a state that persists in the global LayoutContext.
5762
- *
5763
- * @example
5764
- * ```jsx
5765
- * function Group(props) {
5766
- * const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
5767
- * }
5768
- * ```
5769
- *
5770
- * @param {(string|number)[]} path
5771
- * @param {any} [defaultValue]
5772
- *
5773
- * @returns {[ any, Function ]}
5798
+ /**
5799
+ * Creates a state that persists in the global LayoutContext.
5800
+ *
5801
+ * @example
5802
+ * ```jsx
5803
+ * function Group(props) {
5804
+ * const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
5805
+ * }
5806
+ * ```
5807
+ *
5808
+ * @param {(string|number)[]} path
5809
+ * @param {any} [defaultValue]
5810
+ *
5811
+ * @returns {[ any, Function ]}
5774
5812
  */
5775
5813
  function useLayoutState(path, defaultValue) {
5776
5814
  const {
@@ -5784,11 +5822,11 @@ function useLayoutState(path, defaultValue) {
5784
5822
  return [layoutForKey, setState];
5785
5823
  }
5786
5824
 
5787
- /**
5788
- * @pinussilvestrus: we need to introduce our own hook to persist the previous
5789
- * state on updates.
5790
- *
5791
- * cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
5825
+ /**
5826
+ * @pinussilvestrus: we need to introduce our own hook to persist the previous
5827
+ * state on updates.
5828
+ *
5829
+ * cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
5792
5830
  */
5793
5831
 
5794
5832
  function usePrevious(value) {
@@ -5799,12 +5837,12 @@ function usePrevious(value) {
5799
5837
  return ref.current;
5800
5838
  }
5801
5839
 
5802
- /**
5803
- * Subscribe to `propertiesPanel.showEntry`.
5804
- *
5805
- * @param {string} id
5806
- *
5807
- * @returns {import('preact').Ref}
5840
+ /**
5841
+ * Subscribe to `propertiesPanel.showEntry`.
5842
+ *
5843
+ * @param {string} id
5844
+ *
5845
+ * @returns {import('preact').Ref}
5808
5846
  */
5809
5847
  function useShowEntryEvent(id) {
5810
5848
  const {
@@ -5835,20 +5873,20 @@ function useShowEntryEvent(id) {
5835
5873
  return ref;
5836
5874
  }
5837
5875
 
5838
- /**
5839
- * @callback setSticky
5840
- * @param {boolean} value
5876
+ /**
5877
+ * @callback setSticky
5878
+ * @param {boolean} value
5841
5879
  */
5842
5880
 
5843
- /**
5844
- * Use IntersectionObserver to identify when DOM element is in sticky mode.
5845
- * If sticky is observered setSticky(true) will be called.
5846
- * If sticky mode is left, setSticky(false) will be called.
5847
- *
5848
- *
5849
- * @param {Object} ref
5850
- * @param {string} scrollContainerSelector
5851
- * @param {setSticky} setSticky
5881
+ /**
5882
+ * Use IntersectionObserver to identify when DOM element is in sticky mode.
5883
+ * If sticky is observered setSticky(true) will be called.
5884
+ * If sticky mode is left, setSticky(false) will be called.
5885
+ *
5886
+ *
5887
+ * @param {Object} ref
5888
+ * @param {string} scrollContainerSelector
5889
+ * @param {setSticky} setSticky
5852
5890
  */
5853
5891
  function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky) {
5854
5892
  const [scrollContainer, setScrollContainer] = hooks.useState(minDom.query(scrollContainerSelector));
@@ -5902,19 +5940,19 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
5902
5940
  }, [ref.current, scrollContainer, setSticky]);
5903
5941
  }
5904
5942
 
5905
- /**
5906
- * Creates a static function reference with changing body.
5907
- * This is necessary when external libraries require a callback function
5908
- * that has references to state variables.
5909
- *
5910
- * Usage:
5911
- * const callback = useStaticCallback((val) => {val === currentState});
5912
- *
5913
- * The `callback` reference is static and can be safely used in external
5914
- * libraries or as a prop that does not cause rerendering of children.
5915
- *
5916
- * @param {Function} callback function with changing reference
5917
- * @returns {Function} static function reference
5943
+ /**
5944
+ * Creates a static function reference with changing body.
5945
+ * This is necessary when external libraries require a callback function
5946
+ * that has references to state variables.
5947
+ *
5948
+ * Usage:
5949
+ * const callback = useStaticCallback((val) => {val === currentState});
5950
+ *
5951
+ * The `callback` reference is static and can be safely used in external
5952
+ * libraries or as a prop that does not cause rerendering of children.
5953
+ *
5954
+ * @param {Function} callback function with changing reference
5955
+ * @returns {Function} static function reference
5918
5956
  */
5919
5957
  function useStaticCallback(callback) {
5920
5958
  const callbackRef = hooks.useRef(callback);
@@ -6055,13 +6093,13 @@ function DataMarker(props) {
6055
6093
  return null;
6056
6094
  }
6057
6095
 
6058
- /**
6059
- * @typedef { {
6060
- * text: (element: object) => string,
6061
- * icon?: (element: Object) => import('preact').Component
6062
- * } } PlaceholderDefinition
6063
- *
6064
- * @param { PlaceholderDefinition } props
6096
+ /**
6097
+ * @typedef { {
6098
+ * text: (element: object) => string,
6099
+ * icon?: (element: Object) => import('preact').Component
6100
+ * } } PlaceholderDefinition
6101
+ *
6102
+ * @param { PlaceholderDefinition } props
6065
6103
  */
6066
6104
  function Placeholder(props) {
6067
6105
  const {
@@ -6098,9 +6136,9 @@ function Description$1(props) {
6098
6136
  }
6099
6137
  const noop$6 = () => {};
6100
6138
 
6101
- /**
6102
- * Buffer `.focus()` calls while the editor is not initialized.
6103
- * Set Focus inside when the editor is ready.
6139
+ /**
6140
+ * Buffer `.focus()` calls while the editor is not initialized.
6141
+ * Set Focus inside when the editor is ready.
6104
6142
  */
6105
6143
  const useBufferedFocus$1 = function (editor, ref) {
6106
6144
  const [buffer, setBuffer] = hooks.useState(undefined);
@@ -6200,9 +6238,9 @@ const CodeEditor$1 = React.forwardRef((props, ref) => {
6200
6238
  });
6201
6239
  const noop$5 = () => {};
6202
6240
 
6203
- /**
6204
- * Buffer `.focus()` calls while the editor is not initialized.
6205
- * Set Focus inside when the editor is ready.
6241
+ /**
6242
+ * Buffer `.focus()` calls while the editor is not initialized.
6243
+ * Set Focus inside when the editor is ready.
6206
6244
  */
6207
6245
  const useBufferedFocus = function (editor, ref) {
6208
6246
  const [buffer, setBuffer] = hooks.useState(undefined);
@@ -6251,10 +6289,10 @@ const CodeEditor = React.forwardRef((props, ref) => {
6251
6289
  hooks.useEffect(() => {
6252
6290
  let editor;
6253
6291
 
6254
- /* Trigger FEEL toggle when
6255
- *
6256
- * - `backspace` is pressed
6257
- * - AND the cursor is at the beginning of the input
6292
+ /* Trigger FEEL toggle when
6293
+ *
6294
+ * - `backspace` is pressed
6295
+ * - AND the cursor is at the beginning of the input
6258
6296
  */
6259
6297
  const onKeyDown = e => {
6260
6298
  if (e.key !== 'Backspace' || !editor) {
@@ -6343,10 +6381,10 @@ function FeelIndicator(props) {
6343
6381
  }
6344
6382
  const noop$4 = () => {};
6345
6383
 
6346
- /**
6347
- * @param {Object} props
6348
- * @param {Object} props.label
6349
- * @param {String} props.feel
6384
+ /**
6385
+ * @param {Object} props
6386
+ * @param {Object} props.label
6387
+ * @param {String} props.feel
6350
6388
  */
6351
6389
  function FeelIcon(props) {
6352
6390
  const {
@@ -6380,22 +6418,22 @@ const FeelPopupContext = preact.createContext({
6380
6418
  source: null
6381
6419
  });
6382
6420
 
6383
- /**
6384
- * Add a dragger that calls back the passed function with
6385
- * { event, delta } on drag.
6386
- *
6387
- * @example
6388
- *
6389
- * function dragMove(event, delta) {
6390
- * // we are dragging (!!)
6391
- * }
6392
- *
6393
- * domElement.addEventListener('dragstart', dragger(dragMove));
6394
- *
6395
- * @param {Function} fn
6396
- * @param {Element} [dragPreview]
6397
- *
6398
- * @return {Function} drag start callback function
6421
+ /**
6422
+ * Add a dragger that calls back the passed function with
6423
+ * { event, delta } on drag.
6424
+ *
6425
+ * @example
6426
+ *
6427
+ * function dragMove(event, delta) {
6428
+ * // we are dragging (!!)
6429
+ * }
6430
+ *
6431
+ * domElement.addEventListener('dragstart', dragger(dragMove));
6432
+ *
6433
+ * @param {Function} fn
6434
+ * @param {Element} [dragPreview]
6435
+ *
6436
+ * @return {Function} drag start callback function
6399
6437
  */
6400
6438
  function createDragger(fn, dragPreview) {
6401
6439
  let self;
@@ -6449,23 +6487,23 @@ function emptyCanvas() {
6449
6487
  }
6450
6488
  const noop$3 = () => {};
6451
6489
 
6452
- /**
6453
- * A generic popup component.
6454
- *
6455
- * @param {Object} props
6456
- * @param {HTMLElement} [props.container]
6457
- * @param {string} [props.className]
6458
- * @param {boolean} [props.delayInitialFocus]
6459
- * @param {{x: number, y: number}} [props.position]
6460
- * @param {number} [props.width]
6461
- * @param {number} [props.height]
6462
- * @param {Function} props.onClose
6463
- * @param {Function} [props.onPostActivate]
6464
- * @param {Function} [props.onPostDeactivate]
6465
- * @param {boolean} [props.returnFocus]
6466
- * @param {boolean} [props.closeOnEscape]
6467
- * @param {string} props.title
6468
- * @param {Ref} [ref]
6490
+ /**
6491
+ * A generic popup component.
6492
+ *
6493
+ * @param {Object} props
6494
+ * @param {HTMLElement} [props.container]
6495
+ * @param {string} [props.className]
6496
+ * @param {boolean} [props.delayInitialFocus]
6497
+ * @param {{x: number, y: number}} [props.position]
6498
+ * @param {number} [props.width]
6499
+ * @param {number} [props.height]
6500
+ * @param {Function} props.onClose
6501
+ * @param {Function} [props.onPostActivate]
6502
+ * @param {Function} [props.onPostDeactivate]
6503
+ * @param {boolean} [props.returnFocus]
6504
+ * @param {boolean} [props.closeOnEscape]
6505
+ * @param {string} props.title
6506
+ * @param {Ref} [ref]
6469
6507
  */
6470
6508
  function PopupComponent(props, globalRef) {
6471
6509
  const {
@@ -6683,12 +6721,12 @@ function getContainerNode(node) {
6683
6721
  const FEEL_POPUP_WIDTH = 700;
6684
6722
  const FEEL_POPUP_HEIGHT = 250;
6685
6723
 
6686
- /**
6687
- * FEEL popup component, built as a singleton. Emits lifecycle events as follows:
6688
- * - `feelPopup.open` - fired before the popup is mounted
6689
- * - `feelPopup.opened` - fired after the popup is mounted. Event context contains the DOM node of the popup
6690
- * - `feelPopup.close` - fired before the popup is unmounted. Event context contains the DOM node of the popup
6691
- * - `feelPopup.closed` - fired after the popup is unmounted
6724
+ /**
6725
+ * FEEL popup component, built as a singleton. Emits lifecycle events as follows:
6726
+ * - `feelPopup.open` - fired before the popup is mounted
6727
+ * - `feelPopup.opened` - fired after the popup is mounted. Event context contains the DOM node of the popup
6728
+ * - `feelPopup.close` - fired before the popup is unmounted. Event context contains the DOM node of the popup
6729
+ * - `feelPopup.closed` - fired after the popup is unmounted
6692
6730
  */
6693
6731
  function FEELPopupRoot(props) {
6694
6732
  const {
@@ -6698,7 +6736,8 @@ function FEELPopupRoot(props) {
6698
6736
  on() {},
6699
6737
  off() {}
6700
6738
  },
6701
- popupContainer
6739
+ popupContainer,
6740
+ getPopupLinks = () => []
6702
6741
  } = props;
6703
6742
  const prevElement = usePrevious(element);
6704
6743
  const [popupConfig, setPopupConfig] = hooks.useState({});
@@ -6773,6 +6812,7 @@ function FEELPopupRoot(props) {
6773
6812
  children: [open && jsxRuntime.jsx(FeelPopupComponent, {
6774
6813
  onClose: handleClose,
6775
6814
  container: popupContainer,
6815
+ getLinks: getPopupLinks,
6776
6816
  sourceElement: sourceElement,
6777
6817
  emit: emit,
6778
6818
  ...popupConfig
@@ -6782,6 +6822,7 @@ function FEELPopupRoot(props) {
6782
6822
  function FeelPopupComponent(props) {
6783
6823
  const {
6784
6824
  container,
6825
+ getLinks,
6785
6826
  id,
6786
6827
  hostLanguage,
6787
6828
  onInput,
@@ -6852,24 +6893,24 @@ function FeelPopupComponent(props) {
6852
6893
  height: FEEL_POPUP_HEIGHT,
6853
6894
  width: FEEL_POPUP_WIDTH,
6854
6895
  ref: popupRef,
6855
- children: [jsxRuntime.jsxs(Popup.Title, {
6896
+ children: [jsxRuntime.jsx(Popup.Title, {
6856
6897
  title: title,
6857
6898
  emit: emit,
6858
6899
  showCloseButton: true,
6859
6900
  closeButtonTooltip: "Save and close",
6860
6901
  onClose: onClose,
6861
6902
  draggable: true,
6862
- children: [type === 'feel' && jsxRuntime.jsxs("a", {
6863
- href: "https://docs.camunda.io/docs/components/modeler/feel/what-is-feel/",
6864
- target: "_blank",
6865
- class: "bio-properties-panel-feel-popup__title-link",
6866
- children: ["Learn FEEL expressions", jsxRuntime.jsx(HelpIcon, {})]
6867
- }), type === 'feelers' && jsxRuntime.jsxs("a", {
6868
- href: "https://docs.camunda.io/docs/components/modeler/forms/configuration/forms-config-templating-syntax/",
6869
- target: "_blank",
6870
- class: "bio-properties-panel-feel-popup__title-link",
6871
- children: ["Learn templating", jsxRuntime.jsx(HelpIcon, {})]
6872
- })]
6903
+ children: jsxRuntime.jsx(jsxRuntime.Fragment, {
6904
+ children: getLinks(type).map((link, index) => {
6905
+ return jsxRuntime.jsxs("a", {
6906
+ rel: "noreferrer",
6907
+ href: link.href,
6908
+ target: "_blank",
6909
+ class: "bio-properties-panel-feel-popup__title-link",
6910
+ children: [link.title, jsxRuntime.jsx(LaunchIcon, {})]
6911
+ }, index);
6912
+ })
6913
+ })
6873
6914
  }), jsxRuntime.jsx(Popup.Body, {
6874
6915
  children: jsxRuntime.jsxs("div", {
6875
6916
  onKeyDownCapture: onKeyDownCapture,
@@ -6912,11 +6953,11 @@ function autoCompletionOpen(element) {
6912
6953
  return element.closest('.cm-editor').querySelector('.cm-tooltip-autocomplete');
6913
6954
  }
6914
6955
 
6915
- /**
6916
- * This hook behaves like useEffect, but does not trigger on the first render.
6917
- *
6918
- * @param {Function} effect
6919
- * @param {Array} deps
6956
+ /**
6957
+ * This hook behaves like useEffect, but does not trigger on the first render.
6958
+ *
6959
+ * @param {Function} effect
6960
+ * @param {Array} deps
6920
6961
  */
6921
6962
  function useUpdateEffect(effect, deps) {
6922
6963
  const isMounted = hooks.useRef(false);
@@ -6993,19 +7034,19 @@ function ToggleSwitch(props) {
6993
7034
  });
6994
7035
  }
6995
7036
 
6996
- /**
6997
- * @param {Object} props
6998
- * @param {Object} props.element
6999
- * @param {String} props.id
7000
- * @param {String} props.description
7001
- * @param {String} props.label
7002
- * @param {String} props.switcherLabel
7003
- * @param {Boolean} props.inline
7004
- * @param {Function} props.getValue
7005
- * @param {Function} props.setValue
7006
- * @param {Function} props.onFocus
7007
- * @param {Function} props.onBlur
7008
- * @param {string|import('preact').Component} props.tooltip
7037
+ /**
7038
+ * @param {Object} props
7039
+ * @param {Object} props.element
7040
+ * @param {String} props.id
7041
+ * @param {String} props.description
7042
+ * @param {String} props.label
7043
+ * @param {String} props.switcherLabel
7044
+ * @param {Boolean} props.inline
7045
+ * @param {Function} props.getValue
7046
+ * @param {Function} props.setValue
7047
+ * @param {Function} props.onFocus
7048
+ * @param {Function} props.onBlur
7049
+ * @param {string|import('preact').Component} props.tooltip
7009
7050
  */
7010
7051
  function ToggleSwitchEntry(props) {
7011
7052
  const {
@@ -7112,22 +7153,22 @@ function NumberField(props) {
7112
7153
  });
7113
7154
  }
7114
7155
 
7115
- /**
7116
- * @param {Object} props
7117
- * @param {Boolean} props.debounce
7118
- * @param {String} props.description
7119
- * @param {Boolean} props.disabled
7120
- * @param {Object} props.element
7121
- * @param {Function} props.getValue
7122
- * @param {String} props.id
7123
- * @param {String} props.label
7124
- * @param {String} props.max
7125
- * @param {String} props.min
7126
- * @param {Function} props.setValue
7127
- * @param {Function} props.onFocus
7128
- * @param {Function} props.onBlur
7129
- * @param {String} props.step
7130
- * @param {Function} props.validate
7156
+ /**
7157
+ * @param {Object} props
7158
+ * @param {Boolean} props.debounce
7159
+ * @param {String} props.description
7160
+ * @param {Boolean} props.disabled
7161
+ * @param {Object} props.element
7162
+ * @param {Function} props.getValue
7163
+ * @param {String} props.id
7164
+ * @param {String} props.label
7165
+ * @param {String} props.max
7166
+ * @param {String} props.min
7167
+ * @param {Function} props.setValue
7168
+ * @param {Function} props.onFocus
7169
+ * @param {Function} props.onBlur
7170
+ * @param {String} props.step
7171
+ * @param {Function} props.validate
7131
7172
  */
7132
7173
  function NumberFieldEntry(props) {
7133
7174
  const {
@@ -7612,26 +7653,26 @@ React.forwardRef((props, ref) => {
7612
7653
  });
7613
7654
  });
7614
7655
 
7615
- /**
7616
- * @param {Object} props
7617
- * @param {Object} props.element
7618
- * @param {String} props.id
7619
- * @param {String} props.description
7620
- * @param {Boolean} props.debounce
7621
- * @param {Boolean} props.disabled
7622
- * @param {Boolean} props.feel
7623
- * @param {String} props.label
7624
- * @param {Function} props.getValue
7625
- * @param {Function} props.setValue
7626
- * @param {Function} props.tooltipContainer
7627
- * @param {Function} props.validate
7628
- * @param {Function} props.show
7629
- * @param {Function} props.example
7630
- * @param {Function} props.variables
7631
- * @param {Function} props.onFocus
7632
- * @param {Function} props.onBlur
7633
- * @param {string} [props.placeholder]
7634
- * @param {string|import('preact').Component} props.tooltip
7656
+ /**
7657
+ * @param {Object} props
7658
+ * @param {Object} props.element
7659
+ * @param {String} props.id
7660
+ * @param {String} props.description
7661
+ * @param {Boolean} props.debounce
7662
+ * @param {Boolean} props.disabled
7663
+ * @param {Boolean} props.feel
7664
+ * @param {String} props.label
7665
+ * @param {Function} props.getValue
7666
+ * @param {Function} props.setValue
7667
+ * @param {Function} props.tooltipContainer
7668
+ * @param {Function} props.validate
7669
+ * @param {Function} props.show
7670
+ * @param {Function} props.example
7671
+ * @param {Function} props.variables
7672
+ * @param {Function} props.onFocus
7673
+ * @param {Function} props.onBlur
7674
+ * @param {string} [props.placeholder]
7675
+ * @param {string|import('preact').Component} props.tooltip
7635
7676
  */
7636
7677
  function FeelEntry(props) {
7637
7678
  const {
@@ -7718,27 +7759,27 @@ function FeelEntry(props) {
7718
7759
  });
7719
7760
  }
7720
7761
 
7721
- /**
7722
- * @param {Object} props
7723
- * @param {Object} props.element
7724
- * @param {String} props.id
7725
- * @param {String} props.description
7726
- * @param {Boolean} props.debounce
7727
- * @param {Boolean} props.disabled
7728
- * @param {String} props.max
7729
- * @param {String} props.min
7730
- * @param {String} props.step
7731
- * @param {Boolean} props.feel
7732
- * @param {String} props.label
7733
- * @param {Function} props.getValue
7734
- * @param {Function} props.setValue
7735
- * @param {Function} props.tooltipContainer
7736
- * @param {Function} props.validate
7737
- * @param {Function} props.show
7738
- * @param {Function} props.example
7739
- * @param {Function} props.variables
7740
- * @param {Function} props.onFocus
7741
- * @param {Function} props.onBlur
7762
+ /**
7763
+ * @param {Object} props
7764
+ * @param {Object} props.element
7765
+ * @param {String} props.id
7766
+ * @param {String} props.description
7767
+ * @param {Boolean} props.debounce
7768
+ * @param {Boolean} props.disabled
7769
+ * @param {String} props.max
7770
+ * @param {String} props.min
7771
+ * @param {String} props.step
7772
+ * @param {Boolean} props.feel
7773
+ * @param {String} props.label
7774
+ * @param {Function} props.getValue
7775
+ * @param {Function} props.setValue
7776
+ * @param {Function} props.tooltipContainer
7777
+ * @param {Function} props.validate
7778
+ * @param {Function} props.show
7779
+ * @param {Function} props.example
7780
+ * @param {Function} props.variables
7781
+ * @param {Function} props.onFocus
7782
+ * @param {Function} props.onBlur
7742
7783
  */
7743
7784
  function FeelNumberEntry(props) {
7744
7785
  return jsxRuntime.jsx(FeelEntry, {
@@ -7748,24 +7789,24 @@ function FeelNumberEntry(props) {
7748
7789
  });
7749
7790
  }
7750
7791
 
7751
- /**
7752
- * @param {Object} props
7753
- * @param {Object} props.element
7754
- * @param {String} props.id
7755
- * @param {String} props.description
7756
- * @param {Boolean} props.debounce
7757
- * @param {Boolean} props.disabled
7758
- * @param {Boolean} props.feel
7759
- * @param {String} props.label
7760
- * @param {Function} props.getValue
7761
- * @param {Function} props.setValue
7762
- * @param {Function} props.tooltipContainer
7763
- * @param {Function} props.validate
7764
- * @param {Function} props.show
7765
- * @param {Function} props.example
7766
- * @param {Function} props.variables
7767
- * @param {Function} props.onFocus
7768
- * @param {Function} props.onBlur
7792
+ /**
7793
+ * @param {Object} props
7794
+ * @param {Object} props.element
7795
+ * @param {String} props.id
7796
+ * @param {String} props.description
7797
+ * @param {Boolean} props.debounce
7798
+ * @param {Boolean} props.disabled
7799
+ * @param {Boolean} props.feel
7800
+ * @param {String} props.label
7801
+ * @param {Function} props.getValue
7802
+ * @param {Function} props.setValue
7803
+ * @param {Function} props.tooltipContainer
7804
+ * @param {Function} props.validate
7805
+ * @param {Function} props.show
7806
+ * @param {Function} props.example
7807
+ * @param {Function} props.variables
7808
+ * @param {Function} props.onFocus
7809
+ * @param {Function} props.onBlur
7769
7810
  */
7770
7811
  function FeelToggleSwitchEntry(props) {
7771
7812
  return jsxRuntime.jsx(FeelEntry, {
@@ -7775,26 +7816,26 @@ function FeelToggleSwitchEntry(props) {
7775
7816
  });
7776
7817
  }
7777
7818
 
7778
- /**
7779
- * @param {Object} props
7780
- * @param {Object} props.element
7781
- * @param {String} props.id
7782
- * @param {String} props.description
7783
- * @param {String} props.hostLanguage
7784
- * @param {Boolean} props.singleLine
7785
- * @param {Boolean} props.debounce
7786
- * @param {Boolean} props.disabled
7787
- * @param {Boolean} props.feel
7788
- * @param {String} props.label
7789
- * @param {Function} props.getValue
7790
- * @param {Function} props.setValue
7791
- * @param {Function} props.tooltipContainer
7792
- * @param {Function} props.validate
7793
- * @param {Function} props.show
7794
- * @param {Function} props.example
7795
- * @param {Function} props.variables
7796
- * @param {Function} props.onFocus
7797
- * @param {Function} props.onBlur
7819
+ /**
7820
+ * @param {Object} props
7821
+ * @param {Object} props.element
7822
+ * @param {String} props.id
7823
+ * @param {String} props.description
7824
+ * @param {String} props.hostLanguage
7825
+ * @param {Boolean} props.singleLine
7826
+ * @param {Boolean} props.debounce
7827
+ * @param {Boolean} props.disabled
7828
+ * @param {Boolean} props.feel
7829
+ * @param {String} props.label
7830
+ * @param {Function} props.getValue
7831
+ * @param {Function} props.setValue
7832
+ * @param {Function} props.tooltipContainer
7833
+ * @param {Function} props.validate
7834
+ * @param {Function} props.show
7835
+ * @param {Function} props.example
7836
+ * @param {Function} props.variables
7837
+ * @param {Function} props.onFocus
7838
+ * @param {Function} props.onBlur
7798
7839
  */
7799
7840
  function FeelTemplatingEntry(props) {
7800
7841
  return jsxRuntime.jsx(FeelEntry, {
@@ -7862,84 +7903,85 @@ const DEFAULT_LAYOUT = {};
7862
7903
  const DEFAULT_DESCRIPTION = {};
7863
7904
  const DEFAULT_TOOLTIP = {};
7864
7905
 
7865
- /**
7866
- * @typedef { {
7867
- * component: import('preact').Component,
7868
- * id: String,
7869
- * isEdited?: Function
7870
- * } } EntryDefinition
7871
- *
7872
- * @typedef { {
7873
- * autoFocusEntry: String,
7874
- * autoOpen?: Boolean,
7875
- * entries: Array<EntryDefinition>,
7876
- * id: String,
7877
- * label: String,
7878
- * remove: (event: MouseEvent) => void
7879
- * } } ListItemDefinition
7880
- *
7881
- * @typedef { {
7882
- * add: (event: MouseEvent) => void,
7883
- * component: import('preact').Component,
7884
- * element: Object,
7885
- * id: String,
7886
- * items: Array<ListItemDefinition>,
7887
- * label: String,
7888
- * shouldOpen?: Boolean
7889
- * } } ListGroupDefinition
7890
- *
7891
- * @typedef { {
7892
- * component?: import('preact').Component,
7893
- * entries: Array<EntryDefinition>,
7894
- * id: String,
7895
- * label: String,
7896
- * shouldOpen?: Boolean
7897
- * } } GroupDefinition
7898
- *
7899
- * @typedef { {
7900
- * [id: String]: GetDescriptionFunction
7901
- * } } DescriptionConfig
7902
- *
7903
- * @typedef { {
7904
- * [id: String]: GetTooltipFunction
7905
- * } } TooltipConfig
7906
- *
7907
- * @callback { {
7908
- * @param {string} id
7909
- * @param {Object} element
7910
- * @returns {string}
7911
- * } } GetDescriptionFunction
7912
- *
7913
- * @callback { {
7914
- * @param {string} id
7915
- * @param {Object} element
7916
- * @returns {string}
7917
- * } } GetTooltipFunction
7918
- *
7919
- * @typedef { {
7920
- * getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
7921
- * getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
7922
- * } } PlaceholderProvider
7923
- *
7906
+ /**
7907
+ * @typedef { {
7908
+ * component: import('preact').Component,
7909
+ * id: String,
7910
+ * isEdited?: Function
7911
+ * } } EntryDefinition
7912
+ *
7913
+ * @typedef { {
7914
+ * autoFocusEntry: String,
7915
+ * autoOpen?: Boolean,
7916
+ * entries: Array<EntryDefinition>,
7917
+ * id: String,
7918
+ * label: String,
7919
+ * remove: (event: MouseEvent) => void
7920
+ * } } ListItemDefinition
7921
+ *
7922
+ * @typedef { {
7923
+ * add: (event: MouseEvent) => void,
7924
+ * component: import('preact').Component,
7925
+ * element: Object,
7926
+ * id: String,
7927
+ * items: Array<ListItemDefinition>,
7928
+ * label: String,
7929
+ * shouldOpen?: Boolean
7930
+ * } } ListGroupDefinition
7931
+ *
7932
+ * @typedef { {
7933
+ * component?: import('preact').Component,
7934
+ * entries: Array<EntryDefinition>,
7935
+ * id: String,
7936
+ * label: String,
7937
+ * shouldOpen?: Boolean
7938
+ * } } GroupDefinition
7939
+ *
7940
+ * @typedef { {
7941
+ * [id: String]: GetDescriptionFunction
7942
+ * } } DescriptionConfig
7943
+ *
7944
+ * @typedef { {
7945
+ * [id: String]: GetTooltipFunction
7946
+ * } } TooltipConfig
7947
+ *
7948
+ * @callback { {
7949
+ * @param {string} id
7950
+ * @param {Object} element
7951
+ * @returns {string}
7952
+ * } } GetDescriptionFunction
7953
+ *
7954
+ * @callback { {
7955
+ * @param {string} id
7956
+ * @param {Object} element
7957
+ * @returns {string}
7958
+ * } } GetTooltipFunction
7959
+ *
7960
+ * @typedef { {
7961
+ * getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
7962
+ * getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
7963
+ * } } PlaceholderProvider
7964
+ *
7924
7965
  */
7925
7966
 
7926
- /**
7927
- * A basic properties panel component. Describes *how* content will be rendered, accepts
7928
- * data from implementor to describe *what* will be rendered.
7929
- *
7930
- * @param {Object} props
7931
- * @param {Object|Array} props.element
7932
- * @param {import('./components/Header').HeaderProvider} props.headerProvider
7933
- * @param {PlaceholderProvider} [props.placeholderProvider]
7934
- * @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
7935
- * @param {Object} [props.layoutConfig]
7936
- * @param {Function} [props.layoutChanged]
7937
- * @param {DescriptionConfig} [props.descriptionConfig]
7938
- * @param {Function} [props.descriptionLoaded]
7939
- * @param {TooltipConfig} [props.tooltipConfig]
7940
- * @param {Function} [props.tooltipLoaded]
7941
- * @param {HTMLElement} [props.feelPopupContainer]
7942
- * @param {Object} [props.eventBus]
7967
+ /**
7968
+ * A basic properties panel component. Describes *how* content will be rendered, accepts
7969
+ * data from implementor to describe *what* will be rendered.
7970
+ *
7971
+ * @param {Object} props
7972
+ * @param {Object|Array} props.element
7973
+ * @param {import('./components/Header').HeaderProvider} props.headerProvider
7974
+ * @param {PlaceholderProvider} [props.placeholderProvider]
7975
+ * @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
7976
+ * @param {Object} [props.layoutConfig]
7977
+ * @param {Function} [props.layoutChanged]
7978
+ * @param {DescriptionConfig} [props.descriptionConfig]
7979
+ * @param {Function} [props.descriptionLoaded]
7980
+ * @param {TooltipConfig} [props.tooltipConfig]
7981
+ * @param {Function} [props.tooltipLoaded]
7982
+ * @param {HTMLElement} [props.feelPopupContainer]
7983
+ * @param {Function} [props.getFeelPopupLinks]
7984
+ * @param {Object} [props.eventBus]
7943
7985
  */
7944
7986
  function PropertiesPanel$1(props) {
7945
7987
  const {
@@ -7954,6 +7996,7 @@ function PropertiesPanel$1(props) {
7954
7996
  tooltipConfig,
7955
7997
  tooltipLoaded,
7956
7998
  feelPopupContainer,
7999
+ getFeelPopupLinks,
7957
8000
  eventBus
7958
8001
  } = props;
7959
8002
 
@@ -8058,6 +8101,7 @@ function PropertiesPanel$1(props) {
8058
8101
  element: element,
8059
8102
  eventBus: eventBus,
8060
8103
  popupContainer: feelPopupContainer,
8104
+ getPopupLinks: getFeelPopupLinks,
8061
8105
  children: jsxRuntime.jsxs("div", {
8062
8106
  class: "bio-properties-panel",
8063
8107
  children: [jsxRuntime.jsx(Header, {
@@ -8110,11 +8154,11 @@ function createTooltipContext(overrides = {}) {
8110
8154
 
8111
8155
  // hooks //////////////////
8112
8156
 
8113
- /**
8114
- * This hook behaves like useLayoutEffect, but does not trigger on the first render.
8115
- *
8116
- * @param {Function} effect
8117
- * @param {Array} deps
8157
+ /**
8158
+ * This hook behaves like useLayoutEffect, but does not trigger on the first render.
8159
+ *
8160
+ * @param {Function} effect
8161
+ * @param {Array} deps
8118
8162
  */
8119
8163
  function useUpdateLayoutEffect(effect, deps) {
8120
8164
  const isMounted = hooks.useRef(false);
@@ -8127,20 +8171,20 @@ function useUpdateLayoutEffect(effect, deps) {
8127
8171
  }, deps);
8128
8172
  }
8129
8173
 
8130
- /**
8131
- * @typedef { {
8132
- * [key: string]: string;
8133
- * } } TranslateReplacements
8174
+ /**
8175
+ * @typedef { {
8176
+ * [key: string]: string;
8177
+ * } } TranslateReplacements
8134
8178
  */
8135
8179
 
8136
- /**
8137
- * A simple translation stub to be used for multi-language support.
8138
- * Can be easily replaced with a more sophisticated solution.
8139
- *
8140
- * @param {string} template to interpolate
8141
- * @param {TranslateReplacements} [replacements] a map with substitutes
8142
- *
8143
- * @return {string} the translated string
8180
+ /**
8181
+ * A simple translation stub to be used for multi-language support.
8182
+ * Can be easily replaced with a more sophisticated solution.
8183
+ *
8184
+ * @param {string} template to interpolate
8185
+ * @param {TranslateReplacements} [replacements] a map with substitutes
8186
+ *
8187
+ * @return {string} the translated string
8144
8188
  */
8145
8189
  function translateFallback(template, replacements) {
8146
8190
  replacements = replacements || {};
@@ -8249,8 +8293,8 @@ function ListItem(props) {
8249
8293
  }
8250
8294
  const noop$1 = () => {};
8251
8295
 
8252
- /**
8253
- * @param {import('../PropertiesPanel').ListGroupDefinition} props
8296
+ /**
8297
+ * @param {import('../PropertiesPanel').ListGroupDefinition} props
8254
8298
  */
8255
8299
  function ListGroup(props) {
8256
8300
  const {
@@ -8441,18 +8485,18 @@ function Checkbox(props) {
8441
8485
  });
8442
8486
  }
8443
8487
 
8444
- /**
8445
- * @param {Object} props
8446
- * @param {Object} props.element
8447
- * @param {String} props.id
8448
- * @param {String} props.description
8449
- * @param {String} props.label
8450
- * @param {Function} props.getValue
8451
- * @param {Function} props.setValue
8452
- * @param {Function} props.onFocus
8453
- * @param {Function} props.onBlur
8454
- * @param {string|import('preact').Component} props.tooltip
8455
- * @param {boolean} [props.disabled]
8488
+ /**
8489
+ * @param {Object} props
8490
+ * @param {Object} props.element
8491
+ * @param {String} props.id
8492
+ * @param {String} props.description
8493
+ * @param {String} props.label
8494
+ * @param {Function} props.getValue
8495
+ * @param {Function} props.setValue
8496
+ * @param {Function} props.onFocus
8497
+ * @param {Function} props.onBlur
8498
+ * @param {string|import('preact').Component} props.tooltip
8499
+ * @param {boolean} [props.disabled]
8456
8500
  */
8457
8501
  function CheckboxEntry(props) {
8458
8502
  const {
@@ -8572,20 +8616,20 @@ function Select(props) {
8572
8616
  });
8573
8617
  }
8574
8618
 
8575
- /**
8576
- * @param {object} props
8577
- * @param {object} props.element
8578
- * @param {string} props.id
8579
- * @param {string} [props.description]
8580
- * @param {string} props.label
8581
- * @param {Function} props.getValue
8582
- * @param {Function} props.setValue
8583
- * @param {Function} props.onFocus
8584
- * @param {Function} props.onBlur
8585
- * @param {Function} props.getOptions
8586
- * @param {boolean} [props.disabled]
8587
- * @param {Function} [props.validate]
8588
- * @param {string|import('preact').Component} props.tooltip
8619
+ /**
8620
+ * @param {object} props
8621
+ * @param {object} props.element
8622
+ * @param {string} props.id
8623
+ * @param {string} [props.description]
8624
+ * @param {string} props.label
8625
+ * @param {Function} props.getValue
8626
+ * @param {Function} props.setValue
8627
+ * @param {Function} props.onFocus
8628
+ * @param {Function} props.onBlur
8629
+ * @param {Function} props.getOptions
8630
+ * @param {boolean} [props.disabled]
8631
+ * @param {Function} [props.validate]
8632
+ * @param {string|import('preact').Component} props.tooltip
8589
8633
  */
8590
8634
  function SelectEntry(props) {
8591
8635
  const {
@@ -8876,20 +8920,20 @@ function Textfield(props) {
8876
8920
  });
8877
8921
  }
8878
8922
 
8879
- /**
8880
- * @param {Object} props
8881
- * @param {Object} props.element
8882
- * @param {String} props.id
8883
- * @param {String} props.description
8884
- * @param {Boolean} props.debounce
8885
- * @param {Boolean} props.disabled
8886
- * @param {String} props.label
8887
- * @param {Function} props.getValue
8888
- * @param {Function} props.setValue
8889
- * @param {Function} props.onFocus
8890
- * @param {Function} props.onBlur
8891
- * @param {string|import('preact').Component} props.tooltip
8892
- * @param {Function} props.validate
8923
+ /**
8924
+ * @param {Object} props
8925
+ * @param {Object} props.element
8926
+ * @param {String} props.id
8927
+ * @param {String} props.description
8928
+ * @param {Boolean} props.debounce
8929
+ * @param {Boolean} props.disabled
8930
+ * @param {String} props.label
8931
+ * @param {Function} props.getValue
8932
+ * @param {Function} props.setValue
8933
+ * @param {Function} props.onFocus
8934
+ * @param {Function} props.onBlur
8935
+ * @param {string|import('preact').Component} props.tooltip
8936
+ * @param {Function} props.validate
8893
8937
  */
8894
8938
  function TextfieldEntry(props) {
8895
8939
  const {
@@ -8964,20 +9008,20 @@ class FeelPopupModule {
8964
9008
  this._eventBus = eventBus;
8965
9009
  }
8966
9010
 
8967
- /**
8968
- * Check if the FEEL popup is open.
8969
- * @return {Boolean}
9011
+ /**
9012
+ * Check if the FEEL popup is open.
9013
+ * @return {Boolean}
8970
9014
  */
8971
9015
  isOpen() {
8972
9016
  return this._eventBus.fire('feelPopup._isOpen');
8973
9017
  }
8974
9018
 
8975
- /**
8976
- * Open the FEEL popup.
8977
- *
8978
- * @param {String} entryId
8979
- * @param {Object} popupConfig
8980
- * @param {HTMLElement} sourceElement
9019
+ /**
9020
+ * Open the FEEL popup.
9021
+ *
9022
+ * @param {String} entryId
9023
+ * @param {Object} popupConfig
9024
+ * @param {HTMLElement} sourceElement
8981
9025
  */
8982
9026
  open(entryId, popupConfig, sourceElement) {
8983
9027
  return this._eventBus.fire('feelPopup._open', {
@@ -8987,8 +9031,8 @@ class FeelPopupModule {
8987
9031
  });
8988
9032
  }
8989
9033
 
8990
- /**
8991
- * Close the FEEL popup.
9034
+ /**
9035
+ * Close the FEEL popup.
8992
9036
  */
8993
9037
  close() {
8994
9038
  return this._eventBus.fire('feelPopup._close');
@@ -9485,7 +9529,7 @@ function isProhibitedPath(path) {
9485
9529
  const prohibitedSegments = ['__proto__', 'prototype', 'constructor'];
9486
9530
  return path.split('.').some(segment => prohibitedSegments.includes(segment));
9487
9531
  }
9488
- const LABELED_NON_INPUTS = ['button', 'group', 'dynamiclist', 'iframe', 'table'];
9532
+ const LABELED_NON_INPUTS = ['button', 'group', 'dynamiclist', 'iframe', 'table', 'documentPreview'];
9489
9533
  const INPUTS = ['checkbox', 'checklist', 'datetime', 'number', 'radio', 'select', 'taglist', 'textfield', 'textarea', 'filepicker'];
9490
9534
  const OPTIONS_INPUTS = ['checklist', 'radio', 'select', 'taglist'];
9491
9535
  function hasEntryConfigured(formFieldDefinition, entryId) {
@@ -10332,7 +10376,7 @@ function LabelEntry(props) {
10332
10376
  return field.type === 'datetime' && (field.subtype === formJsViewer.DATETIME_SUBTYPES.TIME || field.subtype === formJsViewer.DATETIME_SUBTYPES.DATETIME);
10333
10377
  }
10334
10378
  });
10335
- const isSimplyLabled = field => {
10379
+ const isSimplyLabeled = field => {
10336
10380
  return [...INPUTS.filter(input => input !== 'datetime'), ...LABELED_NON_INPUTS].includes(field.type);
10337
10381
  };
10338
10382
  entries.push({
@@ -10341,7 +10385,7 @@ function LabelEntry(props) {
10341
10385
  editField,
10342
10386
  field,
10343
10387
  isEdited: isEdited$6,
10344
- isDefaultVisible: isSimplyLabled
10388
+ isDefaultVisible: isSimplyLabeled
10345
10389
  });
10346
10390
  return entries;
10347
10391
  }
@@ -10445,6 +10489,7 @@ function getLabelText(type) {
10445
10489
  case 'table':
10446
10490
  return 'Table label';
10447
10491
  case 'iframe':
10492
+ case 'documentPreview':
10448
10493
  return 'Title';
10449
10494
  default:
10450
10495
  return 'Field label';
@@ -10501,7 +10546,7 @@ function Height(props) {
10501
10546
  id,
10502
10547
  getValue,
10503
10548
  setValue,
10504
- validate: validate$7
10549
+ validate: validate$a
10505
10550
  });
10506
10551
  }
10507
10552
 
@@ -10511,7 +10556,7 @@ function Height(props) {
10511
10556
  * @param {number|void} value
10512
10557
  * @returns {string|null}
10513
10558
  */
10514
- const validate$7 = value => {
10559
+ const validate$a = value => {
10515
10560
  if (typeof value !== 'number') {
10516
10561
  return 'A number is required.';
10517
10562
  }
@@ -10576,7 +10621,7 @@ function Url(props) {
10576
10621
  setValue,
10577
10622
  singleLine: true,
10578
10623
  tooltip: getTooltip$1(),
10579
- validate: validate$6,
10624
+ validate: validate$9,
10580
10625
  variables
10581
10626
  });
10582
10627
  }
@@ -10603,7 +10648,7 @@ function getTooltip$1() {
10603
10648
  * @param {string|void} value
10604
10649
  * @returns {string|null}
10605
10650
  */
10606
- const validate$6 = value => {
10651
+ const validate$9 = value => {
10607
10652
  if (!value || value.startsWith('=')) {
10608
10653
  return;
10609
10654
  }
@@ -10694,7 +10739,7 @@ function Text(props) {
10694
10739
  };
10695
10740
  return FeelTemplatingEntry({
10696
10741
  debounce,
10697
- description: description$2,
10742
+ description: description$4,
10698
10743
  element: field,
10699
10744
  getValue,
10700
10745
  id,
@@ -10704,7 +10749,7 @@ function Text(props) {
10704
10749
  variables
10705
10750
  });
10706
10751
  }
10707
- const description$2 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
10752
+ const description$4 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
10708
10753
  children: ["Supports markdown and templating.", ' ', jsxRuntime.jsx("a", {
10709
10754
  href: "https://docs.camunda.io/docs/components/modeler/forms/form-element-library/forms-element-library-text/",
10710
10755
  target: "_blank",
@@ -10746,13 +10791,13 @@ function Content(props) {
10746
10791
  };
10747
10792
  return FeelTemplatingEntry({
10748
10793
  debounce,
10749
- description: description$1,
10794
+ description: description$3,
10750
10795
  element: field,
10751
10796
  getValue,
10752
10797
  id,
10753
10798
  label: 'Content',
10754
10799
  hostLanguage: 'html',
10755
- validate: validate$5,
10800
+ validate: validate$8,
10756
10801
  setValue,
10757
10802
  variables
10758
10803
  });
@@ -10760,7 +10805,7 @@ function Content(props) {
10760
10805
 
10761
10806
  // helpers //////////
10762
10807
 
10763
- const description$1 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
10808
+ const description$3 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
10764
10809
  children: ["Supports HTML, styling, and templating. Styles are automatically scoped to the HTML component.", ' ', jsxRuntime.jsx("a", {
10765
10810
  href: "https://docs.camunda.io/docs/components/modeler/forms/form-element-library/forms-element-library-html/",
10766
10811
  target: "_blank",
@@ -10772,7 +10817,7 @@ const description$1 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
10772
10817
  * @param {string|void} value
10773
10818
  * @returns {string|null}
10774
10819
  */
10775
- const validate$5 = value => {
10820
+ const validate$8 = value => {
10776
10821
  // allow empty state
10777
10822
  if (typeof value !== 'string' || value === '') {
10778
10823
  return null;
@@ -11611,7 +11656,7 @@ function InputValuesKey(props) {
11611
11656
  id,
11612
11657
  label: 'Input values key',
11613
11658
  setValue,
11614
- validate: validate$4
11659
+ validate: validate$7
11615
11660
  });
11616
11661
  }
11617
11662
 
@@ -11621,7 +11666,7 @@ function InputValuesKey(props) {
11621
11666
  * @param {string|void} value
11622
11667
  * @returns {string|null}
11623
11668
  */
11624
- const validate$4 = value => {
11669
+ const validate$7 = value => {
11625
11670
  if (typeof value !== 'string' || value.length === 0) {
11626
11671
  return 'Must not be empty.';
11627
11672
  }
@@ -12064,7 +12109,7 @@ function Source(props) {
12064
12109
  setValue,
12065
12110
  singleLine: true,
12066
12111
  variables,
12067
- validate: validate$3
12112
+ validate: validate$6
12068
12113
  });
12069
12114
  }
12070
12115
 
@@ -12074,7 +12119,7 @@ function Source(props) {
12074
12119
  * @param {string|void} value
12075
12120
  * @returns {string|null}
12076
12121
  */
12077
- const validate$3 = value => {
12122
+ const validate$6 = value => {
12078
12123
  if (!minDash.isString(value) || value.length === 0) {
12079
12124
  return 'Must not be empty.';
12080
12125
  }
@@ -12178,7 +12223,7 @@ function RowCount(props) {
12178
12223
  id,
12179
12224
  getValue,
12180
12225
  setValue,
12181
- validate: validate$2
12226
+ validate: validate$5
12182
12227
  });
12183
12228
  }
12184
12229
 
@@ -12188,7 +12233,7 @@ function RowCount(props) {
12188
12233
  * @param {string|void} value
12189
12234
  * @returns {string|null}
12190
12235
  */
12191
- const validate$2 = value => {
12236
+ const validate$5 = value => {
12192
12237
  if (minDash.isNil(value)) {
12193
12238
  return null;
12194
12239
  }
@@ -12362,7 +12407,7 @@ function ColumnsExpression(props) {
12362
12407
  setValue,
12363
12408
  singleLine: true,
12364
12409
  variables,
12365
- validate: validate$1
12410
+ validate: validate$4
12366
12411
  });
12367
12412
  }
12368
12413
 
@@ -12372,7 +12417,7 @@ function ColumnsExpression(props) {
12372
12417
  * @param {string|void} value
12373
12418
  * @returns {string|null}
12374
12419
  */
12375
- const validate$1 = value => {
12420
+ const validate$4 = value => {
12376
12421
  if (!minDash.isString(value) || value.length === 0 || value === '=') {
12377
12422
  return 'Must not be empty.';
12378
12423
  }
@@ -12470,7 +12515,7 @@ function Key(props) {
12470
12515
  id,
12471
12516
  label: 'Key',
12472
12517
  setValue,
12473
- validate
12518
+ validate: validate$3
12474
12519
  });
12475
12520
  }
12476
12521
 
@@ -12480,7 +12525,7 @@ function Key(props) {
12480
12525
  * @param {string|void} value
12481
12526
  * @returns {string|null}
12482
12527
  */
12483
- function validate(value) {
12528
+ function validate$3(value) {
12484
12529
  if (!minDash.isString(value) || value.length === 0) {
12485
12530
  return 'Must not be empty.';
12486
12531
  }
@@ -12618,13 +12663,13 @@ function Accept(props) {
12618
12663
  singleLine: true,
12619
12664
  setValue,
12620
12665
  variables,
12621
- description
12666
+ description: description$2
12622
12667
  });
12623
12668
  }
12624
12669
 
12625
12670
  // helpers //////////
12626
12671
 
12627
- const description = jsxRuntime.jsxs(jsxRuntime.Fragment, {
12672
+ const description$2 = jsxRuntime.jsxs(jsxRuntime.Fragment, {
12628
12673
  children: ["A comma-separated list of", ' ', jsxRuntime.jsx("a", {
12629
12674
  href: "https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#unique_file_type_specifiers",
12630
12675
  target: "_blank",
@@ -12678,6 +12723,236 @@ function Multiple(props) {
12678
12723
  });
12679
12724
  }
12680
12725
 
12726
+ function DocumentsDataSourceEntry(props) {
12727
+ const {
12728
+ editField,
12729
+ field
12730
+ } = props;
12731
+ const entries = [];
12732
+ entries.push({
12733
+ id: 'dataSource',
12734
+ component: DocumentsDataSource,
12735
+ editField: editField,
12736
+ field: field,
12737
+ isEdited: isEdited$6,
12738
+ isDefaultVisible: field => field.type === 'documentPreview'
12739
+ });
12740
+ return entries;
12741
+ }
12742
+ function DocumentsDataSource(props) {
12743
+ const {
12744
+ editField,
12745
+ field,
12746
+ id
12747
+ } = props;
12748
+ const debounce = useService('debounce');
12749
+ const variables = useVariables().map(name => ({
12750
+ name
12751
+ }));
12752
+ const path = ['dataSource'];
12753
+ const getValue = () => {
12754
+ return minDash.get(field, path, '');
12755
+ };
12756
+ const setValue = value => {
12757
+ return editField(field, path, value);
12758
+ };
12759
+ const schema = `[
12760
+ {
12761
+ "documentId": "u123",
12762
+ "metadata": {
12763
+ "fileName": "Document.pdf",
12764
+ "contentType": "application/pdf"
12765
+ }
12766
+ }
12767
+ ]`;
12768
+ const tooltip = jsxRuntime.jsxs("div", {
12769
+ children: [jsxRuntime.jsx("p", {
12770
+ children: "A source is a JSON object containing metadata for a document or an array of documents."
12771
+ }), jsxRuntime.jsx("p", {
12772
+ children: "Each entry must include a document ID, name, and MIME type."
12773
+ }), jsxRuntime.jsx("p", {
12774
+ children: "Additional details are optional. The expected format is as follows:"
12775
+ }), jsxRuntime.jsx("pre", {
12776
+ children: jsxRuntime.jsx("code", {
12777
+ children: schema
12778
+ })
12779
+ })]
12780
+ });
12781
+ return FeelTemplatingEntry({
12782
+ debounce,
12783
+ element: field,
12784
+ getValue,
12785
+ id,
12786
+ label: 'Document reference',
12787
+ feel: 'required',
12788
+ singleLine: true,
12789
+ setValue,
12790
+ variables,
12791
+ tooltip,
12792
+ validate: validate$2
12793
+ });
12794
+ }
12795
+
12796
+ // helpers //////////
12797
+
12798
+ /**
12799
+ * @param {string|undefined} value
12800
+ * @returns {string|null}
12801
+ */
12802
+ const validate$2 = value => {
12803
+ if (typeof value !== 'string' || value.length === 0) {
12804
+ return 'The document data source is required.';
12805
+ }
12806
+ };
12807
+
12808
+ function EndpointKeyEntry(props) {
12809
+ const {
12810
+ editField,
12811
+ field
12812
+ } = props;
12813
+ const entries = [];
12814
+ entries.push({
12815
+ id: 'endpointKey',
12816
+ component: EndpointKey,
12817
+ editField: editField,
12818
+ field: field,
12819
+ isEdited: isEdited$6,
12820
+ isDefaultVisible: field => field.type === 'documentPreview'
12821
+ });
12822
+ return entries;
12823
+ }
12824
+ function EndpointKey(props) {
12825
+ const {
12826
+ editField,
12827
+ field,
12828
+ id
12829
+ } = props;
12830
+ const debounce = useService('debounce');
12831
+ const variables = useVariables().map(name => ({
12832
+ name
12833
+ }));
12834
+ const path = ['endpointKey'];
12835
+ const getValue = () => {
12836
+ return minDash.get(field, path, '');
12837
+ };
12838
+ const setValue = value => {
12839
+ return editField(field, path, value);
12840
+ };
12841
+ const tooltip = jsxRuntime.jsxs("div", {
12842
+ children: [jsxRuntime.jsx("p", {
12843
+ children: "Enter a context key that generates a string with the API endpoint to download a document."
12844
+ }), jsxRuntime.jsxs("p", {
12845
+ children: ["The string must contain ", jsxRuntime.jsx("code", {
12846
+ children: '{ documentId }'
12847
+ }), ", which will be replaced with the document ID from the document's reference."]
12848
+ }), jsxRuntime.jsx("p", {
12849
+ children: "If you're using the Camunda Tasklist, this variable is automatically added to the context for you."
12850
+ }), jsxRuntime.jsxs("p", {
12851
+ children: ["For more details, see the", ' ', jsxRuntime.jsx("a", {
12852
+ href: "https://docs.camunda.io",
12853
+ rel: "noopener noreferrer",
12854
+ target: "_blank",
12855
+ children: "Camunda documentation"
12856
+ })]
12857
+ })]
12858
+ });
12859
+ return FeelTemplatingEntry({
12860
+ debounce,
12861
+ element: field,
12862
+ getValue,
12863
+ id,
12864
+ label: 'Document URL',
12865
+ feel: 'required',
12866
+ singleLine: true,
12867
+ setValue,
12868
+ variables,
12869
+ description: description$1,
12870
+ tooltip,
12871
+ validate: validate$1
12872
+ });
12873
+ }
12874
+
12875
+ // helpers //////////
12876
+
12877
+ /**
12878
+ * @param {string|undefined} value
12879
+ * @returns {string|null}
12880
+ */
12881
+ const validate$1 = value => {
12882
+ if (typeof value !== 'string' || value.length === 0) {
12883
+ return 'The document reference is required.';
12884
+ }
12885
+ };
12886
+ const description$1 = jsxRuntime.jsx(jsxRuntime.Fragment, {
12887
+ children: "Define an API URL for downloading a document"
12888
+ });
12889
+
12890
+ function MaxHeightEntry(props) {
12891
+ const {
12892
+ editField,
12893
+ field
12894
+ } = props;
12895
+ const entries = [];
12896
+ entries.push({
12897
+ id: 'maxHeight',
12898
+ component: MaxHeight,
12899
+ editField: editField,
12900
+ field: field,
12901
+ isEdited: isEdited$7,
12902
+ isDefaultVisible: field => field.type === 'documentPreview'
12903
+ });
12904
+ return entries;
12905
+ }
12906
+ function MaxHeight(props) {
12907
+ const {
12908
+ editField,
12909
+ field,
12910
+ id
12911
+ } = props;
12912
+ const debounce = useService('debounce');
12913
+ const path = ['maxHeight'];
12914
+ const getValue = () => {
12915
+ return minDash.get(field, path, '');
12916
+ };
12917
+ const setValue = value => {
12918
+ return editField(field, path, value);
12919
+ };
12920
+ return NumberFieldEntry({
12921
+ debounce,
12922
+ label: 'Max height of preview container',
12923
+ element: field,
12924
+ id,
12925
+ getValue,
12926
+ setValue,
12927
+ validate,
12928
+ description
12929
+ });
12930
+ }
12931
+
12932
+ // helpers //////////
12933
+
12934
+ /**
12935
+ * @param {string|number|undefined} value
12936
+ * @returns {string|null}
12937
+ */
12938
+ const validate = value => {
12939
+ if (value === undefined || value === '') {
12940
+ return null;
12941
+ }
12942
+ if (typeof value === 'string') {
12943
+ return 'Value must be a number.';
12944
+ }
12945
+ if (!Number.isInteger(value)) {
12946
+ return 'Should be an integer.';
12947
+ }
12948
+ if (value < 1) {
12949
+ return 'Should be greater than zero.';
12950
+ }
12951
+ };
12952
+ const description = jsxRuntime.jsx(jsxRuntime.Fragment, {
12953
+ children: "Documents with height that exceeds the defined value will be vertically scrollable"
12954
+ });
12955
+
12681
12956
  function GeneralGroup(field, editField, getService) {
12682
12957
  const entries = [...IdEntry({
12683
12958
  field,
@@ -12765,6 +13040,9 @@ function GeneralGroup(field, editField, getService) {
12765
13040
  }), ...RowCountEntry({
12766
13041
  field,
12767
13042
  editField
13043
+ }), ...DocumentsDataSourceEntry({
13044
+ field,
13045
+ editField
12768
13046
  })];
12769
13047
  if (entries.length === 0) {
12770
13048
  return null;
@@ -13222,6 +13500,9 @@ function AppearanceGroup(field, editField, getService) {
13222
13500
  }), ...LayouterAppearanceEntry({
13223
13501
  field,
13224
13502
  editField
13503
+ }), ...MaxHeightEntry({
13504
+ field,
13505
+ editField
13225
13506
  })];
13226
13507
  if (!entries.length) {
13227
13508
  return null;
@@ -13390,6 +13671,21 @@ const TOOLTIP_TEXT = `"List of items" defines a constant, predefined set of form
13390
13671
  "Expression" defines options that are populated from a FEEL expression.
13391
13672
  `;
13392
13673
 
13674
+ function DownloadSettings(field, editField) {
13675
+ const entries = [...EndpointKeyEntry({
13676
+ field,
13677
+ editField
13678
+ })];
13679
+ if (!entries.length) {
13680
+ return null;
13681
+ }
13682
+ return {
13683
+ id: 'downloadSettings',
13684
+ label: 'Download settings',
13685
+ entries
13686
+ };
13687
+ }
13688
+
13393
13689
  class PropertiesProvider {
13394
13690
  constructor(propertiesPanel, injector) {
13395
13691
  this._injector = injector;
@@ -13425,7 +13721,7 @@ class PropertiesProvider {
13425
13721
  return groups;
13426
13722
  }
13427
13723
  const getService = (type, strict = true) => this._injector.get(type, strict);
13428
- groups = [...groups, GeneralGroup(field, editField, getService), ...OptionsGroups(field, editField, getService), ...TableHeaderGroups(field, editField), SecurityAttributesGroup(field, editField), ConditionGroup(field, editField), LayoutGroup(field, editField), AppearanceGroup(field, editField), SerializationGroup(field, editField), ConstraintsGroup(field, editField), ValidationGroup(field, editField), CustomPropertiesGroup(field, editField)].filter(group => group != null);
13724
+ groups = [...groups, GeneralGroup(field, editField, getService), DownloadSettings(field, editField), ...OptionsGroups(field, editField, getService), ...TableHeaderGroups(field, editField), SecurityAttributesGroup(field, editField), ConditionGroup(field, editField), LayoutGroup(field, editField), AppearanceGroup(field, editField), SerializationGroup(field, editField), ConstraintsGroup(field, editField), ValidationGroup(field, editField), CustomPropertiesGroup(field, editField)].filter(group => group != null);
13429
13725
  this._filterVisibleEntries(groups, field, getService);
13430
13726
 
13431
13727
  // contract: if a group has no entries or items, it should not be displayed at all
@@ -13588,7 +13884,7 @@ class FormEditor {
13588
13884
  * @type {Element}
13589
13885
  */
13590
13886
  this._container = formJsViewer.createFormContainer();
13591
- this._container.setAttribute('input-handle-modified-keys', 'z,y');
13887
+ this._container.setAttribute('tabindex', '0');
13592
13888
  const {
13593
13889
  container,
13594
13890
  exporter,