@bpmn-io/form-js-editor 1.0.0-alpha.9 → 1.0.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
@@ -15,6 +15,25 @@ var feelers = require('feelers');
15
15
  var FeelEditor = require('@bpmn-io/feel-editor');
16
16
  var Big = require('big.js');
17
17
 
18
+ function _interopNamespaceDefault(e) {
19
+ var n = Object.create(null);
20
+ if (e) {
21
+ Object.keys(e).forEach(function (k) {
22
+ if (k !== 'default') {
23
+ var d = Object.getOwnPropertyDescriptor(e, k);
24
+ Object.defineProperty(n, k, d.get ? d : {
25
+ enumerable: true,
26
+ get: function () { return e[k]; }
27
+ });
28
+ }
29
+ });
30
+ }
31
+ n.default = e;
32
+ return Object.freeze(n);
33
+ }
34
+
35
+ var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
36
+
18
37
  var FN_REF = '__fn';
19
38
  var DEFAULT_PRIORITY$2 = 1000;
20
39
  var slice = Array.prototype.slice;
@@ -515,10 +534,10 @@ function invokeFunction(fn, args) {
515
534
  return fn.apply(null, args);
516
535
  }
517
536
 
518
- /**
519
- * A factory to create a configurable debouncer.
520
- *
521
- * @param {number|boolean} [config=true]
537
+ /**
538
+ * A factory to create a configurable debouncer.
539
+ *
540
+ * @param {number|boolean} [config=true]
522
541
  */
