@bpmn-io/form-js-editor 0.7.2 → 0.8.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +1 -0
  2. package/dist/assets/form-js-editor.css +8 -202
  3. package/dist/assets/properties-panel.css +930 -0
  4. package/dist/index.cjs +2777 -844
  5. package/dist/index.cjs.map +1 -1
  6. package/dist/index.es.js +2781 -849
  7. package/dist/index.es.js.map +1 -1
  8. package/dist/types/render/components/palette/icons/index.d.ts +2 -0
  9. package/dist/types/render/components/properties-panel/PropertiesPanel.d.ts +1 -1
  10. package/dist/types/render/components/properties-panel/PropertiesPanelHeaderProvider.d.ts +5 -0
  11. package/dist/types/render/components/properties-panel/PropertiesPanelPlaceholderProvider.d.ts +8 -0
  12. package/dist/types/render/components/properties-panel/Util.d.ts +1 -0
  13. package/dist/types/render/components/properties-panel/entries/ActionEntry.d.ts +9 -1
  14. package/dist/types/render/components/properties-panel/entries/ColumnsEntry.d.ts +9 -1
  15. package/dist/types/render/components/properties-panel/entries/CustomValueEntry.d.ts +11 -1
  16. package/dist/types/render/components/properties-panel/entries/DefaultValueEntry.d.ts +1 -1
  17. package/dist/types/render/components/properties-panel/entries/DescriptionEntry.d.ts +9 -1
  18. package/dist/types/render/components/properties-panel/entries/DisabledEntry.d.ts +9 -1
  19. package/dist/types/render/components/properties-panel/entries/IdEntry.d.ts +9 -1
  20. package/dist/types/render/components/properties-panel/entries/InputKeyValuesSourceEntry.d.ts +11 -0
  21. package/dist/types/render/components/properties-panel/entries/KeyEntry.d.ts +9 -1
  22. package/dist/types/render/components/properties-panel/entries/LabelEntry.d.ts +9 -1
  23. package/dist/types/render/components/properties-panel/entries/StaticValuesSourceEntry.d.ts +4 -0
  24. package/dist/types/render/components/properties-panel/entries/TextEntry.d.ts +9 -1
  25. package/dist/types/render/components/properties-panel/entries/ValueEntry.d.ts +11 -1
  26. package/dist/types/render/components/properties-panel/entries/ValuesSourceSelectEntry.d.ts +9 -0
  27. package/dist/types/render/components/properties-panel/entries/ValuesSourceUtil.d.ts +15 -0
  28. package/dist/types/render/components/properties-panel/entries/index.d.ts +3 -0
  29. package/dist/types/render/components/properties-panel/groups/CustomValuesGroup.d.ts +22 -1
  30. package/dist/types/render/components/properties-panel/groups/GeneralGroup.d.ts +5 -1
  31. package/dist/types/render/components/properties-panel/groups/ValidationGroup.d.ts +14 -1
  32. package/dist/types/render/components/properties-panel/groups/ValuesGroups.d.ts +1 -0
  33. package/dist/types/render/components/properties-panel/groups/index.d.ts +1 -1
  34. package/package.json +5 -4
  35. package/dist/types/render/components/properties-panel/components/CheckboxInput.d.ts +0 -1
  36. package/dist/types/render/components/properties-panel/components/CheckboxInputEntry.d.ts +0 -1
  37. package/dist/types/render/components/properties-panel/components/CollapsibleEntry.d.ts +0 -1
  38. package/dist/types/render/components/properties-panel/components/Group.d.ts +0 -1
  39. package/dist/types/render/components/properties-panel/components/NumberInput.d.ts +0 -1
  40. package/dist/types/render/components/properties-panel/components/NumberInputEntry.d.ts +0 -1
  41. package/dist/types/render/components/properties-panel/components/Select.d.ts +0 -1
  42. package/dist/types/render/components/properties-panel/components/SelectEntry.d.ts +0 -1
  43. package/dist/types/render/components/properties-panel/components/TextInput.d.ts +0 -1
  44. package/dist/types/render/components/properties-panel/components/TextInputEntry.d.ts +0 -1
  45. package/dist/types/render/components/properties-panel/components/Textarea.d.ts +0 -1
  46. package/dist/types/render/components/properties-panel/components/TextareaEntry.d.ts +0 -1
  47. package/dist/types/render/components/properties-panel/components/index.d.ts +0 -12
  48. package/dist/types/render/components/properties-panel/groups/ValuesGroup.d.ts +0 -1
package/dist/index.cjs CHANGED
@@ -9,18 +9,20 @@ var preact = require('preact');
9
9
  var hooks$1 = require('preact/hooks');
10
10
  var React = require('preact/compat');
11
11
  var jsxRuntime = require('preact/jsx-runtime');
12
- var dragula = require('dragula');
12
+ var classnames = require('classnames');
13
13
  var minDom = require('min-dom');
14
+ var dragula = require('dragula');
14
15
  var arrayMove = require('array-move');
15
16
 
16
17
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
17
18
 
18
19
  var Ids__default = /*#__PURE__*/_interopDefaultLegacy(Ids);
19
20
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
21
+ var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
20
22
  var dragula__default = /*#__PURE__*/_interopDefaultLegacy(dragula);
21
23
 
22
24
  var FN_REF = '__fn';
23
- var DEFAULT_PRIORITY$2 = 1000;
25
+ var DEFAULT_PRIORITY$3 = 1000;
24
26
  var slice = Array.prototype.slice;