523
542
  function DebounceFactory(config = true) {
524
543
  const timeout = typeof config === 'number' ? config : config ? 300 : 0;
@@ -531,11 +550,11 @@ function DebounceFactory(config = true) {
531
550
  DebounceFactory.$inject = ['config.debounce'];
532
551
 
533
552
  class FieldFactory {
534
- /**
535
- * @constructor
536
- *
537
- * @param { import('./FormFieldRegistry').default } formFieldRegistry
538
- * @param { import('@bpmn-io/form-js-viewer').FormFields } formFields
553
+ /**
554
+ * @constructor
555
+ *
556
+ * @param { import('./FormFieldRegistry').default } formFieldRegistry
557
+ * @param { import('@bpmn-io/form-js-viewer').FormFields } formFields
539
558
  */
540
559
  constructor(formFieldRegistry, formFields) {
541
560
  this._formFieldRegistry = formFieldRegistry;
@@ -598,11 +617,11 @@ class FieldFactory {
598
617
  FieldFactory.$inject = ['formFieldRegistry', 'formFields'];
599
618
 
600
619
  class FormFieldRegistry extends formJsViewer.FormFieldRegistry {
601
- /**
602
- * Updates a form fields id.
603
- *
604
- * @param {Object} formField
605
- * @param {string} newId
620
+ /**
621
+ * Updates a form fields id.
622
+ *
623
+ * @param {Object} formField
624
+ * @param {string} newId
606
625
  */
607
626
  updateId(formField, newId) {
608
627
  this._validateId(newId);
@@ -623,13 +642,13 @@ class FormFieldRegistry extends formJsViewer.FormFieldRegistry {
623
642
  }
624
643
  }
625
644
 
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
645
+ /**
646
+ * Validate the suitability of the given id and signals a problem
647
+ * with an exception.
648
+ *
649
+ * @param {string} id
650
+ *
651
+ * @throws {Error} if id is empty or already assigned
633
652
  */
634
653
  _validateId(id) {
635
654
  if (!id) {
@@ -646,11 +665,11 @@ const MAX_COLUMNS = 16;
646
665
  const MIN_COLUMNS = 2;
647
666
  const MAX_FIELDS_PER_ROW = 4;
648
667
  class FormLayoutValidator {
649
- /**
650
- * @constructor
651
- *
652
- * @param { import('./FormLayouter').default } formLayouter
653
- * @param { import('./FormFieldRegistry').default } formFieldRegistry
668
+ /**
669
+ * @constructor
670
+ *
671
+ * @param { import('./FormLayouter').default } formLayouter
672
+ * @param { import('./FormFieldRegistry').default } formFieldRegistry
654
673
  */
655
674
  constructor(formLayouter, formFieldRegistry) {
656
675
  this._formLayouter = formLayouter;
@@ -710,11 +729,11 @@ function calculateMaxColumnsWithAuto(autoCols) {
710
729
  }
711
730
 
712
731
  class Importer {
713
- /**
714
- * @constructor
715
- * @param { import('../core/FormFieldRegistry').default } formFieldRegistry
716
- * @param { import('../core/FieldFactory').default } fieldFactory
717
- * @param { import('../core/FormLayouter').default } formLayouter
732
+ /**
733
+ * @constructor
734
+ * @param { import('../core/FormFieldRegistry').default } formFieldRegistry
735
+ * @param { import('../core/FieldFactory').default } fieldFactory
736
+ * @param { import('../core/FormLayouter').default } formLayouter
718
737
  */
719
738
  constructor(formFieldRegistry, fieldFactory, formLayouter) {
720
739
  this._formFieldRegistry = formFieldRegistry;
@@ -722,21 +741,21 @@ class Importer {
722
741
  this._formLayouter = formLayouter;
723
742
  }
724
743
 
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}
744
+ /**
745
+ * Import schema creating rows, fields, attaching additional
746
+ * information to each field and adding fields to the
747
+ * field registry.
748
+ *
749
+ * Additional information attached:
750
+ *
751
+ * * `id` (unless present)
752
+ * * `_parent`
753
+ * * `_path`
754
+ *
755
+ * @param {any} schema
756
+ *
757
+ * @typedef {{ warnings: Error[], schema: any }} ImportResult
758
+ * @returns {ImportResult}
740
759
  */
741
760
  importSchema(schema) {
742
761
  // TODO: Add warnings
@@ -754,12 +773,12 @@ class Importer {
754
773
  }
755
774
  }
756
775
 
757
- /**
758
- * @param {{[x: string]: any}} fieldAttrs
759
- * @param {String} [parentId]
760
- * @param {number} [index]
761
- *
762
- * @return {any} field
776
+ /**
777
+ * @param {{[x: string]: any}} fieldAttrs
778
+ * @param {String} [parentId]
779
+ * @param {number} [index]
780
+ *
781
+ * @return {any} field
763
782
  */
764
783
  importFormField(fieldAttrs, parentId, index) {
765
784
  const {
@@ -796,11 +815,11 @@ class Importer {
796
815
  return field;
797
816
  }
798
817
 
799
- /**
800
- * @param {Array<any>} components
801
- * @param {string} parentId
802
- *
803
- * @return {Array<any>} imported components
818
+ /**
819
+ * @param {Array<any>} components
820
+ * @param {string} parentId
821
+ *
822
+ * @return {Array<any>} imported components
804
823
  */
805
824
  importFormFields(components, parentId) {
806
825
  return components.map((component, index) => {
@@ -825,22 +844,22 @@ function editorFormFieldClasses(type, {
825
844
  });
826
845
  }
827
846
 
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
847
+ /**
848
+ * Add a dragger that calls back the passed function with
849
+ * { event, delta } on drag.
850
+ *
851
+ * @example
852
+ *
853
+ * function dragMove(event, delta) {
854
+ * // we are dragging (!!)
855
+ * }
856
+ *
857
+ * domElement.addEventListener('dragstart', dragger(dragMove));
858
+ *
859
+ * @param {Function} fn
860
+ * @param {Element} dragPreview
861
+ *
862
+ * @return {Function} drag start callback function
844
863
  */
845
864
  function createDragger(fn, dragPreview) {
846
865
  let self;
@@ -881,12 +900,12 @@ function createDragger(fn, dragPreview) {
881
900
  return onDragStart;
882
901
  }
883
902
 
884
- /**
885
- * Throttle function call according UI update cycle.
886
- *
887
- * @param {Function} fn
888
- *
889
- * @return {Function} throttled fn
903
+ /**
904
+ * Throttle function call according UI update cycle.
905
+ *
906
+ * @param {Function} fn
907
+ *
908
+ * @return {Function} throttled fn
890
909
  */
891
910
  function throttle(fn) {
892
911
  let active = false;
@@ -915,11 +934,11 @@ const DragAndDropContext = preact.createContext({
915
934
  });
916
935
  var DragAndDropContext$1 = DragAndDropContext;
917
936
 
918
- /**
919
- * @param {string} type
920
- * @param {boolean} [strict]
921
- *
922
- * @returns {any}
937
+ /**
938
+ * @param {string} type
939
+ * @param {boolean} [strict]
940
+ *
941
+ * @returns {any}
923
942
  */
924
943
  function getService$1(type, strict) {}
925
944
  const FormEditorContext = preact.createContext({
@@ -934,83 +953,91 @@ function useService$1 (type, strict) {
934
953
  return getService(type, strict);
935
954
  }
936
955
 
956
+ var _path$3;
937
957
  function _extends$3() { _extends$3 = 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$3.apply(this, arguments); }
938
- var CloseIcon = (({
939
- styles = {},
940
- ...props
941
- }) => /*#__PURE__*/React.createElement("svg", _extends$3({
942
- width: "16",
943
- height: "16",
944
- fill: "currentColor",
945
- xmlns: "http://www.w3.org/2000/svg"
946
- }, props), /*#__PURE__*/React.createElement("path", {
947
- fillRule: "evenodd",
948
- clipRule: "evenodd",
949
- d: "M12 4.7l-.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"
950
- })));
958
+ var SvgClose = function SvgClose(props) {
959
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$3({
960
+ xmlns: "http://www.w3.org/2000/svg",
961
+ width: 16,
962
+ height: 16,
963
+ fill: "currentColor"
964
+ }, props), _path$3 || (_path$3 = /*#__PURE__*/React__namespace.createElement("path", {
965
+ fillRule: "evenodd",
966
+ 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",
967
+ clipRule: "evenodd"
968
+ })));
969
+ };
970
+ var CloseIcon = SvgClose;
951
971
 
972
+ var _path$2, _path2;
952
973
  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); }
953
- var DeleteIcon$1 = (({
954
- styles = {},
955
- ...props
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
- })));
974
+ var SvgDelete = function SvgDelete(props) {
975
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$2({
976
+ xmlns: "http://www.w3.org/2000/svg",
977
+ width: 16,
978
+ height: 16,
979
+ fill: "none"
980
+ }, props), /*#__PURE__*/React__namespace.createElement("rect", {
981
+ width: 16,
982
+ height: 16,
983
+ x: 0.536,
984
+ fill: "#fff",
985
+ rx: 3,
986
+ style: {
987
+ mixBlendMode: "multiply"
988
+ }
989
+ }), /*#__PURE__*/React__namespace.createElement("path", {
990
+ fill: "#fff",
991
+ d: "M0 0h16v16H0z",
992
+ style: {
993
+ mixBlendMode: "multiply"
994
+ },
995
+ transform: "translate(.536)"
996
+ }), _path$2 || (_path$2 = /*#__PURE__*/React__namespace.createElement("path", {
997
+ fill: "currentcolor",
998
+ d: "M7.536 6h-1v6h1V6Zm3 0h-1v6h1V6Z"
999
+ })), _path2 || (_path2 = /*#__PURE__*/React__namespace.createElement("path", {
1000
+ fill: "currentcolor",
1001
+ d: "M2.536 3v1h1v10a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4h1V3h-12Zm2 11V4h8v10h-8Zm6-13h-4v1h4V1Z"
1002
+ })));
1003
+ };
1004
+ var DeleteIcon$1 = SvgDelete;
983
1005
 
1006
+ var _path$1;
984
1007
  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({
989
- xmlns: "http://www.w3.org/2000/svg",
990
- width: "16",
991
- height: "16",
992
- fill: "currentcolor",
993
- viewBox: "0 0 32 32"
994
- }, props), /*#__PURE__*/React.createElement("path", {
995
- d: "M10 6h4v4h-4zm8 0h4v4h-4zm-8 8h4v4h-4zm8 0h4v4h-4zm-8 8h4v4h-4zm8 0h4v4h-4z"
996
- }), /*#__PURE__*/React.createElement("path", {
997
- d: "M0 0h32v32H0z",
998
- fill: "none"
999
- })));
1008
+ var SvgDraggable = function SvgDraggable(props) {
1009
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$1({
1010
+ xmlns: "http://www.w3.org/2000/svg",
1011
+ xmlSpace: "preserve",
1012
+ width: 16,
1013
+ height: 16,
1014
+ fill: "currentcolor",
1015
+ viewBox: "0 0 32 32"
1016
+ }, props), _path$1 || (_path$1 = /*#__PURE__*/React__namespace.createElement("path", {
1017
+ d: "M10 6h4v4h-4zm8 0h4v4h-4zm-8 8h4v4h-4zm8 0h4v4h-4zm-8 8h4v4h-4zm8 0h4v4h-4z"
1018
+ })), /*#__PURE__*/React__namespace.createElement("path", {
1019
+ d: "M0 0h32v32H0z",
1020
+ style: {
1021
+ fill: "none"
1022
+ }
1023
+ }));
1024
+ };
1025
+ var DraggableIcon = SvgDraggable;
1000
1026
 
1027
+ var _path;
1001
1028
  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); }
1002
- var SearchIcon = (({
1003
- styles = {},
1004
- ...props
1005
- }) => /*#__PURE__*/React.createElement("svg", _extends({
1006
- width: "15",
1007
- height: "15",
1008
- fill: "none",
1009
- xmlns: "http://www.w3.org/2000/svg"
1010
- }, props), /*#__PURE__*/React.createElement("path", {
1011
- d: "M14.5 13.793l-3.776-3.776a5.508 5.508 0 10-.707.707l3.776 3.776.707-.707zM2 6.5a4.5 4.5 0 119 0 4.5 4.5 0 01-9 0z",
1012
- fill: "currentColor"
1013
- })));
1029
+ var SvgSearch = function SvgSearch(props) {
1030
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends({
1031
+ xmlns: "http://www.w3.org/2000/svg",
1032
+ width: 15,
1033
+ height: 15,
1034
+ fill: "none"
1035
+ }, props), _path || (_path = /*#__PURE__*/React__namespace.createElement("path", {
1036
+ fill: "currentColor",
1037
+ d: "m14.5 13.793-3.776-3.776a5.508 5.508 0 1 0-.707.707l3.776 3.776.707-.707ZM2 6.5a4.5 4.5 0 1 1 9 0 4.5 4.5 0 0 1-9 0Z"
1038
+ })));
1039
+ };
1040
+ var SearchIcon = SvgSearch;
1014
1041
 
1015
1042
  function EditorText(props) {
1016
1043
  const {
@@ -1206,23 +1233,23 @@ var Slot = (props => {
1206
1233
  return fillsAndSeparators;
1207
1234
  });
1208
1235
 
1209
- /**
1210
- * Creates a Fragment for a fill.
1211
- *
1212
- * @param {Object} fill Fill to be rendered
1213
- * @returns {Object} Preact Fragment containing fill's children
1236
+ /**
1237
+ * Creates a Fragment for a fill.
1238
+ *
1239
+ * @param {Object} fill Fill to be rendered
1240
+ * @returns {Object} Preact Fragment containing fill's children
1214
1241
  */
1215
1242
  const FillFragment = fill => jsxRuntime.jsx(preact.Fragment, {
1216
1243
  children: fill.children
1217
1244
  }, fill.id);
1218
1245
 
1219
- /**
1220
- * Creates an array of fills, with separators inserted between groups.
1221
- *
1222
- * @param {Array} groups Groups of fills
1223
- * @param {Function} fillRenderer Function to create a fill
1224
- * @param {Function} separatorRenderer Function to create a separator
1225
- * @returns {Array} Array of fills and separators
1246
+ /**
1247
+ * Creates an array of fills, with separators inserted between groups.
1248
+ *
1249
+ * @param {Array} groups Groups of fills
1250
+ * @param {Function} fillRenderer Function to create a fill
1251
+ * @param {Function} separatorRenderer Function to create a separator
1252
+ * @returns {Array} Array of fills and separators
1226
1253
  */
1227
1254
  const buildFills = (groups, fillRenderer, separatorRenderer) => {
1228
1255
  const result = [];
@@ -1240,8 +1267,8 @@ const buildFills = (groups, fillRenderer, separatorRenderer) => {
1240
1267
  return result;
1241
1268
  };
1242
1269
 
1243
- /**
1244
- * Groups fills by group name property.
1270
+ /**
1271
+ * Groups fills by group name property.
1245
1272
  */
1246
1273
  const _groupByGroupName = fills => {
1247
1274
  const groups = [];
@@ -1261,8 +1288,8 @@ const _groupByGroupName = fills => {
1261
1288
  return Object.keys(groupsById).sort().map(id => groupsById[id]);
1262
1289
  };
1263
1290
 
1264
- /**
1265
- * Compares fills by priority.
1291
+ /**
1292
+ * Compares fills by priority.
1266
1293
  */
1267
1294
  const _comparePriority = (a, b) => {
1268
1295
  return (b.priority || 0) - (a.priority || 0);
@@ -1490,19 +1517,19 @@ const DRAG_NO_DROP_CLS = 'fjs-no-drop';
1490
1517
  const DRAG_NO_MOVE_CLS = 'fjs-no-move';
1491
1518
  const ERROR_DROP_CLS = 'fjs-error-drop';
1492
1519
 
1493
- /**
1494
- * @typedef { { id: String, components: Array<any> } } FormRow
1520
+ /**
1521
+ * @typedef { { id: String, components: Array<any> } } FormRow
1495
1522
  */
1496
1523
 
1497
1524
  class Dragging {
1498
- /**
1499
- * @constructor
1500
- *
1501
- * @param { import('../../core/FormFieldRegistry').default } formFieldRegistry
1502
- * @param { import('../../core/FormLayouter').default } formLayouter
1503
- * @param { import('../../core/FormLayoutValidator').default } formLayoutValidator
1504
- * @param { import('../../core/EventBus').default } eventBus
1505
- * @param { import('../modeling/Modeling').default } modeling
1525
+ /**
1526
+ * @constructor
1527
+ *
1528
+ * @param { import('../../core/FormFieldRegistry').default } formFieldRegistry
1529
+ * @param { import('../../core/FormLayouter').default } formLayouter
1530
+ * @param { import('../../core/FormLayoutValidator').default } formLayoutValidator
1531
+ * @param { import('../../core/EventBus').default } eventBus
1532
+ * @param { import('../modeling/Modeling').default } modeling
1506
1533
  */
1507
1534
  constructor(formFieldRegistry, formLayouter, formLayoutValidator, eventBus, modeling) {
1508
1535
  this._formFieldRegistry = formFieldRegistry;
@@ -1512,13 +1539,13 @@ class Dragging {
1512
1539
  this._modeling = modeling;
1513
1540
  }
1514
1541
 
1515
- /**
1516
- * Calculcates position in form schema given the dropped place.
1517
- *
1518
- * @param { FormRow } targetRow
1519
- * @param { any } targetFormField
1520
- * @param { HTMLElement } sibling
1521
- * @returns { number }
1542
+ /**
1543
+ * Calculcates position in form schema given the dropped place.
1544
+ *
1545
+ * @param { FormRow } targetRow
1546
+ * @param { any } targetFormField
1547
+ * @param { HTMLElement } sibling
1548
+ * @returns { number }
1522
1549
  */
1523
1550
  getTargetIndex(targetRow, targetFormField, sibling) {
1524
1551
  /** @type HTMLElement */
@@ -1620,8 +1647,8 @@ class Dragging {
1620
1647
  }
1621
1648
  }
1622
1649
 
1623
- /**
1624
- * @param { { container: Array<string>, direction: string, mirrorContainer: string } } options
1650
+ /**
1651
+ * @param { { container: Array<string>, direction: string, mirrorContainer: string } } options
1625
1652
  */
1626
1653
  createDragulaInstance(options) {
1627
1654
  const {
@@ -2018,7 +2045,7 @@ function DebugColumns(props) {
2018
2045
  return null;
2019
2046
  }
2020
2047
  return jsxRuntime.jsx("div", {
2021
- 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;",
2048
+ 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;",
2022
2049
  class: "fjs-debug-columns",
2023
2050
  children: (field.layout || {}).columns || 'auto'
2024
2051
  });
@@ -3077,10 +3104,10 @@ function updateRow(formField, rowId) {
3077
3104
  }
3078
3105
 
3079
3106
  class AddFormFieldHandler {
3080
- /**
3081
- * @constructor
3082
- * @param { import('../../../FormEditor').default } formEditor
3083
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3107
+ /**
3108
+ * @constructor
3109
+ * @param { import('../../../FormEditor').default } formEditor
3110
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3084
3111
  */
3085
3112
  constructor(formEditor, formFieldRegistry) {
3086
3113
  this._formEditor = formEditor;
@@ -3141,10 +3168,10 @@ class AddFormFieldHandler {
3141
3168
  AddFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
3142
3169
 
3143
3170
  class EditFormFieldHandler {
3144
- /**
3145
- * @constructor
3146
- * @param { import('../../../FormEditor').default } formEditor
3147
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3171
+ /**
3172
+ * @constructor
3173
+ * @param { import('../../../FormEditor').default } formEditor
3174
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3148
3175
  */
3149
3176
  constructor(formEditor, formFieldRegistry) {
3150
3177
  this._formEditor = formEditor;
@@ -3207,10 +3234,10 @@ class EditFormFieldHandler {
3207
3234
  EditFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
3208
3235
 
3209
3236
  class MoveFormFieldHandler {
3210
- /**
3211
- * @constructor
3212
- * @param { import('../../../FormEditor').default } formEditor
3213
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3237
+ /**
3238
+ * @constructor
3239
+ * @param { import('../../../FormEditor').default } formEditor
3240
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3214
3241
  */
3215
3242
  constructor(formEditor, formFieldRegistry) {
3216
3243
  this._formEditor = formEditor;
@@ -3299,10 +3326,10 @@ class MoveFormFieldHandler {
3299
3326
  MoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
3300
3327
 
3301
3328
  class RemoveFormFieldHandler {
3302
- /**
3303
- * @constructor
3304
- * @param { import('../../../FormEditor').default } formEditor
3305
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3329
+ /**
3330
+ * @constructor
3331
+ * @param { import('../../../FormEditor').default } formEditor
3332
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3306
3333
  */
3307
3334
  constructor(formEditor, formFieldRegistry) {
3308
3335
  this._formEditor = formEditor;
@@ -3362,9 +3389,9 @@ class RemoveFormFieldHandler {
3362
3389
  RemoveFormFieldHandler.$inject = ['formEditor', 'formFieldRegistry'];
3363
3390
 
3364
3391
  class UpdateIdClaimHandler {
3365
- /**
3366
- * @constructor
3367
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3392
+ /**
3393
+ * @constructor
3394
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3368
3395
  */
3369
3396
  constructor(formFieldRegistry) {
3370
3397
  this._formFieldRegistry = formFieldRegistry;
@@ -3397,9 +3424,9 @@ class UpdateIdClaimHandler {
3397
3424
  UpdateIdClaimHandler.$inject = ['formFieldRegistry'];
3398
3425
 
3399
3426
  class UpdateKeyClaimHandler {
3400
- /**
3401
- * @constructor
3402
- * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3427
+ /**
3428
+ * @constructor
3429
+ * @param { import('../../../core/FormFieldRegistry').default } formFieldRegistry
3403
3430
  */
3404
3431
  constructor(formFieldRegistry) {
3405
3432
  this._formFieldRegistry = formFieldRegistry;
@@ -3865,8 +3892,8 @@ class ValidateBehavior extends CommandInterceptor {
3865
3892
  constructor(eventBus) {
3866
3893
  super(eventBus);
3867
3894
 
3868
- /**
3869
- * Remove custom validation if <validationType> is about to be added.
3895
+ /**
3896
+ * Remove custom validation if <validationType> is about to be added.
3870
3897
  */
3871
3898
  // @ts-ignore-next-line
3872
3899
  this.preExecute('formField.edit', function (context) {
@@ -4446,22 +4473,22 @@ var SelectionModule = {
4446
4473
  selectionBehavior: ['type', SelectionBehavior]
4447
4474
  };
4448
4475
 
4449
- /**
4450
- * Base class for sectionable UI modules.
4451
- *
4452
- * @property {EventBus} _eventBus - EventBus instance used for event handling.
4453
- * @property {string} managerType - Type of the render manager. Used to form event names.
4454
- *
4455
- * @class SectionModuleBase
4476
+ /**
4477
+ * Base class for sectionable UI modules.
4478
+ *
4479
+ * @property {EventBus} _eventBus - EventBus instance used for event handling.
4480
+ * @property {string} managerType - Type of the render manager. Used to form event names.
4481
+ *
4482
+ * @class SectionModuleBase
4456
4483
  */
4457
4484
  class SectionModuleBase {
4458
- /**
4459
- * Create a SectionModuleBase instance.
4460
- *
4461
- * @param {any} eventBus - The EventBus instance used for event handling.
4462
- * @param {string} sectionKey - The type of render manager. Used to form event names.
4463
- *
4464
- * @constructor
4485
+ /**
4486
+ * Create a SectionModuleBase instance.
4487
+ *
4488
+ * @param {any} eventBus - The EventBus instance used for event handling.
4489
+ * @param {string} sectionKey - The type of render manager. Used to form event names.
4490
+ *
4491
+ * @constructor
4465
4492
  */
4466
4493
  constructor(eventBus, sectionKey) {
4467
4494
  this._eventBus = eventBus;
@@ -4474,10 +4501,10 @@ class SectionModuleBase {
4474
4501
  });
4475
4502
  }
4476
4503
 
4477
- /**
4478
- * Attach the managed section to a parent node.
4479
- *
4480
- * @param {HTMLElement} container - The parent node to attach to.
4504
+ /**
4505
+ * Attach the managed section to a parent node.
4506
+ *
4507
+ * @param {HTMLElement} container - The parent node to attach to.
4481
4508
  */
4482
4509
  attachTo(container) {
4483
4510
  this._onceSectionRendered(() => this._eventBus.fire(`${this._sectionKey}.attach`, {
@@ -4485,22 +4512,22 @@ class SectionModuleBase {
4485
4512
  }));
4486
4513
  }
4487
4514
 
4488
- /**
4489
- * Detach the managed section from its parent node.
4515
+ /**
4516
+ * Detach the managed section from its parent node.
4490
4517
  */
4491
4518
  detach() {
4492
4519
  this._onceSectionRendered(() => this._eventBus.fire(`${this._sectionKey}.detach`));
4493
4520
  }
4494
4521
 
4495
- /**
4496
- * Reset the managed section to its initial state.
4522
+ /**
4523
+ * Reset the managed section to its initial state.
4497
4524
  */
4498
4525
  reset() {
4499
4526
  this._onceSectionRendered(() => this._eventBus.fire(`${this._sectionKey}.reset`));
4500
4527
  }
4501
4528
 
4502
- /**
4503
- * Circumvents timing issues.
4529
+ /**
4530
+ * Circumvents timing issues.
4504
4531
  */
4505
4532
  _onceSectionRendered(callback) {
4506
4533
  if (this.isSectionRendered) {
@@ -5983,150 +6010,309 @@ function isEdited$7(node) {
5983
6010
  function prefixId$6(id) {
5984
6011
  return `bio-properties-panel-${id}`;
5985
6012
  }
5986
- const noop$1 = () => {};
5987
- function FeelTextfield(props) {
6013
+ function NumberField(props) {
5988
6014
  const {
5989
6015
  debounce,
6016
+ disabled,
6017
+ displayLabel = true,
5990
6018
  id,
6019
+ inputRef,
5991
6020
  label,
6021
+ max,
6022
+ min,
5992
6023
  onInput,
5993
- onError,
5994
- feel,
6024
+ step,
5995
6025
  value = '',
5996
- disabled = false,
5997
- variables,
5998
- tooltipContainer,
5999
- OptionalComponent = OptionalFeelInput
6026
+ onFocus,
6027
+ onBlur
6000
6028
  } = props;
6001
- const [localValue, _setLocalValue] = hooks.useState(value);
6002
- const editorRef = useShowEntryEvent(id);
6003
- const containerRef = hooks.useRef();
6004
- const feelActive = minDash.isString(localValue) && localValue.startsWith('=') || feel === 'required';
6005
- const feelOnlyValue = minDash.isString(localValue) && localValue.startsWith('=') ? localValue.substring(1) : localValue;
6006
- const [focus, _setFocus] = hooks.useState(undefined);
6007
- const setFocus = (offset = 0) => {
6008
- const hasFocus = containerRef.current.contains(document.activeElement);
6009
-
6010
- // Keep caret position if it is already focused, otherwise focus at the end
6011
- const position = hasFocus ? document.activeElement.selectionStart : Infinity;
6012
- _setFocus(position + offset);
6013
- };
6029
+ const [localValue, setLocalValue] = hooks.useState(value);
6014
6030
  const handleInputCallback = hooks.useMemo(() => {
6015
- return debounce(newValue => {
6016
- onInput(newValue);
6031
+ return debounce(event => {
6032
+ const {
6033
+ validity,
6034
+ value
6035
+ } = event.target;
6036
+ if (validity.valid) {
6037
+ onInput(value ? parseFloat(value) : undefined);
6038
+ }
6017
6039
  });
6018
6040
  }, [onInput, debounce]);
6019
- const setLocalValue = newValue => {
6020
- _setLocalValue(newValue);
6021
- if (!newValue || newValue === '=') {
6022
- handleInputCallback(undefined);
6023
- } else {
6024
- handleInputCallback(newValue);
6025
- }
6026
- };
6027
- const handleFeelToggle = useStaticCallback(() => {
6028
- if (feel === 'required') {
6029
- return;
6030
- }
6031
- if (!feelActive) {
6032
- setLocalValue('=' + localValue);
6033
- } else {
6034
- setLocalValue(feelOnlyValue);
6035
- }
6036
- });
6037
- const handleLocalInput = newValue => {
6038
- if (feelActive) {
6039
- newValue = '=' + newValue;
6040
- }
6041
- if (newValue === localValue) {
6042
- return;
6043
- }
6044
- setLocalValue(newValue);
6045
- if (!feelActive && minDash.isString(newValue) && newValue.startsWith('=')) {
6046
- // focus is behind `=` sign that will be removed
6047
- setFocus(-1);
6048
- }
6041
+ const handleInput = e => {
6042
+ handleInputCallback(e);
6043
+ setLocalValue(e.target.value);
6049
6044
  };
6050
- const handleLint = useStaticCallback(lint => {
6051
- if (!(lint && lint.length)) {
6052
- onError(undefined);
6053
- return;
6054
- }
6055
- const error = lint[0];
6056
- const message = `${error.source}: ${error.message}`;
6057
- onError(message);
6058
- });
6059
- hooks.useEffect(() => {
6060
- if (typeof focus !== 'undefined') {
6061
- editorRef.current.focus(focus);
6062
- _setFocus(undefined);
6063
- }
6064
- }, [focus]);
6065
6045
  hooks.useEffect(() => {
6066
6046
  if (value === localValue) {
6067
6047
  return;
6068
6048
  }
6069
-
6070
- // External value change removed content => keep FEEL configuration
6071
- if (!value) {
6072
- setLocalValue(feelActive ? '=' : '');
6073
- return;
6074
- }
6075
6049
  setLocalValue(value);
6076
6050
  }, [value]);
6077
-
6078
- // copy-paste integration
6079
- hooks.useEffect(() => {
6080
- const copyHandler = event => {
6081
- if (!feelActive) {
6082
- return;
6083
- }
6084
- event.clipboardData.setData('application/FEEL', event.clipboardData.getData('text'));
6085
- };
6086
- const pasteHandler = event => {
6087
- if (feelActive) {
6088
- return;
6089
- }
6090
- const data = event.clipboardData.getData('application/FEEL');
6091
- if (data) {
6092
- setTimeout(() => {
6093
- handleFeelToggle();
6094
- setFocus();
6095
- });
6096
- }
6097
- };
6098
- containerRef.current.addEventListener('copy', copyHandler);
6099
- containerRef.current.addEventListener('cut', copyHandler);
6100
- containerRef.current.addEventListener('paste', pasteHandler);
6101
- return () => {
6102
- containerRef.current.removeEventListener('copy', copyHandler);
6103
- containerRef.current.removeEventListener('cut', copyHandler);
6104
- containerRef.current.removeEventListener('paste', pasteHandler);
6105
- };
6106
- }, [containerRef, feelActive, handleFeelToggle, setFocus]);
6107
6051
  return jsxRuntime.jsxs("div", {
6108
- class: classnames('bio-properties-panel-feel-entry', {
6109
- 'feel-active': feelActive
6110
- }),
6111
- children: [jsxRuntime.jsxs("label", {
6052
+ class: "bio-properties-panel-numberfield",
6053
+ children: [displayLabel && jsxRuntime.jsx("label", {
6112
6054
  for: prefixId$5(id),
6113
6055
  class: "bio-properties-panel-label",
6114
- onClick: () => setFocus(),
6115
- children: [label, jsxRuntime.jsx(FeelIcon, {
6116
- label: label,
6117
- feel: feel,
6118
- onClick: handleFeelToggle,
6119
- active: feelActive
6120
- })]
6121
- }), jsxRuntime.jsxs("div", {
6122
- class: "bio-properties-panel-feel-container",
6123
- ref: containerRef,
6124
- children: [jsxRuntime.jsx(FeelIndicator, {
6125
- active: feelActive,
6126
- disabled: feel !== 'optional' || disabled,
6056
+ children: label
6057
+ }), jsxRuntime.jsx("input", {
6058
+ id: prefixId$5(id),
6059
+ ref: inputRef,
6060
+ type: "number",
6061
+ name: id,
6062
+ spellCheck: "false",
6063
+ autoComplete: "off",
6064
+ disabled: disabled,
6065
+ class: "bio-properties-panel-input",
6066
+ max: max,
6067
+ min: min,
6068
+ onInput: handleInput,
6069
+ onFocus: onFocus,
6070
+ onBlur: onBlur,
6071
+ step: step,
6072
+ value: localValue
6073
+ })]
6074
+ });
6075
+ }
6076
+
6077
+ /**
6078
+ * @param {Object} props
6079
+ * @param {Boolean} props.debounce
6080
+ * @param {String} props.description
6081
+ * @param {Boolean} props.disabled
6082
+ * @param {Object} props.element
6083
+ * @param {Function} props.getValue
6084
+ * @param {String} props.id
6085
+ * @param {String} props.label
6086
+ * @param {String} props.max
6087
+ * @param {String} props.min
6088
+ * @param {Function} props.setValue
6089
+ * @param {Function} props.onFocus
6090
+ * @param {Function} props.onBlur
6091
+ * @param {String} props.step
6092
+ * @param {Function} props.validate
6093
+ */
6094
+ function NumberFieldEntry(props) {
6095
+ const {
6096
+ debounce,
6097
+ description,
6098
+ disabled,
6099
+ element,
6100
+ getValue,
6101
+ id,
6102
+ label,
6103
+ max,
6104
+ min,
6105
+ setValue,
6106
+ step,
6107
+ onFocus,
6108
+ onBlur,
6109
+ validate
6110
+ } = props;
6111
+ const [cachedInvalidValue, setCachedInvalidValue] = hooks.useState(null);
6112
+ const globalError = useError(id);
6113
+ const [localError, setLocalError] = hooks.useState(null);
6114
+ let value = getValue(element);
6115
+ const previousValue = usePrevious(value);
6116
+ hooks.useEffect(() => {
6117
+ if (minDash.isFunction(validate)) {
6118
+ const newValidationError = validate(value) || null;
6119
+ setLocalError(newValidationError);
6120
+ }
6121
+ }, [value]);
6122
+ const onInput = newValue => {
6123
+ let newValidationError = null;
6124
+ if (minDash.isFunction(validate)) {
6125
+ newValidationError = validate(newValue) || null;
6126
+ }
6127
+ if (newValidationError) {
6128
+ setCachedInvalidValue(newValue);
6129
+ } else {
6130
+ setValue(newValue);
6131
+ }
6132
+ setLocalError(newValidationError);
6133
+ };
6134
+ if (previousValue === value && localError) {
6135
+ value = cachedInvalidValue;
6136
+ }
6137
+ const error = globalError || localError;
6138
+ return jsxRuntime.jsxs("div", {
6139
+ class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
6140
+ "data-entry-id": id,
6141
+ children: [jsxRuntime.jsx(NumberField, {
6142
+ debounce: debounce,
6143
+ disabled: disabled,
6144
+ id: id,
6145
+ label: label,
6146
+ onFocus: onFocus,
6147
+ onBlur: onBlur,
6148
+ onInput: onInput,
6149
+ max: max,
6150
+ min: min,
6151
+ step: step,
6152
+ value: value
6153
+ }, element), error && jsxRuntime.jsx("div", {
6154
+ class: "bio-properties-panel-error",
6155
+ children: error
6156
+ }), jsxRuntime.jsx(Description$1, {
6157
+ forId: id,
6158
+ element: element,
6159
+ value: description
6160
+ })]
6161
+ });
6162
+ }
6163
+ function isEdited$6(node) {
6164
+ return node && !!node.value;
6165
+ }
6166
+
6167
+ // helpers /////////////////
6168
+
6169
+ function prefixId$5(id) {
6170
+ return `bio-properties-panel-${id}`;
6171
+ }
6172
+ const noop$1 = () => {};
6173
+ function FeelTextfield(props) {
6174
+ const {
6175
+ debounce,
6176
+ id,
6177
+ label,
6178
+ onInput,
6179
+ onError,
6180
+ feel,
6181
+ value = '',
6182
+ disabled = false,
6183
+ variables,
6184
+ tooltipContainer,
6185
+ OptionalComponent = OptionalFeelInput
6186
+ } = props;
6187
+ const [localValue, _setLocalValue] = hooks.useState(value);
6188
+ const editorRef = useShowEntryEvent(id);
6189
+ const containerRef = hooks.useRef();
6190
+ const feelActive = minDash.isString(localValue) && localValue.startsWith('=') || feel === 'required';
6191
+ const feelOnlyValue = minDash.isString(localValue) && localValue.startsWith('=') ? localValue.substring(1) : localValue;
6192
+ const [focus, _setFocus] = hooks.useState(undefined);
6193
+ const setFocus = (offset = 0) => {
6194
+ const hasFocus = containerRef.current.contains(document.activeElement);
6195
+
6196
+ // Keep caret position if it is already focused, otherwise focus at the end
6197
+ const position = hasFocus ? document.activeElement.selectionStart : Infinity;
6198
+ _setFocus(position + offset);
6199
+ };
6200
+ const handleInputCallback = hooks.useMemo(() => {
6201
+ return debounce(newValue => {
6202
+ onInput(newValue);
6203
+ });
6204
+ }, [onInput, debounce]);
6205
+ const setLocalValue = newValue => {
6206
+ _setLocalValue(newValue);
6207
+ if (!newValue || newValue === '=') {
6208
+ handleInputCallback(undefined);
6209
+ } else {
6210
+ handleInputCallback(newValue);
6211
+ }
6212
+ };
6213
+ const handleFeelToggle = useStaticCallback(() => {
6214
+ if (feel === 'required') {
6215
+ return;
6216
+ }
6217
+ if (!feelActive) {
6218
+ setLocalValue('=' + localValue);
6219
+ } else {
6220
+ setLocalValue(feelOnlyValue);
6221
+ }
6222
+ });
6223
+ const handleLocalInput = newValue => {
6224
+ if (feelActive) {
6225
+ newValue = '=' + newValue;
6226
+ }
6227
+ if (newValue === localValue) {
6228
+ return;
6229
+ }
6230
+ setLocalValue(newValue);
6231
+ if (!feelActive && minDash.isString(newValue) && newValue.startsWith('=')) {
6232
+ // focus is behind `=` sign that will be removed
6233
+ setFocus(-1);
6234
+ }
6235
+ };
6236
+ const handleLint = useStaticCallback(lint => {
6237
+ if (!(lint && lint.length)) {
6238
+ onError(undefined);
6239
+ return;
6240
+ }
6241
+ const error = lint[0];
6242
+ const message = `${error.source}: ${error.message}`;
6243
+ onError(message);
6244
+ });
6245
+ hooks.useEffect(() => {
6246
+ if (typeof focus !== 'undefined') {
6247
+ editorRef.current.focus(focus);
6248
+ _setFocus(undefined);
6249
+ }
6250
+ }, [focus]);
6251
+ hooks.useEffect(() => {
6252
+ if (value === localValue) {
6253
+ return;
6254
+ }
6255
+
6256
+ // External value change removed content => keep FEEL configuration
6257
+ if (!value) {
6258
+ setLocalValue(feelActive ? '=' : '');
6259
+ return;
6260
+ }
6261
+ setLocalValue(value);
6262
+ }, [value]);
6263
+
6264
+ // copy-paste integration
6265
+ hooks.useEffect(() => {
6266
+ const copyHandler = event => {
6267
+ if (!feelActive) {
6268
+ return;
6269
+ }
6270
+ event.clipboardData.setData('application/FEEL', event.clipboardData.getData('text'));
6271
+ };
6272
+ const pasteHandler = event => {
6273
+ if (feelActive) {
6274
+ return;
6275
+ }
6276
+ const data = event.clipboardData.getData('application/FEEL');
6277
+ if (data) {
6278
+ setTimeout(() => {
6279
+ handleFeelToggle();
6280
+ setFocus();
6281
+ });
6282
+ }
6283
+ };
6284
+ containerRef.current.addEventListener('copy', copyHandler);
6285
+ containerRef.current.addEventListener('cut', copyHandler);
6286
+ containerRef.current.addEventListener('paste', pasteHandler);
6287
+ return () => {
6288
+ containerRef.current.removeEventListener('copy', copyHandler);
6289
+ containerRef.current.removeEventListener('cut', copyHandler);
6290
+ containerRef.current.removeEventListener('paste', pasteHandler);
6291
+ };
6292
+ }, [containerRef, feelActive, handleFeelToggle, setFocus]);
6293
+ return jsxRuntime.jsxs("div", {
6294
+ class: classnames('bio-properties-panel-feel-entry', {
6295
+ 'feel-active': feelActive
6296
+ }),
6297
+ children: [jsxRuntime.jsxs("label", {
6298
+ for: prefixId$4(id),
6299
+ class: "bio-properties-panel-label",
6300
+ onClick: () => setFocus(),
6301
+ children: [label, jsxRuntime.jsx(FeelIcon, {
6302
+ label: label,
6303
+ feel: feel,
6304
+ onClick: handleFeelToggle,
6305
+ active: feelActive
6306
+ })]
6307
+ }), jsxRuntime.jsxs("div", {
6308
+ class: "bio-properties-panel-feel-container",
6309
+ ref: containerRef,
6310
+ children: [jsxRuntime.jsx(FeelIndicator, {
6311
+ active: feelActive,
6312
+ disabled: feel !== 'optional' || disabled,
6127
6313
  onClick: handleFeelToggle
6128
6314
  }), feelActive ? jsxRuntime.jsx(CodeEditor, {
6129
- id: prefixId$5(id),
6315
+ id: prefixId$4(id),
6130
6316
  name: id,
6131
6317
  onInput: handleLocalInput,
6132
6318
  disabled: disabled,
@@ -6143,7 +6329,7 @@ function FeelTextfield(props) {
6143
6329
  ...props,
6144
6330
  onInput: handleLocalInput,
6145
6331
  contentAttributes: {
6146
- 'id': prefixId$5(id),
6332
+ 'id': prefixId$4(id),
6147
6333
  'aria-label': label
6148
6334
  },
6149
6335
  value: localValue,
@@ -6181,7 +6367,7 @@ const OptionalFeelInput = React.forwardRef((props, ref) => {
6181
6367
  }
6182
6368
  };
6183
6369
  return jsxRuntime.jsx("input", {
6184
- id: prefixId$5(id),
6370
+ id: prefixId$4(id),
6185
6371
  type: "text",
6186
6372
  ref: inputRef,
6187
6373
  name: id,
@@ -6195,6 +6381,53 @@ const OptionalFeelInput = React.forwardRef((props, ref) => {
6195
6381
  value: value || ''
6196
6382
  });
6197
6383
  });
6384
+ const OptionalFeelNumberField = React.forwardRef((props, ref) => {
6385
+ const {
6386
+ id,
6387
+ debounce,
6388
+ disabled,
6389
+ onInput,
6390
+ value,
6391
+ min,
6392
+ max,
6393
+ step,
6394
+ onFocus,
6395
+ onBlur
6396
+ } = props;
6397
+ const inputRef = hooks.useRef();
6398
+
6399
+ // To be consistent with the FEEL editor, set focus at start of input
6400
+ // this ensures clean editing experience when switching with the keyboard
6401
+ ref.current = {
6402
+ focus: position => {
6403
+ const input = inputRef.current;
6404
+ if (!input) {
6405
+ return;
6406
+ }
6407
+ input.focus();
6408
+ if (typeof position === 'number' && position !== Infinity) {
6409
+ if (position > value.length) {
6410
+ position = value.length;
6411
+ }
6412
+ input.setSelectionRange(position, position);
6413
+ }
6414
+ }
6415
+ };
6416
+ return jsxRuntime.jsx(NumberField, {
6417
+ id: id,
6418
+ debounce: debounce,
6419
+ disabled: disabled,
6420
+ displayLabel: false,
6421
+ inputRef: inputRef,
6422
+ max: max,
6423
+ min: min,
6424
+ onInput: onInput,
6425
+ step: step,
6426
+ value: value,
6427
+ onFocus: onFocus,
6428
+ onBlur: onBlur
6429
+ });
6430
+ });
6198
6431
  React.forwardRef((props, ref) => {
6199
6432
  const {
6200
6433
  id,
@@ -6219,7 +6452,7 @@ React.forwardRef((props, ref) => {
6219
6452
  }
6220
6453
  };
6221
6454
  return jsxRuntime.jsx("textarea", {
6222
- id: prefixId$5(id),
6455
+ id: prefixId$4(id),
6223
6456
  type: "text",
6224
6457
  ref: inputRef,
6225
6458
  name: id,
@@ -6295,7 +6528,7 @@ React.forwardRef((props, ref) => {
6295
6528
  };
6296
6529
  return jsxRuntime.jsx("input", {
6297
6530
  ref: inputRef,
6298
- id: prefixId$5(id),
6531
+ id: prefixId$4(id),
6299
6532
  name: id,
6300
6533
  onFocus: onFocus,
6301
6534
  onBlur: onBlur,
@@ -6384,11 +6617,13 @@ function FeelEntry(props) {
6384
6617
  return jsxRuntime.jsxs("div", {
6385
6618
  class: classnames(props.class, 'bio-properties-panel-entry', error ? 'has-error' : ''),
6386
6619
  "data-entry-id": id,
6387
- children: [jsxRuntime.jsx(FeelTextfield, {
6620
+ children: [preact.createElement(FeelTextfield, {
6621
+ ...props,
6388
6622
  debounce: debounce,
6389
6623
  disabled: disabled,
6390
6624
  feel: feel,
6391
6625
  id: id,
6626
+ key: element,
6392
6627
  label: label,
6393
6628
  onInput: onInput,
6394
6629
  onError: onError,
@@ -6402,7 +6637,7 @@ function FeelEntry(props) {
6402
6637
  variables: variables,
6403
6638
  tooltipContainer: tooltipContainer,
6404
6639
  OptionalComponent: props.OptionalComponent
6405
- }, element), error && jsxRuntime.jsx("div", {
6640
+ }), error && jsxRuntime.jsx("div", {
6406
6641
  class: "bio-properties-panel-error",
6407
6642
  children: error
6408
6643
  }), jsxRuntime.jsx(Description$1, {
@@ -6420,218 +6655,92 @@ function FeelEntry(props) {
6420
6655
  * @param {String} props.description
6421
6656
  * @param {Boolean} props.debounce
6422
6657
  * @param {Boolean} props.disabled
6658
+ * @param {String} props.max
6659
+ * @param {String} props.min
6660
+ * @param {String} props.step
6423
6661
  * @param {Boolean} props.feel
6424
6662
  * @param {String} props.label
6425
6663
  * @param {Function} props.getValue
6426
6664
  * @param {Function} props.setValue
6427
6665
  * @param {Function} props.tooltipContainer
6428
6666
  * @param {Function} props.validate
6429
- * @param {Function} props.show
6430
- * @param {Function} props.example
6431
- * @param {Function} props.variables
6432
- * @param {Function} props.onFocus
6433
- * @param {Function} props.onBlur
6434
- */
6435
- function FeelToggleSwitchEntry(props) {
6436
- return jsxRuntime.jsx(FeelEntry, {
6437
- class: "bio-properties-panel-feel-toggle-switch",
6438
- OptionalComponent: OptionalFeelToggleSwitch,
6439
- ...props
6440
- });
6441
- }
6442
-
6443
- /**
6444
- * @param {Object} props
6445
- * @param {Object} props.element
6446
- * @param {String} props.id
6447
- * @param {String} props.description
6448
- * @param {String} props.hostLanguage
6449
- * @param {Boolean} props.singleLine
6450
- * @param {Boolean} props.debounce
6451
- * @param {Boolean} props.disabled
6452
- * @param {Boolean} props.feel
6453
- * @param {String} props.label
6454
- * @param {Function} props.getValue
6455
- * @param {Function} props.setValue
6456
- * @param {Function} props.tooltipContainer
6457
- * @param {Function} props.validate
6458
- * @param {Function} props.show
6459
- * @param {Function} props.example
6460
- * @param {Function} props.variables
6461
- * @param {Function} props.onFocus
6462
- * @param {Function} props.onBlur
6463
- */
6464
- function FeelTemplatingEntry(props) {
6465
- return jsxRuntime.jsx(FeelEntry, {
6466
- class: "bio-properties-panel-feel-templating",
6467
- OptionalComponent: CodeEditor$1,
6468
- ...props
6469
- });
6470
- }
6471
- function isEdited$6(node) {
6472
- if (!node) {
6473
- return false;
6474
- }
6475
- if (node.type === 'checkbox') {
6476
- return !!node.checked || node.classList.contains('edited');
6477
- }
6478
- return !!node.value || node.classList.contains('edited');
6479
- }
6480
-
6481
- // helpers /////////////////
6482
-
6483
- function prefixId$5(id) {
6484
- return `bio-properties-panel-${id}`;
6485
- }
6486
- function NumberField(props) {
6487
- const {
6488
- debounce,
6489
- disabled,
6490
- id,
6491
- label,
6492
- max,
6493
- min,
6494
- onInput,
6495
- step,
6496
- value = '',
6497
- onFocus,
6498
- onBlur
6499
- } = props;
6500
- const [localValue, setLocalValue] = hooks.useState(value);
6501
- const handleInputCallback = hooks.useMemo(() => {
6502
- return debounce(event => {
6503
- const {
6504
- validity,
6505
- value
6506
- } = event.target;
6507
- if (validity.valid) {
6508
- onInput(value ? parseFloat(value) : undefined);
6509
- }
6510
- });
6511
- }, [onInput, debounce]);
6512
- const handleInput = e => {
6513
- handleInputCallback(e);
6514
- setLocalValue(e.target.value);
6515
- };
6516
- hooks.useEffect(() => {
6517
- if (value === localValue) {
6518
- return;
6519
- }
6520
- setLocalValue(value);
6521
- }, [value]);
6522
- return jsxRuntime.jsxs("div", {
6523
- class: "bio-properties-panel-numberfield",
6524
- children: [jsxRuntime.jsx("label", {
6525
- for: prefixId$4(id),
6526
- class: "bio-properties-panel-label",
6527
- children: label
6528
- }), jsxRuntime.jsx("input", {
6529
- id: prefixId$4(id),
6530
- type: "number",
6531
- name: id,
6532
- spellCheck: "false",
6533
- autoComplete: "off",
6534
- disabled: disabled,
6535
- class: "bio-properties-panel-input",
6536
- max: max,
6537
- min: min,
6538
- onInput: handleInput,
6539
- onFocus: onFocus,
6540
- onBlur: onBlur,
6541
- step: step,
6542
- value: localValue
6543
- })]
6544
- });
6545
- }
6546
-
6547
- /**
6548
- * @param {Object} props
6549
- * @param {Boolean} props.debounce
6550
- * @param {String} props.description
6551
- * @param {Boolean} props.disabled
6552
- * @param {Object} props.element
6553
- * @param {Function} props.getValue
6554
- * @param {String} props.id
6555
- * @param {String} props.label
6556
- * @param {String} props.max
6557
- * @param {String} props.min
6558
- * @param {Function} props.setValue
6559
- * @param {Function} props.onFocus
6560
- * @param {Function} props.onBlur
6561
- * @param {String} props.step
6562
- * @param {Function} props.validate
6563
- */
6564
- function NumberFieldEntry(props) {
6565
- const {
6566
- debounce,
6567
- description,
6568
- disabled,
6569
- element,
6570
- getValue,
6571
- id,
6572
- label,
6573
- max,
6574
- min,
6575
- setValue,
6576
- step,
6577
- onFocus,
6578
- onBlur,
6579
- validate
6580
- } = props;
6581
- const [cachedInvalidValue, setCachedInvalidValue] = hooks.useState(null);
6582
- const globalError = useError(id);
6583
- const [localError, setLocalError] = hooks.useState(null);
6584
- let value = getValue(element);
6585
- const previousValue = usePrevious(value);
6586
- hooks.useEffect(() => {
6587
- if (minDash.isFunction(validate)) {
6588
- const newValidationError = validate(value) || null;
6589
- setLocalError(newValidationError);
6590
- }
6591
- }, [value]);
6592
- const onInput = newValue => {
6593
- let newValidationError = null;
6594
- if (minDash.isFunction(validate)) {
6595
- newValidationError = validate(newValue) || null;
6596
- }
6597
- if (newValidationError) {
6598
- setCachedInvalidValue(newValue);
6599
- } else {
6600
- setValue(newValue);
6601
- }
6602
- setLocalError(newValidationError);
6603
- };
6604
- if (previousValue === value && localError) {
6605
- value = cachedInvalidValue;
6606
- }
6607
- const error = globalError || localError;
6608
- return jsxRuntime.jsxs("div", {
6609
- class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
6610
- "data-entry-id": id,
6611
- children: [jsxRuntime.jsx(NumberField, {
6612
- debounce: debounce,
6613
- disabled: disabled,
6614
- id: id,
6615
- label: label,
6616
- onFocus: onFocus,
6617
- onBlur: onBlur,
6618
- onInput: onInput,
6619
- max: max,
6620
- min: min,
6621
- step: step,
6622
- value: value
6623
- }, element), error && jsxRuntime.jsx("div", {
6624
- class: "bio-properties-panel-error",
6625
- children: error
6626
- }), jsxRuntime.jsx(Description$1, {
6627
- forId: id,
6628
- element: element,
6629
- value: description
6630
- })]
6667
+ * @param {Function} props.show
6668
+ * @param {Function} props.example
6669
+ * @param {Function} props.variables
6670
+ * @param {Function} props.onFocus
6671
+ * @param {Function} props.onBlur
6672
+ */
6673
+ function FeelNumberEntry(props) {
6674
+ return jsxRuntime.jsx(FeelEntry, {
6675
+ class: "bio-properties-panel-feel-number",
6676
+ OptionalComponent: OptionalFeelNumberField,
6677
+ ...props
6631
6678
  });
6632
6679
  }
6633
- function isEdited$4(node) {
6634
- return node && !!node.value;
6680
+
6681
+ /**
6682
+ * @param {Object} props
6683
+ * @param {Object} props.element
6684
+ * @param {String} props.id
6685
+ * @param {String} props.description
6686
+ * @param {Boolean} props.debounce
6687
+ * @param {Boolean} props.disabled
6688
+ * @param {Boolean} props.feel
6689
+ * @param {String} props.label
6690
+ * @param {Function} props.getValue
6691
+ * @param {Function} props.setValue
6692
+ * @param {Function} props.tooltipContainer
6693
+ * @param {Function} props.validate
6694
+ * @param {Function} props.show
6695
+ * @param {Function} props.example
6696
+ * @param {Function} props.variables
6697
+ * @param {Function} props.onFocus
6698
+ * @param {Function} props.onBlur
6699
+ */
6700
+ function FeelToggleSwitchEntry(props) {
6701
+ return jsxRuntime.jsx(FeelEntry, {
6702
+ class: "bio-properties-panel-feel-toggle-switch",
6703
+ OptionalComponent: OptionalFeelToggleSwitch,
6704
+ ...props
6705
+ });
6706
+ }
6707
+
6708
+ /**
6709
+ * @param {Object} props
6710
+ * @param {Object} props.element
6711
+ * @param {String} props.id
6712
+ * @param {String} props.description
6713
+ * @param {String} props.hostLanguage
6714
+ * @param {Boolean} props.singleLine
6715
+ * @param {Boolean} props.debounce
6716
+ * @param {Boolean} props.disabled
6717
+ * @param {Boolean} props.feel
6718
+ * @param {String} props.label
6719
+ * @param {Function} props.getValue
6720
+ * @param {Function} props.setValue
6721
+ * @param {Function} props.tooltipContainer
6722
+ * @param {Function} props.validate
6723
+ * @param {Function} props.show
6724
+ * @param {Function} props.example
6725
+ * @param {Function} props.variables
6726
+ * @param {Function} props.onFocus
6727
+ * @param {Function} props.onBlur
6728
+ */
6729
+ function FeelTemplatingEntry(props) {
6730
+ return jsxRuntime.jsx(FeelEntry, {
6731
+ class: "bio-properties-panel-feel-templating",
6732
+ OptionalComponent: CodeEditor$1,
6733
+ ...props
6734
+ });
6735
+ }
6736
+ function isEdited$5(node) {
6737
+ if (!node) {
6738
+ return false;
6739
+ }
6740
+ if (node.type === 'checkbox') {
6741
+ return !!node.checked || node.classList.contains('edited');
6742
+ }
6743
+ return !!node.value || node.classList.contains('edited');
6635
6744
  }
6636
6745
 
6637
6746
  // helpers /////////////////
@@ -7088,11 +7197,11 @@ function prefixId(id) {
7088
7197
  return `bio-properties-panel-${id}`;
7089
7198
  }
7090
7199
 
7091
- /**
7092
- * @param {string} type
7093
- * @param {boolean} [strict]
7094
- *
7095
- * @returns {any}
7200
+ /**
7201
+ * @param {string} type
7202
+ * @param {boolean} [strict]
7203
+ *
7204
+ * @returns {any}
7096
7205
  */
7097
7206
  function getService(type, strict) {}
7098
7207
  const PropertiesPanelContext = preact.createContext({
@@ -7181,8 +7290,8 @@ const PropertiesPanelHeaderProvider = {
7181
7290
  }
7182
7291
  };
7183
7292
 
7184
- /**
7185
- * Provide placeholders for empty and multiple state.
7293
+ /**
7294
+ * Provide placeholders for empty and multiple state.
7186
7295
  */
7187
7296
  const PropertiesPanelPlaceholderProvider = {
7188
7297
  getEmpty: () => {
@@ -7254,10 +7363,10 @@ function useService (type, strict) {
7254
7363
  return getService(type, strict);
7255
7364
  }
7256
7365
 
7257
- /**
7258
- * Retrieve list of variables from the form schema.
7259
- *
7260
- * @returns { string[] } list of variables used in form schema
7366
+ /**
7367
+ * Retrieve list of variables from the form schema.
7368
+ *
7369
+ * @returns { string[] } list of variables used in form schema
7261
7370
  */
7262
7371
  function useVariables() {
7263
7372
  const form = useService('formEditor');
@@ -7280,7 +7389,7 @@ function AltTextEntry(props) {
7280
7389
  component: AltText,
7281
7390
  editField: editField,
7282
7391
  field: field,
7283
- isEdited: isEdited$6
7392
+ isEdited: isEdited$5
7284
7393
  });
7285
7394
  }
7286
7395
  return entries;
@@ -7302,7 +7411,7 @@ function AltText(props) {
7302
7411
  const setValue = value => {
7303
7412
  return editField(field, path, value);
7304
7413
  };
7305
- return FeelEntry({
7414
+ return FeelTemplatingEntry({
7306
7415
  debounce,
7307
7416
  element: field,
7308
7417
  feel: 'optional',
@@ -7310,6 +7419,7 @@ function AltText(props) {
7310
7419
  id,
7311
7420
  label: 'Alternative text',
7312
7421
  setValue,
7422
+ singleLine: true,
7313
7423
  variables
7314
7424
  });
7315
7425
  }
@@ -7398,7 +7508,7 @@ function DescriptionEntry(props) {
7398
7508
  component: Description,
7399
7509
  editField: editField,
7400
7510
  field: field,
7401
- isEdited: isEdited$6
7511
+ isEdited: isEdited$5
7402
7512
  });
7403
7513
  }
7404
7514
  return entries;
@@ -7864,7 +7974,7 @@ function LabelEntry(props) {
7864
7974
  component: DateLabel,
7865
7975
  editField,
7866
7976
  field,
7867
- isEdited: isEdited$6
7977
+ isEdited: isEdited$5
7868
7978
  });
7869
7979
  }
7870
7980
  if (subtype === formJsViewer.DATETIME_SUBTYPES.TIME || subtype === formJsViewer.DATETIME_SUBTYPES.DATETIME) {
@@ -7873,7 +7983,7 @@ function LabelEntry(props) {
7873
7983
  component: TimeLabel,
7874
7984
  editField,
7875
7985
  field,
7876
- isEdited: isEdited$6
7986
+ isEdited: isEdited$5
7877
7987
  });
7878
7988
  }
7879
7989
  } else if (INPUTS.includes(type) || type === 'button') {
@@ -7882,7 +7992,7 @@ function LabelEntry(props) {
7882
7992
  component: Label$1,
7883
7993
  editField,
7884
7994
  field,
7885
- isEdited: isEdited$6
7995
+ isEdited: isEdited$5
7886
7996
  });
7887
7997
  }
7888
7998
  return entries;
@@ -7987,7 +8097,7 @@ function SourceEntry(props) {
7987
8097
  component: Source,
7988
8098
  editField: editField,
7989
8099
  field: field,
7990
- isEdited: isEdited$6
8100
+ isEdited: isEdited$5
7991
8101
  });
7992
8102
  }
7993
8103
  return entries;
@@ -8009,7 +8119,7 @@ function Source(props) {
8009
8119
  const setValue = value => {
8010
8120
  return editField(field, path, value);
8011
8121
  };
8012
- return FeelEntry({
8122
+ return FeelTemplatingEntry({
8013
8123
  debounce,
8014
8124
  description: 'Expression or static value (link/data URI)',
8015
8125
  element: field,
@@ -8018,6 +8128,7 @@ function Source(props) {
8018
8128
  id,
8019
8129
  label: 'Image source',
8020
8130
  setValue,
8131
+ singleLine: true,
8021
8132
  variables
8022
8133
  });
8023
8134
  }
@@ -8042,7 +8153,7 @@ function TextEntry(props) {
8042
8153
  component: Text,
8043
8154
  editField: editField,
8044
8155
  field: field,
8045
- isEdited: isEdited$6
8156
+ isEdited: isEdited$5
8046
8157
  }];
8047
8158
 
8048
8159
  // todo: skipped to make the release without too much risk
@@ -8111,7 +8222,7 @@ function NumberEntries(props) {
8111
8222
  entries.push({
8112
8223
  id: id + '-decimalDigits',
8113
8224
  component: NumberDecimalDigits,
8114
- isEdited: isEdited$4,
8225
+ isEdited: isEdited$6,
8115
8226
  editField,
8116
8227
  field
8117
8228
  });
@@ -8707,14 +8818,14 @@ function Value(props) {
8707
8818
 
8708
8819
  // helpers //////////
8709
8820
 
8710
- /**
8711
- * Returns copy of object with updated value.
8712
- *
8713
- * @param {Object} properties
8714
- * @param {string} key
8715
- * @param {string} value
8716
- *
8717
- * @returns {Object}
8821
+ /**
8822
+ * Returns copy of object with updated value.
8823
+ *
8824
+ * @param {Object} properties
8825
+ * @param {string} key
8826
+ * @param {string} value
8827
+ *
8828
+ * @returns {Object}
8718
8829
  */
8719
8830
  function updateValue(properties, key, value) {
8720
8831
  return {
@@ -8723,14 +8834,14 @@ function updateValue(properties, key, value) {
8723
8834
  };
8724
8835
  }
8725
8836
 
8726
- /**
8727
- * Returns copy of object with updated key.
8728
- *
8729
- * @param {Object} properties
8730
- * @param {string} oldKey
8731
- * @param {string} newKey
8732
- *
8733
- * @returns {Object}
8837
+ /**
8838
+ * Returns copy of object with updated key.
8839
+ *
8840
+ * @param {Object} properties
8841
+ * @param {string} oldKey
8842
+ * @param {string} newKey
8843
+ *
8844
+ * @returns {Object}
8734
8845
  */
8735
8846
  function updateKey(properties, oldKey, newKey) {
8736
8847
  return Object.entries(properties).reduce((newProperties, entry) => {
@@ -8742,6 +8853,34 @@ function updateKey(properties, oldKey, newKey) {
8742
8853
  }, {});
8743
8854
  }
8744
8855
 
8856
+ function AutoFocusSelectEntry(props) {
8857
+ const {
8858
+ autoFocusEntry,
8859
+ element,
8860
+ getValue
8861
+ } = props;
8862
+ const value = getValue(element);
8863
+ const prevValue = usePrevious(value);
8864
+ const eventBus = useService('eventBus');
8865
+
8866
+ // auto focus specifc other entry when selected value changed
8867
+ hooks.useEffect(() => {
8868
+ if (autoFocusEntry && prevValue && value !== prevValue) {
8869
+ // @Note(pinussilvestrus): There is an issue in the properties
8870
+ // panel so we have to wait a bit before showing the entry.
8871
+ // Cf. https://github.com/camunda/linting/blob/4f5328e2722f73ae60ae584c5f576eaec3999cb2/lib/modeler/Linting.js#L37
8872
+ setTimeout(() => {
8873
+ eventBus.fire('propertiesPanel.showEntry', {
8874
+ id: autoFocusEntry
8875
+ });
8876
+ });
8877
+ }
8878
+ }, [value, autoFocusEntry, prevValue, eventBus]);
8879
+ return jsxRuntime.jsx(SelectEntry, {
8880
+ ...props
8881
+ });
8882
+ }
8883
+
8745
8884
  function ValuesSourceSelectEntry(props) {
8746
8885
  const {
8747
8886
  editField,
@@ -8780,7 +8919,8 @@ function ValuesSourceSelect(props) {
8780
8919
  value: valueSource
8781
8920
  }));
8782
8921
  };
8783
- return SelectEntry({
8922
+ return AutoFocusSelectEntry({
8923
+ autoFocusEntry: getAutoFocusEntryId(field),
8784
8924
  label: 'Type',
8785
8925
  element: field,
8786
8926
  getOptions: getValuesSourceOptions,
@@ -8790,6 +8930,20 @@ function ValuesSourceSelect(props) {
8790
8930
  });
8791
8931
  }
8792
8932
 
8933
+ // helpers //////////
8934
+
8935
+ function getAutoFocusEntryId(field) {
8936
+ const valuesSource = formJsViewer.getValuesSource(field);
8937
+ if (valuesSource === formJsViewer.VALUES_SOURCES.EXPRESSION) {
8938
+ return `${field.id}-valuesExpression-expression`;
8939
+ } else if (valuesSource === formJsViewer.VALUES_SOURCES.INPUT) {
8940
+ return `${field.id}-dynamicValues-key`;
8941
+ } else if (valuesSource === formJsViewer.VALUES_SOURCES.STATIC) {
8942
+ return `${field.id}-staticValues-0-label`;
8943
+ }
8944
+ return null;
8945
+ }
8946
+
8793
8947
  function InputKeyValuesSourceEntry(props) {
8794
8948
  const {
8795
8949
  editField,
@@ -8946,7 +9100,7 @@ function AdornerEntry(props) {
8946
9100
  entries.push({
8947
9101
  id: 'prefix-adorner',
8948
9102
  component: PrefixAdorner,
8949
- isEdited: isEdited,
9103
+ isEdited: isEdited$5,
8950
9104
  editField,
8951
9105
  field,
8952
9106
  onChange,
@@ -8955,7 +9109,7 @@ function AdornerEntry(props) {
8955
9109
  entries.push({
8956
9110
  id: 'suffix-adorner',
8957
9111
  component: SuffixAdorner,
8958
- isEdited: isEdited,
9112
+ isEdited: isEdited$5,
8959
9113
  editField,
8960
9114
  field,
8961
9115
  onChange,
@@ -8972,13 +9126,19 @@ function PrefixAdorner(props) {
8972
9126
  getValue
8973
9127
  } = props;
8974
9128
  const debounce = useService('debounce');
8975
- return TextfieldEntry({
9129
+ const variables = useVariables().map(name => ({
9130
+ name
9131
+ }));
9132
+ return FeelTemplatingEntry({
8976
9133
  debounce,
8977
9134
  element: field,
9135
+ feel: 'optional',
8978
9136
  getValue: getValue('prefixAdorner'),
8979
9137
  id,
8980
9138
  label: 'Prefix',
8981
- setValue: onChange('prefixAdorner')
9139
+ setValue: onChange('prefixAdorner'),
9140
+ singleLine: true,
9141
+ variables
8982
9142
  });
8983
9143
  }
8984
9144
  function SuffixAdorner(props) {
@@ -8989,13 +9149,18 @@ function SuffixAdorner(props) {
8989
9149
  getValue
8990
9150
  } = props;
8991
9151
  const debounce = useService('debounce');
8992
- return TextfieldEntry({
9152
+ const variables = useVariables().map(name => ({
9153
+ name
9154
+ }));
9155
+ return FeelTemplatingEntry({
8993
9156
  debounce,
8994
9157
  element: field,
8995
9158
  getValue: getValue('suffixAdorner'),
8996
9159
  id,
8997
9160
  label: 'Suffix',
8998
- setValue: onChange('suffixAdorner')
9161
+ setValue: onChange('suffixAdorner'),
9162
+ singleLine: true,
9163
+ variables
8999
9164
  });
9000
9165
  }
9001
9166
 
@@ -9014,7 +9179,7 @@ function ReadonlyEntry(props) {
9014
9179
  component: Readonly,
9015
9180
  editField: editField,
9016
9181
  field: field,
9017
- isEdited: isEdited$6
9182
+ isEdited: isEdited$5
9018
9183
  });
9019
9184
  }
9020
9185
  return entries;
@@ -9058,7 +9223,7 @@ function ConditionEntry(props) {
9058
9223
  component: Condition,
9059
9224
  editField: editField,
9060
9225
  field: field,
9061
- isEdited: isEdited$6
9226
+ isEdited: isEdited$5
9062
9227
  }];
9063
9228
  }
9064
9229
  function Condition(props) {
@@ -9096,6 +9261,55 @@ function Condition(props) {
9096
9261
  });
9097
9262
  }
9098
9263
 
9264
+ function ValuesExpressionEntry(props) {
9265
+ const {
9266
+ editField,
9267
+ field,
9268
+ id
9269
+ } = props;
9270
+ return [{
9271
+ id: id + '-expression',
9272
+ component: ValuesExpression,
9273
+ label: 'Values expression',
9274
+ isEdited: isEdited$5,
9275
+ editField,
9276
+ field
9277
+ }];
9278
+ }
9279
+ function ValuesExpression(props) {
9280
+ const {
9281
+ editField,
9282
+ field,
9283
+ id
9284
+ } = props;
9285
+ const debounce = useService('debounce');
9286
+ const variables = useVariables().map(name => ({
9287
+ name
9288
+ }));
9289
+ const path = formJsViewer.VALUES_SOURCES_PATHS[formJsViewer.VALUES_SOURCES.EXPRESSION];
9290
+ const schema = '[\n {\n "label": "dollar",\n "value": "$"\n }\n]';
9291
+ const description = jsxRuntime.jsxs("div", {
9292
+ children: ["Define an expression to populate the options from.", jsxRuntime.jsx("br", {}), jsxRuntime.jsx("br", {}), "The expression may result in an array of simple values or alternatively follow this schema:", jsxRuntime.jsx("pre", {
9293
+ children: jsxRuntime.jsx("code", {
9294
+ children: schema
9295
+ })
9296
+ })]
9297
+ });
9298
+ const getValue = () => minDash.get(field, path, '');
9299
+ const setValue = value => editField(field, path, value || '');
9300
+ return FeelEntry({
9301
+ debounce,
9302
+ description,
9303
+ element: field,
9304
+ feel: 'required',
9305
+ getValue,
9306
+ id,
9307
+ label: 'Options expression',
9308
+ setValue,
9309
+ variables
9310
+ });
9311
+ }
9312
+
9099
9313
  function GeneralGroup(field, editField, getService) {
9100
9314
  const entries = [...IdEntry({
9101
9315
  field,
@@ -9240,14 +9454,14 @@ function ValidationGroup(field, editField) {
9240
9454
  component: MinLength,
9241
9455
  getValue,
9242
9456
  field,
9243
- isEdited: isEdited$4,
9457
+ isEdited: isEdited$5,
9244
9458
  onChange
9245
9459
  }, {
9246
9460
  id: 'maxLength',
9247
9461
  component: MaxLength,
9248
9462
  getValue,
9249
9463
  field,
9250
- isEdited: isEdited$4,
9464
+ isEdited: isEdited$5,
9251
9465
  onChange
9252
9466
  });
9253
9467
  }
@@ -9267,14 +9481,14 @@ function ValidationGroup(field, editField) {
9267
9481
  component: Min,
9268
9482
  getValue,
9269
9483
  field,
9270
- isEdited: isEdited$4,
9484
+ isEdited: isEdited$5,
9271
9485
  onChange
9272
9486
  }, {
9273
9487
  id: 'max',
9274
9488
  component: Max,
9275
9489
  getValue,
9276
9490
  field,
9277
- isEdited: isEdited$4,
9491
+ isEdited: isEdited$5,
9278
9492
  onChange
9279
9493
  });
9280
9494
  }
@@ -9307,14 +9521,19 @@ function MinLength(props) {
9307
9521
  onChange
9308
9522
  } = props;
9309
9523
  const debounce = useService('debounce');
9310
- return NumberFieldEntry({
9524
+ const variables = useVariables().map(name => ({
9525
+ name
9526
+ }));
9527
+ return FeelNumberEntry({
9311
9528
  debounce,
9312
9529
  element: field,
9530
+ feel: 'optional',
9313
9531
  getValue: getValue('minLength'),
9314
9532
  id,
9315
9533
  label: 'Minimum length',
9316
9534
  min: 0,
9317
- setValue: onChange('minLength')
9535
+ setValue: onChange('minLength'),
9536
+ variables
9318
9537
  });
9319
9538
  }
9320
9539
  function MaxLength(props) {
@@ -9325,14 +9544,19 @@ function MaxLength(props) {
9325
9544
  onChange
9326
9545
  } = props;
9327
9546
  const debounce = useService('debounce');
9328
- return NumberFieldEntry({
9547
+ const variables = useVariables().map(name => ({
9548
+ name
9549
+ }));
9550
+ return FeelNumberEntry({
9329
9551
  debounce,
9330
9552
  element: field,
9553
+ feel: 'optional',
9331
9554
  getValue: getValue('maxLength'),
9332
9555
  id,
9333
9556
  label: 'Maximum length',
9334
9557
  min: 0,
9335
- setValue: onChange('maxLength')
9558
+ setValue: onChange('maxLength'),
9559
+ variables
9336
9560
  });
9337
9561
  }
9338
9562
  function Pattern(props) {
@@ -9360,14 +9584,19 @@ function Min(props) {
9360
9584
  onChange
9361
9585
  } = props;
9362
9586
  const debounce = useService('debounce');
9363
- return NumberFieldEntry({
9587
+ const variables = useVariables().map(name => ({
9588
+ name
9589
+ }));
9590
+ return FeelNumberEntry({
9364
9591
  debounce,
9365
9592
  element: field,
9593
+ feel: 'optional',
9366
9594
  id,
9367
9595
  label: 'Minimum',
9368
9596
  step: 'any',
9369
9597
  getValue: getValue('min'),
9370
- setValue: onChange('min')
9598
+ setValue: onChange('min'),
9599
+ variables
9371
9600
  });
9372
9601
  }
9373
9602
  function Max(props) {
@@ -9378,14 +9607,19 @@ function Max(props) {
9378
9607
  onChange
9379
9608
  } = props;
9380
9609
  const debounce = useService('debounce');
9381
- return NumberFieldEntry({
9610
+ const variables = useVariables().map(name => ({
9611
+ name
9612
+ }));
9613
+ return FeelNumberEntry({
9382
9614
  debounce,
9383
9615
  element: field,
9616
+ feel: 'optional',
9384
9617
  id,
9385
9618
  label: 'Maximum',
9386
9619
  step: 'any',
9387
9620
  getValue: getValue('max'),
9388
- setValue: onChange('max')
9621
+ setValue: onChange('max'),
9622
+ variables
9389
9623
  });
9390
9624
  }
9391
9625
  function ValidationType(props) {
@@ -9424,8 +9658,8 @@ function ValuesGroups(field, editField) {
9424
9658
  };
9425
9659
  const valuesSourceId = `${fieldId}-valuesSource`;
9426
9660
 
9427
- /**
9428
- * @type {Array<Group|ListGroup>}
9661
+ /**
9662
+ * @type {Array<Group|ListGroup>}
9429
9663
  */
9430
9664
  const groups = [{
9431
9665
  id: valuesSourceId,
@@ -9459,6 +9693,17 @@ function ValuesGroups(field, editField) {
9459
9693
  id: staticValuesId
9460
9694
  })
9461
9695
  });
9696
+ } else if (valuesSource === formJsViewer.VALUES_SOURCES.EXPRESSION) {
9697
+ const valuesExpressionId = `${fieldId}-valuesExpression`;
9698
+ groups.push({
9699
+ id: valuesExpressionId,
9700
+ label: 'Options expression',
9701
+ component: Group,
9702
+ entries: ValuesExpressionEntry({
9703
+ ...context,
9704
+ id: valuesExpressionId
9705
+ })
9706
+ });
9462
9707
  }
9463
9708
  return groups;
9464
9709
  }
@@ -9527,13 +9772,13 @@ function CustomValuesGroup(field, editField) {
9527
9772
 
9528
9773
  // helpers //////////
9529
9774
 
9530
- /**
9531
- * Returns copy of object without key.
9532
- *
9533
- * @param {Object} properties
9534
- * @param {string} oldKey
9535
- *
9536
- * @returns {Object}
9775
+ /**
9776
+ * Returns copy of object without key.
9777
+ *
9778
+ * @param {Object} properties
9779
+ * @param {string} oldKey
9780
+ *
9781
+ * @returns {Object}
9537
9782
  */
9538
9783
  function removeKey(properties, oldKey) {
9539
9784
  return Object.entries(properties).reduce((newProperties, entry) => {
@@ -9636,9 +9881,9 @@ function FormPropertiesPanel(props) {
9636
9881
  });
9637
9882
  }, [eventBus, formEditor, selectionModule]);
9638
9883
  hooks.useLayoutEffect(() => {
9639
- /**
9640
- * TODO(pinussilvestrus): update with actual updated element,
9641
- * once we have a proper updater/change support
9884
+ /**
9885
+ * TODO(pinussilvestrus): update with actual updated element,
9886
+ * once we have a proper updater/change support
9642
9887
  */
9643
9888
  eventBus.on('changed', refresh);
9644
9889
  eventBus.on('import.done', refresh);
@@ -9690,10 +9935,10 @@ class PropertiesPanelRenderer {
9690
9935
  });
9691
9936
  }
9692
9937
 
9693
- /**
9694
- * Attach the properties panel to a parent node.
9695
- *
9696
- * @param {HTMLElement} container
9938
+ /**
9939
+ * Attach the properties panel to a parent node.
9940
+ *
9941
+ * @param {HTMLElement} container
9697
9942
  */
9698
9943
  attachTo(container) {
9699
9944
  if (!container) {
@@ -9713,8 +9958,8 @@ class PropertiesPanelRenderer {
9713
9958
  this._eventBus.fire('propertiesPanel.attach');
9714
9959
  }
9715
9960
 
9716
- /**
9717
- * Detach the properties panel from its parent node.
9961
+ /**
9962
+ * Detach the properties panel from its parent node.
9718
9963
  */
9719
9964
  detach() {
9720
9965
  const parentNode = this._container.parentNode;
@@ -9744,10 +9989,10 @@ var PropertiesPanelModule = {
9744
9989
  propertiesPanel: ['type', PropertiesPanelRenderer]
9745
9990
  };
9746
9991
 
9747
- /**
9748
- * Manages the rendering of visual plugins.
9749
- * @constructor
9750
- * @param {Object} eventBus - Event bus for the application.
9992
+ /**
9993
+ * Manages the rendering of visual plugins.
9994
+ * @constructor
9995
+ * @param {Object} eventBus - Event bus for the application.
9751
9996
  */
9752
9997
  class RenderInjector extends SectionModuleBase {
9753
9998
  constructor(eventBus) {
@@ -9756,10 +10001,10 @@ class RenderInjector extends SectionModuleBase {
9756
10001
  this.registeredRenderers = [];
9757
10002
  }
9758
10003
 
9759
- /**
9760
- * Inject a new renderer into the injector.
9761
- * @param {string} identifier - Identifier for the renderer.
9762
- * @param {Function} Renderer - The renderer function.
10004
+ /**
10005
+ * Inject a new renderer into the injector.
10006
+ * @param {string} identifier - Identifier for the renderer.
10007
+ * @param {Function} Renderer - The renderer function.
9763
10008
  */
9764
10009
  attachRenderer(identifier, Renderer) {
9765
10010
  this.registeredRenderers = [...this.registeredRenderers, {
@@ -9768,17 +10013,17 @@ class RenderInjector extends SectionModuleBase {
9768
10013
  }];
9769
10014
  }
9770
10015
 
9771
- /**
9772
- * Detach a renderer from the by key injector.
9773
- * @param {string} identifier - Identifier for the renderer.
10016
+ /**
10017
+ * Detach a renderer from the by key injector.
10018
+ * @param {string} identifier - Identifier for the renderer.
9774
10019
  */
9775
10020
  detachRenderer(identifier) {
9776
10021
  this.registeredRenderers = this.registeredRenderers.filter(r => r.identifier !== identifier);
9777
10022
  }
9778
10023
 
9779
- /**
9780
- * Returns the registered renderers.
9781
- * @returns {Array} Array of registered renderers.
10024
+ /**
10025
+ * Returns the registered renderers.
10026
+ * @returns {Array} Array of registered renderers.
9782
10027
  */
9783
10028
  fetchRenderers() {
9784
10029
  return this.registeredRenderers;
@@ -9812,48 +10057,48 @@ var ExpressionLanguageModule = {
9812
10057
 
9813
10058
  const ids = new Ids([32, 36, 1]);
9814
10059
 
9815
- /**
9816
- * @typedef { import('./types').Injector } Injector
9817
- * @typedef { import('./types').Module } Module
9818
- * @typedef { import('./types').Schema } Schema
9819
- *
9820
- * @typedef { import('./types').FormEditorOptions } FormEditorOptions
9821
- * @typedef { import('./types').FormEditorProperties } FormEditorProperties
9822
- *
9823
- * @typedef { {
9824
- * properties: FormEditorProperties,
9825
- * schema: Schema
9826
- * } } State
9827
- *
9828
- * @typedef { (type:string, priority:number, handler:Function) => void } OnEventWithPriority
9829
- * @typedef { (type:string, handler:Function) => void } OnEventWithOutPriority
9830
- * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
10060
+ /**
10061
+ * @typedef { import('./types').Injector } Injector
10062
+ * @typedef { import('./types').Module } Module
10063
+ * @typedef { import('./types').Schema } Schema
10064
+ *
10065
+ * @typedef { import('./types').FormEditorOptions } FormEditorOptions
10066
+ * @typedef { import('./types').FormEditorProperties } FormEditorProperties
10067
+ *
10068
+ * @typedef { {
10069
+ * properties: FormEditorProperties,
10070
+ * schema: Schema
10071
+ * } } State
10072
+ *
10073
+ * @typedef { (type:string, priority:number, handler:Function) => void } OnEventWithPriority
10074
+ * @typedef { (type:string, handler:Function) => void } OnEventWithOutPriority
10075
+ * @typedef { OnEventWithPriority & OnEventWithOutPriority } OnEventType
9831
10076
  */
9832
10077
 
9833
- /**
9834
- * The form editor.
10078
+ /**
10079
+ * The form editor.
9835
10080
  */
9836
10081
  class FormEditor {
9837
- /**
9838
- * @constructor
9839
- * @param {FormEditorOptions} options
10082
+ /**
10083
+ * @constructor
10084
+ * @param {FormEditorOptions} options
9840
10085
  */
9841
10086
  constructor(options = {}) {
9842
- /**
9843
- * @public
9844
- * @type {OnEventType}
10087
+ /**
10088
+ * @public
10089
+ * @type {OnEventType}
9845
10090
  */
9846
10091
  this.on = this._onEvent;
9847
10092
 
9848
- /**
9849
- * @public
9850
- * @type {String}
10093
+ /**
10094
+ * @public
10095
+ * @type {String}
9851
10096
  */
9852
10097
  this._id = ids.next();
9853
10098
 
9854
- /**
9855
- * @private
9856
- * @type {Element}
10099
+ /**
10100
+ * @private
10101
+ * @type {Element}
9857
10102
  */
9858
10103
  this._container = formJsViewer.createFormContainer();
9859
10104
  this._container.setAttribute('input-handle-modified-keys', 'z,y');
@@ -9864,15 +10109,15 @@ class FormEditor {
9864
10109
  properties = {}
9865
10110
  } = options;
9866
10111
 
9867
- /**
9868
- * @private
9869
- * @type {any}
10112
+ /**
10113
+ * @private
10114
+ * @type {any}
9870
10115
  */
9871
10116
  this.exporter = exporter;
9872
10117
 
9873
- /**
9874
- * @private
9875
- * @type {State}
10118
+ /**
10119
+ * @private
10120
+ * @type {State}
9876
10121
  */
9877
10122
  this._state = {
9878
10123
  properties,
@@ -9901,10 +10146,10 @@ class FormEditor {
9901
10146
  this._detach(false);
9902
10147
  }
9903
10148
 
9904
- /**
9905
- * @param {Schema} schema
9906
- *
9907
- * @return {Promise<{ warnings: Array<any> }>}
10149
+ /**
10150
+ * @param {Schema} schema
10151
+ *
10152
+ * @return {Promise<{ warnings: Array<any> }>}
9908
10153
  */
9909
10154
  importSchema(schema) {
9910
10155
  return new Promise((resolve, reject) => {
@@ -9933,15 +10178,15 @@ class FormEditor {
9933
10178
  });
9934
10179
  }
9935
10180
 
9936
- /**
9937
- * @returns {Schema}
10181
+ /**
10182
+ * @returns {Schema}
9938
10183
  */
9939
10184
  saveSchema() {
9940
10185
  return this.getSchema();
9941
10186
  }
9942
10187
 
9943
- /**
9944
- * @returns {Schema}
10188
+ /**
10189
+ * @returns {Schema}
9945
10190
  */
9946
10191
  getSchema() {
9947
10192
  const {
@@ -9950,8 +10195,8 @@ class FormEditor {
9950
10195
  return exportSchema(schema, this.exporter, formJsViewer.schemaVersion);
9951
10196
  }
9952
10197
 
9953
- /**
9954
- * @param {Element|string} parentNode
10198
+ /**
10199
+ * @param {Element|string} parentNode
9955
10200
  */
9956
10201
  attachTo(parentNode) {
9957
10202
  if (!parentNode) {
@@ -9969,10 +10214,10 @@ class FormEditor {
9969
10214
  this._detach();
9970
10215
  }
9971
10216
 
9972
- /**
9973
- * @internal
9974
- *
9975
- * @param {boolean} [emit]
10217
+ /**
10218
+ * @internal
10219
+ *
10220
+ * @param {boolean} [emit]
9976
10221
  */
9977
10222
  _detach(emit = true) {
9978
10223
  const container = this._container,
@@ -9986,9 +10231,9 @@ class FormEditor {
9986
10231
  parentNode.removeChild(container);
9987
10232
  }
9988
10233
 
9989
- /**
9990
- * @param {any} property
9991
- * @param {any} value
10234
+ /**
10235
+ * @param {any} property
10236
+ * @param {any} value
9992
10237
  */
9993
10238
  setProperty(property, value) {
9994
10239
  const properties = minDash.set(this._getState().properties, [property], value);
@@ -9997,21 +10242,21 @@ class FormEditor {
9997
10242
  });
9998
10243
  }
9999
10244
 
10000
- /**
10001
- * @param {string} type
10002
- * @param {Function} handler
10245
+ /**
10246
+ * @param {string} type
10247
+ * @param {Function} handler
10003
10248
  */
10004
10249
  off(type, handler) {
10005
10250
  this.get('eventBus').off(type, handler);
10006
10251
  }
10007
10252
 
10008
- /**
10009
- * @internal
10010
- *
10011
- * @param {FormEditorOptions} options
10012
- * @param {Element} container
10013
- *
10014
- * @returns {Injector}
10253
+ /**
10254
+ * @internal
10255
+ *
10256
+ * @param {FormEditorOptions} options
10257
+ * @param {Element} container
10258
+ *
10259
+ * @returns {Injector}
10015
10260
  */
10016
10261
  _createInjector(options, container) {
10017
10262
  const {
@@ -10033,22 +10278,22 @@ class FormEditor {
10033
10278
  }, core, ...modules, ...additionalModules]);
10034
10279
  }
10035
10280
 
10036
- /**
10037
- * @internal
10281
+ /**
10282
+ * @internal
10038
10283
  */
10039
10284
  _emit(type, data) {
10040
10285
  this.get('eventBus').fire(type, data);
10041
10286
  }
10042
10287
 
10043
- /**
10044
- * @internal
10288
+ /**
10289
+ * @internal
10045
10290
  */
10046
10291
  _getState() {
10047
10292
  return this._state;
10048
10293
  }
10049
10294
 
10050
- /**
10051
- * @internal
10295
+ /**
10296
+ * @internal
10052
10297
  */
10053
10298
  _setState(state) {
10054
10299
  this._state = {
@@ -10058,15 +10303,15 @@ class FormEditor {
10058
10303
  this._emit('changed', this._getState());
10059
10304
  }
10060
10305
 
10061
- /**
10062
- * @internal
10306
+ /**
10307
+ * @internal
10063
10308
  */
10064
10309
  _getModules() {
10065
10310
  return [ModelingModule, EditorActionsModule, DraggingModule, KeyboardModule, SelectionModule, PaletteModule, ExpressionLanguageModule, formJsViewer.MarkdownModule, PropertiesPanelModule, RenderInjectionModule];
10066
10311
  }
10067
10312
 
10068
- /**
10069
- * @internal
10313
+ /**
10314
+ * @internal
10070
10315
  */
10071
10316
  _onEvent(type, priority, handler) {
10072
10317
  this.get('eventBus').on(type, priority, handler);