25
27
  /**
26
28
  * A general purpose event bus.
@@ -136,7 +138,7 @@ EventBus.prototype.on = function (events, priority, callback, that) {
136
138
  if (minDash.isFunction(priority)) {
137
139
  that = callback;
138
140
  callback = priority;
139
- priority = DEFAULT_PRIORITY$2;
141
+ priority = DEFAULT_PRIORITY$3;
140
142
  }
141
143
 
142
144
  if (!minDash.isNumber(priority)) {
@@ -178,7 +180,7 @@ EventBus.prototype.once = function (event, priority, callback, that) {
178
180
  if (minDash.isFunction(priority)) {
179
181
  that = callback;
180
182
  callback = priority;
181
- priority = DEFAULT_PRIORITY$2;
183
+ priority = DEFAULT_PRIORITY$3;
182
184
  }
183
185
 
184
186
  if (!minDash.isNumber(priority)) {
@@ -774,11 +776,11 @@ function useService (type, strict) {
774
776
  return getService(type, strict);
775
777
  }
776
778
 
777
- function _extends$c() { _extends$c = Object.assign || 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$c.apply(this, arguments); }
779
+ function _extends$b() { _extends$b = Object.assign || 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$b.apply(this, arguments); }
778
780
  var ButtonIcon = (({
779
781
  styles = {},
780
782
  ...props
781
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$c({
783
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$b({
782
784
  xmlns: "http://www.w3.org/2000/svg",
783
785
  width: "54",
784
786
  height: "54"
@@ -787,11 +789,11 @@ var ButtonIcon = (({
787
789
  d: "M45 17a3 3 0 013 3v14a3 3 0 01-3 3H9a3 3 0 01-3-3V20a3 3 0 013-3h36zm-9 8.889H18v2.222h18V25.89z"
788
790
  })));
789
791
 
790
- function _extends$b() { _extends$b = Object.assign || 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$b.apply(this, arguments); }
792
+ function _extends$a() { _extends$a = Object.assign || 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$a.apply(this, arguments); }
791
793
  var CheckboxIcon = (({
792
794
  styles = {},
793
795
  ...props
794
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$b({
796
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$a({
795
797
  xmlns: "http://www.w3.org/2000/svg",
796
798
  width: "54",
797
799
  height: "54"
@@ -799,11 +801,49 @@ var CheckboxIcon = (({
799
801
  d: "M34 18H20a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V20a2 2 0 00-2-2zm-9 14l-5-5 1.41-1.41L25 29.17l7.59-7.59L34 23l-9 9z"
800
802
  })));
801
803
 
802
- function _extends$a() { _extends$a = Object.assign || 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$a.apply(this, arguments); }
804
+ function _extends$9() { _extends$9 = Object.assign || 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$9.apply(this, arguments); }
805
+ var ChecklistIcon = (({
806
+ styles = {},
807
+ ...props
808
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$9({
809
+ width: "54",
810
+ height: "54",
811
+ fill: "none",
812
+ xmlns: "http://www.w3.org/2000/svg"
813
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
814
+ fillRule: "evenodd",
815
+ clipRule: "evenodd",
816
+ d: "M19 24h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zm6 18h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zm6-30h-6v6h6V8zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2V8a2 2 0 00-2-2h-6z",
817
+ fill: "#22242A"
818
+ }), /*#__PURE__*/React__default['default'].createElement("path", {
819
+ d: "M26 26a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2zm0 16a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2zm0-32a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2z",
820
+ fill: "#22242A"
821
+ })));
822
+
823
+ function _extends$8() { _extends$8 = Object.assign || 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$8.apply(this, arguments); }
824
+ var TaglistIcon = (({
825
+ styles = {},
826
+ ...props
827
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$8({
828
+ width: "54",
829
+ height: "54",
830
+ fill: "none",
831
+ xmlns: "http://www.w3.org/2000/svg"
832
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
833
+ fillRule: "evenodd",
834
+ clipRule: "evenodd",
835
+ d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1z",
836
+ fill: "#000"
837
+ }), /*#__PURE__*/React__default['default'].createElement("path", {
838
+ d: "M11 22a1 1 0 011-1h19a1 1 0 011 1v10a1 1 0 01-1 1H12a1 1 0 01-1-1V22z",
839
+ fill: "#505562"
840
+ })));
841
+
842
+ function _extends$7() { _extends$7 = Object.assign || 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$7.apply(this, arguments); }
803
843
  var FormIcon = (({
804
844
  styles = {},
805
845
  ...props
806
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$a({
846
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$7({
807
847
  xmlns: "http://www.w3.org/2000/svg",
808
848
  width: "54",
809
849
  height: "54"
@@ -827,11 +867,11 @@ var FormIcon = (({
827
867
  rx: "1"
828
868
  })));
829
869
 
830
- function _extends$9() { _extends$9 = Object.assign || 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$9.apply(this, arguments); }
870
+ function _extends$6() { _extends$6 = Object.assign || 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$6.apply(this, arguments); }
831
871
  var ColumnsIcon = (({
832
872
  styles = {},
833
873
  ...props
834
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$9({
874
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$6({
835
875
  xmlns: "http://www.w3.org/2000/svg",
836
876
  width: "54",
837
877
  height: "54"
@@ -840,11 +880,11 @@ var ColumnsIcon = (({
840
880
  d: "M8 33v5a1 1 0 001 1h4v2H9a3 3 0 01-3-3v-5h2zm18 6v2H15v-2h11zm13 0v2H28v-2h11zm9-6v5a3 3 0 01-3 3h-4v-2h4a1 1 0 00.993-.883L46 38v-5h2zM8 22v9H6v-9h2zm40 0v9h-2v-9h2zm-35-9v2H9a1 1 0 00-.993.883L8 16v4H6v-4a3 3 0 013-3h4zm32 0a3 3 0 013 3v4h-2v-4a1 1 0 00-.883-.993L45 15h-4v-2h4zm-6 0v2H28v-2h11zm-13 0v2H15v-2h11z"
841
881
  })));
842
882
 
843
- function _extends$8() { _extends$8 = Object.assign || 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$8.apply(this, arguments); }
883
+ function _extends$5() { _extends$5 = Object.assign || 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$5.apply(this, arguments); }
844
884
  var NumberIcon = (({
845
885
  styles = {},
846
886
  ...props
847
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$8({
887
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$5({
848
888
  xmlns: "http://www.w3.org/2000/svg",
849
889
  width: "54",
850
890
  height: "54"
@@ -853,11 +893,11 @@ var NumberIcon = (({
853
893
  d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1zM35 28.444h7l-3.5 4-3.5-4zM35 26h7l-3.5-4-3.5 4z"
854
894
  })));
855
895
 
856
- function _extends$7() { _extends$7 = Object.assign || 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$7.apply(this, arguments); }
896
+ function _extends$4() { _extends$4 = Object.assign || 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$4.apply(this, arguments); }
857
897
  var RadioIcon = (({
858
898
  styles = {},
859
899
  ...props
860
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$7({
900
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$4({
861
901
  xmlns: "http://www.w3.org/2000/svg",
862
902
  width: "54",
863
903
  height: "54"
@@ -865,11 +905,11 @@ var RadioIcon = (({
865
905
  d: "M27 22c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"
866
906
  })));
867
907
 
868
- function _extends$6() { _extends$6 = Object.assign || 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$6.apply(this, arguments); }
908
+ function _extends$3() { _extends$3 = Object.assign || 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); }
869
909
  var SelectIcon = (({
870
910
  styles = {},
871
911
  ...props
872
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$6({
912
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$3({
873
913
  xmlns: "http://www.w3.org/2000/svg",
874
914
  width: "54",
875
915
  height: "54"
@@ -878,11 +918,11 @@ var SelectIcon = (({
878
918
  d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1zm-12 7h9l-4.5 6-4.5-6z"
879
919
  })));
880
920
 
881
- function _extends$5() { _extends$5 = Object.assign || 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$5.apply(this, arguments); }
921
+ function _extends$2() { _extends$2 = Object.assign || 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); }
882
922
  var TextIcon = (({
883
923
  styles = {},
884
924
  ...props
885
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$5({
925
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$2({
886
926
  xmlns: "http://www.w3.org/2000/svg",
887
927
  width: "54",
888
928
  height: "54"
@@ -890,11 +930,11 @@ var TextIcon = (({
890
930
  d: "M20.58 33.77h-3l-1.18-3.08H11l-1.1 3.08H7l5.27-13.54h2.89zm-5-5.36l-1.86-5-1.83 5zM22 20.23h5.41a15.47 15.47 0 012.4.14 3.42 3.42 0 011.41.55 3.47 3.47 0 011 1.14 3 3 0 01.42 1.58 3.26 3.26 0 01-1.91 2.94 3.63 3.63 0 011.91 1.22 3.28 3.28 0 01.66 2 4 4 0 01-.43 1.8 3.63 3.63 0 01-1.09 1.4 3.89 3.89 0 01-1.83.65q-.69.07-3.3.09H22zm2.73 2.25v3.13h3.8a1.79 1.79 0 001.1-.49 1.41 1.41 0 00.41-1 1.49 1.49 0 00-.35-1 1.54 1.54 0 00-1-.48c-.27 0-1.05-.05-2.34-.05zm0 5.39v3.62h2.57a11.52 11.52 0 001.88-.09 1.65 1.65 0 001-.54 1.6 1.6 0 00.38-1.14 1.75 1.75 0 00-.29-1 1.69 1.69 0 00-.86-.62 9.28 9.28 0 00-2.41-.23zM44.35 28.79l2.65.84a5.94 5.94 0 01-2 3.29A5.74 5.74 0 0141.38 34a5.87 5.87 0 01-4.44-1.84 7.09 7.09 0 01-1.73-5A7.43 7.43 0 0137 21.87 6 6 0 0141.54 20a5.64 5.64 0 014 1.47A5.33 5.33 0 0147 24l-2.7.65a2.8 2.8 0 00-2.86-2.27A3.09 3.09 0 0039 23.42a5.31 5.31 0 00-.93 3.5 5.62 5.62 0 00.93 3.65 3 3 0 002.4 1.09 2.72 2.72 0 001.82-.66 4 4 0 001.13-2.21z"
891
931
  })));
892
932
 
893
- function _extends$4() { _extends$4 = Object.assign || 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$4.apply(this, arguments); }
933
+ function _extends$1() { _extends$1 = Object.assign || 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); }
894
934
  var TextfieldIcon = (({
895
935
  styles = {},
896
936
  ...props
897
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$4({
937
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$1({
898
938
  xmlns: "http://www.w3.org/2000/svg",
899
939
  width: "54",
900
940
  height: "54"
@@ -906,10 +946,12 @@ var TextfieldIcon = (({
906
946
  const iconsByType = {
907
947
  button: ButtonIcon,
908
948
  checkbox: CheckboxIcon,
949
+ checklist: ChecklistIcon,
909
950
  columns: ColumnsIcon,
910
951
  number: NumberIcon,
911
952
  radio: RadioIcon,
912
953
  select: SelectIcon,
954
+ taglist: TaglistIcon,
913
955
  text: TextIcon,
914
956
  textfield: TextfieldIcon,
915
957
  default: FormIcon
@@ -924,6 +966,12 @@ const types = [{
924
966
  }, {
925
967
  label: 'Checkbox',
926
968
  type: 'checkbox'
969
+ }, {
970
+ label: 'Checklist',
971
+ type: 'checklist'
972
+ }, {
973
+ label: 'Taglist',
974
+ type: 'taglist'
927
975
  }, {
928
976
  label: 'Radio',
929
977
  type: 'radio'
@@ -973,564 +1021,1763 @@ function Palette(props) {
973
1021
  });
974
1022
  }
975
1023
 
976
- function arrayAdd$1(array, index, item) {
977
- const copy = [...array];
978
- copy.splice(index, 0, item);
979
- return copy;
980
- }
981
- function arrayRemove$1(array, index) {
982
- const copy = [...array];
983
- copy.splice(index, 1);
984
- return copy;
985
- }
986
- function prefixId(id) {
987
- return `fjs-properties-panel-${id}`;
988
- }
989
- function stopPropagation(listener) {
990
- return event => {
991
- event.stopPropagation();
992
- listener(event);
993
- };
994
- }
995
- function textToLabel(text = '...') {
996
- if (text.length > 10) {
997
- return `${text.substring(0, 30)}...`;
998
- }
1024
+ var ArrowIcon = function ArrowIcon(props) {
1025
+ return jsxRuntime.jsx("svg", { ...props,
1026
+ children: jsxRuntime.jsx("path", {
1027
+ fillRule: "evenodd",
1028
+ d: "m11.657 8-4.95 4.95a1 1 0 0 1-1.414-1.414L8.828 8 5.293 4.464A1 1 0 1 1 6.707 3.05L11.657 8z"
1029
+ })
1030
+ });
1031
+ };
999
1032
 
1000
- return text;
1001
- }
1002
- const INPUTS = ['checkbox', 'number', 'radio', 'select', 'textfield'];
1033
+ ArrowIcon.defaultProps = {
1034
+ xmlns: "http://www.w3.org/2000/svg",
1035
+ width: "16",
1036
+ height: "16"
1037
+ };
1003
1038
 
1004
- function CheckboxInput(props) {
1005
- const {
1006
- id,
1007
- label,
1008
- onChange,
1009
- value = false
1010
- } = props;
1039
+ var CreateIcon = function CreateIcon(props) {
1040
+ return jsxRuntime.jsx("svg", { ...props,
1041
+ children: jsxRuntime.jsx("path", {
1042
+ fillRule: "evenodd",
1043
+ d: "M9 13V9h4a1 1 0 0 0 0-2H9V3a1 1 0 1 0-2 0v4H3a1 1 0 1 0 0 2h4v4a1 1 0 0 0 2 0z"
1044
+ })
1045
+ });
1046
+ };
1011
1047
 
1012
- const handleChange = ({
1013
- target
1014
- }) => {
1015
- onChange(target.checked);
1016
- };
1048
+ CreateIcon.defaultProps = {
1049
+ xmlns: "http://www.w3.org/2000/svg",
1050
+ width: "16",
1051
+ height: "16"
1052
+ };
1017
1053
 
1018
- return jsxRuntime.jsxs("div", {
1019
- class: "fjs-properties-panel-checkbox",
1020
- children: [jsxRuntime.jsx("label", {
1021
- for: prefixId(id),
1022
- class: "fjs-properties-panel-label",
1023
- children: label
1024
- }), jsxRuntime.jsx("input", {
1025
- id: prefixId(id),
1026
- type: "checkbox",
1027
- class: "fjs-properties-panel-input",
1028
- onChange: handleChange,
1029
- checked: value
1030
- })]
1054
+ var DeleteIcon = function DeleteIcon(props) {
1055
+ return jsxRuntime.jsx("svg", { ...props,
1056
+ children: jsxRuntime.jsx("path", {
1057
+ fillRule: "evenodd",
1058
+ d: "M12 6v7c0 1.1-.4 1.55-1.5 1.55h-5C4.4 14.55 4 14.1 4 13V6h8zm-1.5 1.5h-5v4.3c0 .66.5 1.2 1.111 1.2H9.39c.611 0 1.111-.54 1.111-1.2V7.5zM13 3h-2l-1-1H6L5 3H3v1.5h10V3z"
1059
+ })
1031
1060
  });
1032
- }
1033
-
1034
- function usePrevious(value) {
1035
- const ref = hooks$1.useRef();
1036
- hooks$1.useEffect(() => ref.current = value);
1037
- return ref.current;
1038
- }
1061
+ };
1039
1062
 
1040
- function useDebounce(fn, dependencies = []) {
1041
- const debounce = useService('debounce');
1042
- const callback = hooks$1.useMemo(() => {
1043
- return debounce(fn);
1044
- }, dependencies); // cleanup async side-effect if callback #flush is provided.
1063
+ DeleteIcon.defaultProps = {
1064
+ xmlns: "http://www.w3.org/2000/svg",
1065
+ width: "16",
1066
+ height: "16"
1067
+ };
1045
1068
 
1046
- hooks$1.useEffect(() => {
1047
- return () => {
1048
- typeof callback.flush === 'function' && callback.flush();
1049
- };
1050
- }, [callback]);
1051
- return callback;
1052
- }
1069
+ var ExternalLinkIcon = function ExternalLinkIcon(props) {
1070
+ return jsxRuntime.jsx("svg", { ...props,
1071
+ children: jsxRuntime.jsx("path", {
1072
+ fillRule: "evenodd",
1073
+ clipRule: "evenodd",
1074
+ d: "M12.637 12.637v-4.72h1.362v4.721c0 .36-.137.676-.411.95-.275.275-.591.412-.95.412H3.362c-.38 0-.703-.132-.967-.396A1.315 1.315 0 0 1 2 12.638V3.362c0-.38.132-.703.396-.967S2.982 2 3.363 2h4.553v1.363H3.363v9.274h9.274zM14 2H9.28l-.001 1.362h2.408L5.065 9.984l.95.95 6.622-6.622v2.409H14V2z",
1075
+ fill: "#818798"
1076
+ })
1077
+ });
1078
+ };
1053
1079
 
1054
- function NumberInput(props) {
1055
- const {
1056
- id,
1057
- label,
1058
- max,
1059
- min,
1060
- value = '',
1061
- onInput: _onInput
1062
- } = props;
1063
- const onInput = useDebounce(event => {
1064
- const {
1065
- validity,
1066
- value
1067
- } = event.target;
1080
+ ExternalLinkIcon.defaultProps = {
1081
+ width: "16",
1082
+ height: "16",
1083
+ fill: "none",
1084
+ xmlns: "http://www.w3.org/2000/svg"
1085
+ };
1068
1086
 
1069
- if (validity.valid) {
1070
- _onInput(value ? parseInt(value, 10) : undefined);
1071
- }
1072
- }, [_onInput]);
1073
- return jsxRuntime.jsxs("div", {
1074
- class: "fjs-properties-panel-number",
1075
- children: [jsxRuntime.jsx("label", {
1076
- for: prefixId(id),
1077
- class: "fjs-properties-panel-label",
1078
- children: label
1079
- }), jsxRuntime.jsx("input", {
1080
- id: prefixId(id),
1081
- type: "number",
1082
- class: "fjs-properties-panel-input",
1083
- max: max,
1084
- min: min,
1085
- onInput: onInput,
1086
- value: value
1087
+ var FeelRequiredIcon = function FeelRequiredIcon(props) {
1088
+ return jsxRuntime.jsxs("svg", { ...props,
1089
+ children: [jsxRuntime.jsx("path", {
1090
+ d: "M5.8 7.06V5.95h4.307v1.11H5.8zm0 3.071v-1.11h4.307v1.11H5.8z",
1091
+ fill: "#505562"
1092
+ }), jsxRuntime.jsx("path", {
1093
+ fillRule: "evenodd",
1094
+ clipRule: "evenodd",
1095
+ d: "M8 3.268A4.732 4.732 0 1 0 12.732 8H14a6 6 0 1 1-6-6v1.268z",
1096
+ fill: "#505562"
1097
+ }), jsxRuntime.jsx("path", {
1098
+ d: "m11.28 6.072-.832-.56 1.016-1.224L10 3.848l.312-.912 1.392.584L11.632 2h1.032l-.072 1.52 1.392-.584.312.912-1.464.44 1.008 1.224-.832.552-.864-1.296-.864 1.304z",
1099
+ fill: "#505562"
1087
1100
  })]
1088
1101
  });
1089
- }
1090
-
1091
- function Select(props) {
1092
- const {
1093
- id,
1094
- label,
1095
- onChange,
1096
- options,
1097
- value
1098
- } = props;
1102
+ };
1099
1103
 
1100
- const handleChange = ({
1101
- target
1102
- }) => {
1103
- onChange(target.value);
1104
- };
1104
+ FeelRequiredIcon.defaultProps = {
1105
+ viewBox: "0 0 16 16",
1106
+ fill: "none",
1107
+ xmlns: "http://www.w3.org/2000/svg"
1108
+ };
1105
1109
 
1106
- return jsxRuntime.jsxs("div", {
1107
- class: "fjs-properties-panel-select",
1108
- children: [jsxRuntime.jsx("label", {
1109
- for: prefixId(id),
1110
- class: "fjs-properties-panel-label",
1111
- children: label
1112
- }), jsxRuntime.jsx("select", {
1113
- id: prefixId(id),
1114
- class: "fjs-properties-panel-input",
1115
- onInput: handleChange,
1116
- children: options.map(option => {
1117
- return jsxRuntime.jsx("option", {
1118
- value: option.value,
1119
- selected: option.value === value,
1120
- children: option.label
1121
- });
1122
- })
1110
+ var FeelOptionalIcon = function FeelOptionalIcon(props) {
1111
+ return jsxRuntime.jsxs("svg", { ...props,
1112
+ children: [jsxRuntime.jsx("path", {
1113
+ d: "M5.845 7.04V5.93h4.307v1.11H5.845zm0 3.07V9h4.307v1.11H5.845z",
1114
+ fill: "#505562"
1115
+ }), jsxRuntime.jsx("path", {
1116
+ fillRule: "evenodd",
1117
+ clipRule: "evenodd",
1118
+ d: "M3.286 8a4.714 4.714 0 1 0 9.428 0 4.714 4.714 0 0 0-9.428 0zM8 2a6 6 0 1 0 0 12A6 6 0 0 0 8 2z",
1119
+ fill: "#505562"
1123
1120
  })]
1124
1121
  });
1125
- }
1122
+ };
1123
+
1124
+ FeelOptionalIcon.defaultProps = {
1125
+ viewBox: "0 0 16 16",
1126
+ fill: "none",
1127
+ xmlns: "http://www.w3.org/2000/svg"
1128
+ };
1126
1129
 
1127
- function Textarea(props) {
1130
+ function Header(props) {
1128
1131
  const {
1129
- id,
1130
- label,
1131
- rows = 10,
1132
- value = '',
1133
- onInput: _onInput
1132
+ element,
1133
+ headerProvider
1134
1134
  } = props;
1135
- const onInput = useDebounce(event => {
1136
- const value = event.target.value;
1137
-
1138
- _onInput(value.length ? value : undefined);
1139
- }, [_onInput]);
1135
+ const {
1136
+ getElementIcon,
1137
+ getDocumentationRef,
1138
+ getElementLabel,
1139
+ getTypeLabel
1140
+ } = headerProvider;
1141
+ const label = getElementLabel(element);
1142
+ const type = getTypeLabel(element);
1143
+ const documentationRef = getDocumentationRef && getDocumentationRef(element);
1144
+ const ElementIcon = getElementIcon(element);
1140
1145
  return jsxRuntime.jsxs("div", {
1141
- class: "fjs-properties-panel-textarea",
1142
- children: [jsxRuntime.jsx("label", {
1143
- for: prefixId(id),
1144
- class: "fjs-properties-panel-label",
1145
- children: label
1146
- }), jsxRuntime.jsx("textarea", {
1147
- id: prefixId(id),
1148
- spellcheck: false,
1149
- class: "fjs-properties-panel-input",
1150
- onInput: onInput,
1151
- rows: rows,
1152
- value: value
1146
+ class: "bio-properties-panel-header",
1147
+ children: [jsxRuntime.jsx("div", {
1148
+ class: "bio-properties-panel-header-icon",
1149
+ children: ElementIcon && jsxRuntime.jsx(ElementIcon, {
1150
+ width: "32",
1151
+ height: "32",
1152
+ viewBox: "0 0 32 32"
1153
+ })
1154
+ }), jsxRuntime.jsxs("div", {
1155
+ class: "bio-properties-panel-header-labels",
1156
+ children: [jsxRuntime.jsx("div", {
1157
+ title: type,
1158
+ class: "bio-properties-panel-header-type",
1159
+ children: type
1160
+ }), label ? jsxRuntime.jsx("div", {
1161
+ title: label,
1162
+ class: "bio-properties-panel-header-label",
1163
+ children: label
1164
+ }) : null]
1165
+ }), jsxRuntime.jsx("div", {
1166
+ class: "bio-properties-panel-header-actions",
1167
+ children: documentationRef ? jsxRuntime.jsx("a", {
1168
+ rel: "noopener",
1169
+ class: "bio-properties-panel-header-link",
1170
+ href: documentationRef,
1171
+ title: "Open documentation",
1172
+ target: "_blank",
1173
+ children: jsxRuntime.jsx(ExternalLinkIcon, {})
1174
+ }) : null
1153
1175
  })]
1154
1176
  });
1155
1177
  }
1156
1178
 
1157
- function TextInput(props) {
1158
- let {
1159
- id,
1160
- label,
1161
- validate = () => null,
1162
- onInput: _onInput,
1163
- value = ''
1164
- } = props;
1165
- const prevValue = usePrevious(value);
1166
- const [cachedValue, setCachedValue] = hooks$1.useState(null);
1167
- const [error, setError] = hooks$1.useState(null);
1168
- hooks$1.useEffect(() => setError(validate(value)), [validate, value]);
1169
- const onInput = useDebounce(event => {
1170
- const value = event.target.value;
1171
- const error = validate(value);
1172
-
1173
- if (error) {
1174
- setCachedValue(value);
1175
- } else {
1176
- _onInput(value.length ? value : undefined);
1177
- }
1179
+ const DescriptionContext = preact.createContext({
1180
+ description: {},
1181
+ getDescriptionForId: () => {}
1182
+ });
1183
+ /**
1184
+ * @typedef {Function} <propertiesPanel.showEntry> callback
1185
+ *
1186
+ * @example
1187
+ *
1188
+ * useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
1189
+ * // ...
1190
+ * });
1191
+ *
1192
+ * @param {Object} context
1193
+ * @param {boolean} [context.focus]
1194
+ *
1195
+ * @returns void
1196
+ */
1178
1197
 
1179
- setError(error);
1180
- }, [validate, setCachedValue, _onInput]);
1198
+ const EventContext = preact.createContext({
1199
+ eventBus: null
1200
+ });
1201
+ const LayoutContext = preact.createContext({
1202
+ layout: {},
1203
+ setLayout: () => {},
1204
+ getLayoutForKey: () => {},
1205
+ setLayoutForKey: () => {}
1206
+ });
1207
+ /**
1208
+ * Accesses the global DescriptionContext and returns a description for a given id and element.
1209
+ *
1210
+ * @example
1211
+ * ```jsx
1212
+ * function TextField(props) {
1213
+ * const description = useDescriptionContext('input1', element);
1214
+ * }
1215
+ * ```
1216
+ *
1217
+ * @param {string} id
1218
+ * @param {object} element
1219
+ *
1220
+ * @returns {string}
1221
+ */
1181
1222
 
1182
- if (prevValue === value && error) {
1183
- value = cachedValue;
1184
- }
1223
+ function useDescriptionContext(id, element) {
1224
+ const {
1225
+ getDescriptionForId
1226
+ } = hooks$1.useContext(DescriptionContext);
1227
+ return getDescriptionForId(id, element);
1228
+ }
1185
1229
 
1186
- const classes = ['fjs-properties-panel-input'];
1230
+ const DEFAULT_PRIORITY$2 = 1000;
1231
+ /**
1232
+ * Subscribe to an event.
1233
+ *
1234
+ * @param {string} event
1235
+ * @param {Function} callback
1236
+ * @param {number} [priority]
1237
+ *
1238
+ * @returns {import('preact').Ref}
1239
+ */
1187
1240
 
1188
- if (error) {
1189
- classes.push('fjs-has-error');
1190
- }
1241
+ function useEvent(event, callback, priority = DEFAULT_PRIORITY$2) {
1242
+ const {
1243
+ eventBus
1244
+ } = hooks$1.useContext(EventContext);
1245
+ hooks$1.useEffect(() => {
1246
+ if (!eventBus) {
1247
+ return;
1248
+ }
1191
1249
 
1192
- return jsxRuntime.jsxs("div", {
1193
- class: "fjs-properties-panel-text",
1194
- children: [jsxRuntime.jsx("label", {
1195
- for: prefixId(id),
1196
- class: "fjs-properties-panel-label",
1197
- children: label
1198
- }), jsxRuntime.jsx("input", {
1199
- id: prefixId(id),
1200
- type: "text",
1201
- spellcheck: false,
1202
- class: classes.join(' '),
1203
- onInput: onInput,
1204
- value: value
1205
- }), error && jsxRuntime.jsx("div", {
1206
- class: "fjs-properties-panel-error",
1207
- children: error
1208
- })]
1209
- });
1250
+ eventBus.on(event, priority, callback);
1251
+ return () => eventBus.off(event, callback);
1252
+ }, [callback, event, eventBus, priority]);
1210
1253
  }
1211
1254
 
1212
- function CheckboxInputEntry(props) {
1213
- const {
1214
- editField,
1215
- field,
1216
- id,
1217
- label,
1218
- path
1219
- } = props;
1255
+ const HIGH_PRIORITY = 10000;
1256
+ /**
1257
+ * Buffer events and re-fire during passive effect phase.
1258
+ *
1259
+ * @param {string[]} bufferedEvents
1260
+ * @param {Object} [eventBus]
1261
+ */
1220
1262
 
1221
- const onChange = value => {
1222
- if (editField && path) {
1223
- editField(field, path, value);
1224
- } else {
1225
- props.onChange(value);
1263
+ function useEventBuffer(bufferedEvents, eventBus) {
1264
+ const buffer = hooks$1.useRef([]),
1265
+ buffering = hooks$1.useRef(true);
1266
+
1267
+ const createCallback = event => data => {
1268
+ if (buffering.current === true) {
1269
+ buffer.current.unshift([event, data]);
1226
1270
  }
1227
- };
1271
+ }; // (1) buffer events
1228
1272
 
1229
- const value = path ? minDash.get(field, path, false) : props.value;
1230
- return jsxRuntime.jsx("div", {
1231
- class: "fjs-properties-panel-entry",
1232
- children: jsxRuntime.jsx(CheckboxInput, {
1233
- id: id,
1234
- label: label,
1235
- onChange: onChange,
1236
- value: value
1237
- })
1238
- });
1239
- }
1240
1273
 
1241
- function NumberInputEntry(props) {
1242
- const {
1243
- editField,
1244
- field,
1274
+ hooks$1.useEffect(() => {
1275
+ if (!eventBus) {
1276
+ return;
1277
+ }
1278
+
1279
+ const listeners = bufferedEvents.map(event => {
1280
+ return [event, createCallback(event)];
1281
+ });
1282
+ listeners.forEach(([event, callback]) => {
1283
+ eventBus.on(event, HIGH_PRIORITY, callback);
1284
+ });
1285
+ return () => {
1286
+ listeners.forEach(([event, callback]) => {
1287
+ eventBus.off(event, callback);
1288
+ });
1289
+ };
1290
+ }, [bufferedEvents, eventBus]); // (2) re-fire events
1291
+
1292
+ hooks$1.useEffect(() => {
1293
+ if (!eventBus) {
1294
+ return;
1295
+ }
1296
+
1297
+ buffering.current = false;
1298
+
1299
+ while (buffer.current.length) {
1300
+ const [event, data] = buffer.current.pop();
1301
+ eventBus.fire(event, data);
1302
+ }
1303
+
1304
+ buffering.current = true;
1305
+ });
1306
+ }
1307
+ /**
1308
+ * Creates a state that persists in the global LayoutContext.
1309
+ *
1310
+ * @example
1311
+ * ```jsx
1312
+ * function Group(props) {
1313
+ * const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
1314
+ * }
1315
+ * ```
1316
+ *
1317
+ * @param {(string|number)[]} path
1318
+ * @param {any} [defaultValue]
1319
+ *
1320
+ * @returns {[ any, Function ]}
1321
+ */
1322
+
1323
+
1324
+ function useLayoutState(path, defaultValue) {
1325
+ const {
1326
+ getLayoutForKey,
1327
+ setLayoutForKey
1328
+ } = hooks$1.useContext(LayoutContext);
1329
+ const layoutForKey = getLayoutForKey(path, defaultValue);
1330
+ const [value, set] = hooks$1.useState(layoutForKey);
1331
+
1332
+ const setState = newValue => {
1333
+ // (1) set component state
1334
+ set(newValue); // (2) set context
1335
+
1336
+ setLayoutForKey(path, newValue);
1337
+ };
1338
+
1339
+ return [value, setState];
1340
+ }
1341
+ /**
1342
+ * @pinussilvestrus: we need to introduce our own hook to persist the previous
1343
+ * state on updates.
1344
+ *
1345
+ * cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
1346
+ */
1347
+
1348
+
1349
+ function usePrevious(value) {
1350
+ const ref = hooks$1.useRef();
1351
+ hooks$1.useEffect(() => {
1352
+ ref.current = value;
1353
+ });
1354
+ return ref.current;
1355
+ }
1356
+ /**
1357
+ * Subscribe to `propertiesPanel.showEntry`.
1358
+ *
1359
+ * @param {Function} show
1360
+ *
1361
+ * @returns {import('preact').Ref}
1362
+ */
1363
+
1364
+
1365
+ function useShowEntryEvent(show) {
1366
+ const {
1367
+ onShow
1368
+ } = hooks$1.useContext(LayoutContext);
1369
+ const ref = hooks$1.useRef();
1370
+ const [focus, setFocus] = hooks$1.useState(false);
1371
+ const onShowEntry = hooks$1.useCallback(event => {
1372
+ if (show(event)) {
1373
+ if (minDash.isFunction(onShow)) {
1374
+ onShow();
1375
+ }
1376
+
1377
+ if (event.focus && !focus) {
1378
+ setFocus(true);
1379
+ }
1380
+ }
1381
+ }, [show]);
1382
+ hooks$1.useEffect(() => {
1383
+ if (focus && ref.current) {
1384
+ if (minDash.isFunction(ref.current.focus)) {
1385
+ ref.current.focus();
1386
+ }
1387
+
1388
+ if (minDash.isFunction(ref.current.select)) {
1389
+ ref.current.select();
1390
+ }
1391
+
1392
+ setFocus(false);
1393
+ }
1394
+ }, [focus]);
1395
+ useEvent('propertiesPanel.showEntry', onShowEntry);
1396
+ return ref;
1397
+ }
1398
+ /**
1399
+ * Subscribe to `propertiesPanel.showError`. On `propertiesPanel.showError` set
1400
+ * temporary error. Fire `propertiesPanel.showEntry` for temporary error to be
1401
+ * visible. Unset error on `propertiesPanel.updated`.
1402
+ *
1403
+ * @param {Function} show
1404
+ *
1405
+ * @returns {import('preact').Ref}
1406
+ */
1407
+
1408
+
1409
+ function useShowErrorEvent(show) {
1410
+ const {
1411
+ eventBus
1412
+ } = hooks$1.useContext(EventContext);
1413
+ const [temporaryError, setTemporaryError] = hooks$1.useState(null);
1414
+ const onPropertiesPanelUpdated = hooks$1.useCallback(() => setTemporaryError(null), []);
1415
+ useEvent('propertiesPanel.updated', onPropertiesPanelUpdated);
1416
+ const onShowError = hooks$1.useCallback(event => {
1417
+ setTemporaryError(null);
1418
+
1419
+ if (show(event)) {
1420
+ if (eventBus) {
1421
+ eventBus.fire('propertiesPanel.showEntry', event);
1422
+ }
1423
+
1424
+ setTemporaryError(event.message);
1425
+ }
1426
+ }, [show]);
1427
+ useEvent('propertiesPanel.showError', onShowError);
1428
+ return temporaryError;
1429
+ }
1430
+ /**
1431
+ * @callback setSticky
1432
+ * @param {boolean} value
1433
+ */
1434
+
1435
+ /**
1436
+ * Use IntersectionObserver to identify when DOM element is in sticky mode.
1437
+ * If sticky is observered setSticky(true) will be called.
1438
+ * If sticky mode is left, setSticky(false) will be called.
1439
+ *
1440
+ *
1441
+ * @param {Object} ref
1442
+ * @param {string} scrollContainerSelector
1443
+ * @param {setSticky} setSticky
1444
+ */
1445
+
1446
+
1447
+ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky) {
1448
+ hooks$1.useEffect(() => {
1449
+ // return early if IntersectionObserver is not available
1450
+ if (!IntersectionObserver) {
1451
+ return;
1452
+ }
1453
+
1454
+ let observer;
1455
+
1456
+ if (ref.current) {
1457
+ const scrollContainer = minDom.query(scrollContainerSelector);
1458
+ observer = new IntersectionObserver(entries => {
1459
+ if (entries[0].intersectionRatio < 1) {
1460
+ setSticky(true);
1461
+ } else if (entries[0].intersectionRatio === 1) {
1462
+ setSticky(false);
1463
+ }
1464
+ }, {
1465
+ root: scrollContainer,
1466
+ rootMargin: '0px 0px 999999% 0px',
1467
+ // Use bottom margin to avoid stickyness when scrolling out to bottom
1468
+ threshold: [1]
1469
+ });
1470
+ observer.observe(ref.current);
1471
+ } // Unobserve if unmounted
1472
+
1473
+
1474
+ return () => {
1475
+ if (ref.current && observer) {
1476
+ observer.unobserve(ref.current);
1477
+ }
1478
+ };
1479
+ }, [ref]);
1480
+ }
1481
+
1482
+ function Group(props) {
1483
+ const {
1484
+ element,
1485
+ entries = [],
1486
+ id,
1487
+ label,
1488
+ shouldOpen = false
1489
+ } = props;
1490
+ const groupRef = hooks$1.useRef(null);
1491
+ const [open, setOpen] = useLayoutState(['groups', id, 'open'], shouldOpen);
1492
+ const onShow = hooks$1.useCallback(() => setOpen(true), [setOpen]);
1493
+
1494
+ const toggleOpen = () => setOpen(!open);
1495
+
1496
+ const [edited, setEdited] = hooks$1.useState(false);
1497
+ const [sticky, setSticky] = hooks$1.useState(false); // set edited state depending on all entries
1498
+
1499
+ hooks$1.useEffect(() => {
1500
+ const hasOneEditedEntry = entries.find(entry => {
1501
+ const {
1502
+ id,
1503
+ isEdited
1504
+ } = entry;
1505
+ const entryNode = minDom.query(`[data-entry-id="${id}"]`);
1506
+
1507
+ if (!minDash.isFunction(isEdited) || !entryNode) {
1508
+ return false;
1509
+ }
1510
+
1511
+ const inputNode = minDom.query('.bio-properties-panel-input', entryNode);
1512
+ return isEdited(inputNode);
1513
+ });
1514
+ setEdited(hasOneEditedEntry);
1515
+ }, [entries]); // set css class when group is sticky to top
1516
+
1517
+ useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
1518
+ const propertiesPanelContext = { ...hooks$1.useContext(LayoutContext),
1519
+ onShow
1520
+ };
1521
+ return jsxRuntime.jsxs("div", {
1522
+ class: "bio-properties-panel-group",
1523
+ "data-group-id": 'group-' + id,
1524
+ ref: groupRef,
1525
+ children: [jsxRuntime.jsxs("div", {
1526
+ class: classnames__default['default']('bio-properties-panel-group-header', edited ? '' : 'empty', open ? 'open' : '', sticky && open ? 'sticky' : ''),
1527
+ onClick: toggleOpen,
1528
+ children: [jsxRuntime.jsx("div", {
1529
+ title: label,
1530
+ class: "bio-properties-panel-group-header-title",
1531
+ children: label
1532
+ }), jsxRuntime.jsxs("div", {
1533
+ class: "bio-properties-panel-group-header-buttons",
1534
+ children: [edited && jsxRuntime.jsx(DataMarker, {}), jsxRuntime.jsx("button", {
1535
+ title: "Toggle section",
1536
+ class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
1537
+ children: jsxRuntime.jsx(ArrowIcon, {
1538
+ class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
1539
+ })
1540
+ })]
1541
+ })]
1542
+ }), jsxRuntime.jsx("div", {
1543
+ class: classnames__default['default']('bio-properties-panel-group-entries', open ? 'open' : ''),
1544
+ children: jsxRuntime.jsx(LayoutContext.Provider, {
1545
+ value: propertiesPanelContext,
1546
+ children: entries.map(entry => {
1547
+ const {
1548
+ component: Component,
1549
+ id
1550
+ } = entry;
1551
+ return preact.createElement(Component, { ...entry,
1552
+ element: element,
1553
+ key: id
1554
+ });
1555
+ })
1556
+ })
1557
+ })]
1558
+ });
1559
+ }
1560
+
1561
+ function DataMarker() {
1562
+ return jsxRuntime.jsx("div", {
1563
+ title: "Section contains data",
1564
+ class: "bio-properties-panel-dot"
1565
+ });
1566
+ }
1567
+ /**
1568
+ * @typedef { {
1569
+ * text: (element: object) => string,
1570
+ * icon?: (element: Object) => import('preact').Component
1571
+ * } } PlaceholderDefinition
1572
+ *
1573
+ * @param { PlaceholderDefinition } props
1574
+ */
1575
+
1576
+
1577
+ function Placeholder(props) {
1578
+ const {
1579
+ text,
1580
+ icon: Icon
1581
+ } = props;
1582
+ return jsxRuntime.jsx("div", {
1583
+ class: "bio-properties-panel open",
1584
+ children: jsxRuntime.jsxs("section", {
1585
+ class: "bio-properties-panel-placeholder",
1586
+ children: [Icon && jsxRuntime.jsx(Icon, {
1587
+ class: "bio-properties-panel-placeholder-icon"
1588
+ }), jsxRuntime.jsx("p", {
1589
+ class: "bio-properties-panel-placeholder-text",
1590
+ children: text
1591
+ })]
1592
+ })
1593
+ });
1594
+ }
1595
+
1596
+ const DEFAULT_LAYOUT = {
1597
+ open: true
1598
+ };
1599
+ const DEFAULT_DESCRIPTION = {};
1600
+ const bufferedEvents = ['propertiesPanel.showEntry', 'propertiesPanel.showError'];
1601
+ /**
1602
+ * @typedef { {
1603
+ * component: import('preact').Component,
1604
+ * id: String,
1605
+ * isEdited?: Function
1606
+ * } } EntryDefinition
1607
+ *
1608
+ * @typedef { {
1609
+ * autoFocusEntry: String,
1610
+ * autoOpen?: Boolean,
1611
+ * entries: Array<EntryDefinition>,
1612
+ * id: String,
1613
+ * label: String,
1614
+ * remove: (event: MouseEvent) => void
1615
+ * } } ListItemDefinition
1616
+ *
1617
+ * @typedef { {
1618
+ * add: (event: MouseEvent) => void,
1619
+ * component: import('preact').Component,
1620
+ * element: Object,
1621
+ * id: String,
1622
+ * items: Array<ListItemDefinition>,
1623
+ * label: String,
1624
+ * shouldSort?: Boolean,
1625
+ * shouldOpen?: Boolean
1626
+ * } } ListGroupDefinition
1627
+ *
1628
+ * @typedef { {
1629
+ * component?: import('preact').Component,
1630
+ * entries: Array<EntryDefinition>,
1631
+ * id: String,
1632
+ * label: String,
1633
+ * shouldOpen?: Boolean
1634
+ * } } GroupDefinition
1635
+ *
1636
+ * @typedef { {
1637
+ * [id: String]: GetDescriptionFunction
1638
+ * } } DescriptionConfig
1639
+ *
1640
+ * @callback { {
1641
+ * @param {string} id
1642
+ * @param {Object} element
1643
+ * @returns {string}
1644
+ * } } GetDescriptionFunction
1645
+ *
1646
+ * @typedef { {
1647
+ * getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
1648
+ * getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
1649
+ * } } PlaceholderProvider
1650
+ *
1651
+ */
1652
+
1653
+ /**
1654
+ * A basic properties panel component. Describes *how* content will be rendered, accepts
1655
+ * data from implementor to describe *what* will be rendered.
1656
+ *
1657
+ * @param {Object} props
1658
+ * @param {Object|Array} props.element
1659
+ * @param {import('./components/Header').HeaderProvider} props.headerProvider
1660
+ * @param {PlaceholderProvider} [props.placeholderProvider]
1661
+ * @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
1662
+ * @param {Object} [props.layoutConfig]
1663
+ * @param {Function} [props.layoutChanged]
1664
+ * @param {DescriptionConfig} [props.descriptionConfig]
1665
+ * @param {Function} [props.descriptionLoaded]
1666
+ * @param {Object} [props.eventBus]
1667
+ */
1668
+
1669
+ function PropertiesPanel(props) {
1670
+ const {
1671
+ element,
1672
+ headerProvider,
1673
+ placeholderProvider,
1674
+ groups,
1675
+ layoutConfig = {},
1676
+ layoutChanged,
1677
+ descriptionConfig = {},
1678
+ descriptionLoaded,
1679
+ eventBus
1680
+ } = props; // set-up layout context
1681
+
1682
+ const [layout, setLayout] = hooks$1.useState(createLayout(layoutConfig));
1683
+ hooks$1.useEffect(() => {
1684
+ if (typeof layoutChanged === 'function') {
1685
+ layoutChanged(layout);
1686
+ }
1687
+ }, [layout, layoutChanged]);
1688
+
1689
+ const getLayoutForKey = (key, defaultValue) => {
1690
+ return minDash.get(layout, key, defaultValue);
1691
+ };
1692
+
1693
+ const setLayoutForKey = (key, config) => {
1694
+ const newLayout = minDash.assign({}, layout);
1695
+ minDash.set(newLayout, key, config);
1696
+ setLayout(newLayout);
1697
+ };
1698
+
1699
+ const layoutContext = {
1700
+ layout,
1701
+ setLayout,
1702
+ getLayoutForKey,
1703
+ setLayoutForKey
1704
+ }; // set-up description context
1705
+
1706
+ const description = createDescriptionContext(descriptionConfig);
1707
+
1708
+ if (typeof descriptionLoaded === 'function') {
1709
+ descriptionLoaded(description);
1710
+ }
1711
+
1712
+ const getDescriptionForId = (id, element) => {
1713
+ return description[id] && description[id](element);
1714
+ };
1715
+
1716
+ const descriptionContext = {
1717
+ description,
1718
+ getDescriptionForId
1719
+ };
1720
+ useEventBuffer(bufferedEvents, eventBus);
1721
+ const eventContext = {
1722
+ eventBus
1723
+ };
1724
+ const propertiesPanelContext = {
1725
+ element
1726
+ }; // empty state
1727
+
1728
+ if (placeholderProvider && !element) {
1729
+ return jsxRuntime.jsx(Placeholder, { ...placeholderProvider.getEmpty()
1730
+ });
1731
+ } // multiple state
1732
+
1733
+
1734
+ if (placeholderProvider && minDash.isArray(element)) {
1735
+ return jsxRuntime.jsx(Placeholder, { ...placeholderProvider.getMultiple()
1736
+ });
1737
+ }
1738
+
1739
+ return jsxRuntime.jsx(LayoutContext.Provider, {
1740
+ value: propertiesPanelContext,
1741
+ children: jsxRuntime.jsx(DescriptionContext.Provider, {
1742
+ value: descriptionContext,
1743
+ children: jsxRuntime.jsx(LayoutContext.Provider, {
1744
+ value: layoutContext,
1745
+ children: jsxRuntime.jsx(EventContext.Provider, {
1746
+ value: eventContext,
1747
+ children: jsxRuntime.jsxs("div", {
1748
+ class: classnames__default['default']('bio-properties-panel', layout.open ? 'open' : ''),
1749
+ children: [jsxRuntime.jsx(Header, {
1750
+ element: element,
1751
+ headerProvider: headerProvider
1752
+ }), jsxRuntime.jsx("div", {
1753
+ class: "bio-properties-panel-scroll-container",
1754
+ children: groups.map(group => {
1755
+ const {
1756
+ component: Component = Group,
1757
+ id
1758
+ } = group;
1759
+ return preact.createElement(Component, { ...group,
1760
+ key: id,
1761
+ element: element
1762
+ });
1763
+ })
1764
+ })]
1765
+ })
1766
+ })
1767
+ })
1768
+ })
1769
+ });
1770
+ } // helpers //////////////////
1771
+
1772
+
1773
+ function createLayout(overrides) {
1774
+ return { ...DEFAULT_LAYOUT,
1775
+ ...overrides
1776
+ };
1777
+ }
1778
+
1779
+ function createDescriptionContext(overrides) {
1780
+ return { ...DEFAULT_DESCRIPTION,
1781
+ ...overrides
1782
+ };
1783
+ }
1784
+
1785
+ function CollapsibleEntry(props) {
1786
+ const {
1787
+ element,
1788
+ entries = [],
1789
+ id,
1790
+ label,
1791
+ open: shouldOpen,
1792
+ remove
1793
+ } = props;
1794
+ const [open, setOpen] = hooks$1.useState(shouldOpen);
1795
+
1796
+ const toggleOpen = () => setOpen(!open);
1797
+
1798
+ const {
1799
+ onShow
1800
+ } = hooks$1.useContext(LayoutContext);
1801
+ const propertiesPanelContext = { ...hooks$1.useContext(LayoutContext),
1802
+ onShow: hooks$1.useCallback(() => {
1803
+ setOpen(true);
1804
+
1805
+ if (minDash.isFunction(onShow)) {
1806
+ onShow();
1807
+ }
1808
+ }, [onShow, setOpen])
1809
+ }; // todo(pinussilvestrus): translate once we have a translate mechanism for the core
1810
+
1811
+ const placeholderLabel = '<empty>';
1812
+ return jsxRuntime.jsxs("div", {
1813
+ "data-entry-id": id,
1814
+ class: classnames__default['default']('bio-properties-panel-collapsible-entry', open ? 'open' : ''),
1815
+ children: [jsxRuntime.jsxs("div", {
1816
+ class: "bio-properties-panel-collapsible-entry-header",
1817
+ onClick: toggleOpen,
1818
+ children: [jsxRuntime.jsx("div", {
1819
+ title: label || placeholderLabel,
1820
+ class: classnames__default['default']('bio-properties-panel-collapsible-entry-header-title', !label && 'empty'),
1821
+ children: label || placeholderLabel
1822
+ }), jsxRuntime.jsx("button", {
1823
+ title: "Toggle list item",
1824
+ class: "bio-properties-panel-arrow bio-properties-panel-collapsible-entry-arrow",
1825
+ children: jsxRuntime.jsx(ArrowIcon, {
1826
+ class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
1827
+ })
1828
+ }), remove ? jsxRuntime.jsx("button", {
1829
+ title: "Delete item",
1830
+ class: "bio-properties-panel-remove-entry",
1831
+ onClick: remove,
1832
+ children: jsxRuntime.jsx(DeleteIcon, {})
1833
+ }) : null]
1834
+ }), jsxRuntime.jsx("div", {
1835
+ class: classnames__default['default']('bio-properties-panel-collapsible-entry-entries', open ? 'open' : ''),
1836
+ children: jsxRuntime.jsx(LayoutContext.Provider, {
1837
+ value: propertiesPanelContext,
1838
+ children: entries.map(entry => {
1839
+ const {
1840
+ component: Component,
1841
+ id
1842
+ } = entry;
1843
+ return preact.createElement(Component, { ...entry,
1844
+ element: element,
1845
+ key: id
1846
+ });
1847
+ })
1848
+ })
1849
+ })]
1850
+ });
1851
+ }
1852
+
1853
+ function ListItem(props) {
1854
+ const {
1855
+ autoFocusEntry,
1856
+ autoOpen
1857
+ } = props; // focus specified entry on auto open
1858
+
1859
+ hooks$1.useEffect(() => {
1860
+ if (autoOpen && autoFocusEntry) {
1861
+ const entry = minDom.query(`[data-entry-id="${autoFocusEntry}"]`);
1862
+ const focusableInput = minDom.query('.bio-properties-panel-input', entry);
1863
+
1864
+ if (focusableInput) {
1865
+ if (minDash.isFunction(focusableInput.select)) {
1866
+ focusableInput.select();
1867
+ } else if (minDash.isFunction(focusableInput.focus)) {
1868
+ focusableInput.focus();
1869
+ }
1870
+ }
1871
+ }
1872
+ }, [autoOpen, autoFocusEntry]);
1873
+ return jsxRuntime.jsx("div", {
1874
+ class: "bio-properties-panel-list-item",
1875
+ children: jsxRuntime.jsx(CollapsibleEntry, { ...props,
1876
+ open: autoOpen
1877
+ })
1878
+ });
1879
+ }
1880
+
1881
+ const noop$3 = () => {};
1882
+ /**
1883
+ * @param {import('../PropertiesPanel').ListGroupDefinition} props
1884
+ */
1885
+
1886
+
1887
+ function ListGroup(props) {
1888
+ const {
1889
+ add,
1890
+ element,
1891
+ id,
1892
+ items,
1893
+ label,
1894
+ shouldOpen = true,
1895
+ shouldSort = true
1896
+ } = props;
1897
+ const groupRef = hooks$1.useRef(null);
1898
+ const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
1899
+ const [sticky, setSticky] = hooks$1.useState(false);
1900
+ const onShow = hooks$1.useCallback(() => setOpen(true), [setOpen]);
1901
+ const [ordering, setOrdering] = hooks$1.useState([]);
1902
+ const [newItemAdded, setNewItemAdded] = hooks$1.useState(false);
1903
+ const prevItems = usePrevious(items);
1904
+ const prevElement = usePrevious(element);
1905
+ const elementChanged = element !== prevElement;
1906
+ const shouldHandleEffects = !elementChanged && (shouldSort || shouldOpen); // reset initial ordering when element changes (before first render)
1907
+
1908
+ if (elementChanged) {
1909
+ setOrdering(createOrdering(shouldSort ? sortItems(items) : items));
1910
+ } // keep ordering in sync to items - and open changes
1911
+ // (0) set initial ordering from given items
1912
+
1913
+
1914
+ hooks$1.useEffect(() => {
1915
+ if (!prevItems || !shouldSort) {
1916
+ setOrdering(createOrdering(items));
1917
+ }
1918
+ }, [items, element]); // (1) items were added
1919
+
1920
+ hooks$1.useEffect(() => {
1921
+ if (shouldHandleEffects && prevItems && items.length > prevItems.length) {
1922
+ let add = [];
1923
+ items.forEach(item => {
1924
+ if (!ordering.includes(item.id)) {
1925
+ add.push(item.id);
1926
+ }
1927
+ });
1928
+ let newOrdering = ordering; // open if not open and configured
1929
+
1930
+ if (!open && shouldOpen) {
1931
+ toggleOpen(); // if I opened and I should sort, then sort items
1932
+
1933
+ if (shouldSort) {
1934
+ newOrdering = createOrdering(sortItems(items));
1935
+ }
1936
+ } // add new items on top or bottom depending on sorting behavior
1937
+
1938
+
1939
+ newOrdering = newOrdering.filter(item => !add.includes(item));
1940
+
1941
+ if (shouldSort) {
1942
+ newOrdering.unshift(...add);
1943
+ } else {
1944
+ newOrdering.push(...add);
1945
+ }
1946
+
1947
+ setOrdering(newOrdering);
1948
+ setNewItemAdded(true);
1949
+ } else {
1950
+ setNewItemAdded(false);
1951
+ }
1952
+ }, [items, open, shouldHandleEffects]); // (2) sort items on open if shouldSort is set
1953
+
1954
+ hooks$1.useEffect(() => {
1955
+ if (shouldSort && open && !newItemAdded) {
1956
+ setOrdering(createOrdering(sortItems(items)));
1957
+ }
1958
+ }, [open, shouldSort]); // (3) items were deleted
1959
+
1960
+ hooks$1.useEffect(() => {
1961
+ if (shouldHandleEffects && prevItems && items.length < prevItems.length) {
1962
+ let keep = [];
1963
+ ordering.forEach(o => {
1964
+ if (getItem(items, o)) {
1965
+ keep.push(o);
1966
+ }
1967
+ });
1968
+ setOrdering(keep);
1969
+ }
1970
+ }, [items, shouldHandleEffects]); // set css class when group is sticky to top
1971
+
1972
+ useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
1973
+
1974
+ const toggleOpen = () => setOpen(!open);
1975
+
1976
+ const hasItems = !!items.length;
1977
+ const propertiesPanelContext = { ...hooks$1.useContext(LayoutContext),
1978
+ onShow
1979
+ };
1980
+ return jsxRuntime.jsxs("div", {
1981
+ class: "bio-properties-panel-group",
1982
+ "data-group-id": 'group-' + id,
1983
+ ref: groupRef,
1984
+ children: [jsxRuntime.jsxs("div", {
1985
+ class: classnames__default['default']('bio-properties-panel-group-header', hasItems ? '' : 'empty', hasItems && open ? 'open' : '', sticky && open ? 'sticky' : ''),
1986
+ onClick: hasItems ? toggleOpen : noop$3,
1987
+ children: [jsxRuntime.jsx("div", {
1988
+ title: label,
1989
+ class: "bio-properties-panel-group-header-title",
1990
+ children: label
1991
+ }), jsxRuntime.jsxs("div", {
1992
+ class: "bio-properties-panel-group-header-buttons",
1993
+ children: [add ? jsxRuntime.jsxs("button", {
1994
+ title: "Create new list item",
1995
+ class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
1996
+ onClick: add,
1997
+ children: [jsxRuntime.jsx(CreateIcon, {}), !hasItems ? jsxRuntime.jsx("span", {
1998
+ class: "bio-properties-panel-add-entry-label",
1999
+ children: "Create"
2000
+ }) : null]
2001
+ }) : null, hasItems ? jsxRuntime.jsx("div", {
2002
+ title: `List contains ${items.length} item${items.length != 1 ? 's' : ''}`,
2003
+ class: "bio-properties-panel-list-badge",
2004
+ children: items.length
2005
+ }) : null, hasItems ? jsxRuntime.jsx("button", {
2006
+ title: "Toggle section",
2007
+ class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
2008
+ children: jsxRuntime.jsx(ArrowIcon, {
2009
+ class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
2010
+ })
2011
+ }) : null]
2012
+ })]
2013
+ }), jsxRuntime.jsx("div", {
2014
+ class: classnames__default['default']('bio-properties-panel-list', open && hasItems ? 'open' : ''),
2015
+ children: jsxRuntime.jsx(LayoutContext.Provider, {
2016
+ value: propertiesPanelContext,
2017
+ children: ordering.map((o, index) => {
2018
+ const item = getItem(items, o);
2019
+
2020
+ if (!item) {
2021
+ return;
2022
+ }
2023
+
2024
+ const {
2025
+ id
2026
+ } = item; // if item was added, open first or last item based on ordering
2027
+
2028
+ const autoOpen = newItemAdded && (shouldSort ? index === 0 : index === ordering.length - 1);
2029
+ return preact.createElement(ListItem, { ...item,
2030
+ autoOpen: autoOpen,
2031
+ element: element,
2032
+ index: index,
2033
+ key: id
2034
+ });
2035
+ })
2036
+ })
2037
+ })]
2038
+ });
2039
+ } // helpers ////////////////////
2040
+
2041
+ /**
2042
+ * Sorts given items alphanumeric by label
2043
+ */
2044
+
2045
+
2046
+ function sortItems(items) {
2047
+ return minDash.sortBy(items, i => i.label.toLowerCase());
2048
+ }
2049
+
2050
+ function getItem(items, id) {
2051
+ return minDash.find(items, i => i.id === id);
2052
+ }
2053
+
2054
+ function createOrdering(items) {
2055
+ return items.map(i => i.id);
2056
+ }
2057
+
2058
+ function Description$1(props) {
2059
+ const {
2060
+ element,
2061
+ forId,
2062
+ value
2063
+ } = props;
2064
+ const contextDescription = useDescriptionContext(forId, element);
2065
+ const description = value || contextDescription;
2066
+
2067
+ if (description) {
2068
+ return jsxRuntime.jsx("div", {
2069
+ class: "bio-properties-panel-description",
2070
+ children: description
2071
+ });
2072
+ }
2073
+ }
2074
+
2075
+ const noop$2 = () => {};
2076
+
2077
+ function Checkbox(props) {
2078
+ const {
2079
+ id,
2080
+ label,
2081
+ onChange,
2082
+ disabled,
2083
+ value = false,
2084
+ show = noop$2
2085
+ } = props;
2086
+
2087
+ const handleChange = ({
2088
+ target
2089
+ }) => {
2090
+ onChange(target.checked);
2091
+ };
2092
+
2093
+ const ref = useShowEntryEvent(show);
2094
+ return jsxRuntime.jsxs("div", {
2095
+ class: "bio-properties-panel-checkbox",
2096
+ children: [jsxRuntime.jsx("input", {
2097
+ ref: ref,
2098
+ id: prefixId$6(id),
2099
+ name: id,
2100
+ type: "checkbox",
2101
+ class: "bio-properties-panel-input",
2102
+ onChange: handleChange,
2103
+ checked: value,
2104
+ disabled: disabled
2105
+ }), jsxRuntime.jsx("label", {
2106
+ for: prefixId$6(id),
2107
+ class: "bio-properties-panel-label",
2108
+ children: label
2109
+ })]
2110
+ });
2111
+ }
2112
+ /**
2113
+ * @param {Object} props
2114
+ * @param {Object} props.element
2115
+ * @param {String} props.id
2116
+ * @param {String} props.description
2117
+ * @param {String} props.label
2118
+ * @param {Function} props.getValue
2119
+ * @param {Function} props.setValue
2120
+ * @param {boolean} [props.disabled]
2121
+ */
2122
+
2123
+
2124
+ function CheckboxEntry(props) {
2125
+ const {
2126
+ element,
2127
+ id,
2128
+ description,
2129
+ label,
2130
+ getValue,
2131
+ setValue,
2132
+ disabled,
2133
+ show = noop$2
2134
+ } = props;
2135
+ const value = getValue(element);
2136
+ const error = useShowErrorEvent(show);
2137
+ return jsxRuntime.jsxs("div", {
2138
+ class: "bio-properties-panel-entry bio-properties-panel-checkbox-entry",
2139
+ "data-entry-id": id,
2140
+ children: [jsxRuntime.jsx(Checkbox, {
2141
+ disabled: disabled,
2142
+ id: id,
2143
+ label: label,
2144
+ onChange: setValue,
2145
+ show: show,
2146
+ value: value
2147
+ }), error && jsxRuntime.jsx("div", {
2148
+ class: "bio-properties-panel-error",
2149
+ children: error
2150
+ }), jsxRuntime.jsx(Description$1, {
2151
+ forId: id,
2152
+ element: element,
2153
+ value: description
2154
+ })]
2155
+ });
2156
+ }
2157
+
2158
+ function isEdited$6(node) {
2159
+ return node && !!node.checked;
2160
+ } // helpers /////////////////
2161
+
2162
+
2163
+ function prefixId$6(id) {
2164
+ return `bio-properties-panel-${id}`;
2165
+ }
2166
+
2167
+ function NumberField(props) {
2168
+ const {
2169
+ debounce,
2170
+ disabled,
1245
2171
  id,
1246
2172
  label,
1247
2173
  max,
1248
2174
  min,
1249
- onChange,
1250
- path
2175
+ onInput,
2176
+ step,
2177
+ value = ''
1251
2178
  } = props;
2179
+ const handleInput = hooks$1.useMemo(() => {
2180
+ return debounce(event => {
2181
+ const {
2182
+ validity,
2183
+ value
2184
+ } = event.target;
1252
2185
 
1253
- const onInput = value => {
1254
- if (editField && path) {
1255
- editField(field, path, value);
1256
- } else {
1257
- onChange(value);
1258
- }
1259
- };
2186
+ if (validity.valid) {
2187
+ onInput(value ? parseFloat(value) : undefined);
2188
+ }
2189
+ });
2190
+ }, [onInput, debounce]);
2191
+ return jsxRuntime.jsxs("div", {
2192
+ class: "bio-properties-panel-numberfield",
2193
+ children: [jsxRuntime.jsx("label", {
2194
+ for: prefixId$5(id),
2195
+ class: "bio-properties-panel-label",
2196
+ children: label
2197
+ }), jsxRuntime.jsx("input", {
2198
+ id: prefixId$5(id),
2199
+ type: "number",
2200
+ name: id,
2201
+ spellCheck: "false",
2202
+ autoComplete: "off",
2203
+ disabled: disabled,
2204
+ class: "bio-properties-panel-input",
2205
+ max: max,
2206
+ min: min,
2207
+ onInput: handleInput,
2208
+ step: step,
2209
+ value: value
2210
+ })]
2211
+ });
2212
+ }
2213
+ /**
2214
+ * @param {Object} props
2215
+ * @param {Boolean} props.debounce
2216
+ * @param {String} props.description
2217
+ * @param {Boolean} props.disabled
2218
+ * @param {Object} props.element
2219
+ * @param {Function} props.getValue
2220
+ * @param {String} props.id
2221
+ * @param {String} props.label
2222
+ * @param {String} props.max
2223
+ * @param {String} props.min
2224
+ * @param {Function} props.setValue
2225
+ * @param {String} props.step
2226
+ */
1260
2227
 
1261
- const value = path ? minDash.get(field, path, '') : props.value;
1262
- return jsxRuntime.jsx("div", {
1263
- class: "fjs-properties-panel-entry",
1264
- children: jsxRuntime.jsx(NumberInput, {
2228
+
2229
+ function NumberFieldEntry(props) {
2230
+ const {
2231
+ debounce,
2232
+ description,
2233
+ disabled,
2234
+ element,
2235
+ getValue,
2236
+ id,
2237
+ label,
2238
+ max,
2239
+ min,
2240
+ setValue,
2241
+ step
2242
+ } = props;
2243
+ const value = getValue(element);
2244
+ return jsxRuntime.jsxs("div", {
2245
+ class: "bio-properties-panel-entry",
2246
+ "data-entry-id": id,
2247
+ children: [jsxRuntime.jsx(NumberField, {
2248
+ debounce: debounce,
2249
+ disabled: disabled,
1265
2250
  id: id,
1266
2251
  label: label,
2252
+ onInput: setValue,
1267
2253
  max: max,
1268
2254
  min: min,
1269
- onInput: onInput,
2255
+ step: step,
1270
2256
  value: value
1271
- })
2257
+ }), jsxRuntime.jsx(Description$1, {
2258
+ forId: id,
2259
+ element: element,
2260
+ value: description
2261
+ })]
1272
2262
  });
1273
2263
  }
1274
2264
 
1275
- function SelectEntry(props) {
2265
+ function isEdited$5(node) {
2266
+ return node && !!node.value;
2267
+ } // helpers /////////////////
2268
+
2269
+
2270
+ function prefixId$5(id) {
2271
+ return `bio-properties-panel-${id}`;
2272
+ }
2273
+
2274
+ const noop$1 = () => {};
2275
+ /**
2276
+ * @typedef { { value: string, label: string, disabled: boolean } } Option
2277
+ */
2278
+
2279
+ /**
2280
+ * Provides basic select input.
2281
+ *
2282
+ * @param {object} props
2283
+ * @param {string} props.id
2284
+ * @param {string[]} props.path
2285
+ * @param {string} props.label
2286
+ * @param {Function} props.onChange
2287
+ * @param {Array<Option>} [props.options]
2288
+ * @param {string} props.value
2289
+ * @param {boolean} [props.disabled]
2290
+ */
2291
+
2292
+
2293
+ function Select(props) {
1276
2294
  const {
1277
- editField,
1278
- field,
1279
2295
  id,
1280
- description,
1281
2296
  label,
1282
- options,
1283
- path
2297
+ onChange,
2298
+ options = [],
2299
+ value,
2300
+ disabled,
2301
+ show = noop$1
1284
2302
  } = props;
2303
+ const ref = useShowEntryEvent(show);
1285
2304
 
1286
- const onChange = value => {
1287
- if (editField && path) {
1288
- editField(field, path, value);
1289
- } else {
1290
- props.onChange(value);
1291
- }
2305
+ const handleChange = ({
2306
+ target
2307
+ }) => {
2308
+ onChange(target.value);
1292
2309
  };
1293
2310
 
1294
- const value = path ? minDash.get(field, path, '') : props.value;
1295
2311
  return jsxRuntime.jsxs("div", {
1296
- class: "fjs-properties-panel-entry",
2312
+ class: "bio-properties-panel-select",
2313
+ children: [jsxRuntime.jsx("label", {
2314
+ for: prefixId$4(id),
2315
+ class: "bio-properties-panel-label",
2316
+ children: label
2317
+ }), jsxRuntime.jsx("select", {
2318
+ ref: ref,
2319
+ id: prefixId$4(id),
2320
+ name: id,
2321
+ class: "bio-properties-panel-input",
2322
+ onInput: handleChange,
2323
+ value: value,
2324
+ disabled: disabled,
2325
+ children: options.map((option, idx) => {
2326
+ return jsxRuntime.jsx("option", {
2327
+ value: option.value,
2328
+ disabled: option.disabled,
2329
+ children: option.label
2330
+ }, idx);
2331
+ })
2332
+ })]
2333
+ });
2334
+ }
2335
+ /**
2336
+ * @param {object} props
2337
+ * @param {object} props.element
2338
+ * @param {string} props.id
2339
+ * @param {string} [props.description]
2340
+ * @param {string} props.label
2341
+ * @param {Function} props.getValue
2342
+ * @param {Function} props.setValue
2343
+ * @param {Function} props.getOptions
2344
+ * @param {boolean} [props.disabled]
2345
+ */
2346
+
2347
+
2348
+ function SelectEntry(props) {
2349
+ const {
2350
+ element,
2351
+ id,
2352
+ description,
2353
+ label,
2354
+ getValue,
2355
+ setValue,
2356
+ getOptions,
2357
+ disabled,
2358
+ show = noop$1
2359
+ } = props;
2360
+ const value = getValue(element);
2361
+ const options = getOptions(element);
2362
+ const error = useShowErrorEvent(show);
2363
+ return jsxRuntime.jsxs("div", {
2364
+ class: classnames__default['default']('bio-properties-panel-entry', error ? 'has-error' : ''),
2365
+ "data-entry-id": id,
1297
2366
  children: [jsxRuntime.jsx(Select, {
1298
2367
  id: id,
1299
2368
  label: label,
1300
- onChange: onChange,
2369
+ value: value,
2370
+ onChange: setValue,
1301
2371
  options: options,
1302
- value: value
1303
- }), description && jsxRuntime.jsx("div", {
1304
- class: "fjs-properties-panel-description",
1305
- children: description
2372
+ disabled: disabled,
2373
+ show: show
2374
+ }), error && jsxRuntime.jsx("div", {
2375
+ class: "bio-properties-panel-error",
2376
+ children: error
2377
+ }), jsxRuntime.jsx(Description$1, {
2378
+ forId: id,
2379
+ element: element,
2380
+ value: description
1306
2381
  })]
1307
2382
  });
1308
2383
  }
1309
2384
 
1310
- function TextareaEntry(props) {
2385
+ function isEdited$4(node) {
2386
+ return node && !!node.value;
2387
+ } // helpers /////////////////
2388
+
2389
+
2390
+ function prefixId$4(id) {
2391
+ return `bio-properties-panel-${id}`;
2392
+ }
2393
+
2394
+ function FeelIcon(props) {
2395
+ const {
2396
+ label,
2397
+ feel = false
2398
+ } = props;
2399
+ const feelRequiredLabel = ' must be a FEEL expression';
2400
+ const feelOptionalLabel = ' can optionally be a FEEL expression';
2401
+ return jsxRuntime.jsx("i", {
2402
+ class: "bio-properties-panel-feel-icon",
2403
+ title: label + (feel === 'required' ? feelRequiredLabel : feelOptionalLabel),
2404
+ children: feel === 'required' ? jsxRuntime.jsx(FeelRequiredIcon, {}) : jsxRuntime.jsx(FeelOptionalIcon, {})
2405
+ });
2406
+ }
2407
+
2408
+ function TextArea(props) {
1311
2409
  const {
1312
- editField,
1313
- field,
1314
2410
  id,
1315
- description,
1316
2411
  label,
1317
- onChange,
1318
- path
2412
+ rows = 2,
2413
+ debounce,
2414
+ feel,
2415
+ onInput,
2416
+ value = '',
2417
+ disabled,
2418
+ monospace
1319
2419
  } = props;
2420
+ const handleInput = hooks$1.useMemo(() => {
2421
+ return debounce(({
2422
+ target
2423
+ }) => onInput(target.value.length ? target.value : undefined));
2424
+ }, [onInput, debounce]);
2425
+ return jsxRuntime.jsxs("div", {
2426
+ class: "bio-properties-panel-textarea",
2427
+ children: [jsxRuntime.jsxs("label", {
2428
+ for: prefixId$2(id),
2429
+ class: "bio-properties-panel-label",
2430
+ children: [label, feel && jsxRuntime.jsx(FeelIcon, {
2431
+ feel: feel,
2432
+ label: label
2433
+ })]
2434
+ }), jsxRuntime.jsx("textarea", {
2435
+ id: prefixId$2(id),
2436
+ name: id,
2437
+ spellCheck: "false",
2438
+ class: classnames__default['default']('bio-properties-panel-input', monospace ? 'bio-properties-panel-input-monospace' : ''),
2439
+ onInput: handleInput,
2440
+ onFocus: props.onFocus,
2441
+ onBlur: props.onBlur,
2442
+ rows: rows,
2443
+ value: value,
2444
+ disabled: disabled
2445
+ })]
2446
+ });
2447
+ }
2448
+ /**
2449
+ * @param {object} props
2450
+ * @param {object} props.element
2451
+ * @param {string} props.id
2452
+ * @param {string} props.description
2453
+ * @param {boolean} props.debounce
2454
+ * @param {string} props.label
2455
+ * @param {Function} props.getValue
2456
+ * @param {Function} props.setValue
2457
+ * @param {number} props.rows
2458
+ * @param {boolean} props.monospace
2459
+ * @param {boolean} [props.disabled]
2460
+ */
1320
2461
 
1321
- const onInput = value => {
1322
- if (editField && path) {
1323
- editField(field, path, value);
1324
- } else {
1325
- onChange(value);
1326
- }
1327
- };
1328
2462
 
1329
- const value = path ? minDash.get(field, path, '') : props.value;
2463
+ function TextAreaEntry(props) {
2464
+ const {
2465
+ element,
2466
+ id,
2467
+ description,
2468
+ debounce,
2469
+ feel,
2470
+ label,
2471
+ getValue,
2472
+ setValue,
2473
+ rows,
2474
+ monospace,
2475
+ disabled
2476
+ } = props;
2477
+ const value = getValue(element);
1330
2478
  return jsxRuntime.jsxs("div", {
1331
- class: "fjs-properties-panel-entry",
1332
- children: [jsxRuntime.jsx(Textarea, {
2479
+ class: "bio-properties-panel-entry",
2480
+ "data-entry-id": id,
2481
+ children: [jsxRuntime.jsx(TextArea, {
1333
2482
  id: id,
1334
2483
  label: label,
1335
- onInput: onInput,
1336
- value: value
1337
- }), description && jsxRuntime.jsx("div", {
1338
- class: "fjs-properties-panel-description",
1339
- children: description
2484
+ value: value,
2485
+ onInput: setValue,
2486
+ rows: rows,
2487
+ debounce: debounce,
2488
+ monospace: monospace,
2489
+ feel: feel,
2490
+ disabled: disabled
2491
+ }), jsxRuntime.jsx(Description$1, {
2492
+ forId: id,
2493
+ element: element,
2494
+ value: description
2495
+ })]
2496
+ });
2497
+ }
2498
+
2499
+ function isEdited$2(node) {
2500
+ return node && !!node.value;
2501
+ } // helpers /////////////////
2502
+
2503
+
2504
+ function prefixId$2(id) {
2505
+ return `bio-properties-panel-${id}`;
2506
+ }
2507
+
2508
+ const noop = () => {};
2509
+
2510
+ function Textfield(props) {
2511
+ const {
2512
+ debounce,
2513
+ disabled = false,
2514
+ id,
2515
+ label,
2516
+ onInput,
2517
+ feel = false,
2518
+ value = '',
2519
+ show = noop
2520
+ } = props;
2521
+ const ref = useShowEntryEvent(show);
2522
+ const handleInput = hooks$1.useMemo(() => {
2523
+ return debounce(({
2524
+ target
2525
+ }) => onInput(target.value.length ? target.value : undefined));
2526
+ }, [onInput, debounce]);
2527
+ return jsxRuntime.jsxs("div", {
2528
+ class: "bio-properties-panel-textfield",
2529
+ children: [jsxRuntime.jsxs("label", {
2530
+ for: prefixId$1(id),
2531
+ class: "bio-properties-panel-label",
2532
+ children: [label, feel && jsxRuntime.jsx(FeelIcon, {
2533
+ feel: feel,
2534
+ label: label
2535
+ })]
2536
+ }), jsxRuntime.jsx("input", {
2537
+ ref: ref,
2538
+ id: prefixId$1(id),
2539
+ type: "text",
2540
+ name: id,
2541
+ spellCheck: "false",
2542
+ autoComplete: "off",
2543
+ disabled: disabled,
2544
+ class: "bio-properties-panel-input",
2545
+ onInput: handleInput,
2546
+ onFocus: props.onFocus,
2547
+ onBlur: props.onBlur,
2548
+ value: value || ''
1340
2549
  })]
1341
2550
  });
1342
2551
  }
2552
+ /**
2553
+ * @param {Object} props
2554
+ * @param {Object} props.element
2555
+ * @param {String} props.id
2556
+ * @param {String} props.description
2557
+ * @param {Boolean} props.debounce
2558
+ * @param {Boolean} props.disabled
2559
+ * @param {String} props.label
2560
+ * @param {Function} props.getValue
2561
+ * @param {Function} props.setValue
2562
+ * @param {Function} props.validate
2563
+ */
2564
+
1343
2565
 
1344
- function TextInputEntry(props) {
2566
+ function TextfieldEntry(props) {
1345
2567
  const {
1346
- editField,
1347
- field,
2568
+ element,
1348
2569
  id,
1349
2570
  description,
2571
+ debounce,
2572
+ disabled,
2573
+ feel,
1350
2574
  label,
1351
- onChange,
1352
- path,
1353
- validate
2575
+ getValue,
2576
+ setValue,
2577
+ validate,
2578
+ show = noop
1354
2579
  } = props;
2580
+ const [cachedInvalidValue, setCachedInvalidValue] = hooks$1.useState(null);
2581
+ const [validationError, setValidationError] = hooks$1.useState(null);
2582
+ let value = getValue(element);
2583
+ const previousValue = usePrevious(value);
2584
+ hooks$1.useEffect(() => {
2585
+ if (minDash.isFunction(validate)) {
2586
+ const newValidationError = validate(value) || null;
2587
+ setValidationError(newValidationError);
2588
+ }
2589
+ }, [value]);
2590
+
2591
+ const onInput = newValue => {
2592
+ let newValidationError = null;
2593
+
2594
+ if (minDash.isFunction(validate)) {
2595
+ newValidationError = validate(newValue) || null;
2596
+ }
1355
2597
 
1356
- const onInput = value => {
1357
- if (editField && path) {
1358
- editField(field, path, value);
2598
+ if (newValidationError) {
2599
+ setCachedInvalidValue(newValue);
1359
2600
  } else {
1360
- onChange(value);
2601
+ setValue(newValue);
1361
2602
  }
2603
+
2604
+ setValidationError(newValidationError);
1362
2605
  };
1363
2606
 
1364
- const value = path ? minDash.get(field, path, '') : props.value;
2607
+ if (previousValue === value && validationError) {
2608
+ value = cachedInvalidValue;
2609
+ }
2610
+
2611
+ const temporaryError = useShowErrorEvent(show);
2612
+ const error = temporaryError || validationError;
1365
2613
  return jsxRuntime.jsxs("div", {
1366
- class: "fjs-properties-panel-entry",
1367
- children: [jsxRuntime.jsx(TextInput, {
2614
+ class: classnames__default['default']('bio-properties-panel-entry', error ? 'has-error' : ''),
2615
+ "data-entry-id": id,
2616
+ children: [jsxRuntime.jsx(Textfield, {
2617
+ debounce: debounce,
2618
+ disabled: disabled,
2619
+ feel: feel,
1368
2620
  id: id,
1369
2621
  label: label,
1370
2622
  onInput: onInput,
1371
- validate: validate,
2623
+ show: show,
1372
2624
  value: value
1373
- }), description && jsxRuntime.jsx("div", {
1374
- class: "fjs-properties-panel-description",
1375
- children: description
2625
+ }), error && jsxRuntime.jsx("div", {
2626
+ class: "bio-properties-panel-error",
2627
+ children: error
2628
+ }), jsxRuntime.jsx(Description$1, {
2629
+ forId: id,
2630
+ element: element,
2631
+ value: description
1376
2632
  })]
1377
2633
  });
1378
2634
  }
1379
2635
 
1380
- function _extends$3() { _extends$3 = Object.assign || 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); }
1381
- var CreateIcon = (({
1382
- styles = {},
1383
- ...props
1384
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$3({
1385
- xmlns: "http://www.w3.org/2000/svg",
1386
- width: "12",
1387
- height: "12"
1388
- }, props), /*#__PURE__*/React__default['default'].createElement("path", {
1389
- fillRule: "evenodd",
1390
- d: "M7 0v5h5v2H7v5H5V7H0V5h5V0h2z"
1391
- })));
2636
+ function isEdited$1(node) {
2637
+ return node && !!node.value;
2638
+ } // helpers /////////////////
1392
2639
 
1393
- function _extends$2() { _extends$2 = Object.assign || 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); }
1394
- var ListArrowIcon = (({
1395
- styles = {},
1396
- ...props
1397
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$2({
1398
- xmlns: "http://www.w3.org/2000/svg",
1399
- width: "7",
1400
- height: "9"
1401
- }, props), /*#__PURE__*/React__default['default'].createElement("path", {
1402
- fillRule: "evenodd",
1403
- d: "M6.25 4.421L4.836 5.835h-.001L2.007 8.663.593 7.249 3.421 4.42.593 1.593 2.007.178 6.25 4.421z"
1404
- })));
1405
2640
 
1406
- function _extends$1() { _extends$1 = Object.assign || 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); }
1407
- var ListDeleteIcon = (({
1408
- styles = {},
1409
- ...props
1410
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$1({
1411
- xmlns: "http://www.w3.org/2000/svg",
1412
- width: "11",
1413
- height: "14"
1414
- }, props), /*#__PURE__*/React__default['default'].createElement("path", {
1415
- d: "M10 4v8c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V4h9zM8 6H3v4.8c0 .66.5 1.2 1.111 1.2H6.89C7.5 12 8 11.46 8 10.8V6zm3-5H8.5l-1-1h-4l-1 1H0v1.5h11V1z"
1416
- })));
2641
+ function prefixId$1(id) {
2642
+ return `bio-properties-panel-${id}`;
2643
+ }
1417
2644
 
1418
- function _extends() { _extends = Object.assign || 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); }
1419
- var SectionArrowIcon = (({
1420
- styles = {},
1421
- ...props
1422
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends({
1423
- xmlns: "http://www.w3.org/2000/svg",
1424
- width: "8",
1425
- height: "12"
1426
- }, props), /*#__PURE__*/React__default['default'].createElement("path", {
1427
- fillRule: "evenodd",
1428
- d: "M2.007 11.66L.593 10.248l4.242-4.243L.593 1.761 2.007.347l5.657 5.657-5.657 5.657z"
1429
- })));
2645
+ function arrayAdd$1(array, index, item) {
2646
+ const copy = [...array];
2647
+ copy.splice(index, 0, item);
2648
+ return copy;
2649
+ }
2650
+ function textToLabel(text = '...') {
2651
+ if (text.length > 10) {
2652
+ return `${text.substring(0, 30)}...`;
2653
+ }
1430
2654
 
1431
- function CollapsibleEntry(props) {
1432
- const {
1433
- children,
1434
- label,
1435
- removeEntry = () => {}
1436
- } = props;
1437
- const [collapsed, setCollapsed] = hooks$1.useState(false);
2655
+ return text;
2656
+ }
2657
+ const INPUTS = ['checkbox', 'checklist', 'number', 'radio', 'select', 'taglist', 'textfield'];
2658
+ const VALUES_INPUTS = ['checklist', 'radio', 'select', 'taglist'];
2659
+
2660
+ const labelsByType = {
2661
+ button: 'BUTTON',
2662
+ checkbox: 'CHECKBOX',
2663
+ checklist: 'CHECKLIST',
2664
+ columns: 'COLUMNS',
2665
+ default: 'FORM',
2666
+ number: 'NUMBER',
2667
+ radio: 'RADIO',
2668
+ select: 'SELECT',
2669
+ taglist: 'TAGLIST',
2670
+ text: 'TEXT',
2671
+ textfield: 'TEXT FIELD'
2672
+ };
2673
+ const PropertiesPanelHeaderProvider = {
2674
+ getElementLabel: field => {
2675
+ const {
2676
+ type
2677
+ } = field;
1438
2678
 
1439
- const toggleCollapsed = () => setCollapsed(!collapsed);
2679
+ if (type === 'text') {
2680
+ return textToLabel(field.text);
2681
+ }
1440
2682
 
1441
- const classes = ['fjs-properties-panel-collapsible-entry'];
2683
+ if (type === 'default') {
2684
+ return field.id;
2685
+ }
1442
2686
 
1443
- if (collapsed) {
1444
- classes.push('fjs-properties-panel-collapsible-entry-collapsed');
2687
+ return field.label;
2688
+ },
2689
+ getElementIcon: field => {
2690
+ const {
2691
+ type
2692
+ } = field;
2693
+ const Icon = iconsByType[type];
2694
+
2695
+ if (Icon) {
2696
+ return () => jsxRuntime.jsx(Icon, {
2697
+ width: "36",
2698
+ height: "36",
2699
+ viewBox: "0 0 54 54"
2700
+ });
2701
+ }
2702
+ },
2703
+ getTypeLabel: field => {
2704
+ const {
2705
+ type
2706
+ } = field;
2707
+ return labelsByType[type];
1445
2708
  }
2709
+ };
1446
2710
 
1447
- return jsxRuntime.jsxs("div", {
1448
- class: classes.join(' '),
1449
- children: [jsxRuntime.jsxs("div", {
1450
- class: "fjs-properties-panel-collapsible-entry-header",
1451
- onClick: toggleCollapsed,
1452
- children: [jsxRuntime.jsxs("div", {
1453
- children: [jsxRuntime.jsx(ListArrowIcon, {
1454
- class: collapsed ? 'fjs-arrow-right' : 'fjs-arrow-down'
1455
- }), jsxRuntime.jsx("span", {
1456
- class: "fjs-properties-panel-collapsible-entry-header-label",
1457
- children: label
1458
- })]
1459
- }), jsxRuntime.jsx("button", {
1460
- class: "fjs-properties-panel-collapsible-entry-header-remove-entry",
1461
- onClick: stopPropagation(removeEntry),
1462
- children: jsxRuntime.jsx(ListDeleteIcon, {})
1463
- })]
1464
- }), collapsed ? null : jsxRuntime.jsx("div", {
1465
- class: "fjs-properties-panel-collapsible-entry-entries",
1466
- children: children
1467
- })]
1468
- });
1469
- }
2711
+ /**
2712
+ * Provide placeholders for empty and multiple state.
2713
+ */
2714
+ const PropertiesPanelPlaceholderProvider = {
2715
+ getEmpty: () => {
2716
+ return {
2717
+ text: 'Select a form field to edit its properties.'
2718
+ };
2719
+ },
2720
+ getMultiple: () => {
2721
+ return {
2722
+ text: 'Multiple form fields are selected. Select a single form field to edit its properties.'
2723
+ };
2724
+ }
2725
+ };
1470
2726
 
1471
- function Group(props) {
2727
+ function ActionEntry(props) {
1472
2728
  const {
1473
- children,
1474
- hasEntries = true,
1475
- label
2729
+ editField,
2730
+ field
1476
2731
  } = props;
1477
- const [open, setOpen] = hooks$1.useState(hasEntries);
1478
-
1479
- const toggleOpen = () => setOpen(!open);
2732
+ const {
2733
+ type
2734
+ } = field;
2735
+ const entries = [];
1480
2736
 
1481
- const addEntry = event => {
1482
- event.stopPropagation();
1483
- setOpen(true);
1484
- props.addEntry();
1485
- };
2737
+ if (type === 'button') {
2738
+ entries.push({
2739
+ id: 'action',
2740
+ component: Action,
2741
+ editField: editField,
2742
+ field: field,
2743
+ isEdited: isEdited$4
2744
+ });
2745
+ }
1486
2746
 
1487
- return jsxRuntime.jsxs("div", {
1488
- class: "fjs-properties-panel-group",
1489
- children: [jsxRuntime.jsxs("div", {
1490
- class: "fjs-properties-panel-group-header",
1491
- onClick: hasEntries ? toggleOpen : () => {},
1492
- children: [jsxRuntime.jsx("span", {
1493
- class: "fjs-properties-panel-group-header-label",
1494
- children: label
1495
- }), jsxRuntime.jsxs("div", {
1496
- class: "fjs-properties-panel-group-header-buttons",
1497
- children: [props.addEntry ? jsxRuntime.jsx("button", {
1498
- class: "fjs-properties-panel-group-header-button fjs-properties-panel-group-header-button-add-entry",
1499
- onClick: addEntry,
1500
- children: jsxRuntime.jsx(CreateIcon, {})
1501
- }) : null, jsxRuntime.jsx("button", {
1502
- class: "fjs-properties-panel-group-header-button fjs-properties-panel-group-header-button-toggle-open",
1503
- children: jsxRuntime.jsx(SectionArrowIcon, {
1504
- class: hasEntries && open ? 'fjs-arrow-down' : 'fjs-arrow-right'
1505
- })
1506
- })]
1507
- })]
1508
- }), hasEntries && open ? jsxRuntime.jsx("div", {
1509
- class: "fjs-properties-panel-group-entries",
1510
- children: children
1511
- }) : null]
1512
- });
2747
+ return entries;
1513
2748
  }
1514
2749
 
1515
- function ActionEntry(props) {
2750
+ function Action(props) {
1516
2751
  const {
1517
2752
  editField,
1518
- field
2753
+ field,
2754
+ id
1519
2755
  } = props;
1520
- const options = [{
2756
+ const path = ['action'];
2757
+
2758
+ const getValue = () => {
2759
+ return minDash.get(field, path, '');
2760
+ };
2761
+
2762
+ const setValue = value => {
2763
+ return editField(field, path, value);
2764
+ };
2765
+
2766
+ const getOptions = () => [{
1521
2767
  label: 'Submit',
1522
2768
  value: 'submit'
1523
2769
  }, {
1524
2770
  label: 'Reset',
1525
2771
  value: 'reset'
1526
2772
  }];
1527
- return jsxRuntime.jsx(SelectEntry, {
1528
- editField: editField,
1529
- field: field,
1530
- id: "action",
1531
- label: "Action",
1532
- options: options,
1533
- path: ['action']
2773
+
2774
+ return SelectEntry({
2775
+ element: field,
2776
+ getOptions,
2777
+ getValue,
2778
+ id,
2779
+ label: 'Action',
2780
+ setValue
1534
2781
  });
1535
2782
  }
1536
2783
 
@@ -1539,8 +2786,37 @@ function ColumnsEntry(props) {
1539
2786
  editField,
1540
2787
  field
1541
2788
  } = props;
2789
+ const {
2790
+ type
2791
+ } = field;
2792
+ const entries = [];
2793
+
2794
+ if (type === 'columns') {
2795
+ entries.push({
2796
+ id: 'columns',
2797
+ component: Columns,
2798
+ editField: editField,
2799
+ field: field,
2800
+ isEdited: isEdited$5
2801
+ });
2802
+ }
2803
+
2804
+ return entries;
2805
+ }
2806
+
2807
+ function Columns(props) {
2808
+ const {
2809
+ editField,
2810
+ field,
2811
+ id
2812
+ } = props;
2813
+ const debounce = useService('debounce');
2814
+
2815
+ const getValue = () => {
2816
+ return field.components.length;
2817
+ };
1542
2818
 
1543
- const onInput = value => {
2819
+ const setValue = value => {
1544
2820
  let components = field.components.slice();
1545
2821
 
1546
2822
  if (value > components.length) {
@@ -1556,17 +2832,13 @@ function ColumnsEntry(props) {
1556
2832
  editField(field, 'components', components);
1557
2833
  };
1558
2834
 
1559
- const value = field.components.length;
1560
- return jsxRuntime.jsx("div", {
1561
- class: "fjs-properties-panel-entry",
1562
- children: jsxRuntime.jsx(NumberInputEntry, {
1563
- id: "columns",
1564
- label: "Columns",
1565
- onInput: onInput,
1566
- value: value,
1567
- min: "1",
1568
- max: "3"
1569
- })
2835
+ return NumberFieldEntry({
2836
+ debounce,
2837
+ element: field,
2838
+ getValue,
2839
+ id,
2840
+ label: 'Columns',
2841
+ setValue
1570
2842
  });
1571
2843
  }
1572
2844
 
@@ -1575,87 +2847,238 @@ function DescriptionEntry(props) {
1575
2847
  editField,
1576
2848
  field
1577
2849
  } = props;
1578
- return jsxRuntime.jsx(TextInputEntry, {
1579
- editField: editField,
1580
- field: field,
1581
- id: "description",
1582
- label: "Field Description",
1583
- path: ['description']
2850
+ const {
2851
+ type
2852
+ } = field;
2853
+ const entries = [];
2854
+
2855
+ if (INPUTS.includes(type)) {
2856
+ entries.push({
2857
+ id: 'description',
2858
+ component: Description,
2859
+ editField: editField,
2860
+ field: field,
2861
+ isEdited: isEdited$1
2862
+ });
2863
+ }
2864
+
2865
+ return entries;
2866
+ }
2867
+
2868
+ function Description(props) {
2869
+ const {
2870
+ editField,
2871
+ field,
2872
+ id
2873
+ } = props;
2874
+ const debounce = useService('debounce');
2875
+ const path = ['description'];
2876
+
2877
+ const getValue = () => {
2878
+ return minDash.get(field, path, '');
2879
+ };
2880
+
2881
+ const setValue = value => {
2882
+ return editField(field, path, value);
2883
+ };
2884
+
2885
+ return TextfieldEntry({
2886
+ debounce,
2887
+ element: field,
2888
+ getValue,
2889
+ id,
2890
+ label: 'Field description',
2891
+ setValue
1584
2892
  });
1585
2893
  }
1586
2894
 
1587
- function DefaultValueEntry(props) {
2895
+ function DefaultOptionEntry(props) {
1588
2896
  const {
1589
2897
  editField,
1590
2898
  field
1591
2899
  } = props;
1592
2900
  const {
1593
- defaultValue,
1594
- type,
1595
- values = []
2901
+ type
1596
2902
  } = field;
2903
+ const entries = []; // Only make default values available when they are statically defined
2904
+
2905
+ if (!INPUTS.includes(type) || VALUES_INPUTS.includes(type) && !field.values) {
2906
+ return entries;
2907
+ }
2908
+
2909
+ const defaultOptions = {
2910
+ editField,
2911
+ field,
2912
+ id: 'defaultValue',
2913
+ label: 'Default value'
2914
+ };
1597
2915
 
1598
2916
  if (type === 'checkbox') {
1599
- const options = [{
2917
+ entries.push({ ...defaultOptions,
2918
+ component: DefaultValueCheckbox,
2919
+ isEdited: isEdited$4
2920
+ });
2921
+ }
2922
+
2923
+ if (type === 'number') {
2924
+ entries.push({ ...defaultOptions,
2925
+ component: DefaultValueNumber,
2926
+ isEdited: isEdited$5
2927
+ });
2928
+ }
2929
+
2930
+ if (type === 'radio' || type === 'select') {
2931
+ entries.push({ ...defaultOptions,
2932
+ component: DefaultValueSingleSelect,
2933
+ isEdited: isEdited$4
2934
+ });
2935
+ } // todo(Skaiir): implement a multiselect equivalent (cf. https://github.com/bpmn-io/form-js/issues/265)
2936
+
2937
+
2938
+ if (type === 'textfield') {
2939
+ entries.push({ ...defaultOptions,
2940
+ component: DefaultValueTextfield,
2941
+ isEdited: isEdited$1
2942
+ });
2943
+ }
2944
+
2945
+ return entries;
2946
+ }
2947
+
2948
+ function DefaultValueCheckbox(props) {
2949
+ const {
2950
+ editField,
2951
+ field,
2952
+ id,
2953
+ label
2954
+ } = props;
2955
+ const {
2956
+ defaultValue
2957
+ } = field;
2958
+ const path = ['defaultValue'];
2959
+
2960
+ const getOptions = () => {
2961
+ return [{
1600
2962
  label: 'Checked',
1601
2963
  value: 'true'
1602
2964
  }, {
1603
2965
  label: 'Not checked',
1604
2966
  value: 'false'
1605
2967
  }];
2968
+ };
1606
2969
 
1607
- const onChange = value => {
1608
- editField(field, ['defaultValue'], parseStringToBoolean(value));
1609
- };
2970
+ const setValue = value => {
2971
+ return editField(field, path, parseStringToBoolean(value));
2972
+ };
1610
2973
 
1611
- return jsxRuntime.jsx(SelectEntry, {
1612
- id: "defaultValue",
1613
- label: "Default Value",
1614
- onChange: onChange,
1615
- options: options,
1616
- value: parseBooleanToString(defaultValue)
1617
- });
1618
- }
2974
+ const getValue = () => {
2975
+ return parseBooleanToString(defaultValue);
2976
+ };
1619
2977
 
1620
- if (type === 'number') {
1621
- return jsxRuntime.jsx(NumberInputEntry, {
1622
- editField: editField,
1623
- field: field,
1624
- id: "defaultValue",
1625
- label: "Default Value",
1626
- path: ['defaultValue']
1627
- });
1628
- }
2978
+ return SelectEntry({
2979
+ element: field,
2980
+ getOptions,
2981
+ getValue,
2982
+ id,
2983
+ label,
2984
+ setValue
2985
+ });
2986
+ }
1629
2987
 
1630
- if (type === 'radio' || type === 'select') {
1631
- const options = [{
2988
+ function DefaultValueNumber(props) {
2989
+ const {
2990
+ editField,
2991
+ field,
2992
+ id,
2993
+ label
2994
+ } = props;
2995
+ const debounce = useService('debounce');
2996
+ const path = ['defaultValue'];
2997
+
2998
+ const getValue = () => {
2999
+ return minDash.get(field, path, '');
3000
+ };
3001
+
3002
+ const setValue = value => {
3003
+ return editField(field, path, value);
3004
+ };
3005
+
3006
+ return NumberFieldEntry({
3007
+ debounce,
3008
+ element: field,
3009
+ getValue,
3010
+ id,
3011
+ label,
3012
+ setValue
3013
+ });
3014
+ }
3015
+
3016
+ function DefaultValueSingleSelect(props) {
3017
+ const {
3018
+ editField,
3019
+ field,
3020
+ id,
3021
+ label
3022
+ } = props;
3023
+ const {
3024
+ defaultValue,
3025
+ values = []
3026
+ } = field;
3027
+ const path = ['defaultValue'];
3028
+
3029
+ const getOptions = () => {
3030
+ return [{
1632
3031
  label: '<none>'
1633
3032
  }, ...values];
3033
+ };
1634
3034
 
1635
- const onChange = value => {
1636
- editField(field, ['defaultValue'], value.length ? value : undefined);
1637
- };
3035
+ const setValue = value => {
3036
+ return editField(field, path, value.length ? value : undefined);
3037
+ };
1638
3038
 
1639
- return jsxRuntime.jsx(SelectEntry, {
1640
- id: "defaultValue",
1641
- label: "Default Value",
1642
- onChange: onChange,
1643
- options: options,
1644
- value: defaultValue
1645
- });
1646
- }
3039
+ const getValue = () => {
3040
+ return defaultValue;
3041
+ };
1647
3042
 
1648
- if (type === 'textfield') {
1649
- return jsxRuntime.jsx(TextInputEntry, {
1650
- editField: editField,
1651
- field: field,
1652
- id: "defaultValue",
1653
- label: "Default Value",
1654
- path: ['defaultValue']
1655
- });
1656
- }
3043
+ return SelectEntry({
3044
+ element: field,
3045
+ getOptions,
3046
+ getValue,
3047
+ id,
3048
+ label,
3049
+ setValue
3050
+ });
1657
3051
  }
1658
3052
 
3053
+ function DefaultValueTextfield(props) {
3054
+ const {
3055
+ editField,
3056
+ field,
3057
+ id,
3058
+ label
3059
+ } = props;
3060
+ const debounce = useService('debounce');
3061
+ const path = ['defaultValue'];
3062
+
3063
+ const getValue = () => {
3064
+ return minDash.get(field, path, '');
3065
+ };
3066
+
3067
+ const setValue = value => {
3068
+ return editField(field, path, value);
3069
+ };
3070
+
3071
+ return TextfieldEntry({
3072
+ debounce,
3073
+ element: field,
3074
+ getValue,
3075
+ id,
3076
+ label,
3077
+ setValue
3078
+ });
3079
+ } // helpers /////////////////
3080
+
3081
+
1659
3082
  function parseStringToBoolean(value) {
1660
3083
  if (value === 'true') {
1661
3084
  return true;
@@ -1669,25 +3092,54 @@ function parseBooleanToString(value) {
1669
3092
  return 'true';
1670
3093
  }
1671
3094
 
1672
- return 'false';
3095
+ return 'false';
3096
+ }
3097
+
3098
+ function DisabledEntry(props) {
3099
+ const {
3100
+ editField,
3101
+ field
3102
+ } = props;
3103
+ const {
3104
+ type
3105
+ } = field;
3106
+ const entries = [];
3107
+
3108
+ if (INPUTS.includes(type)) {
3109
+ entries.push({
3110
+ id: 'disabled',
3111
+ component: Disabled,
3112
+ editField: editField,
3113
+ field: field,
3114
+ isEdited: isEdited$6
3115
+ });
3116
+ }
3117
+
3118
+ return entries;
1673
3119
  }
1674
3120
 
1675
- function DisabledEntry(props) {
3121
+ function Disabled(props) {
1676
3122
  const {
1677
3123
  editField,
1678
- field
3124
+ field,
3125
+ id
1679
3126
  } = props;
3127
+ const path = ['disabled'];
3128
+
3129
+ const getValue = () => {
3130
+ return minDash.get(field, path, '');
3131
+ };
1680
3132
 
1681
- const onChange = value => {
1682
- editField(field, ['disabled'], value);
3133
+ const setValue = value => {
3134
+ return editField(field, path, value);
1683
3135
  };
1684
3136
 
1685
- return jsxRuntime.jsx(CheckboxInputEntry, {
1686
- id: "disabled",
1687
- field: field,
1688
- label: "Disabled",
1689
- path: ['disabled'],
1690
- onChange: onChange
3137
+ return CheckboxEntry({
3138
+ element: field,
3139
+ getValue,
3140
+ id,
3141
+ label: 'Disabled',
3142
+ setValue
1691
3143
  });
1692
3144
  }
1693
3145
 
@@ -1696,7 +3148,38 @@ function IdEntry(props) {
1696
3148
  editField,
1697
3149
  field
1698
3150
  } = props;
3151
+ const entries = [];
3152
+
3153
+ if (field.type === 'default') {
3154
+ entries.push({
3155
+ id: 'id',
3156
+ component: Id,
3157
+ editField: editField,
3158
+ field: field,
3159
+ isEdited: isEdited$1
3160
+ });
3161
+ }
3162
+
3163
+ return entries;
3164
+ }
3165
+
3166
+ function Id(props) {
3167
+ const {
3168
+ editField,
3169
+ field,
3170
+ id
3171
+ } = props;
1699
3172
  const formFieldRegistry = useService('formFieldRegistry');
3173
+ const debounce = useService('debounce');
3174
+ const path = ['id'];
3175
+
3176
+ const getValue = () => {
3177
+ return minDash.get(field, path, '');
3178
+ };
3179
+
3180
+ const setValue = value => {
3181
+ return editField(field, path, value);
3182
+ };
1700
3183
 
1701
3184
  const validate = value => {
1702
3185
  if (minDash.isUndefined(value) || !value.length) {
@@ -1712,16 +3195,18 @@ function IdEntry(props) {
1712
3195
  return validateId(value) || null;
1713
3196
  };
1714
3197
 
1715
- return jsxRuntime.jsx(TextInputEntry, {
1716
- editField: editField,
1717
- field: field,
1718
- id: "id",
1719
- label: "Id",
1720
- path: ['id'],
1721
- validate: validate
3198
+ return TextfieldEntry({
3199
+ debounce,
3200
+ element: field,
3201
+ getValue,
3202
+ id,
3203
+ label: 'ID',
3204
+ setValue,
3205
+ validate
1722
3206
  });
1723
3207
  } // id structural validation /////////////
1724
3208
 
3209
+
1725
3210
  const SPACE_REGEX = /\s/; // for QName validation as per http://www.w3.org/TR/REC-xml/#NT-NameChar
1726
3211
 
1727
3212
  const QNAME_REGEX = /^([a-z][\w-.]*:)?[a-z_][\w-.]*$/i; // for ID validation as per BPMN Schema (QName - Namespace)
@@ -1751,7 +3236,41 @@ function KeyEntry(props) {
1751
3236
  editField,
1752
3237
  field
1753
3238
  } = props;
3239
+ const {
3240
+ type
3241
+ } = field;
3242
+ const entries = [];
3243
+
3244
+ if (INPUTS.includes(type)) {
3245
+ entries.push({
3246
+ id: 'key',
3247
+ component: Key$1,
3248
+ editField: editField,
3249
+ field: field,
3250
+ isEdited: isEdited$1
3251
+ });
3252
+ }
3253
+
3254
+ return entries;
3255
+ }
3256
+
3257
+ function Key$1(props) {
3258
+ const {
3259
+ editField,
3260
+ field,
3261
+ id
3262
+ } = props;
1754
3263
  const formFieldRegistry = useService('formFieldRegistry');
3264
+ const debounce = useService('debounce');
3265
+ const path = ['key'];
3266
+
3267
+ const getValue = () => {
3268
+ return minDash.get(field, path, '');
3269
+ };
3270
+
3271
+ const setValue = value => {
3272
+ return editField(field, path, value);
3273
+ };
1755
3274
 
1756
3275
  const validate = value => {
1757
3276
  if (minDash.isUndefined(value) || !value.length) {
@@ -1771,14 +3290,15 @@ function KeyEntry(props) {
1771
3290
  return null;
1772
3291
  };
1773
3292
 
1774
- return jsxRuntime.jsx(TextInputEntry, {
1775
- editField: editField,
1776
- field: field,
1777
- id: "key",
1778
- label: "Key",
1779
- description: "Maps to a process variable.",
1780
- path: ['key'],
1781
- validate: validate
3293
+ return TextfieldEntry({
3294
+ debounce,
3295
+ description: 'Maps to a process variable',
3296
+ element: field,
3297
+ getValue,
3298
+ id,
3299
+ label: 'Key',
3300
+ setValue,
3301
+ validate
1782
3302
  });
1783
3303
  }
1784
3304
 
@@ -1787,12 +3307,48 @@ function LabelEntry(props) {
1787
3307
  editField,
1788
3308
  field
1789
3309
  } = props;
1790
- return jsxRuntime.jsx(TextInputEntry, {
1791
- editField: editField,
1792
- field: field,
1793
- id: "label",
1794
- label: "Field Label",
1795
- path: ['label']
3310
+ const {
3311
+ type
3312
+ } = field;
3313
+ const entries = [];
3314
+
3315
+ if (INPUTS.includes(type) || type === 'button') {
3316
+ entries.push({
3317
+ id: 'label',
3318
+ component: Label$1,
3319
+ editField: editField,
3320
+ field: field,
3321
+ isEdited: isEdited$1
3322
+ });
3323
+ }
3324
+
3325
+ return entries;
3326
+ }
3327
+
3328
+ function Label$1(props) {
3329
+ const {
3330
+ editField,
3331
+ field,
3332
+ id
3333
+ } = props;
3334
+ const debounce = useService('debounce');
3335
+ const path = ['label'];
3336
+
3337
+ const getValue = () => {
3338
+ return minDash.get(field, path, '');
3339
+ };
3340
+
3341
+ const setValue = value => {
3342
+ return editField(field, path, value);
3343
+ };
3344
+
3345
+ return TextfieldEntry({
3346
+ debounce,
3347
+ element: field,
3348
+ getValue,
3349
+ id,
3350
+ label: 'Field label',
3351
+ setValue
1796
3352
  });
1797
3353
  }
1798
3354
 
@@ -1801,13 +3357,50 @@ function TextEntry(props) {
1801
3357
  editField,
1802
3358
  field
1803
3359
  } = props;
1804
- return jsxRuntime.jsx(TextareaEntry, {
1805
- editField: editField,
1806
- field: field,
1807
- id: "text",
1808
- label: "Text",
1809
- path: ['text'],
1810
- description: "Use Markdown or basic HTML to format."
3360
+ const {
3361
+ type
3362
+ } = field;
3363
+ const entries = [];
3364
+
3365
+ if (type === 'text') {
3366
+ entries.push({
3367
+ id: 'text',
3368
+ component: Text,
3369
+ editField: editField,
3370
+ field: field,
3371
+ isEdited: isEdited$2
3372
+ });
3373
+ }
3374
+
3375
+ return entries;
3376
+ }
3377
+
3378
+ function Text(props) {
3379
+ const {
3380
+ editField,
3381
+ field,
3382
+ id
3383
+ } = props;
3384
+ const debounce = useService('debounce');
3385
+ const path = ['text'];
3386
+
3387
+ const getValue = () => {
3388
+ return minDash.get(field, path, '');
3389
+ };
3390
+
3391
+ const setValue = value => {
3392
+ return editField(field, path, value);
3393
+ };
3394
+
3395
+ return TextAreaEntry({
3396
+ debounce,
3397
+ description: 'Use Markdown or basic HTML to format.',
3398
+ element: field,
3399
+ getValue,
3400
+ id,
3401
+ label: 'Text',
3402
+ rows: 10,
3403
+ setValue
1811
3404
  });
1812
3405
  }
1813
3406
 
@@ -1815,38 +3408,87 @@ function ValueEntry(props) {
1815
3408
  const {
1816
3409
  editField,
1817
3410
  field,
3411
+ idPrefix,
1818
3412
  index,
1819
- validate
3413
+ validateFactory
1820
3414
  } = props;
3415
+ const entries = [{
3416
+ component: Label,
3417
+ editField,
3418
+ field,
3419
+ id: idPrefix + '-label',
3420
+ idPrefix,
3421
+ index,
3422
+ validateFactory
3423
+ }, {
3424
+ component: Value$1,
3425
+ editField,
3426
+ field,
3427
+ id: idPrefix + '-value',
3428
+ idPrefix,
3429
+ index,
3430
+ validateFactory
3431
+ }];
3432
+ return entries;
3433
+ }
1821
3434
 
1822
- const getLabel = () => {
1823
- return minDash.get(field, ['values', index, 'label']);
3435
+ function Label(props) {
3436
+ const {
3437
+ editField,
3438
+ field,
3439
+ id,
3440
+ index,
3441
+ validateFactory
3442
+ } = props;
3443
+ const debounce = useService('debounce');
3444
+
3445
+ const setValue = value => {
3446
+ const values = minDash.get(field, ['values']);
3447
+ return editField(field, 'values', minDash.set(values, [index, 'label'], value));
1824
3448
  };
1825
3449
 
1826
3450
  const getValue = () => {
1827
- return minDash.get(field, ['values', index, 'value']);
3451
+ return minDash.get(field, ['values', index, 'label']);
1828
3452
  };
1829
3453
 
1830
- const onChange = key => {
3454
+ return TextfieldEntry({
3455
+ debounce,
3456
+ element: field,
3457
+ getValue,
3458
+ id,
3459
+ label: 'Label',
3460
+ setValue,
3461
+ validate: validateFactory(getValue())
3462
+ });
3463
+ }
3464
+
3465
+ function Value$1(props) {
3466
+ const {
3467
+ editField,
3468
+ field,
3469
+ id,
3470
+ index,
3471
+ validateFactory
3472
+ } = props;
3473
+ const debounce = useService('debounce');
3474
+
3475
+ const setValue = value => {
1831
3476
  const values = minDash.get(field, ['values']);
1832
- return value => {
1833
- editField(field, 'values', minDash.set(values, [index, key], value));
1834
- };
3477
+ return editField(field, 'values', minDash.set(values, [index, 'value'], value));
1835
3478
  };
1836
3479
 
1837
- return jsxRuntime.jsxs(jsxRuntime.Fragment, {
1838
- children: [jsxRuntime.jsx(TextInputEntry, {
1839
- id: `value-label-${index}`,
1840
- label: "Label",
1841
- onChange: onChange('label'),
1842
- value: getLabel()
1843
- }), jsxRuntime.jsx(TextInputEntry, {
1844
- id: `value-value-${index}`,
1845
- label: "Value",
1846
- onChange: onChange('value'),
1847
- value: getValue(),
1848
- validate: validate(getValue())
1849
- })]
3480
+ const getValue = () => {
3481
+ return minDash.get(field, ['values', index, 'value']);
3482
+ };
3483
+
3484
+ return TextfieldEntry({
3485
+ debounce,
3486
+ element: field,
3487
+ getValue,
3488
+ id,
3489
+ label: 'Value',
3490
+ setValue,
3491
+ validate: validateFactory(getValue())
1850
3492
  });
1851
3493
  }
1852
3494
 
@@ -1854,42 +3496,91 @@ function CustomValueEntry(props) {
1854
3496
  const {
1855
3497
  editField,
1856
3498
  field,
3499
+ idPrefix,
1857
3500
  index,
1858
- validate
3501
+ validateFactory
3502
+ } = props;
3503
+ const entries = [{
3504
+ component: Key,
3505
+ editField,
3506
+ field,
3507
+ id: idPrefix + '-key',
3508
+ idPrefix,
3509
+ index,
3510
+ validateFactory
3511
+ }, {
3512
+ component: Value,
3513
+ editField,
3514
+ field,
3515
+ id: idPrefix + '-value',
3516
+ idPrefix,
3517
+ index,
3518
+ validateFactory
3519
+ }];
3520
+ return entries;
3521
+ }
3522
+
3523
+ function Key(props) {
3524
+ const {
3525
+ editField,
3526
+ field,
3527
+ id,
3528
+ index,
3529
+ validateFactory
1859
3530
  } = props;
3531
+ const debounce = useService('debounce');
1860
3532
 
1861
- const getKey = () => {
1862
- return Object.keys(minDash.get(field, ['properties']))[index];
3533
+ const setValue = value => {
3534
+ const properties = minDash.get(field, ['properties']);
3535
+ const key = Object.keys(properties)[index];
3536
+ return editField(field, 'properties', updateKey(properties, key, value));
1863
3537
  };
1864
3538
 
1865
3539
  const getValue = () => {
1866
- return minDash.get(field, ['properties', getKey()]);
3540
+ return Object.keys(minDash.get(field, ['properties']))[index];
1867
3541
  };
1868
3542
 
1869
- const onChange = key => {
3543
+ return TextfieldEntry({
3544
+ debounce,
3545
+ element: field,
3546
+ getValue,
3547
+ id,
3548
+ label: 'Key',
3549
+ setValue,
3550
+ validate: validateFactory(getValue())
3551
+ });
3552
+ }
3553
+
3554
+ function Value(props) {
3555
+ const {
3556
+ editField,
3557
+ field,
3558
+ id,
3559
+ index,
3560
+ validateFactory
3561
+ } = props;
3562
+ const debounce = useService('debounce');
3563
+
3564
+ const setValue = value => {
1870
3565
  const properties = minDash.get(field, ['properties']);
1871
- return value => {
1872
- if (key === 'value') {
1873
- editField(field, 'properties', updateValue(properties, getKey(), value));
1874
- } else if (key === 'key') {
1875
- editField(field, 'properties', updateKey(properties, getKey(), value));
1876
- }
1877
- };
3566
+ const key = Object.keys(properties)[index];
3567
+ editField(field, 'properties', updateValue(properties, key, value));
1878
3568
  };
1879
3569
 
1880
- return jsxRuntime.jsxs(jsxRuntime.Fragment, {
1881
- children: [jsxRuntime.jsx(TextInputEntry, {
1882
- id: `value-key-${index}`,
1883
- label: "Key",
1884
- onChange: onChange('key'),
1885
- value: getKey(),
1886
- validate: validate(getKey())
1887
- }), jsxRuntime.jsx(TextInputEntry, {
1888
- id: `value-value-${index}`,
1889
- label: "Value",
1890
- onChange: onChange('value'),
1891
- value: getValue()
1892
- })]
3570
+ const getValue = () => {
3571
+ const properties = minDash.get(field, ['properties']);
3572
+ const key = Object.keys(properties)[index];
3573
+ return minDash.get(field, ['properties', key]);
3574
+ };
3575
+
3576
+ return TextfieldEntry({
3577
+ debounce,
3578
+ element: field,
3579
+ getValue,
3580
+ id,
3581
+ label: 'Value',
3582
+ setValue,
3583
+ validate: validateFactory(getValue())
1893
3584
  });
1894
3585
  } // helpers //////////
1895
3586
 
@@ -1903,6 +3594,7 @@ function CustomValueEntry(props) {
1903
3594
  * @returns {Object}
1904
3595
  */
1905
3596
 
3597
+
1906
3598
  function updateValue(properties, key, value) {
1907
3599
  return { ...properties,
1908
3600
  [key]: value
@@ -1928,154 +3620,149 @@ function updateKey(properties, oldKey, newKey) {
1928
3620
  }, {});
1929
3621
  }
1930
3622
 
1931
- function GeneralGroup(field, editField) {
1932
- const {
1933
- type
1934
- } = field;
1935
- const entries = [];
1936
-
1937
- if (type === 'default') {
1938
- entries.push(jsxRuntime.jsx(IdEntry, {
1939
- editField: editField,
1940
- field: field
1941
- }));
1942
- }
1943
-
1944
- if (INPUTS.includes(type) || type === 'button') {
1945
- entries.push(jsxRuntime.jsx(LabelEntry, {
1946
- editField: editField,
1947
- field: field
1948
- }));
1949
- }
1950
-
1951
- if (INPUTS.includes(type)) {
1952
- entries.push(jsxRuntime.jsx(DescriptionEntry, {
1953
- editField: editField,
1954
- field: field
1955
- }));
1956
- }
1957
-
1958
- if (INPUTS.includes(type)) {
1959
- entries.push(jsxRuntime.jsx(KeyEntry, {
1960
- editField: editField,
1961
- field: field
1962
- }));
1963
- }
1964
-
1965
- if (INPUTS.includes(type)) {
1966
- entries.push(jsxRuntime.jsx(DefaultValueEntry, {
1967
- editField: editField,
1968
- field: field
1969
- }));
3623
+ const VALUES_SOURCES = {
3624
+ STATIC: 'static',
3625
+ INPUT: 'input'
3626
+ };
3627
+ const VALUES_SOURCE_DEFAULT = VALUES_SOURCES.STATIC;
3628
+ const VALUES_SOURCES_LABELS = {
3629
+ [VALUES_SOURCES.STATIC]: 'Static',
3630
+ [VALUES_SOURCES.INPUT]: 'Input data'
3631
+ };
3632
+ const VALUES_SOURCES_PATHS = {
3633
+ [VALUES_SOURCES.STATIC]: ['values'],
3634
+ [VALUES_SOURCES.INPUT]: ['valuesKey']
3635
+ };
3636
+ const VALUES_SOURCES_DEFAULTS = {
3637
+ [VALUES_SOURCES.STATIC]: [],
3638
+ [VALUES_SOURCES.INPUT]: ''
3639
+ }; // helpers ///////////////////
3640
+
3641
+ function getValuesSource(field) {
3642
+ for (const source of Object.values(VALUES_SOURCES)) {
3643
+ if (minDash.get(field, VALUES_SOURCES_PATHS[source]) !== undefined) {
3644
+ return source;
3645
+ }
1970
3646
  }
1971
3647
 
1972
- if (type === 'button') {
1973
- entries.push(jsxRuntime.jsx(ActionEntry, {
1974
- editField: editField,
1975
- field: field
1976
- }));
1977
- }
3648
+ return VALUES_SOURCE_DEFAULT;
3649
+ }
1978
3650
 
1979
- if (type === 'columns') {
1980
- entries.push(jsxRuntime.jsx(ColumnsEntry, {
1981
- editField: editField,
1982
- field: field
1983
- }));
1984
- }
3651
+ function ValuesSourceSelectEntry(props) {
3652
+ const {
3653
+ editField,
3654
+ field,
3655
+ id
3656
+ } = props;
3657
+ return [{
3658
+ id: id + '-select',
3659
+ component: ValuesSourceSelect,
3660
+ isEdited: isEdited$4,
3661
+ editField,
3662
+ field
3663
+ }];
3664
+ }
1985
3665
 
1986
- if (type === 'text') {
1987
- entries.push(jsxRuntime.jsx(TextEntry, {
1988
- editField: editField,
1989
- field: field
1990
- }));
1991
- }
3666
+ function ValuesSourceSelect(props) {
3667
+ const {
3668
+ editField,
3669
+ field,
3670
+ id
3671
+ } = props;
3672
+ const getValue = getValuesSource;
3673
+
3674
+ const setValue = value => {
3675
+ let newField = field;
3676
+ Object.values(VALUES_SOURCES).forEach(source => {
3677
+ // Clear all values source definitions and default the newly selected one
3678
+ const newValue = value === source ? VALUES_SOURCES_DEFAULTS[source] : undefined;
3679
+ newField = editField(field, VALUES_SOURCES_PATHS[source], newValue);
3680
+ });
3681
+ return newField;
3682
+ };
1992
3683
 
1993
- if (INPUTS.includes(type)) {
1994
- entries.push(jsxRuntime.jsx(DisabledEntry, {
1995
- editField: editField,
1996
- field: field
3684
+ const getValuesSourceOptions = () => {
3685
+ return Object.values(VALUES_SOURCES).map(valueSource => ({
3686
+ label: VALUES_SOURCES_LABELS[valueSource],
3687
+ value: valueSource
1997
3688
  }));
1998
- }
3689
+ };
1999
3690
 
2000
- return jsxRuntime.jsx(Group, {
2001
- label: "General",
2002
- children: entries.length ? entries : null
3691
+ return SelectEntry({
3692
+ label: 'Type',
3693
+ element: field,
3694
+ getOptions: getValuesSourceOptions,
3695
+ getValue,
3696
+ id,
3697
+ setValue
2003
3698
  });
2004
3699
  }
2005
3700
 
2006
- function ValidationGroup(field, editField) {
3701
+ function InputKeyValuesSourceEntry(props) {
2007
3702
  const {
2008
- type
2009
- } = field;
2010
-
2011
- const onChange = key => {
2012
- return value => {
2013
- const validate = minDash.get(field, ['validate'], {});
2014
- editField(field, ['validate'], minDash.set(validate, [key], value));
2015
- };
2016
- };
3703
+ editField,
3704
+ field,
3705
+ id
3706
+ } = props;
3707
+ return [{
3708
+ id: id + '-key',
3709
+ component: InputValuesKey,
3710
+ label: 'Input values key',
3711
+ description: 'Define which input property to populate the values from',
3712
+ isEdited: isEdited$1,
3713
+ editField,
3714
+ field
3715
+ }];
3716
+ }
2017
3717
 
2018
- const entries = [jsxRuntime.jsx(CheckboxInputEntry, {
2019
- id: "required",
2020
- label: "Required",
2021
- onChange: onChange('required'),
2022
- value: minDash.get(field, ['validate', 'required'])
2023
- })];
3718
+ function InputValuesKey(props) {
3719
+ const {
3720
+ editField,
3721
+ field,
3722
+ id,
3723
+ label,
3724
+ description
3725
+ } = props;
3726
+ const debounce = useService('debounce');
3727
+ const path = VALUES_SOURCES_PATHS[VALUES_SOURCES.INPUT];
2024
3728
 
2025
- if (type === 'textfield') {
2026
- entries.push(jsxRuntime.jsx(NumberInputEntry, {
2027
- id: "minLength",
2028
- label: "Minimum Length",
2029
- min: "0",
2030
- onChange: onChange('minLength'),
2031
- value: minDash.get(field, ['validate', 'minLength'])
2032
- }), jsxRuntime.jsx(NumberInputEntry, {
2033
- id: "maxLength",
2034
- label: "Maximum Length",
2035
- min: "0",
2036
- onChange: onChange('maxLength'),
2037
- value: minDash.get(field, ['validate', 'maxLength'])
2038
- }), jsxRuntime.jsx(TextInputEntry, {
2039
- id: "pattern",
2040
- label: "Regular Expression Pattern",
2041
- onChange: onChange('pattern'),
2042
- value: minDash.get(field, ['validate', 'pattern'])
2043
- }));
2044
- }
3729
+ const getValue = () => minDash.get(field, path, '');
2045
3730
 
2046
- if (type === 'number') {
2047
- entries.push(jsxRuntime.jsx(NumberInputEntry, {
2048
- id: "min",
2049
- label: "Minimum",
2050
- onChange: onChange('min'),
2051
- value: minDash.get(field, ['validate', 'min'])
2052
- }), jsxRuntime.jsx(NumberInputEntry, {
2053
- id: "max",
2054
- label: "Maximum",
2055
- onChange: onChange('max'),
2056
- value: minDash.get(field, ['validate', 'max'])
2057
- }));
2058
- }
3731
+ const setValue = value => editField(field, path, value || '');
2059
3732
 
2060
- return jsxRuntime.jsx(Group, {
2061
- label: "Validation",
2062
- children: entries.length ? entries : null
3733
+ return TextfieldEntry({
3734
+ debounce,
3735
+ description,
3736
+ element: field,
3737
+ getValue,
3738
+ id,
3739
+ label,
3740
+ setValue
2063
3741
  });
2064
3742
  }
2065
3743
 
2066
- function ValuesGroup(field, editField) {
3744
+ function StaticValuesSourceEntry(props) {
2067
3745
  const {
2068
- id,
2069
- values = []
3746
+ editField,
3747
+ field,
3748
+ id: idPrefix
3749
+ } = props;
3750
+ const {
3751
+ values
2070
3752
  } = field;
2071
3753
 
2072
- const addEntry = () => {
3754
+ const addEntry = e => {
3755
+ e.stopPropagation();
2073
3756
  const index = values.length + 1;
2074
3757
  const entry = {
2075
3758
  label: `Value ${index}`,
2076
3759
  value: `value${index}`
2077
3760
  };
2078
- editField(field, ['values'], arrayAdd$1(values, values.length, entry));
3761
+ editField(field, VALUES_SOURCES_PATHS[VALUES_SOURCES.STATIC], arrayAdd$1(values, values.length, entry));
3762
+ };
3763
+
3764
+ const removeEntry = entry => {
3765
+ editField(field, VALUES_SOURCES_PATHS[VALUES_SOURCES.STATIC], minDash.without(values, entry));
2079
3766
  };
2080
3767
 
2081
3768
  const validateFactory = key => {
@@ -2096,41 +3783,321 @@ function ValuesGroup(field, editField) {
2096
3783
  };
2097
3784
  };
2098
3785
 
2099
- const hasEntries = values.length > 0;
2100
- return jsxRuntime.jsx(Group, {
2101
- label: "Values",
2102
- addEntry: addEntry,
2103
- hasEntries: hasEntries,
2104
- children: values.map((value, index) => {
2105
- const {
2106
- label
2107
- } = value;
3786
+ const items = values.map((entry, index) => {
3787
+ const id = idPrefix + '-' + index;
3788
+ return {
3789
+ id,
3790
+ label: entry.label,
3791
+ entries: ValueEntry({
3792
+ editField,
3793
+ field,
3794
+ idPrefix: id,
3795
+ index,
3796
+ validateFactory
3797
+ }),
3798
+ autoFocusEntry: id + '-label',
3799
+ remove: () => removeEntry(entry)
3800
+ };
3801
+ });
3802
+ return {
3803
+ items,
3804
+ add: addEntry
3805
+ };
3806
+ }
2108
3807
 
2109
- const removeEntry = () => {
2110
- editField(field, ['values'], arrayRemove$1(values, index));
2111
- };
3808
+ function GeneralGroup(field, editField) {
3809
+ const entries = [...IdEntry({
3810
+ field,
3811
+ editField
3812
+ }), ...LabelEntry({
3813
+ field,
3814
+ editField
3815
+ }), ...DescriptionEntry({
3816
+ field,
3817
+ editField
3818
+ }), ...KeyEntry({
3819
+ field,
3820
+ editField
3821
+ }), ...DefaultOptionEntry({
3822
+ field,
3823
+ editField
3824
+ }), ...ActionEntry({
3825
+ field,
3826
+ editField
3827
+ }), ...ColumnsEntry({
3828
+ field,
3829
+ editField
3830
+ }), ...TextEntry({
3831
+ field,
3832
+ editField
3833
+ }), ...DisabledEntry({
3834
+ field,
3835
+ editField
3836
+ })];
3837
+ return {
3838
+ id: 'general',
3839
+ label: 'General',
3840
+ entries
3841
+ };
3842
+ }
2112
3843
 
2113
- return jsxRuntime.jsx(CollapsibleEntry, {
2114
- label: label,
2115
- removeEntry: removeEntry,
2116
- children: jsxRuntime.jsx(ValueEntry, {
2117
- editField: editField,
2118
- field: field,
2119
- index: index,
2120
- validate: validateFactory
2121
- })
2122
- }, `${id}-${index}`);
2123
- })
3844
+ function ValidationGroup(field, editField) {
3845
+ const {
3846
+ type
3847
+ } = field;
3848
+
3849
+ if (!(INPUTS.includes(type) && type !== 'checkbox' && type !== 'checklist' && type !== 'taglist')) {
3850
+ return null;
3851
+ }
3852
+
3853
+ const onChange = key => {
3854
+ return value => {
3855
+ const validate = minDash.get(field, ['validate'], {});
3856
+ editField(field, ['validate'], minDash.set(validate, [key], value));
3857
+ };
3858
+ };
3859
+
3860
+ const getValue = key => {
3861
+ return () => {
3862
+ return minDash.get(field, ['validate', key]);
3863
+ };
3864
+ };
3865
+
3866
+ let entries = [{
3867
+ id: 'required',
3868
+ component: Required,
3869
+ getValue,
3870
+ field,
3871
+ isEdited: isEdited$6,
3872
+ onChange
3873
+ }];
3874
+
3875
+ if (type === 'textfield') {
3876
+ entries.push({
3877
+ id: 'minLength',
3878
+ component: MinLength,
3879
+ getValue,
3880
+ field,
3881
+ isEdited: isEdited$5,
3882
+ onChange
3883
+ }, {
3884
+ id: 'maxLength',
3885
+ component: MaxLength,
3886
+ getValue,
3887
+ field,
3888
+ isEdited: isEdited$5,
3889
+ onChange
3890
+ }, {
3891
+ id: 'pattern',
3892
+ component: Pattern,
3893
+ getValue,
3894
+ field,
3895
+ isEdited: isEdited$1,
3896
+ onChange
3897
+ });
3898
+ }
3899
+
3900
+ if (type === 'number') {
3901
+ entries.push({
3902
+ id: 'min',
3903
+ component: Min,
3904
+ getValue,
3905
+ field,
3906
+ isEdited: isEdited$5,
3907
+ onChange
3908
+ }, {
3909
+ id: 'max',
3910
+ component: Max,
3911
+ getValue,
3912
+ field,
3913
+ isEdited: isEdited$5,
3914
+ onChange
3915
+ });
3916
+ }
3917
+
3918
+ return {
3919
+ id: 'validation',
3920
+ label: 'Validation',
3921
+ entries
3922
+ };
3923
+ }
3924
+
3925
+ function Required(props) {
3926
+ const {
3927
+ field,
3928
+ getValue,
3929
+ id,
3930
+ onChange
3931
+ } = props;
3932
+ return CheckboxEntry({
3933
+ element: field,
3934
+ getValue: getValue('required'),
3935
+ id,
3936
+ label: 'Required',
3937
+ setValue: onChange('required')
2124
3938
  });
2125
3939
  }
2126
3940
 
2127
- function CustomValuesGroup(field, editField) {
3941
+ function MinLength(props) {
3942
+ const {
3943
+ field,
3944
+ getValue,
3945
+ id,
3946
+ onChange
3947
+ } = props;
3948
+ const debounce = useService('debounce');
3949
+ return NumberFieldEntry({
3950
+ debounce,
3951
+ element: field,
3952
+ getValue: getValue('minLength'),
3953
+ id,
3954
+ label: 'Minimum length',
3955
+ min: 0,
3956
+ setValue: onChange('minLength')
3957
+ });
3958
+ }
3959
+
3960
+ function MaxLength(props) {
3961
+ const {
3962
+ field,
3963
+ getValue,
3964
+ id,
3965
+ onChange
3966
+ } = props;
3967
+ const debounce = useService('debounce');
3968
+ return NumberFieldEntry({
3969
+ debounce,
3970
+ element: field,
3971
+ getValue: getValue('maxLength'),
3972
+ id,
3973
+ label: 'Maximum length',
3974
+ min: 0,
3975
+ setValue: onChange('maxLength')
3976
+ });
3977
+ }
3978
+
3979
+ function Pattern(props) {
3980
+ const {
3981
+ field,
3982
+ getValue,
3983
+ id,
3984
+ onChange
3985
+ } = props;
3986
+ const debounce = useService('debounce');
3987
+ return TextfieldEntry({
3988
+ debounce,
3989
+ element: field,
3990
+ getValue: getValue('pattern'),
3991
+ id,
3992
+ label: 'Regular expression pattern',
3993
+ setValue: onChange('pattern')
3994
+ });
3995
+ }
3996
+
3997
+ function Min(props) {
2128
3998
  const {
3999
+ field,
4000
+ getValue,
4001
+ id,
4002
+ onChange
4003
+ } = props;
4004
+ const debounce = useService('debounce');
4005
+ return NumberFieldEntry({
4006
+ debounce,
4007
+ element: field,
4008
+ getValue: getValue('min'),
4009
+ id,
4010
+ label: 'Minimum',
4011
+ min: 0,
4012
+ setValue: onChange('min')
4013
+ });
4014
+ }
4015
+
4016
+ function Max(props) {
4017
+ const {
4018
+ field,
4019
+ getValue,
4020
+ id,
4021
+ onChange
4022
+ } = props;
4023
+ const debounce = useService('debounce');
4024
+ return NumberFieldEntry({
4025
+ debounce,
4026
+ element: field,
4027
+ getValue: getValue('max'),
2129
4028
  id,
2130
- properties = {}
4029
+ label: 'Maximum',
4030
+ min: 0,
4031
+ setValue: onChange('max')
4032
+ });
4033
+ }
4034
+
4035
+ function ValuesGroups(field, editField) {
4036
+ const {
4037
+ type,
4038
+ id: fieldId
4039
+ } = field;
4040
+
4041
+ if (!VALUES_INPUTS.includes(type)) {
4042
+ return [];
4043
+ }
4044
+
4045
+ const context = {
4046
+ editField,
4047
+ field
4048
+ };
4049
+ const valuesSourceId = `${fieldId}-valuesSource`;
4050
+ /**
4051
+ * @type {Array<Group|ListGroup>}
4052
+ */
4053
+
4054
+ const groups = [{
4055
+ id: valuesSourceId,
4056
+ label: 'Values source',
4057
+ component: Group,
4058
+ entries: ValuesSourceSelectEntry({ ...context,
4059
+ id: valuesSourceId
4060
+ })
4061
+ }];
4062
+ const valuesSource = getValuesSource(field);
4063
+
4064
+ if (valuesSource === VALUES_SOURCES.INPUT) {
4065
+ const dynamicValuesId = `${fieldId}-dynamicValues`;
4066
+ groups.push({
4067
+ id: dynamicValuesId,
4068
+ label: 'Dynamic values',
4069
+ component: Group,
4070
+ entries: InputKeyValuesSourceEntry({ ...context,
4071
+ id: dynamicValuesId
4072
+ })
4073
+ });
4074
+ } else if (valuesSource === VALUES_SOURCES.STATIC) {
4075
+ const staticValuesId = `${fieldId}-staticValues`;
4076
+ groups.push({
4077
+ id: staticValuesId,
4078
+ label: 'Static values',
4079
+ component: ListGroup,
4080
+ ...StaticValuesSourceEntry({ ...context,
4081
+ id: staticValuesId
4082
+ })
4083
+ });
4084
+ }
4085
+
4086
+ return groups;
4087
+ }
4088
+
4089
+ function CustomValuesGroup(field, editField) {
4090
+ const {
4091
+ properties = {},
4092
+ type
2131
4093
  } = field;
2132
4094
 
2133
- const addEntry = () => {
4095
+ if (type === 'default') {
4096
+ return null;
4097
+ }
4098
+
4099
+ const addEntry = event => {
4100
+ event.stopPropagation();
2134
4101
  const index = Object.keys(properties).length + 1;
2135
4102
  const key = `key${index}`,
2136
4103
  value = 'value';
@@ -2155,28 +4122,35 @@ function CustomValuesGroup(field, editField) {
2155
4122
  };
2156
4123
  };
2157
4124
 
2158
- const hasEntries = Object.keys(properties).length > 0;
2159
- return jsxRuntime.jsx(Group, {
2160
- label: "Custom Properties",
2161
- addEntry: addEntry,
2162
- hasEntries: hasEntries,
2163
- children: Object.keys(properties).map((key, index) => {
2164
- const removeEntry = () => {
2165
- editField(field, ['properties'], removeKey(properties, key));
2166
- };
4125
+ const items = Object.keys(properties).map((key, index) => {
4126
+ const removeEntry = event => {
4127
+ event.stopPropagation();
4128
+ return editField(field, ['properties'], removeKey(properties, key));
4129
+ };
2167
4130
 
2168
- return jsxRuntime.jsx(CollapsibleEntry, {
2169
- label: key,
2170
- removeEntry: removeEntry,
2171
- children: jsxRuntime.jsx(CustomValueEntry, {
2172
- editField: editField,
2173
- field: field,
2174
- index: index,
2175
- validate: validateFactory
2176
- })
2177
- }, `${id}-${index}`);
2178
- })
4131
+ const id = `${field.id}-property-${index}`;
4132
+ return {
4133
+ autoFocusEntry: id + '-key',
4134
+ entries: CustomValueEntry({
4135
+ editField,
4136
+ field,
4137
+ idPrefix: id,
4138
+ index,
4139
+ validateFactory
4140
+ }),
4141
+ id,
4142
+ label: key || '',
4143
+ remove: removeEntry
4144
+ };
2179
4145
  });
4146
+ return {
4147
+ add: addEntry,
4148
+ component: ListGroup,
4149
+ id: 'custom-values',
4150
+ items,
4151
+ label: 'Custom properties',
4152
+ shouldSort: false
4153
+ };
2180
4154
  } // helpers //////////
2181
4155
 
2182
4156
  /**
@@ -2202,95 +4176,54 @@ function removeKey(properties, oldKey) {
2202
4176
  }, {});
2203
4177
  }
2204
4178
 
2205
- const labelsByType = {
2206
- button: 'BUTTON',
2207
- checkbox: 'CHECKBOX',
2208
- columns: 'COLUMNS',
2209
- default: 'FORM',
2210
- number: 'NUMBER',
2211
- radio: 'RADIO',
2212
- select: 'SELECT',
2213
- text: 'TEXT',
2214
- textfield: 'TEXT FIELD'
2215
- };
2216
-
2217
4179
  function getGroups(field, editField) {
2218
- const {
2219
- type
2220
- } = field;
2221
- const groups = [GeneralGroup(field, editField)];
2222
-
2223
- if (type === 'radio' || type === 'select') {
2224
- groups.push(ValuesGroup(field, editField));
2225
- }
2226
-
2227
- if (INPUTS.includes(type) && type !== 'checkbox') {
2228
- groups.push(ValidationGroup(field, editField));
4180
+ if (!field) {
4181
+ return [];
2229
4182
  }
2230
4183
 
2231
- if (type !== 'default') {
2232
- groups.push(CustomValuesGroup(field, editField));
2233
- }
4184
+ const groups = [GeneralGroup(field, editField), ...ValuesGroups(field, editField), ValidationGroup(field, editField), CustomValuesGroup(field, editField)]; // contract: if a group returns null, it should not be displayed at all
2234
4185
 
2235
- return groups;
4186
+ return groups.filter(group => group !== null);
2236
4187
  }
2237
4188
 
2238
- function PropertiesPanel(props) {
4189
+ function FormPropertiesPanel(props) {
2239
4190
  const {
2240
4191
  editField,
2241
4192
  field
2242
4193
  } = props;
2243
4194
  const eventBus = useService('eventBus');
2244
4195
 
2245
- if (!field) {
2246
- return jsxRuntime.jsx("div", {
2247
- class: "fjs-properties-panel-placeholder",
2248
- children: "Select a form field to edit its properties."
2249
- });
2250
- }
2251
-
2252
4196
  const onFocus = () => eventBus.fire('propertiesPanel.focusin');
2253
4197
 
2254
4198
  const onBlur = () => eventBus.fire('propertiesPanel.focusout');
2255
4199
 
2256
- const {
2257
- type
2258
- } = field;
2259
- const Icon = iconsByType[type];
2260
- const label = labelsByType[type];
2261
- return jsxRuntime.jsxs("div", {
4200
+ return jsxRuntime.jsx("div", {
2262
4201
  class: "fjs-properties-panel",
2263
- "data-field": field.id,
4202
+ "data-field": field && field.id,
2264
4203
  onFocusCapture: onFocus,
2265
4204
  onBlurCapture: onBlur,
2266
- children: [jsxRuntime.jsxs("div", {
2267
- class: "fjs-properties-panel-header",
2268
- children: [jsxRuntime.jsx("div", {
2269
- class: "fjs-properties-panel-header-icon",
2270
- children: jsxRuntime.jsx(Icon, {
2271
- width: "36",
2272
- height: "36",
2273
- viewBox: "0 0 54 54"
2274
- })
2275
- }), jsxRuntime.jsxs("div", {
2276
- children: [jsxRuntime.jsx("span", {
2277
- class: "fjs-properties-panel-header-type",
2278
- children: label
2279
- }), type === 'text' ? jsxRuntime.jsx("div", {
2280
- class: "fjs-properties-panel-header-label",
2281
- children: textToLabel(field.text)
2282
- }) : type === 'default' ? jsxRuntime.jsx("div", {
2283
- class: "fjs-properties-panel-header-label",
2284
- children: field.id
2285
- }) : jsxRuntime.jsx("div", {
2286
- class: "fjs-properties-panel-header-label",
2287
- children: field.label
2288
- })]
2289
- })]
2290
- }), getGroups(field, editField)]
4205
+ children: jsxRuntime.jsx(PropertiesPanel, {
4206
+ element: field,
4207
+ eventBus: eventBus,
4208
+ groups: getGroups(field, editField),
4209
+ headerProvider: PropertiesPanelHeaderProvider,
4210
+ placeholderProvider: PropertiesPanelPlaceholderProvider
4211
+ })
2291
4212
  });
2292
4213
  }
2293
4214
 
4215
+ function _extends() { _extends = Object.assign || 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); }
4216
+ var ListDeleteIcon = (({
4217
+ styles = {},
4218
+ ...props
4219
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends({
4220
+ xmlns: "http://www.w3.org/2000/svg",
4221
+ width: "11",
4222
+ height: "14"
4223
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
4224
+ d: "M10 4v8c0 1.1-.9 2-2 2H3c-1.1 0-2-.9-2-2V4h9zM8 6H3v4.8c0 .66.5 1.2 1.111 1.2H6.89C7.5 12 8 11.46 8 10.8V6zm3-5H8.5l-1-1h-4l-1 1H0v1.5h11V1z"
4225
+ })));
4226
+
2294
4227
  function ContextPad(props) {
2295
4228
  if (!props.children) {
2296
4229
  return null;
@@ -2551,7 +4484,7 @@ function FormEditor$1(props) {
2551
4484
  }), jsxRuntime.jsx(CreatePreview, {})]
2552
4485
  }), jsxRuntime.jsx("div", {
2553
4486
  class: "fjs-properties-container",
2554
- children: jsxRuntime.jsx(PropertiesPanel, {
4487
+ children: jsxRuntime.jsx(FormPropertiesPanel, {
2555
4488
  field: selectedFormField,
2556
4489
  editField: editField
2557
4490
  })