@bpmn-io/form-js-editor 0.12.2 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -3
- package/dist/assets/form-js-editor-base.css +486 -0
- package/dist/assets/form-js-editor.css +1161 -60
- package/dist/index.cjs +1247 -526
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +1249 -528
- package/dist/index.es.js.map +1 -1
- package/dist/types/FormEditor.d.ts +9 -0
- package/dist/types/core/FormFieldRegistry.d.ts +1 -1
- package/dist/types/core/FormLayoutValidator.d.ts +16 -0
- package/dist/types/core/FormLayouter.d.ts +1 -0
- package/dist/types/core/index.d.ts +8 -4
- package/dist/types/features/dragging/Dragging.d.ts +60 -0
- package/dist/types/features/dragging/index.d.ts +6 -0
- package/dist/types/features/editor-actions/index.d.ts +1 -1
- package/dist/types/features/expression-language/index.d.ts +8 -0
- package/dist/types/features/keyboard/index.d.ts +1 -1
- package/dist/types/features/modeling/FormLayoutUpdater.d.ts +13 -0
- package/dist/types/features/modeling/Modeling.d.ts +7 -7
- package/dist/types/features/modeling/behavior/index.d.ts +3 -3
- package/dist/types/features/modeling/cmd/Util.d.ts +1 -0
- package/dist/types/features/modeling/index.d.ts +3 -1
- package/dist/types/features/palette/index.d.ts +1 -1
- package/dist/types/features/properties-panel/entries/ColumnsEntry.d.ts +2 -1
- package/dist/types/features/properties-panel/entries/InputKeyValuesSourceEntry.d.ts +1 -1
- package/dist/types/features/properties-panel/entries/SelectEntries.d.ts +1 -0
- package/dist/types/features/properties-panel/entries/factories/simpleBoolEntryFactory.d.ts +1 -0
- package/dist/types/features/properties-panel/groups/GeneralGroup.d.ts +1 -1
- package/dist/types/features/properties-panel/groups/LayoutGroup.d.ts +11 -0
- package/dist/types/features/properties-panel/groups/index.d.ts +1 -0
- package/dist/types/features/properties-panel/index.d.ts +1 -1
- package/dist/types/features/selection/index.d.ts +2 -2
- package/dist/types/import/Importer.d.ts +4 -2
- package/dist/types/import/index.d.ts +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/render/EditorFormFields.d.ts +1 -1
- package/dist/types/render/components/FieldDragPreview.d.ts +1 -0
- package/dist/types/render/components/editor-form-fields/EditorText.d.ts +1 -1
- package/dist/types/render/components/editor-form-fields/index.d.ts +1 -1
- package/dist/types/render/components/icons/index.d.ts +1 -1
- package/dist/types/render/hooks/index.d.ts +3 -0
- package/dist/types/render/hooks/useDebounce.d.ts +1 -0
- package/dist/types/render/hooks/usePrevious.d.ts +1 -0
- package/dist/types/render/index.d.ts +2 -2
- package/package.json +10 -8
- package/dist/assets/dragula.css +0 -22
- package/dist/assets/properties-panel.css +0 -1016
package/dist/index.cjs
CHANGED
|
@@ -5,12 +5,13 @@ var Ids = require('ids');
|
|
|
5
5
|
var minDash = require('min-dash');
|
|
6
6
|
var classnames = require('classnames');
|
|
7
7
|
var jsxRuntime = require('preact/jsx-runtime');
|
|
8
|
-
var preact = require('preact');
|
|
9
8
|
var hooks$1 = require('preact/hooks');
|
|
10
|
-
var
|
|
9
|
+
var preact = require('preact');
|
|
11
10
|
var React = require('preact/compat');
|
|
11
|
+
var dragula = require('dragula');
|
|
12
12
|
var minDom = require('min-dom');
|
|
13
13
|
var arrayMove = require('array-move');
|
|
14
|
+
var feelers = require('feelers');
|
|
14
15
|
var FeelEditor = require('@bpmn-io/feel-editor');
|
|
15
16
|
var Big = require('big.js');
|
|
16
17
|
|
|
@@ -570,19 +571,78 @@ class FormFieldRegistry extends formJsViewer.FormFieldRegistry {
|
|
|
570
571
|
}
|
|
571
572
|
}
|
|
572
573
|
|
|
574
|
+
class FormLayoutValidator {
|
|
575
|
+
/**
|
|
576
|
+
* @constructor
|
|
577
|
+
*
|
|
578
|
+
* @param { import('./FormLayouter').default } formLayouter
|
|
579
|
+
* @param { import('./FormFieldRegistry').default } formFieldRegistry
|
|
580
|
+
*/
|
|
581
|
+
constructor(formLayouter, formFieldRegistry) {
|
|
582
|
+
this._formLayouter = formLayouter;
|
|
583
|
+
this._formFieldRegistry = formFieldRegistry;
|
|
584
|
+
}
|
|
585
|
+
validateField(field = {}, columns, row) {
|
|
586
|
+
// allow empty (auto columns)
|
|
587
|
+
if (columns) {
|
|
588
|
+
// allow minimum 2 cols
|
|
589
|
+
if (columns < 2) {
|
|
590
|
+
return 'Minimum 2 columns are allowed';
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
// allow maximum 16 cols
|
|
594
|
+
if (columns > 16) {
|
|
595
|
+
return 'Maximum 16 columns are allowed';
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
if (!row) {
|
|
599
|
+
row = this._formLayouter.getRowForField(field);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// calculate columns with and without updated field
|
|
603
|
+
let sumColumns = parseInt(columns) || 0;
|
|
604
|
+
let sumFields = 1;
|
|
605
|
+
let sumAutoCols = columns ? 0 : 1;
|
|
606
|
+
row.components.forEach(id => {
|
|
607
|
+
if (field.id === id) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
const component = this._formFieldRegistry.get(id);
|
|
611
|
+
const cols = (component.layout || {}).columns;
|
|
612
|
+
if (!cols) {
|
|
613
|
+
sumAutoCols++;
|
|
614
|
+
}
|
|
615
|
+
sumColumns += parseInt(cols) || 0;
|
|
616
|
+
sumFields++;
|
|
617
|
+
});
|
|
618
|
+
|
|
619
|
+
// do not allow overflows
|
|
620
|
+
if (sumColumns > 16 || sumColumns === 16 && sumAutoCols > 0 || columns === 16 && sumFields > 1) {
|
|
621
|
+
return 'New value exceeds the maximum of 16 columns per row';
|
|
622
|
+
}
|
|
623
|
+
if (sumFields > 4) {
|
|
624
|
+
return 'Maximum 4 fields per row are allowed';
|
|
625
|
+
}
|
|
626
|
+
return null;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
FormLayoutValidator.$inject = ['formLayouter', 'formFieldRegistry'];
|
|
630
|
+
|
|
573
631
|
class Importer {
|
|
574
632
|
/**
|
|
575
633
|
* @constructor
|
|
576
634
|
* @param { import('../core/FormFieldRegistry').default } formFieldRegistry
|
|
577
635
|
* @param { import('../core/FieldFactory').default } fieldFactory
|
|
636
|
+
* @param { import('../core/FormLayouter').default } formLayouter
|
|
578
637
|
*/
|
|
579
|
-
constructor(formFieldRegistry, fieldFactory) {
|
|
638
|
+
constructor(formFieldRegistry, fieldFactory, formLayouter) {
|
|
580
639
|
this._formFieldRegistry = formFieldRegistry;
|
|
581
640
|
this._fieldFactory = fieldFactory;
|
|
641
|
+
this._formLayouter = formLayouter;
|
|
582
642
|
}
|
|
583
643
|
|
|
584
644
|
/**
|
|
585
|
-
* Import schema creating fields, attaching additional
|
|
645
|
+
* Import schema creating rows, fields, attaching additional
|
|
586
646
|
* information to each field and adding fields to the
|
|
587
647
|
* field registry.
|
|
588
648
|
*
|
|
@@ -602,6 +662,7 @@ class Importer {
|
|
|
602
662
|
const warnings = [];
|
|
603
663
|
try {
|
|
604
664
|
const importedSchema = this.importFormField(formJsViewer.clone(schema));
|
|
665
|
+
this._formLayouter.calculateLayout(formJsViewer.clone(importedSchema));
|
|
605
666
|
return {
|
|
606
667
|
schema: importedSchema,
|
|
607
668
|
warnings
|
|
@@ -666,7 +727,7 @@ class Importer {
|
|
|
666
727
|
});
|
|
667
728
|
}
|
|
668
729
|
}
|
|
669
|
-
Importer.$inject = ['formFieldRegistry', 'fieldFactory'];
|
|
730
|
+
Importer.$inject = ['formFieldRegistry', 'fieldFactory', 'formLayouter'];
|
|
670
731
|
|
|
671
732
|
var importModule = {
|
|
672
733
|
importer: ['type', Importer]
|
|
@@ -683,11 +744,35 @@ function editorFormFieldClasses(type, {
|
|
|
683
744
|
});
|
|
684
745
|
}
|
|
685
746
|
|
|
686
|
-
|
|
747
|
+
const DragAndDropContext = preact.createContext({
|
|
748
|
+
drake: null
|
|
749
|
+
});
|
|
750
|
+
var DragAndDropContext$1 = DragAndDropContext;
|
|
751
|
+
|
|
752
|
+
/**
|
|
753
|
+
* @param {string} type
|
|
754
|
+
* @param {boolean} [strict]
|
|
755
|
+
*
|
|
756
|
+
* @returns {any}
|
|
757
|
+
*/
|
|
758
|
+
function getService$1(type, strict) {}
|
|
759
|
+
const FormEditorContext = preact.createContext({
|
|
760
|
+
getService: getService$1
|
|
761
|
+
});
|
|
762
|
+
var FormEditorContext$1 = FormEditorContext;
|
|
763
|
+
|
|
764
|
+
function useService$1 (type, strict) {
|
|
765
|
+
const {
|
|
766
|
+
getService
|
|
767
|
+
} = hooks$1.useContext(FormEditorContext$1);
|
|
768
|
+
return getService(type, strict);
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
function _extends$3() { _extends$3 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3.apply(this, arguments); }
|
|
687
772
|
var CloseIcon = (({
|
|
688
773
|
styles = {},
|
|
689
774
|
...props
|
|
690
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
775
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$3({
|
|
691
776
|
width: "16",
|
|
692
777
|
height: "16",
|
|
693
778
|
fill: "currentColor",
|
|
@@ -698,6 +783,23 @@ var CloseIcon = (({
|
|
|
698
783
|
d: "M12 4.7l-.7-.7L8 7.3 4.7 4l-.7.7L7.3 8 4 11.3l.7.7L8 8.7l3.3 3.3.7-.7L8.7 8 12 4.7z"
|
|
699
784
|
})));
|
|
700
785
|
|
|
786
|
+
function _extends$2() { _extends$2 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$2.apply(this, arguments); }
|
|
787
|
+
var DraggableIcon = (({
|
|
788
|
+
styles = {},
|
|
789
|
+
...props
|
|
790
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$2({
|
|
791
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
792
|
+
width: "16",
|
|
793
|
+
height: "16",
|
|
794
|
+
fill: "currentcolor",
|
|
795
|
+
viewBox: "0 0 32 32"
|
|
796
|
+
}, props), /*#__PURE__*/React.createElement("path", {
|
|
797
|
+
d: "M10 6h4v4h-4zm8 0h4v4h-4zm-8 8h4v4h-4zm8 0h4v4h-4zm-8 8h4v4h-4zm8 0h4v4h-4z"
|
|
798
|
+
}), /*#__PURE__*/React.createElement("path", {
|
|
799
|
+
d: "M0 0h32v32H0z",
|
|
800
|
+
fill: "none"
|
|
801
|
+
})));
|
|
802
|
+
|
|
701
803
|
function _extends$1() { _extends$1 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
|
|
702
804
|
var SearchIcon = (({
|
|
703
805
|
styles = {},
|
|
@@ -718,6 +820,8 @@ function EditorText(props) {
|
|
|
718
820
|
text = ''
|
|
719
821
|
} = props.field;
|
|
720
822
|
const Icon = formJsViewer.iconsByType('text');
|
|
823
|
+
const templating = useService$1('templating');
|
|
824
|
+
const expressionLanguage = useService$1('expressionLanguage');
|
|
721
825
|
if (!text) {
|
|
722
826
|
return jsxRuntime.jsx("div", {
|
|
723
827
|
class: editorFormFieldClasses(type),
|
|
@@ -729,7 +833,7 @@ function EditorText(props) {
|
|
|
729
833
|
})
|
|
730
834
|
});
|
|
731
835
|
}
|
|
732
|
-
if (
|
|
836
|
+
if (expressionLanguage.isExpression(text)) {
|
|
733
837
|
return jsxRuntime.jsx("div", {
|
|
734
838
|
class: editorFormFieldClasses(type),
|
|
735
839
|
children: jsxRuntime.jsxs("div", {
|
|
@@ -740,6 +844,17 @@ function EditorText(props) {
|
|
|
740
844
|
})
|
|
741
845
|
});
|
|
742
846
|
}
|
|
847
|
+
if (templating.isTemplate(text)) {
|
|
848
|
+
return jsxRuntime.jsx("div", {
|
|
849
|
+
class: editorFormFieldClasses(type),
|
|
850
|
+
children: jsxRuntime.jsxs("div", {
|
|
851
|
+
class: "fjs-form-field-placeholder",
|
|
852
|
+
children: [jsxRuntime.jsx(Icon, {
|
|
853
|
+
viewBox: "0 0 54 54"
|
|
854
|
+
}), "Text view is templated"]
|
|
855
|
+
})
|
|
856
|
+
});
|
|
857
|
+
}
|
|
743
858
|
return jsxRuntime.jsx(formJsViewer.Text, {
|
|
744
859
|
...props,
|
|
745
860
|
disableLinks: true
|
|
@@ -760,30 +875,6 @@ class EditorFormFields extends formJsViewer.FormFields {
|
|
|
760
875
|
}
|
|
761
876
|
}
|
|
762
877
|
|
|
763
|
-
const DragAndDropContext = preact.createContext({
|
|
764
|
-
drake: null
|
|
765
|
-
});
|
|
766
|
-
var DragAndDropContext$1 = DragAndDropContext;
|
|
767
|
-
|
|
768
|
-
/**
|
|
769
|
-
* @param {string} type
|
|
770
|
-
* @param {boolean} [strict]
|
|
771
|
-
*
|
|
772
|
-
* @returns {any}
|
|
773
|
-
*/
|
|
774
|
-
function getService$1(type, strict) {}
|
|
775
|
-
const FormEditorContext = preact.createContext({
|
|
776
|
-
getService: getService$1
|
|
777
|
-
});
|
|
778
|
-
var FormEditorContext$1 = FormEditorContext;
|
|
779
|
-
|
|
780
|
-
function useService$1 (type, strict) {
|
|
781
|
-
const {
|
|
782
|
-
getService
|
|
783
|
-
} = hooks$1.useContext(FormEditorContext$1);
|
|
784
|
-
return getService(type, strict);
|
|
785
|
-
}
|
|
786
|
-
|
|
787
878
|
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
|
|
788
879
|
var ListDeleteIcon = (({
|
|
789
880
|
styles = {},
|
|
@@ -945,6 +1036,307 @@ function unset() {
|
|
|
945
1036
|
set(null);
|
|
946
1037
|
}
|
|
947
1038
|
|
|
1039
|
+
const DRAG_CONTAINER_CLS = 'fjs-drag-container';
|
|
1040
|
+
const DROP_CONTAINER_VERTICAL_CLS = 'fjs-drop-container-vertical';
|
|
1041
|
+
const DROP_CONTAINER_HORIZONTAL_CLS = 'fjs-drop-container-horizontal';
|
|
1042
|
+
const DRAG_MOVE_CLS = 'fjs-drag-move';
|
|
1043
|
+
const DRAG_ROW_MOVE_CLS = 'fjs-drag-row-move';
|
|
1044
|
+
const DRAG_COPY_CLS = 'fjs-drag-copy';
|
|
1045
|
+
const DRAG_NO_DROP_CLS = 'fjs-no-drop';
|
|
1046
|
+
const DRAG_NO_MOVE_CLS = 'fjs-no-move';
|
|
1047
|
+
const ERROR_DROP_CLS = 'fjs-error-drop';
|
|
1048
|
+
|
|
1049
|
+
/**
|
|
1050
|
+
* @typedef { { id: String, components: Array<any> } } FormRow
|
|
1051
|
+
*/
|
|
1052
|
+
|
|
1053
|
+
class Dragging {
|
|
1054
|
+
/**
|
|
1055
|
+
* @constructor
|
|
1056
|
+
*
|
|
1057
|
+
* @param { import('../../core/FormFieldRegistry').default } formFieldRegistry
|
|
1058
|
+
* @param { import('../../core/FormLayouter').default } formLayouter
|
|
1059
|
+
* @param { import('../../core/FormLayoutValidator').default } formLayoutValidator
|
|
1060
|
+
* @param { import('../../core/EventBus').default } eventBus
|
|
1061
|
+
* @param { import('../modeling/Modeling').default } modeling
|
|
1062
|
+
*/
|
|
1063
|
+
constructor(formFieldRegistry, formLayouter, formLayoutValidator, eventBus, modeling) {
|
|
1064
|
+
this._formFieldRegistry = formFieldRegistry;
|
|
1065
|
+
this._formLayouter = formLayouter;
|
|
1066
|
+
this._formLayoutValidator = formLayoutValidator;
|
|
1067
|
+
this._eventBus = eventBus;
|
|
1068
|
+
this._modeling = modeling;
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
/**
|
|
1072
|
+
* Calculcates position in form schema given the dropped place.
|
|
1073
|
+
*
|
|
1074
|
+
* @param { FormRow } targetRow
|
|
1075
|
+
* @param { any } targetFormField
|
|
1076
|
+
* @param { HTMLElement } sibling
|
|
1077
|
+
* @returns { number }
|
|
1078
|
+
*/
|
|
1079
|
+
getTargetIndex(targetRow, targetFormField, sibling) {
|
|
1080
|
+
/** @type HTMLElement */
|
|
1081
|
+
const siblingFormFieldNode = sibling && sibling.querySelector('.fjs-element');
|
|
1082
|
+
const siblingFormField = siblingFormFieldNode && this._formFieldRegistry.get(siblingFormFieldNode.dataset.id);
|
|
1083
|
+
|
|
1084
|
+
// (1) dropped before existing field => place before
|
|
1085
|
+
if (siblingFormField) {
|
|
1086
|
+
return getFormFieldIndex$1(targetFormField, siblingFormField);
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1089
|
+
// (2) dropped in row => place at the end of row (after last field in row)
|
|
1090
|
+
if (targetRow) {
|
|
1091
|
+
return getFormFieldIndex$1(targetFormField, this._formFieldRegistry.get(targetRow.components[targetRow.components.length - 1])) + 1;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
// (3) dropped as last item
|
|
1095
|
+
return targetFormField.components.length;
|
|
1096
|
+
}
|
|
1097
|
+
validateDrop(element, target) {
|
|
1098
|
+
const formFieldNode = element.querySelector('.fjs-element');
|
|
1099
|
+
const targetRow = this._formLayouter.getRow(target.dataset.rowId);
|
|
1100
|
+
let columns;
|
|
1101
|
+
let formField;
|
|
1102
|
+
if (formFieldNode) {
|
|
1103
|
+
formField = this._formFieldRegistry.get(formFieldNode.dataset.id);
|
|
1104
|
+
columns = (formField.layout || {}).columns;
|
|
1105
|
+
}
|
|
1106
|
+
return this._formLayoutValidator.validateField(formField, columns, targetRow);
|
|
1107
|
+
}
|
|
1108
|
+
moveField(element, source, targetRow, targetFormField, targetIndex) {
|
|
1109
|
+
const formFieldNode = element.querySelector('.fjs-element');
|
|
1110
|
+
const formField = this._formFieldRegistry.get(formFieldNode.dataset.id);
|
|
1111
|
+
const sourceParent = getFormParent(source);
|
|
1112
|
+
const sourceFormField = this._formFieldRegistry.get(sourceParent.dataset.id);
|
|
1113
|
+
const sourceIndex = getFormFieldIndex$1(sourceFormField, formField);
|
|
1114
|
+
const sourceRow = this._formLayouter.getRowForField(formField);
|
|
1115
|
+
this._modeling.moveFormField(formField, sourceFormField, targetFormField, sourceIndex, targetIndex, sourceRow, targetRow);
|
|
1116
|
+
}
|
|
1117
|
+
createNewField(element, targetRow, targetFormField, targetIndex) {
|
|
1118
|
+
const type = element.dataset.fieldType;
|
|
1119
|
+
let attrs = {
|
|
1120
|
+
type
|
|
1121
|
+
};
|
|
1122
|
+
attrs = {
|
|
1123
|
+
...attrs,
|
|
1124
|
+
layout: {
|
|
1125
|
+
row: targetRow ? targetRow.id : this._formLayouter.nextRowId(),
|
|
1126
|
+
// enable auto columns
|
|
1127
|
+
columns: null
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
this._modeling.addFormField(attrs, targetFormField, targetIndex);
|
|
1131
|
+
}
|
|
1132
|
+
handleRowDrop(el, target, source, sibling) {
|
|
1133
|
+
const targetFormField = this._formFieldRegistry.get(target.dataset.id);
|
|
1134
|
+
const rowNode = el.querySelector('.fjs-layout-row');
|
|
1135
|
+
const row = this._formLayouter.getRow(rowNode.dataset.rowId);
|
|
1136
|
+
|
|
1137
|
+
// move each field in the row before first field of sibling row
|
|
1138
|
+
row.components.forEach((id, index) => {
|
|
1139
|
+
const formField = this._formFieldRegistry.get(id);
|
|
1140
|
+
const sourceParent = getFormParent(source);
|
|
1141
|
+
const sourceFormField = this._formFieldRegistry.get(sourceParent.dataset.id);
|
|
1142
|
+
const siblingRowNode = sibling && sibling.querySelector('.fjs-layout-row');
|
|
1143
|
+
const siblingRow = siblingRowNode && this._formLayouter.getRow(siblingRowNode.dataset.rowId);
|
|
1144
|
+
const siblingFormField = sibling && this._formFieldRegistry.get(siblingRow.components[0]);
|
|
1145
|
+
const sourceIndex = getFormFieldIndex$1(sourceFormField, formField);
|
|
1146
|
+
const targetIndex = (siblingRowNode ? getFormFieldIndex$1(targetFormField, siblingFormField) : targetFormField.components.length) + index;
|
|
1147
|
+
this._modeling.moveFormField(formField, sourceFormField, targetFormField, sourceIndex, targetIndex, row, row);
|
|
1148
|
+
});
|
|
1149
|
+
}
|
|
1150
|
+
handleElementDrop(el, target, source, sibling, drake) {
|
|
1151
|
+
// (1) detect drop target
|
|
1152
|
+
const targetFormField = this._formFieldRegistry.get(getFormParent(target).dataset.id);
|
|
1153
|
+
let targetRow;
|
|
1154
|
+
|
|
1155
|
+
// (2.1) dropped in existing row
|
|
1156
|
+
if (isRow(target)) {
|
|
1157
|
+
unsetDropNotAllowed(target);
|
|
1158
|
+
targetRow = this._formLayouter.getRow(target.dataset.rowId);
|
|
1159
|
+
|
|
1160
|
+
// validate whether drop is allowed
|
|
1161
|
+
const validationError = this.validateDrop(el, target);
|
|
1162
|
+
if (validationError) {
|
|
1163
|
+
return drake.cancel(true);
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
drake.remove();
|
|
1167
|
+
|
|
1168
|
+
// (3) detect position to drop field in schema order
|
|
1169
|
+
const targetIndex = this.getTargetIndex(targetRow, targetFormField, sibling);
|
|
1170
|
+
|
|
1171
|
+
// (4) create new field or move existing
|
|
1172
|
+
if (isPalette(source)) {
|
|
1173
|
+
this.createNewField(el, targetRow, targetFormField, targetIndex);
|
|
1174
|
+
} else {
|
|
1175
|
+
this.moveField(el, source, targetRow, targetFormField, targetIndex);
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
/**
|
|
1180
|
+
* @param { { container: Array<string>, direction: string, mirrorContainer: string } } options
|
|
1181
|
+
*/
|
|
1182
|
+
createDragulaInstance(options) {
|
|
1183
|
+
const {
|
|
1184
|
+
container,
|
|
1185
|
+
direction,
|
|
1186
|
+
mirrorContainer
|
|
1187
|
+
} = options || {};
|
|
1188
|
+
const dragulaInstance = dragula({
|
|
1189
|
+
direction,
|
|
1190
|
+
mirrorContainer,
|
|
1191
|
+
isContainer(el) {
|
|
1192
|
+
return container.some(cls => el.classList.contains(cls));
|
|
1193
|
+
},
|
|
1194
|
+
moves(el, source, handle) {
|
|
1195
|
+
return !handle.classList.contains(DRAG_NO_MOVE_CLS) && (el.classList.contains(DRAG_MOVE_CLS) || el.classList.contains(DRAG_COPY_CLS) || el.classList.contains(DRAG_ROW_MOVE_CLS));
|
|
1196
|
+
},
|
|
1197
|
+
copy(el) {
|
|
1198
|
+
return el.classList.contains(DRAG_COPY_CLS);
|
|
1199
|
+
},
|
|
1200
|
+
accepts: (el, target) => {
|
|
1201
|
+
unsetDropNotAllowed(target);
|
|
1202
|
+
|
|
1203
|
+
// allow dropping rows only between rows
|
|
1204
|
+
if (el.classList.contains(DRAG_ROW_MOVE_CLS)) {
|
|
1205
|
+
return !target.classList.contains(DROP_CONTAINER_HORIZONTAL_CLS);
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
// validate field drop in row
|
|
1209
|
+
if (isRow(target)) {
|
|
1210
|
+
const validationError = this.validateDrop(el, target);
|
|
1211
|
+
if (validationError) {
|
|
1212
|
+
// set error feedback to row
|
|
1213
|
+
setDropNotAllowed(target);
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
return !target.classList.contains(DRAG_NO_DROP_CLS);
|
|
1217
|
+
},
|
|
1218
|
+
slideFactorX: 10,
|
|
1219
|
+
slideFactorY: 5
|
|
1220
|
+
});
|
|
1221
|
+
|
|
1222
|
+
// bind life cycle events
|
|
1223
|
+
dragulaInstance.on('drag', (element, source) => {
|
|
1224
|
+
this.emit('drag.start', {
|
|
1225
|
+
element,
|
|
1226
|
+
source
|
|
1227
|
+
});
|
|
1228
|
+
});
|
|
1229
|
+
dragulaInstance.on('dragend', element => {
|
|
1230
|
+
this.emit('drag.end', {
|
|
1231
|
+
element
|
|
1232
|
+
});
|
|
1233
|
+
});
|
|
1234
|
+
dragulaInstance.on('drop', (element, target, source, sibling) => {
|
|
1235
|
+
this.emit('drag.drop', {
|
|
1236
|
+
element,
|
|
1237
|
+
target,
|
|
1238
|
+
source,
|
|
1239
|
+
sibling
|
|
1240
|
+
});
|
|
1241
|
+
});
|
|
1242
|
+
dragulaInstance.on('over', (element, container, source) => {
|
|
1243
|
+
this.emit('drag.hover', {
|
|
1244
|
+
element,
|
|
1245
|
+
container,
|
|
1246
|
+
source
|
|
1247
|
+
});
|
|
1248
|
+
});
|
|
1249
|
+
dragulaInstance.on('out', (element, container, source) => {
|
|
1250
|
+
this.emit('drag.out', {
|
|
1251
|
+
element,
|
|
1252
|
+
container,
|
|
1253
|
+
source
|
|
1254
|
+
});
|
|
1255
|
+
});
|
|
1256
|
+
dragulaInstance.on('cancel', (element, container, source) => {
|
|
1257
|
+
this.emit('drag.cancel', {
|
|
1258
|
+
element,
|
|
1259
|
+
container,
|
|
1260
|
+
source
|
|
1261
|
+
});
|
|
1262
|
+
});
|
|
1263
|
+
dragulaInstance.on('drop', (el, target, source, sibling) => {
|
|
1264
|
+
if (!target) {
|
|
1265
|
+
dragulaInstance.remove();
|
|
1266
|
+
return;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
// (1) handle row drop
|
|
1270
|
+
if (isDragRow(el)) {
|
|
1271
|
+
this.handleRowDrop(el, target, source, sibling);
|
|
1272
|
+
} else {
|
|
1273
|
+
// (2) handle form field drop
|
|
1274
|
+
this.handleElementDrop(el, target, source, sibling, dragulaInstance);
|
|
1275
|
+
}
|
|
1276
|
+
});
|
|
1277
|
+
this.emit('dragula.created', dragulaInstance);
|
|
1278
|
+
return dragulaInstance;
|
|
1279
|
+
}
|
|
1280
|
+
emit(event, context) {
|
|
1281
|
+
this._eventBus.fire(event, context);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
Dragging.$inject = ['formFieldRegistry', 'formLayouter', 'formLayoutValidator', 'eventBus', 'modeling'];
|
|
1285
|
+
|
|
1286
|
+
// helper //////////
|
|
1287
|
+
|
|
1288
|
+
function getFormFieldIndex$1(parent, formField) {
|
|
1289
|
+
let fieldFormIndex = parent.components.length;
|
|
1290
|
+
parent.components.forEach(({
|
|
1291
|
+
id
|
|
1292
|
+
}, index) => {
|
|
1293
|
+
if (id === formField.id) {
|
|
1294
|
+
fieldFormIndex = index;
|
|
1295
|
+
}
|
|
1296
|
+
});
|
|
1297
|
+
return fieldFormIndex;
|
|
1298
|
+
}
|
|
1299
|
+
function isRow(node) {
|
|
1300
|
+
return node.classList.contains('fjs-layout-row');
|
|
1301
|
+
}
|
|
1302
|
+
function isDragRow(node) {
|
|
1303
|
+
return node.classList.contains(DRAG_ROW_MOVE_CLS);
|
|
1304
|
+
}
|
|
1305
|
+
function isPalette(node) {
|
|
1306
|
+
return node.classList.contains('fjs-palette-fields');
|
|
1307
|
+
}
|
|
1308
|
+
function getFormParent(node) {
|
|
1309
|
+
return node.closest('.fjs-element');
|
|
1310
|
+
}
|
|
1311
|
+
function setDropNotAllowed(node) {
|
|
1312
|
+
node.classList.add(ERROR_DROP_CLS);
|
|
1313
|
+
set('not-allowed');
|
|
1314
|
+
}
|
|
1315
|
+
function unsetDropNotAllowed(node) {
|
|
1316
|
+
node.classList.remove(ERROR_DROP_CLS);
|
|
1317
|
+
set('grabbing');
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
function FieldDragPreview(props) {
|
|
1321
|
+
const {
|
|
1322
|
+
class: className,
|
|
1323
|
+
Icon,
|
|
1324
|
+
label
|
|
1325
|
+
} = props;
|
|
1326
|
+
return jsxRuntime.jsxs("div", {
|
|
1327
|
+
class: classnames('fjs-field-preview', className),
|
|
1328
|
+
children: [jsxRuntime.jsx(Icon, {
|
|
1329
|
+
class: "fjs-field-preview-icon",
|
|
1330
|
+
width: "36",
|
|
1331
|
+
height: "36",
|
|
1332
|
+
viewBox: "0 0 54 54"
|
|
1333
|
+
}), jsxRuntime.jsx("span", {
|
|
1334
|
+
class: "fjs-field-preview-text",
|
|
1335
|
+
children: label
|
|
1336
|
+
})]
|
|
1337
|
+
});
|
|
1338
|
+
}
|
|
1339
|
+
|
|
948
1340
|
function ContextPad(props) {
|
|
949
1341
|
if (!props.children) {
|
|
950
1342
|
return null;
|
|
@@ -991,7 +1383,7 @@ function Element(props) {
|
|
|
991
1383
|
event.stopPropagation();
|
|
992
1384
|
selection.toggle(field);
|
|
993
1385
|
}
|
|
994
|
-
const classes = [
|
|
1386
|
+
const classes = [];
|
|
995
1387
|
if (props.class) {
|
|
996
1388
|
classes.push(...props.class.split(' '));
|
|
997
1389
|
}
|
|
@@ -1010,7 +1402,9 @@ function Element(props) {
|
|
|
1010
1402
|
"data-field-type": type,
|
|
1011
1403
|
onClick: onClick,
|
|
1012
1404
|
ref: ref,
|
|
1013
|
-
children: [jsxRuntime.jsx(
|
|
1405
|
+
children: [jsxRuntime.jsx(DebugColumns, {
|
|
1406
|
+
field: field
|
|
1407
|
+
}), jsxRuntime.jsx(ContextPad, {
|
|
1014
1408
|
children: selection.isSelected(field) && field.type !== 'default' ? jsxRuntime.jsx("button", {
|
|
1015
1409
|
class: "fjs-context-pad-item",
|
|
1016
1410
|
onClick: onRemove,
|
|
@@ -1019,6 +1413,20 @@ function Element(props) {
|
|
|
1019
1413
|
}), props.children]
|
|
1020
1414
|
});
|
|
1021
1415
|
}
|
|
1416
|
+
function DebugColumns(props) {
|
|
1417
|
+
const {
|
|
1418
|
+
field
|
|
1419
|
+
} = props;
|
|
1420
|
+
const debugColumnsConfig = useService$1('config.debugColumns');
|
|
1421
|
+
if (!debugColumnsConfig || field.type == 'default') {
|
|
1422
|
+
return null;
|
|
1423
|
+
}
|
|
1424
|
+
return jsxRuntime.jsx("div", {
|
|
1425
|
+
style: "width: fit-content; padding: 2px 6px; height: 16px; background: var(--color-blue-205-100-95); display: flex; justify-content: center; align-items: center; position: absolute; bottom: -2px; z-index: 2; font-size: 10px; right: 3px;",
|
|
1426
|
+
class: "fjs-debug-columns",
|
|
1427
|
+
children: (field.layout || {}).columns || 'auto'
|
|
1428
|
+
});
|
|
1429
|
+
}
|
|
1022
1430
|
function Children(props) {
|
|
1023
1431
|
const {
|
|
1024
1432
|
field
|
|
@@ -1026,7 +1434,7 @@ function Children(props) {
|
|
|
1026
1434
|
const {
|
|
1027
1435
|
id
|
|
1028
1436
|
} = field;
|
|
1029
|
-
const classes = ['fjs-children',
|
|
1437
|
+
const classes = ['fjs-children', DROP_CONTAINER_VERTICAL_CLS];
|
|
1030
1438
|
if (props.class) {
|
|
1031
1439
|
classes.push(...props.class.split(' '));
|
|
1032
1440
|
}
|
|
@@ -1036,12 +1444,51 @@ function Children(props) {
|
|
|
1036
1444
|
children: props.children
|
|
1037
1445
|
});
|
|
1038
1446
|
}
|
|
1447
|
+
function Row(props) {
|
|
1448
|
+
const {
|
|
1449
|
+
row
|
|
1450
|
+
} = props;
|
|
1451
|
+
const {
|
|
1452
|
+
id
|
|
1453
|
+
} = row;
|
|
1454
|
+
const classes = [DROP_CONTAINER_HORIZONTAL_CLS];
|
|
1455
|
+
if (props.class) {
|
|
1456
|
+
classes.push(...props.class.split(' '));
|
|
1457
|
+
}
|
|
1458
|
+
return jsxRuntime.jsxs("div", {
|
|
1459
|
+
class: classnames(DRAG_ROW_MOVE_CLS),
|
|
1460
|
+
children: [jsxRuntime.jsx("span", {
|
|
1461
|
+
class: "fjs-row-dragger",
|
|
1462
|
+
children: jsxRuntime.jsx(DraggableIcon, {})
|
|
1463
|
+
}), jsxRuntime.jsx("div", {
|
|
1464
|
+
class: classes.join(' '),
|
|
1465
|
+
"data-row-id": id,
|
|
1466
|
+
children: props.children
|
|
1467
|
+
})]
|
|
1468
|
+
});
|
|
1469
|
+
}
|
|
1470
|
+
function Column(props) {
|
|
1471
|
+
const {
|
|
1472
|
+
field
|
|
1473
|
+
} = props;
|
|
1474
|
+
const classes = [DRAG_MOVE_CLS];
|
|
1475
|
+
if (field.type === 'default') {
|
|
1476
|
+
return props.children;
|
|
1477
|
+
}
|
|
1478
|
+
if (props.class) {
|
|
1479
|
+
classes.push(...props.class.split(' '));
|
|
1480
|
+
}
|
|
1481
|
+
return jsxRuntime.jsx("div", {
|
|
1482
|
+
"data-field-type": field.type,
|
|
1483
|
+
class: classes.join(' '),
|
|
1484
|
+
children: props.children
|
|
1485
|
+
});
|
|
1486
|
+
}
|
|
1039
1487
|
function FormEditor$1(props) {
|
|
1040
|
-
const
|
|
1488
|
+
const dragging = useService$1('dragging'),
|
|
1489
|
+
eventBus = useService$1('eventBus'),
|
|
1041
1490
|
formEditor = useService$1('formEditor'),
|
|
1042
|
-
formFieldRegistry = useService$1('formFieldRegistry'),
|
|
1043
1491
|
injector = useService$1('injector'),
|
|
1044
|
-
modeling = useService$1('modeling'),
|
|
1045
1492
|
selection = useService$1('selection'),
|
|
1046
1493
|
palette = useService$1('palette'),
|
|
1047
1494
|
paletteConfig = useService$1('config.palette'),
|
|
@@ -1050,6 +1497,7 @@ function FormEditor$1(props) {
|
|
|
1050
1497
|
const {
|
|
1051
1498
|
schema
|
|
1052
1499
|
} = formEditor._getState();
|
|
1500
|
+
const formContainerRef = hooks$1.useRef(null);
|
|
1053
1501
|
const paletteRef = hooks$1.useRef(null);
|
|
1054
1502
|
const propertiesPanelRef = hooks$1.useRef(null);
|
|
1055
1503
|
const [, setSelection] = hooks$1.useState(schema);
|
|
@@ -1068,98 +1516,12 @@ function FormEditor$1(props) {
|
|
|
1068
1516
|
drake
|
|
1069
1517
|
};
|
|
1070
1518
|
hooks$1.useEffect(() => {
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
return el.classList.contains('fjs-drag-container');
|
|
1078
|
-
},
|
|
1079
|
-
copy(el) {
|
|
1080
|
-
return el.classList.contains('fjs-drag-copy');
|
|
1081
|
-
},
|
|
1082
|
-
accepts(el, target) {
|
|
1083
|
-
return !target.classList.contains('fjs-no-drop');
|
|
1084
|
-
},
|
|
1085
|
-
slideFactorX: 10,
|
|
1086
|
-
slideFactorY: 5
|
|
1087
|
-
});
|
|
1088
|
-
|
|
1089
|
-
// bind life cycle events
|
|
1090
|
-
dragulaInstance.on('drag', (element, source) => {
|
|
1091
|
-
handleDragEvent('drag.start', {
|
|
1092
|
-
element,
|
|
1093
|
-
source
|
|
1094
|
-
});
|
|
1095
|
-
});
|
|
1096
|
-
dragulaInstance.on('dragend', element => {
|
|
1097
|
-
handleDragEvent('drag.end', {
|
|
1098
|
-
element
|
|
1099
|
-
});
|
|
1100
|
-
});
|
|
1101
|
-
dragulaInstance.on('drop', (element, target, source, sibling) => {
|
|
1102
|
-
handleDragEvent('drag.drop', {
|
|
1103
|
-
element,
|
|
1104
|
-
target,
|
|
1105
|
-
source,
|
|
1106
|
-
sibling
|
|
1107
|
-
});
|
|
1108
|
-
});
|
|
1109
|
-
dragulaInstance.on('over', (element, container, source) => {
|
|
1110
|
-
handleDragEvent('drag.hover', {
|
|
1111
|
-
element,
|
|
1112
|
-
container,
|
|
1113
|
-
source
|
|
1114
|
-
});
|
|
1115
|
-
});
|
|
1116
|
-
dragulaInstance.on('out', (element, container, source) => {
|
|
1117
|
-
handleDragEvent('drag.out', {
|
|
1118
|
-
element,
|
|
1119
|
-
container,
|
|
1120
|
-
source
|
|
1121
|
-
});
|
|
1122
|
-
});
|
|
1123
|
-
dragulaInstance.on('cancel', (element, container, source) => {
|
|
1124
|
-
handleDragEvent('drag.cancel', {
|
|
1125
|
-
element,
|
|
1126
|
-
container,
|
|
1127
|
-
source
|
|
1128
|
-
});
|
|
1129
|
-
});
|
|
1130
|
-
|
|
1131
|
-
// set custom styling
|
|
1132
|
-
dragulaInstance.on('drag', () => {
|
|
1133
|
-
set('grabbing');
|
|
1134
|
-
});
|
|
1135
|
-
dragulaInstance.on('dragend', () => {
|
|
1136
|
-
unset();
|
|
1137
|
-
});
|
|
1138
|
-
dragulaInstance.on('drop', (el, target, source, sibling) => {
|
|
1139
|
-
dragulaInstance.remove();
|
|
1140
|
-
if (!target) {
|
|
1141
|
-
return;
|
|
1142
|
-
}
|
|
1143
|
-
const targetFormField = formFieldRegistry.get(target.dataset.id);
|
|
1144
|
-
const siblingFormField = sibling && formFieldRegistry.get(sibling.dataset.id),
|
|
1145
|
-
targetIndex = siblingFormField ? getFormFieldIndex(targetFormField, siblingFormField) : targetFormField.components.length;
|
|
1146
|
-
if (source.classList.contains('fjs-palette-fields')) {
|
|
1147
|
-
const type = el.dataset.fieldType;
|
|
1148
|
-
modeling.addFormField({
|
|
1149
|
-
type
|
|
1150
|
-
}, targetFormField, targetIndex);
|
|
1151
|
-
} else {
|
|
1152
|
-
const formField = formFieldRegistry.get(el.dataset.id),
|
|
1153
|
-
sourceFormField = formFieldRegistry.get(source.dataset.id),
|
|
1154
|
-
sourceIndex = getFormFieldIndex(sourceFormField, formField);
|
|
1155
|
-
modeling.moveFormField(formField, sourceFormField, targetFormField, sourceIndex, targetIndex);
|
|
1156
|
-
}
|
|
1157
|
-
});
|
|
1158
|
-
eventBus.fire('dragula.created');
|
|
1159
|
-
setDrake(dragulaInstance);
|
|
1160
|
-
return dragulaInstance;
|
|
1161
|
-
};
|
|
1162
|
-
let dragulaInstance = createDragulaInstance();
|
|
1519
|
+
let dragulaInstance = dragging.createDragulaInstance({
|
|
1520
|
+
container: [DRAG_CONTAINER_CLS, DROP_CONTAINER_VERTICAL_CLS, DROP_CONTAINER_HORIZONTAL_CLS],
|
|
1521
|
+
direction: 'vertical',
|
|
1522
|
+
mirrorContainer: formContainerRef.current
|
|
1523
|
+
});
|
|
1524
|
+
setDrake(dragulaInstance);
|
|
1163
1525
|
const onDetach = () => {
|
|
1164
1526
|
if (dragulaInstance) {
|
|
1165
1527
|
dragulaInstance.destroy();
|
|
@@ -1168,14 +1530,34 @@ function FormEditor$1(props) {
|
|
|
1168
1530
|
};
|
|
1169
1531
|
const onAttach = () => {
|
|
1170
1532
|
onDetach();
|
|
1171
|
-
dragulaInstance = createDragulaInstance(
|
|
1533
|
+
dragulaInstance = dragging.createDragulaInstance({
|
|
1534
|
+
container: [DRAG_CONTAINER_CLS, DROP_CONTAINER_VERTICAL_CLS, DROP_CONTAINER_HORIZONTAL_CLS],
|
|
1535
|
+
direction: 'vertical',
|
|
1536
|
+
mirrorContainer: formContainerRef.current
|
|
1537
|
+
});
|
|
1538
|
+
setDrake(dragulaInstance);
|
|
1539
|
+
};
|
|
1540
|
+
const onCreate = drake => {
|
|
1541
|
+
setDrake(drake);
|
|
1542
|
+
};
|
|
1543
|
+
const onDragStart = () => {
|
|
1544
|
+
set('grabbing');
|
|
1545
|
+
};
|
|
1546
|
+
const onDragEnd = () => {
|
|
1547
|
+
unset();
|
|
1172
1548
|
};
|
|
1173
1549
|
eventBus.on('attach', onAttach);
|
|
1174
1550
|
eventBus.on('detach', onDetach);
|
|
1551
|
+
eventBus.on('dragula.created', onCreate);
|
|
1552
|
+
eventBus.on('drag.start', onDragStart);
|
|
1553
|
+
eventBus.on('drag.end', onDragEnd);
|
|
1175
1554
|
return () => {
|
|
1176
1555
|
onDetach();
|
|
1177
1556
|
eventBus.off('attach', onAttach);
|
|
1178
1557
|
eventBus.off('detach', onDetach);
|
|
1558
|
+
eventBus.off('dragula.created', onCreate);
|
|
1559
|
+
eventBus.off('drag.start', onDragStart);
|
|
1560
|
+
eventBus.off('drag.end', onDragEnd);
|
|
1179
1561
|
};
|
|
1180
1562
|
}, []);
|
|
1181
1563
|
|
|
@@ -1185,8 +1567,10 @@ function FormEditor$1(props) {
|
|
|
1185
1567
|
}, []);
|
|
1186
1568
|
const formRenderContext = {
|
|
1187
1569
|
Children,
|
|
1570
|
+
Column,
|
|
1188
1571
|
Element,
|
|
1189
|
-
Empty
|
|
1572
|
+
Empty,
|
|
1573
|
+
Row
|
|
1190
1574
|
};
|
|
1191
1575
|
const formContext = {
|
|
1192
1576
|
getService(type, strict = true) {
|
|
@@ -1235,6 +1619,7 @@ function FormEditor$1(props) {
|
|
|
1235
1619
|
class: "fjs-editor-palette-container",
|
|
1236
1620
|
ref: paletteRef
|
|
1237
1621
|
}), jsxRuntime.jsx("div", {
|
|
1622
|
+
ref: formContainerRef,
|
|
1238
1623
|
class: "fjs-form-container",
|
|
1239
1624
|
children: jsxRuntime.jsx(formJsViewer.FormContext.Provider, {
|
|
1240
1625
|
value: formContext,
|
|
@@ -1270,29 +1655,39 @@ function CreatePreview(props) {
|
|
|
1270
1655
|
} = hooks$1.useContext(DragAndDropContext$1);
|
|
1271
1656
|
function handleCloned(clone, original, type) {
|
|
1272
1657
|
const fieldType = clone.dataset.fieldType;
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
label
|
|
1276
|
-
} = findPaletteEntry(fieldType);
|
|
1658
|
+
|
|
1659
|
+
// (1) field preview
|
|
1277
1660
|
if (fieldType) {
|
|
1661
|
+
const {
|
|
1662
|
+
label
|
|
1663
|
+
} = findPaletteEntry(fieldType);
|
|
1664
|
+
const Icon = formJsViewer.iconsByType(fieldType);
|
|
1278
1665
|
clone.innerHTML = '';
|
|
1279
1666
|
clone.class = 'gu-mirror';
|
|
1667
|
+
clone.classList.add('fjs-field-preview-container');
|
|
1280
1668
|
if (original.classList.contains('fjs-palette-field')) {
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
children: [jsxRuntime.jsx(Icon, {
|
|
1284
|
-
class: "fjs-palette-field-icon",
|
|
1285
|
-
width: "36",
|
|
1286
|
-
height: "36",
|
|
1287
|
-
viewBox: "0 0 54 54"
|
|
1288
|
-
}), jsxRuntime.jsx("span", {
|
|
1289
|
-
class: "fjs-palette-field-text",
|
|
1290
|
-
children: label
|
|
1291
|
-
})]
|
|
1292
|
-
}), clone);
|
|
1293
|
-
} else {
|
|
1294
|
-
preact.render(jsxRuntime.jsx(Icon, {}), clone);
|
|
1669
|
+
// default to auto columns when creating from palette
|
|
1670
|
+
clone.classList.add('cds--col');
|
|
1295
1671
|
}
|
|
1672
|
+
|
|
1673
|
+
// todo(pinussilvestrus): dragula, how to mitigate cursor position
|
|
1674
|
+
// https://github.com/bevacqua/dragula/issues/285
|
|
1675
|
+
preact.render(jsxRuntime.jsx(FieldDragPreview, {
|
|
1676
|
+
label: label,
|
|
1677
|
+
Icon: Icon
|
|
1678
|
+
}), clone);
|
|
1679
|
+
} else {
|
|
1680
|
+
// (2) row preview
|
|
1681
|
+
|
|
1682
|
+
// remove elements from copy (context pad, row dragger, ...)
|
|
1683
|
+
['fjs-context-pad', 'fjs-row-dragger', 'fjs-debug-columns'].forEach(cls => {
|
|
1684
|
+
const cloneNode = clone.querySelectorAll('.' + cls);
|
|
1685
|
+
cloneNode.length && cloneNode.forEach(e => e.remove());
|
|
1686
|
+
});
|
|
1687
|
+
|
|
1688
|
+
// mirror grid
|
|
1689
|
+
clone.classList.add('cds--grid');
|
|
1690
|
+
clone.classList.add('cds--grid--condensed');
|
|
1296
1691
|
}
|
|
1297
1692
|
}
|
|
1298
1693
|
hooks$1.useEffect(() => {
|
|
@@ -1365,10 +1760,12 @@ var renderModule = {
|
|
|
1365
1760
|
|
|
1366
1761
|
var core = {
|
|
1367
1762
|
__depends__: [importModule, renderModule],
|
|
1763
|
+
debounce: ['factory', DebounceFactory],
|
|
1368
1764
|
eventBus: ['type', EventBus],
|
|
1369
1765
|
formFieldRegistry: ['type', FormFieldRegistry],
|
|
1370
|
-
|
|
1371
|
-
|
|
1766
|
+
formLayouter: ['type', formJsViewer.FormLayouter],
|
|
1767
|
+
formLayoutValidator: ['type', FormLayoutValidator],
|
|
1768
|
+
fieldFactory: ['type', FieldFactory]
|
|
1372
1769
|
};
|
|
1373
1770
|
|
|
1374
1771
|
var NOT_REGISTERED_ERROR = 'is not a registered action',
|
|
@@ -1646,6 +2043,11 @@ var EditorActionsModule = {
|
|
|
1646
2043
|
editorActions: ['type', FormEditorActions]
|
|
1647
2044
|
};
|
|
1648
2045
|
|
|
2046
|
+
var DraggingModule = {
|
|
2047
|
+
__init__: ['dragging'],
|
|
2048
|
+
dragging: ['type', Dragging]
|
|
2049
|
+
};
|
|
2050
|
+
|
|
1649
2051
|
var KEYS_COPY = ['c', 'C', 'KeyC'];
|
|
1650
2052
|
var KEYS_PASTE = ['v', 'V', 'KeyV'];
|
|
1651
2053
|
var KEYS_REDO$1 = ['y', 'Y', 'KeyY'];
|
|
@@ -2058,6 +2460,13 @@ function updatePath(formFieldRegistry, formField, index) {
|
|
|
2058
2460
|
formField._path = [...parent._path, 'components', index];
|
|
2059
2461
|
return formField;
|
|
2060
2462
|
}
|
|
2463
|
+
function updateRow(formField, rowId) {
|
|
2464
|
+
formField.layout = {
|
|
2465
|
+
...(formField.layout || {}),
|
|
2466
|
+
row: rowId
|
|
2467
|
+
};
|
|
2468
|
+
return formField;
|
|
2469
|
+
}
|
|
2061
2470
|
|
|
2062
2471
|
class AddFormFieldHandler {
|
|
2063
2472
|
/**
|
|
@@ -2207,13 +2616,17 @@ class MoveFormFieldHandler {
|
|
|
2207
2616
|
sourceFormField,
|
|
2208
2617
|
targetFormField,
|
|
2209
2618
|
sourceIndex,
|
|
2210
|
-
targetIndex
|
|
2619
|
+
targetIndex,
|
|
2620
|
+
sourceRow,
|
|
2621
|
+
targetRow
|
|
2211
2622
|
} = context;
|
|
2212
2623
|
this.moveFormField({
|
|
2213
2624
|
sourceFormField: targetFormField,
|
|
2214
2625
|
targetFormField: sourceFormField,
|
|
2215
2626
|
sourceIndex: targetIndex,
|
|
2216
|
-
targetIndex: sourceIndex
|
|
2627
|
+
targetIndex: sourceIndex,
|
|
2628
|
+
sourceRow: targetRow,
|
|
2629
|
+
targetRow: sourceRow
|
|
2217
2630
|
}, true);
|
|
2218
2631
|
}
|
|
2219
2632
|
moveFormField(context, revert) {
|
|
@@ -2221,7 +2634,8 @@ class MoveFormFieldHandler {
|
|
|
2221
2634
|
sourceFormField,
|
|
2222
2635
|
targetFormField,
|
|
2223
2636
|
sourceIndex,
|
|
2224
|
-
targetIndex
|
|
2637
|
+
targetIndex,
|
|
2638
|
+
targetRow
|
|
2225
2639
|
} = context;
|
|
2226
2640
|
let {
|
|
2227
2641
|
schema
|
|
@@ -2237,11 +2651,15 @@ class MoveFormFieldHandler {
|
|
|
2237
2651
|
targetIndex--;
|
|
2238
2652
|
}
|
|
2239
2653
|
}
|
|
2654
|
+
const formField = minDash.get(schema, [...sourcePath, sourceIndex]);
|
|
2655
|
+
|
|
2656
|
+
// (1) Add to row
|
|
2657
|
+
updateRow(formField, targetRow ? targetRow.id : null);
|
|
2240
2658
|
|
|
2241
|
-
// (
|
|
2659
|
+
// (2) Move form field
|
|
2242
2660
|
arrayMove.mutate(minDash.get(schema, sourcePath), sourceIndex, targetIndex);
|
|
2243
2661
|
|
|
2244
|
-
// (
|
|
2662
|
+
// (3) Update paths of new form field and its siblings
|
|
2245
2663
|
minDash.get(schema, sourcePath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
2246
2664
|
} else {
|
|
2247
2665
|
const formField = minDash.get(schema, [...sourcePath, sourceIndex]);
|
|
@@ -2254,10 +2672,13 @@ class MoveFormFieldHandler {
|
|
|
2254
2672
|
minDash.get(schema, sourcePath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
2255
2673
|
const targetPath = [...targetFormField._path, 'components'];
|
|
2256
2674
|
|
|
2257
|
-
// (3) Add
|
|
2675
|
+
// (3) Add to row
|
|
2676
|
+
updateRow(formField, targetRow ? targetRow.id : null);
|
|
2677
|
+
|
|
2678
|
+
// (4) Add form field
|
|
2258
2679
|
arrayAdd$1(minDash.get(schema, targetPath), targetIndex, formField);
|
|
2259
2680
|
|
|
2260
|
-
// (
|
|
2681
|
+
// (5) Update paths of siblings
|
|
2261
2682
|
minDash.get(schema, targetPath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
|
|
2262
2683
|
}
|
|
2263
2684
|
|
|
@@ -2449,13 +2870,15 @@ class Modeling {
|
|
|
2449
2870
|
};
|
|
2450
2871
|
this._commandStack.execute('formField.edit', context);
|
|
2451
2872
|
}
|
|
2452
|
-
moveFormField(formField, sourceFormField, targetFormField, sourceIndex, targetIndex) {
|
|
2873
|
+
moveFormField(formField, sourceFormField, targetFormField, sourceIndex, targetIndex, sourceRow, targetRow) {
|
|
2453
2874
|
const context = {
|
|
2454
2875
|
formField,
|
|
2455
2876
|
sourceFormField,
|
|
2456
2877
|
targetFormField,
|
|
2457
2878
|
sourceIndex,
|
|
2458
|
-
targetIndex
|
|
2879
|
+
targetIndex,
|
|
2880
|
+
sourceRow,
|
|
2881
|
+
targetRow
|
|
2459
2882
|
};
|
|
2460
2883
|
this._commandStack.execute('formField.move', context);
|
|
2461
2884
|
}
|
|
@@ -2614,6 +3037,44 @@ minDash.forEach(hooks, function (hook) {
|
|
|
2614
3037
|
};
|
|
2615
3038
|
});
|
|
2616
3039
|
|
|
3040
|
+
class FormLayoutUpdater extends CommandInterceptor {
|
|
3041
|
+
constructor(eventBus, formLayouter, modeling, formEditor) {
|
|
3042
|
+
super(eventBus);
|
|
3043
|
+
this._eventBus = eventBus;
|
|
3044
|
+
this._formLayouter = formLayouter;
|
|
3045
|
+
this._modeling = modeling;
|
|
3046
|
+
this._formEditor = formEditor;
|
|
3047
|
+
|
|
3048
|
+
// @ts-ignore
|
|
3049
|
+
this.preExecute(['formField.add', 'formField.remove', 'formField.move', 'id.updateClaim'], event => this.updateRowIds(event));
|
|
3050
|
+
|
|
3051
|
+
// we need that as the state got updates
|
|
3052
|
+
// on the next tick (not in post execute)
|
|
3053
|
+
eventBus.on('changed', context => {
|
|
3054
|
+
const {
|
|
3055
|
+
schema
|
|
3056
|
+
} = context;
|
|
3057
|
+
this.updateLayout(schema);
|
|
3058
|
+
});
|
|
3059
|
+
}
|
|
3060
|
+
updateLayout(schema) {
|
|
3061
|
+
this._formLayouter.clear();
|
|
3062
|
+
this._formLayouter.calculateLayout(formJsViewer.clone(schema));
|
|
3063
|
+
}
|
|
3064
|
+
updateRowIds(event) {
|
|
3065
|
+
const {
|
|
3066
|
+
schema
|
|
3067
|
+
} = this._formEditor._getState();
|
|
3068
|
+
|
|
3069
|
+
// make sure rows are persisted in schema (e.g. for migration case)
|
|
3070
|
+
schema.components.forEach(formField => {
|
|
3071
|
+
const row = this._formLayouter.getRowForField(formField);
|
|
3072
|
+
updateRow(formField, row.id);
|
|
3073
|
+
});
|
|
3074
|
+
}
|
|
3075
|
+
}
|
|
3076
|
+
FormLayoutUpdater.$inject = ['eventBus', 'formLayouter', 'modeling', 'formEditor'];
|
|
3077
|
+
|
|
2617
3078
|
class IdBehavior extends CommandInterceptor {
|
|
2618
3079
|
constructor(eventBus, modeling) {
|
|
2619
3080
|
super(eventBus);
|
|
@@ -3135,7 +3596,8 @@ var commandModule = {
|
|
|
3135
3596
|
|
|
3136
3597
|
var ModelingModule = {
|
|
3137
3598
|
__depends__: [behaviorModule, commandModule],
|
|
3138
|
-
__init__: ['modeling'],
|
|
3599
|
+
__init__: ['formLayoutUpdater', 'modeling'],
|
|
3600
|
+
formLayoutUpdater: ['type', FormLayoutUpdater],
|
|
3139
3601
|
modeling: ['type', Modeling]
|
|
3140
3602
|
};
|
|
3141
3603
|
|
|
@@ -3431,19 +3893,19 @@ const ErrorsContext = preact.createContext({
|
|
|
3431
3893
|
errors: {}
|
|
3432
3894
|
});
|
|
3433
3895
|
|
|
3434
|
-
/**
|
|
3435
|
-
* @typedef {Function} <propertiesPanel.showEntry> callback
|
|
3436
|
-
*
|
|
3437
|
-
* @example
|
|
3438
|
-
*
|
|
3439
|
-
* useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
|
|
3440
|
-
* // ...
|
|
3441
|
-
* });
|
|
3442
|
-
*
|
|
3443
|
-
* @param {Object} context
|
|
3444
|
-
* @param {boolean} [context.focus]
|
|
3445
|
-
*
|
|
3446
|
-
* @returns void
|
|
3896
|
+
/**
|
|
3897
|
+
* @typedef {Function} <propertiesPanel.showEntry> callback
|
|
3898
|
+
*
|
|
3899
|
+
* @example
|
|
3900
|
+
*
|
|
3901
|
+
* useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
|
|
3902
|
+
* // ...
|
|
3903
|
+
* });
|
|
3904
|
+
*
|
|
3905
|
+
* @param {Object} context
|
|
3906
|
+
* @param {boolean} [context.focus]
|
|
3907
|
+
*
|
|
3908
|
+
* @returns void
|
|
3447
3909
|
*/
|
|
3448
3910
|
const EventContext = preact.createContext({
|
|
3449
3911
|
eventBus: null
|
|
@@ -3455,20 +3917,20 @@ const LayoutContext = preact.createContext({
|
|
|
3455
3917
|
setLayoutForKey: () => {}
|
|
3456
3918
|
});
|
|
3457
3919
|
|
|
3458
|
-
/**
|
|
3459
|
-
* Accesses the global DescriptionContext and returns a description for a given id and element.
|
|
3460
|
-
*
|
|
3461
|
-
* @example
|
|
3462
|
-
* ```jsx
|
|
3463
|
-
* function TextField(props) {
|
|
3464
|
-
* const description = useDescriptionContext('input1', element);
|
|
3465
|
-
* }
|
|
3466
|
-
* ```
|
|
3467
|
-
*
|
|
3468
|
-
* @param {string} id
|
|
3469
|
-
* @param {object} element
|
|
3470
|
-
*
|
|
3471
|
-
* @returns {string}
|
|
3920
|
+
/**
|
|
3921
|
+
* Accesses the global DescriptionContext and returns a description for a given id and element.
|
|
3922
|
+
*
|
|
3923
|
+
* @example
|
|
3924
|
+
* ```jsx
|
|
3925
|
+
* function TextField(props) {
|
|
3926
|
+
* const description = useDescriptionContext('input1', element);
|
|
3927
|
+
* }
|
|
3928
|
+
* ```
|
|
3929
|
+
*
|
|
3930
|
+
* @param {string} id
|
|
3931
|
+
* @param {object} element
|
|
3932
|
+
*
|
|
3933
|
+
* @returns {string}
|
|
3472
3934
|
*/
|
|
3473
3935
|
function useDescriptionContext(id, element) {
|
|
3474
3936
|
const {
|
|
@@ -3483,11 +3945,11 @@ function useError(id) {
|
|
|
3483
3945
|
return errors[id];
|
|
3484
3946
|
}
|
|
3485
3947
|
|
|
3486
|
-
/**
|
|
3487
|
-
* Subscribe to an event immediately. Update subscription after inputs changed.
|
|
3488
|
-
*
|
|
3489
|
-
* @param {string} event
|
|
3490
|
-
* @param {Function} callback
|
|
3948
|
+
/**
|
|
3949
|
+
* Subscribe to an event immediately. Update subscription after inputs changed.
|
|
3950
|
+
*
|
|
3951
|
+
* @param {string} event
|
|
3952
|
+
* @param {Function} callback
|
|
3491
3953
|
*/
|
|
3492
3954
|
function useEvent(event, callback, eventBus) {
|
|
3493
3955
|
const eventContext = hooks$1.useContext(EventContext);
|
|
@@ -3517,20 +3979,20 @@ function useEvent(event, callback, eventBus) {
|
|
|
3517
3979
|
}, [callback, event, eventBus]);
|
|
3518
3980
|
}
|
|
3519
3981
|
|
|
3520
|
-
/**
|
|
3521
|
-
* Creates a state that persists in the global LayoutContext.
|
|
3522
|
-
*
|
|
3523
|
-
* @example
|
|
3524
|
-
* ```jsx
|
|
3525
|
-
* function Group(props) {
|
|
3526
|
-
* const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
|
|
3527
|
-
* }
|
|
3528
|
-
* ```
|
|
3529
|
-
*
|
|
3530
|
-
* @param {(string|number)[]} path
|
|
3531
|
-
* @param {any} [defaultValue]
|
|
3532
|
-
*
|
|
3533
|
-
* @returns {[ any, Function ]}
|
|
3982
|
+
/**
|
|
3983
|
+
* Creates a state that persists in the global LayoutContext.
|
|
3984
|
+
*
|
|
3985
|
+
* @example
|
|
3986
|
+
* ```jsx
|
|
3987
|
+
* function Group(props) {
|
|
3988
|
+
* const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
|
|
3989
|
+
* }
|
|
3990
|
+
* ```
|
|
3991
|
+
*
|
|
3992
|
+
* @param {(string|number)[]} path
|
|
3993
|
+
* @param {any} [defaultValue]
|
|
3994
|
+
*
|
|
3995
|
+
* @returns {[ any, Function ]}
|
|
3534
3996
|
*/
|
|
3535
3997
|
function useLayoutState(path, defaultValue) {
|
|
3536
3998
|
const {
|
|
@@ -3538,22 +4000,17 @@ function useLayoutState(path, defaultValue) {
|
|
|
3538
4000
|
setLayoutForKey
|
|
3539
4001
|
} = hooks$1.useContext(LayoutContext);
|
|
3540
4002
|
const layoutForKey = getLayoutForKey(path, defaultValue);
|
|
3541
|
-
const
|
|
3542
|
-
const setState = newValue => {
|
|
3543
|
-
// (1) set component state
|
|
3544
|
-
set(newValue);
|
|
3545
|
-
|
|
3546
|
-
// (2) set context
|
|
4003
|
+
const setState = hooks$1.useCallback(newValue => {
|
|
3547
4004
|
setLayoutForKey(path, newValue);
|
|
3548
|
-
};
|
|
3549
|
-
return [
|
|
4005
|
+
}, [setLayoutForKey]);
|
|
4006
|
+
return [layoutForKey, setState];
|
|
3550
4007
|
}
|
|
3551
4008
|
|
|
3552
|
-
/**
|
|
3553
|
-
* @pinussilvestrus: we need to introduce our own hook to persist the previous
|
|
3554
|
-
* state on updates.
|
|
3555
|
-
*
|
|
3556
|
-
* cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
|
|
4009
|
+
/**
|
|
4010
|
+
* @pinussilvestrus: we need to introduce our own hook to persist the previous
|
|
4011
|
+
* state on updates.
|
|
4012
|
+
*
|
|
4013
|
+
* cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
|
|
3557
4014
|
*/
|
|
3558
4015
|
|
|
3559
4016
|
function usePrevious(value) {
|
|
@@ -3564,12 +4021,12 @@ function usePrevious(value) {
|
|
|
3564
4021
|
return ref.current;
|
|
3565
4022
|
}
|
|
3566
4023
|
|
|
3567
|
-
/**
|
|
3568
|
-
* Subscribe to `propertiesPanel.showEntry`.
|
|
3569
|
-
*
|
|
3570
|
-
* @param {string} id
|
|
3571
|
-
*
|
|
3572
|
-
* @returns {import('preact').Ref}
|
|
4024
|
+
/**
|
|
4025
|
+
* Subscribe to `propertiesPanel.showEntry`.
|
|
4026
|
+
*
|
|
4027
|
+
* @param {string} id
|
|
4028
|
+
*
|
|
4029
|
+
* @returns {import('preact').Ref}
|
|
3573
4030
|
*/
|
|
3574
4031
|
function useShowEntryEvent(id) {
|
|
3575
4032
|
const {
|
|
@@ -3600,20 +4057,20 @@ function useShowEntryEvent(id) {
|
|
|
3600
4057
|
return ref;
|
|
3601
4058
|
}
|
|
3602
4059
|
|
|
3603
|
-
/**
|
|
3604
|
-
* @callback setSticky
|
|
3605
|
-
* @param {boolean} value
|
|
4060
|
+
/**
|
|
4061
|
+
* @callback setSticky
|
|
4062
|
+
* @param {boolean} value
|
|
3606
4063
|
*/
|
|
3607
4064
|
|
|
3608
|
-
/**
|
|
3609
|
-
* Use IntersectionObserver to identify when DOM element is in sticky mode.
|
|
3610
|
-
* If sticky is observered setSticky(true) will be called.
|
|
3611
|
-
* If sticky mode is left, setSticky(false) will be called.
|
|
3612
|
-
*
|
|
3613
|
-
*
|
|
3614
|
-
* @param {Object} ref
|
|
3615
|
-
* @param {string} scrollContainerSelector
|
|
3616
|
-
* @param {setSticky} setSticky
|
|
4065
|
+
/**
|
|
4066
|
+
* Use IntersectionObserver to identify when DOM element is in sticky mode.
|
|
4067
|
+
* If sticky is observered setSticky(true) will be called.
|
|
4068
|
+
* If sticky mode is left, setSticky(false) will be called.
|
|
4069
|
+
*
|
|
4070
|
+
*
|
|
4071
|
+
* @param {Object} ref
|
|
4072
|
+
* @param {string} scrollContainerSelector
|
|
4073
|
+
* @param {setSticky} setSticky
|
|
3617
4074
|
*/
|
|
3618
4075
|
function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky) {
|
|
3619
4076
|
hooks$1.useEffect(() => {
|
|
@@ -3652,19 +4109,19 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
|
|
|
3652
4109
|
}, [ref, scrollContainerSelector, setSticky]);
|
|
3653
4110
|
}
|
|
3654
4111
|
|
|
3655
|
-
/**
|
|
3656
|
-
* Creates a static function reference with changing body.
|
|
3657
|
-
* This is necessary when external libraries require a callback function
|
|
3658
|
-
* that has references to state variables.
|
|
3659
|
-
*
|
|
3660
|
-
* Usage:
|
|
3661
|
-
* const callback = useStaticCallback((val) => {val === currentState});
|
|
3662
|
-
*
|
|
3663
|
-
* The `callback` reference is static and can be safely used in external
|
|
3664
|
-
* libraries or as a prop that does not cause rerendering of children.
|
|
3665
|
-
*
|
|
3666
|
-
* @param {Function} callback function with changing reference
|
|
3667
|
-
* @returns {Function} static function reference
|
|
4112
|
+
/**
|
|
4113
|
+
* Creates a static function reference with changing body.
|
|
4114
|
+
* This is necessary when external libraries require a callback function
|
|
4115
|
+
* that has references to state variables.
|
|
4116
|
+
*
|
|
4117
|
+
* Usage:
|
|
4118
|
+
* const callback = useStaticCallback((val) => {val === currentState});
|
|
4119
|
+
*
|
|
4120
|
+
* The `callback` reference is static and can be safely used in external
|
|
4121
|
+
* libraries or as a prop that does not cause rerendering of children.
|
|
4122
|
+
*
|
|
4123
|
+
* @param {Function} callback function with changing reference
|
|
4124
|
+
* @returns {Function} static function reference
|
|
3668
4125
|
*/
|
|
3669
4126
|
function useStaticCallback(callback) {
|
|
3670
4127
|
const callbackRef = hooks$1.useRef(callback);
|
|
@@ -3756,13 +4213,13 @@ function DataMarker() {
|
|
|
3756
4213
|
});
|
|
3757
4214
|
}
|
|
3758
4215
|
|
|
3759
|
-
/**
|
|
3760
|
-
* @typedef { {
|
|
3761
|
-
* text: (element: object) => string,
|
|
3762
|
-
* icon?: (element: Object) => import('preact').Component
|
|
3763
|
-
* } } PlaceholderDefinition
|
|
3764
|
-
*
|
|
3765
|
-
* @param { PlaceholderDefinition } props
|
|
4216
|
+
/**
|
|
4217
|
+
* @typedef { {
|
|
4218
|
+
* text: (element: object) => string,
|
|
4219
|
+
* icon?: (element: Object) => import('preact').Component
|
|
4220
|
+
* } } PlaceholderDefinition
|
|
4221
|
+
*
|
|
4222
|
+
* @param { PlaceholderDefinition } props
|
|
3766
4223
|
*/
|
|
3767
4224
|
function Placeholder(props) {
|
|
3768
4225
|
const {
|
|
@@ -3787,72 +4244,72 @@ const DEFAULT_LAYOUT = {
|
|
|
3787
4244
|
};
|
|
3788
4245
|
const DEFAULT_DESCRIPTION = {};
|
|
3789
4246
|
|
|
3790
|
-
/**
|
|
3791
|
-
* @typedef { {
|
|
3792
|
-
* component: import('preact').Component,
|
|
3793
|
-
* id: String,
|
|
3794
|
-
* isEdited?: Function
|
|
3795
|
-
* } } EntryDefinition
|
|
3796
|
-
*
|
|
3797
|
-
* @typedef { {
|
|
3798
|
-
* autoFocusEntry: String,
|
|
3799
|
-
* autoOpen?: Boolean,
|
|
3800
|
-
* entries: Array<EntryDefinition>,
|
|
3801
|
-
* id: String,
|
|
3802
|
-
* label: String,
|
|
3803
|
-
* remove: (event: MouseEvent) => void
|
|
3804
|
-
* } } ListItemDefinition
|
|
3805
|
-
*
|
|
3806
|
-
* @typedef { {
|
|
3807
|
-
* add: (event: MouseEvent) => void,
|
|
3808
|
-
* component: import('preact').Component,
|
|
3809
|
-
* element: Object,
|
|
3810
|
-
* id: String,
|
|
3811
|
-
* items: Array<ListItemDefinition>,
|
|
3812
|
-
* label: String,
|
|
3813
|
-
* shouldSort?: Boolean,
|
|
3814
|
-
* shouldOpen?: Boolean
|
|
3815
|
-
* } } ListGroupDefinition
|
|
3816
|
-
*
|
|
3817
|
-
* @typedef { {
|
|
3818
|
-
* component?: import('preact').Component,
|
|
3819
|
-
* entries: Array<EntryDefinition>,
|
|
3820
|
-
* id: String,
|
|
3821
|
-
* label: String,
|
|
3822
|
-
* shouldOpen?: Boolean
|
|
3823
|
-
* } } GroupDefinition
|
|
3824
|
-
*
|
|
3825
|
-
* @typedef { {
|
|
3826
|
-
* [id: String]: GetDescriptionFunction
|
|
3827
|
-
* } } DescriptionConfig
|
|
3828
|
-
*
|
|
3829
|
-
* @callback { {
|
|
3830
|
-
* @param {string} id
|
|
3831
|
-
* @param {Object} element
|
|
3832
|
-
* @returns {string}
|
|
3833
|
-
* } } GetDescriptionFunction
|
|
3834
|
-
*
|
|
3835
|
-
* @typedef { {
|
|
3836
|
-
* getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
|
|
3837
|
-
* getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
|
|
3838
|
-
* } } PlaceholderProvider
|
|
3839
|
-
*
|
|
4247
|
+
/**
|
|
4248
|
+
* @typedef { {
|
|
4249
|
+
* component: import('preact').Component,
|
|
4250
|
+
* id: String,
|
|
4251
|
+
* isEdited?: Function
|
|
4252
|
+
* } } EntryDefinition
|
|
4253
|
+
*
|
|
4254
|
+
* @typedef { {
|
|
4255
|
+
* autoFocusEntry: String,
|
|
4256
|
+
* autoOpen?: Boolean,
|
|
4257
|
+
* entries: Array<EntryDefinition>,
|
|
4258
|
+
* id: String,
|
|
4259
|
+
* label: String,
|
|
4260
|
+
* remove: (event: MouseEvent) => void
|
|
4261
|
+
* } } ListItemDefinition
|
|
4262
|
+
*
|
|
4263
|
+
* @typedef { {
|
|
4264
|
+
* add: (event: MouseEvent) => void,
|
|
4265
|
+
* component: import('preact').Component,
|
|
4266
|
+
* element: Object,
|
|
4267
|
+
* id: String,
|
|
4268
|
+
* items: Array<ListItemDefinition>,
|
|
4269
|
+
* label: String,
|
|
4270
|
+
* shouldSort?: Boolean,
|
|
4271
|
+
* shouldOpen?: Boolean
|
|
4272
|
+
* } } ListGroupDefinition
|
|
4273
|
+
*
|
|
4274
|
+
* @typedef { {
|
|
4275
|
+
* component?: import('preact').Component,
|
|
4276
|
+
* entries: Array<EntryDefinition>,
|
|
4277
|
+
* id: String,
|
|
4278
|
+
* label: String,
|
|
4279
|
+
* shouldOpen?: Boolean
|
|
4280
|
+
* } } GroupDefinition
|
|
4281
|
+
*
|
|
4282
|
+
* @typedef { {
|
|
4283
|
+
* [id: String]: GetDescriptionFunction
|
|
4284
|
+
* } } DescriptionConfig
|
|
4285
|
+
*
|
|
4286
|
+
* @callback { {
|
|
4287
|
+
* @param {string} id
|
|
4288
|
+
* @param {Object} element
|
|
4289
|
+
* @returns {string}
|
|
4290
|
+
* } } GetDescriptionFunction
|
|
4291
|
+
*
|
|
4292
|
+
* @typedef { {
|
|
4293
|
+
* getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
|
|
4294
|
+
* getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
|
|
4295
|
+
* } } PlaceholderProvider
|
|
4296
|
+
*
|
|
3840
4297
|
*/
|
|
3841
4298
|
|
|
3842
|
-
/**
|
|
3843
|
-
* A basic properties panel component. Describes *how* content will be rendered, accepts
|
|
3844
|
-
* data from implementor to describe *what* will be rendered.
|
|
3845
|
-
*
|
|
3846
|
-
* @param {Object} props
|
|
3847
|
-
* @param {Object|Array} props.element
|
|
3848
|
-
* @param {import('./components/Header').HeaderProvider} props.headerProvider
|
|
3849
|
-
* @param {PlaceholderProvider} [props.placeholderProvider]
|
|
3850
|
-
* @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
|
|
3851
|
-
* @param {Object} [props.layoutConfig]
|
|
3852
|
-
* @param {Function} [props.layoutChanged]
|
|
3853
|
-
* @param {DescriptionConfig} [props.descriptionConfig]
|
|
3854
|
-
* @param {Function} [props.descriptionLoaded]
|
|
3855
|
-
* @param {Object} [props.eventBus]
|
|
4299
|
+
/**
|
|
4300
|
+
* A basic properties panel component. Describes *how* content will be rendered, accepts
|
|
4301
|
+
* data from implementor to describe *what* will be rendered.
|
|
4302
|
+
*
|
|
4303
|
+
* @param {Object} props
|
|
4304
|
+
* @param {Object|Array} props.element
|
|
4305
|
+
* @param {import('./components/Header').HeaderProvider} props.headerProvider
|
|
4306
|
+
* @param {PlaceholderProvider} [props.placeholderProvider]
|
|
4307
|
+
* @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
|
|
4308
|
+
* @param {Object} [props.layoutConfig]
|
|
4309
|
+
* @param {Function} [props.layoutChanged]
|
|
4310
|
+
* @param {DescriptionConfig} [props.descriptionConfig]
|
|
4311
|
+
* @param {Function} [props.descriptionLoaded]
|
|
4312
|
+
* @param {Object} [props.eventBus]
|
|
3856
4313
|
*/
|
|
3857
4314
|
function PropertiesPanel(props) {
|
|
3858
4315
|
const {
|
|
@@ -3860,15 +4317,21 @@ function PropertiesPanel(props) {
|
|
|
3860
4317
|
headerProvider,
|
|
3861
4318
|
placeholderProvider,
|
|
3862
4319
|
groups,
|
|
3863
|
-
layoutConfig
|
|
4320
|
+
layoutConfig,
|
|
3864
4321
|
layoutChanged,
|
|
3865
|
-
descriptionConfig
|
|
4322
|
+
descriptionConfig,
|
|
3866
4323
|
descriptionLoaded,
|
|
3867
4324
|
eventBus
|
|
3868
4325
|
} = props;
|
|
3869
4326
|
|
|
3870
4327
|
// set-up layout context
|
|
3871
4328
|
const [layout, setLayout] = hooks$1.useState(createLayout(layoutConfig));
|
|
4329
|
+
|
|
4330
|
+
// react to external changes in the layout config
|
|
4331
|
+
useUpdateEffect(() => {
|
|
4332
|
+
const newLayout = createLayout(layoutConfig);
|
|
4333
|
+
setLayout(newLayout);
|
|
4334
|
+
}, [layoutConfig]);
|
|
3872
4335
|
hooks$1.useEffect(() => {
|
|
3873
4336
|
if (typeof layoutChanged === 'function') {
|
|
3874
4337
|
layoutChanged(layout);
|
|
@@ -3890,10 +4353,12 @@ function PropertiesPanel(props) {
|
|
|
3890
4353
|
};
|
|
3891
4354
|
|
|
3892
4355
|
// set-up description context
|
|
3893
|
-
const description = createDescriptionContext(descriptionConfig);
|
|
3894
|
-
|
|
3895
|
-
descriptionLoaded
|
|
3896
|
-
|
|
4356
|
+
const description = hooks$1.useMemo(() => createDescriptionContext(descriptionConfig), [descriptionConfig]);
|
|
4357
|
+
hooks$1.useEffect(() => {
|
|
4358
|
+
if (typeof descriptionLoaded === 'function') {
|
|
4359
|
+
descriptionLoaded(description);
|
|
4360
|
+
}
|
|
4361
|
+
}, [description, descriptionLoaded]);
|
|
3897
4362
|
const getDescriptionForId = (id, element) => {
|
|
3898
4363
|
return description[id] && description[id](element);
|
|
3899
4364
|
};
|
|
@@ -3968,18 +4433,37 @@ function PropertiesPanel(props) {
|
|
|
3968
4433
|
|
|
3969
4434
|
// helpers //////////////////
|
|
3970
4435
|
|
|
3971
|
-
function createLayout(overrides) {
|
|
4436
|
+
function createLayout(overrides = {}, defaults = DEFAULT_LAYOUT) {
|
|
3972
4437
|
return {
|
|
3973
|
-
...
|
|
4438
|
+
...defaults,
|
|
3974
4439
|
...overrides
|
|
3975
4440
|
};
|
|
3976
4441
|
}
|
|
3977
|
-
function createDescriptionContext(overrides) {
|
|
4442
|
+
function createDescriptionContext(overrides = {}) {
|
|
3978
4443
|
return {
|
|
3979
4444
|
...DEFAULT_DESCRIPTION,
|
|
3980
4445
|
...overrides
|
|
3981
4446
|
};
|
|
3982
4447
|
}
|
|
4448
|
+
|
|
4449
|
+
// hooks //////////////////
|
|
4450
|
+
|
|
4451
|
+
/**
|
|
4452
|
+
* This hook behaves like useEffect, but does not trigger on the first render.
|
|
4453
|
+
*
|
|
4454
|
+
* @param {Function} effect
|
|
4455
|
+
* @param {Array} deps
|
|
4456
|
+
*/
|
|
4457
|
+
function useUpdateEffect(effect, deps) {
|
|
4458
|
+
const isMounted = hooks$1.useRef(false);
|
|
4459
|
+
hooks$1.useEffect(() => {
|
|
4460
|
+
if (isMounted.current) {
|
|
4461
|
+
return effect();
|
|
4462
|
+
} else {
|
|
4463
|
+
isMounted.current = true;
|
|
4464
|
+
}
|
|
4465
|
+
}, deps);
|
|
4466
|
+
}
|
|
3983
4467
|
function CollapsibleEntry(props) {
|
|
3984
4468
|
const {
|
|
3985
4469
|
element,
|
|
@@ -4075,10 +4559,10 @@ function ListItem(props) {
|
|
|
4075
4559
|
})
|
|
4076
4560
|
});
|
|
4077
4561
|
}
|
|
4078
|
-
const noop$
|
|
4562
|
+
const noop$3 = () => {};
|
|
4079
4563
|
|
|
4080
|
-
/**
|
|
4081
|
-
* @param {import('../PropertiesPanel').ListGroupDefinition} props
|
|
4564
|
+
/**
|
|
4565
|
+
* @param {import('../PropertiesPanel').ListGroupDefinition} props
|
|
4082
4566
|
*/
|
|
4083
4567
|
function ListGroup(props) {
|
|
4084
4568
|
const {
|
|
@@ -4096,6 +4580,9 @@ function ListGroup(props) {
|
|
|
4096
4580
|
const onShow = hooks$1.useCallback(() => setOpen(true), [setOpen]);
|
|
4097
4581
|
const [ordering, setOrdering] = hooks$1.useState([]);
|
|
4098
4582
|
const [newItemAdded, setNewItemAdded] = hooks$1.useState(false);
|
|
4583
|
+
|
|
4584
|
+
// Flag to mark that add button was clicked in the last render cycle
|
|
4585
|
+
const [addTriggered, setAddTriggered] = hooks$1.useState(false);
|
|
4099
4586
|
const prevItems = usePrevious(items);
|
|
4100
4587
|
const prevElement = usePrevious(element);
|
|
4101
4588
|
const elementChanged = element !== prevElement;
|
|
@@ -4117,6 +4604,8 @@ function ListGroup(props) {
|
|
|
4117
4604
|
|
|
4118
4605
|
// (1) items were added
|
|
4119
4606
|
hooks$1.useEffect(() => {
|
|
4607
|
+
// reset addTriggered flag
|
|
4608
|
+
setAddTriggered(false);
|
|
4120
4609
|
if (shouldHandleEffects && prevItems && items.length > prevItems.length) {
|
|
4121
4610
|
let add = [];
|
|
4122
4611
|
items.forEach(item => {
|
|
@@ -4126,14 +4615,18 @@ function ListGroup(props) {
|
|
|
4126
4615
|
});
|
|
4127
4616
|
let newOrdering = ordering;
|
|
4128
4617
|
|
|
4129
|
-
// open if not open and
|
|
4130
|
-
|
|
4618
|
+
// open if not open, configured and triggered by add button
|
|
4619
|
+
//
|
|
4620
|
+
// TODO(marstamm): remove once we refactor layout handling for listGroups.
|
|
4621
|
+
// Ideally, opening should be handled as part of the `add` callback and
|
|
4622
|
+
// not be a concern for the ListGroup component.
|
|
4623
|
+
if (addTriggered && !open && shouldOpen) {
|
|
4131
4624
|
toggleOpen();
|
|
4625
|
+
}
|
|
4132
4626
|
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
}
|
|
4627
|
+
// filter when not open and configured
|
|
4628
|
+
if (!open && shouldSort) {
|
|
4629
|
+
newOrdering = createOrdering(sortItems(items));
|
|
4137
4630
|
}
|
|
4138
4631
|
|
|
4139
4632
|
// add new items on top or bottom depending on sorting behavior
|
|
@@ -4144,11 +4637,11 @@ function ListGroup(props) {
|
|
|
4144
4637
|
newOrdering.push(...add);
|
|
4145
4638
|
}
|
|
4146
4639
|
setOrdering(newOrdering);
|
|
4147
|
-
setNewItemAdded(
|
|
4640
|
+
setNewItemAdded(addTriggered);
|
|
4148
4641
|
} else {
|
|
4149
4642
|
setNewItemAdded(false);
|
|
4150
4643
|
}
|
|
4151
|
-
}, [items, open, shouldHandleEffects]);
|
|
4644
|
+
}, [items, open, shouldHandleEffects, addTriggered]);
|
|
4152
4645
|
|
|
4153
4646
|
// (2) sort items on open if shouldSort is set
|
|
4154
4647
|
hooks$1.useEffect(() => {
|
|
@@ -4178,13 +4671,17 @@ function ListGroup(props) {
|
|
|
4178
4671
|
...hooks$1.useContext(LayoutContext),
|
|
4179
4672
|
onShow
|
|
4180
4673
|
};
|
|
4674
|
+
const handleAddClick = e => {
|
|
4675
|
+
setAddTriggered(true);
|
|
4676
|
+
add(e);
|
|
4677
|
+
};
|
|
4181
4678
|
return jsxRuntime.jsxs("div", {
|
|
4182
4679
|
class: "bio-properties-panel-group",
|
|
4183
4680
|
"data-group-id": 'group-' + id,
|
|
4184
4681
|
ref: groupRef,
|
|
4185
4682
|
children: [jsxRuntime.jsxs("div", {
|
|
4186
4683
|
class: classnames('bio-properties-panel-group-header', hasItems ? '' : 'empty', hasItems && open ? 'open' : '', sticky && open ? 'sticky' : ''),
|
|
4187
|
-
onClick: hasItems ? toggleOpen : noop$
|
|
4684
|
+
onClick: hasItems ? toggleOpen : noop$3,
|
|
4188
4685
|
children: [jsxRuntime.jsx("div", {
|
|
4189
4686
|
title: label,
|
|
4190
4687
|
class: "bio-properties-panel-group-header-title",
|
|
@@ -4194,7 +4691,7 @@ function ListGroup(props) {
|
|
|
4194
4691
|
children: [add ? jsxRuntime.jsxs("button", {
|
|
4195
4692
|
title: "Create new list item",
|
|
4196
4693
|
class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
|
|
4197
|
-
onClick:
|
|
4694
|
+
onClick: handleAddClick,
|
|
4198
4695
|
children: [jsxRuntime.jsx(CreateIcon, {}), !hasItems ? jsxRuntime.jsx("span", {
|
|
4199
4696
|
class: "bio-properties-panel-add-entry-label",
|
|
4200
4697
|
children: "Create"
|
|
@@ -4224,8 +4721,9 @@ function ListGroup(props) {
|
|
|
4224
4721
|
id
|
|
4225
4722
|
} = item;
|
|
4226
4723
|
|
|
4227
|
-
// if item was added, open
|
|
4228
|
-
|
|
4724
|
+
// if item was added, open it
|
|
4725
|
+
// Existing items will not be affected as autoOpen is only applied on first render
|
|
4726
|
+
const autoOpen = newItemAdded;
|
|
4229
4727
|
return preact.createElement(ListItem, {
|
|
4230
4728
|
...item,
|
|
4231
4729
|
autoOpen: autoOpen,
|
|
@@ -4241,8 +4739,8 @@ function ListGroup(props) {
|
|
|
4241
4739
|
|
|
4242
4740
|
// helpers ////////////////////
|
|
4243
4741
|
|
|
4244
|
-
/**
|
|
4245
|
-
* Sorts given items alphanumeric by label
|
|
4742
|
+
/**
|
|
4743
|
+
* Sorts given items alphanumeric by label
|
|
4246
4744
|
*/
|
|
4247
4745
|
function sortItems(items) {
|
|
4248
4746
|
return minDash.sortBy(items, i => i.label.toLowerCase());
|
|
@@ -4316,17 +4814,17 @@ function Checkbox(props) {
|
|
|
4316
4814
|
});
|
|
4317
4815
|
}
|
|
4318
4816
|
|
|
4319
|
-
/**
|
|
4320
|
-
* @param {Object} props
|
|
4321
|
-
* @param {Object} props.element
|
|
4322
|
-
* @param {String} props.id
|
|
4323
|
-
* @param {String} props.description
|
|
4324
|
-
* @param {String} props.label
|
|
4325
|
-
* @param {Function} props.getValue
|
|
4326
|
-
* @param {Function} props.setValue
|
|
4327
|
-
* @param {Function} props.onFocus
|
|
4328
|
-
* @param {Function} props.onBlur
|
|
4329
|
-
* @param {boolean} [props.disabled]
|
|
4817
|
+
/**
|
|
4818
|
+
* @param {Object} props
|
|
4819
|
+
* @param {Object} props.element
|
|
4820
|
+
* @param {String} props.id
|
|
4821
|
+
* @param {String} props.description
|
|
4822
|
+
* @param {String} props.label
|
|
4823
|
+
* @param {Function} props.getValue
|
|
4824
|
+
* @param {Function} props.setValue
|
|
4825
|
+
* @param {Function} props.onFocus
|
|
4826
|
+
* @param {Function} props.onBlur
|
|
4827
|
+
* @param {boolean} [props.disabled]
|
|
4330
4828
|
*/
|
|
4331
4829
|
function CheckboxEntry(props) {
|
|
4332
4830
|
const {
|
|
@@ -4363,7 +4861,7 @@ function CheckboxEntry(props) {
|
|
|
4363
4861
|
})]
|
|
4364
4862
|
});
|
|
4365
4863
|
}
|
|
4366
|
-
function isEdited$
|
|
4864
|
+
function isEdited$8(node) {
|
|
4367
4865
|
return node && !!node.checked;
|
|
4368
4866
|
}
|
|
4369
4867
|
|
|
@@ -4372,6 +4870,87 @@ function isEdited$7(node) {
|
|
|
4372
4870
|
function prefixId$7(id) {
|
|
4373
4871
|
return `bio-properties-panel-${id}`;
|
|
4374
4872
|
}
|
|
4873
|
+
const useBufferedFocus$1 = function (editor, ref) {
|
|
4874
|
+
const [buffer, setBuffer] = hooks$1.useState(undefined);
|
|
4875
|
+
ref.current = hooks$1.useMemo(() => ({
|
|
4876
|
+
focus: offset => {
|
|
4877
|
+
if (editor) {
|
|
4878
|
+
editor.focus(offset);
|
|
4879
|
+
} else {
|
|
4880
|
+
if (typeof offset === 'undefined') {
|
|
4881
|
+
offset = Infinity;
|
|
4882
|
+
}
|
|
4883
|
+
setBuffer(offset);
|
|
4884
|
+
}
|
|
4885
|
+
}
|
|
4886
|
+
}), [editor]);
|
|
4887
|
+
hooks$1.useEffect(() => {
|
|
4888
|
+
if (typeof buffer !== 'undefined' && editor) {
|
|
4889
|
+
editor.focus(buffer);
|
|
4890
|
+
setBuffer(false);
|
|
4891
|
+
}
|
|
4892
|
+
}, [editor, buffer]);
|
|
4893
|
+
};
|
|
4894
|
+
const CodeEditor$1 = React.forwardRef((props, ref) => {
|
|
4895
|
+
const {
|
|
4896
|
+
onInput,
|
|
4897
|
+
disabled,
|
|
4898
|
+
tooltipContainer,
|
|
4899
|
+
enableGutters,
|
|
4900
|
+
value,
|
|
4901
|
+
onLint = () => {},
|
|
4902
|
+
contentAttributes = {},
|
|
4903
|
+
hostLanguage = null,
|
|
4904
|
+
singleLine = false
|
|
4905
|
+
} = props;
|
|
4906
|
+
const inputRef = hooks$1.useRef();
|
|
4907
|
+
const [editor, setEditor] = hooks$1.useState();
|
|
4908
|
+
const [localValue, setLocalValue] = hooks$1.useState(value || '');
|
|
4909
|
+
useBufferedFocus$1(editor, ref);
|
|
4910
|
+
const handleInput = useStaticCallback(newValue => {
|
|
4911
|
+
onInput(newValue);
|
|
4912
|
+
setLocalValue(newValue);
|
|
4913
|
+
});
|
|
4914
|
+
hooks$1.useEffect(() => {
|
|
4915
|
+
let editor;
|
|
4916
|
+
editor = new feelers.FeelersEditor({
|
|
4917
|
+
container: inputRef.current,
|
|
4918
|
+
onChange: handleInput,
|
|
4919
|
+
value: localValue,
|
|
4920
|
+
onLint,
|
|
4921
|
+
contentAttributes,
|
|
4922
|
+
tooltipContainer,
|
|
4923
|
+
enableGutters,
|
|
4924
|
+
hostLanguage,
|
|
4925
|
+
singleLine
|
|
4926
|
+
});
|
|
4927
|
+
setEditor(editor);
|
|
4928
|
+
return () => {
|
|
4929
|
+
onLint([]);
|
|
4930
|
+
inputRef.current.innerHTML = '';
|
|
4931
|
+
setEditor(null);
|
|
4932
|
+
};
|
|
4933
|
+
}, []);
|
|
4934
|
+
hooks$1.useEffect(() => {
|
|
4935
|
+
if (!editor) {
|
|
4936
|
+
return;
|
|
4937
|
+
}
|
|
4938
|
+
if (value === localValue) {
|
|
4939
|
+
return;
|
|
4940
|
+
}
|
|
4941
|
+
editor.setValue(value);
|
|
4942
|
+
setLocalValue(value);
|
|
4943
|
+
}, [value]);
|
|
4944
|
+
const handleClick = () => {
|
|
4945
|
+
ref.current.focus();
|
|
4946
|
+
};
|
|
4947
|
+
return jsxRuntime.jsx("div", {
|
|
4948
|
+
name: props.name,
|
|
4949
|
+
class: classnames('bio-properties-panel-feelers-editor bio-properties-panel-input', localValue ? 'edited' : null, disabled ? 'disabled' : null),
|
|
4950
|
+
ref: inputRef,
|
|
4951
|
+
onClick: handleClick
|
|
4952
|
+
});
|
|
4953
|
+
});
|
|
4375
4954
|
const useBufferedFocus = function (editor, ref) {
|
|
4376
4955
|
const [buffer, setBuffer] = hooks$1.useState(undefined);
|
|
4377
4956
|
ref.current = hooks$1.useMemo(() => ({
|
|
@@ -4414,10 +4993,10 @@ const CodeEditor = React.forwardRef((props, ref) => {
|
|
|
4414
4993
|
hooks$1.useEffect(() => {
|
|
4415
4994
|
let editor;
|
|
4416
4995
|
|
|
4417
|
-
/* Trigger FEEL toggle when
|
|
4418
|
-
*
|
|
4419
|
-
* - `backspace` is pressed
|
|
4420
|
-
* - AND the cursor is at the beginning of the input
|
|
4996
|
+
/* Trigger FEEL toggle when
|
|
4997
|
+
*
|
|
4998
|
+
* - `backspace` is pressed
|
|
4999
|
+
* - AND the cursor is at the beginning of the input
|
|
4421
5000
|
*/
|
|
4422
5001
|
const onKeyDown = e => {
|
|
4423
5002
|
if (e.key !== 'Backspace' || !editor) {
|
|
@@ -4486,12 +5065,12 @@ function FeelIndicator(props) {
|
|
|
4486
5065
|
children: "="
|
|
4487
5066
|
});
|
|
4488
5067
|
}
|
|
4489
|
-
const noop$
|
|
5068
|
+
const noop$2 = () => {};
|
|
4490
5069
|
|
|
4491
|
-
/**
|
|
4492
|
-
* @param {Object} props
|
|
4493
|
-
* @param {Object} props.label
|
|
4494
|
-
* @param {String} props.feel
|
|
5070
|
+
/**
|
|
5071
|
+
* @param {Object} props
|
|
5072
|
+
* @param {Object} props.label
|
|
5073
|
+
* @param {String} props.feel
|
|
4495
5074
|
*/
|
|
4496
5075
|
function FeelIcon(props) {
|
|
4497
5076
|
const {
|
|
@@ -4499,7 +5078,7 @@ function FeelIcon(props) {
|
|
|
4499
5078
|
feel = false,
|
|
4500
5079
|
active,
|
|
4501
5080
|
disabled = false,
|
|
4502
|
-
onClick = noop$
|
|
5081
|
+
onClick = noop$2
|
|
4503
5082
|
} = props;
|
|
4504
5083
|
const feelRequiredLabel = ' must be a FEEL expression';
|
|
4505
5084
|
const feelOptionalLabel = ' can optionally be a FEEL expression';
|
|
@@ -4519,7 +5098,7 @@ function FeelIcon(props) {
|
|
|
4519
5098
|
children: feel === 'required' ? jsxRuntime.jsx(FeelRequiredIcon, {}) : jsxRuntime.jsx(FeelOptionalIcon, {})
|
|
4520
5099
|
});
|
|
4521
5100
|
}
|
|
4522
|
-
const noop = () => {};
|
|
5101
|
+
const noop$1 = () => {};
|
|
4523
5102
|
function FeelTextfield(props) {
|
|
4524
5103
|
const {
|
|
4525
5104
|
debounce,
|
|
@@ -4676,6 +5255,9 @@ function FeelTextfield(props) {
|
|
|
4676
5255
|
}) : jsxRuntime.jsx(OptionalComponent, {
|
|
4677
5256
|
...props,
|
|
4678
5257
|
onInput: handleLocalInput,
|
|
5258
|
+
contentAttributes: {
|
|
5259
|
+
'id': prefixId$6(id)
|
|
5260
|
+
},
|
|
4679
5261
|
value: localValue,
|
|
4680
5262
|
ref: editorRef
|
|
4681
5263
|
})]
|
|
@@ -4725,7 +5307,7 @@ const OptionalFeelInput = React.forwardRef((props, ref) => {
|
|
|
4725
5307
|
value: value || ''
|
|
4726
5308
|
});
|
|
4727
5309
|
});
|
|
4728
|
-
|
|
5310
|
+
React.forwardRef((props, ref) => {
|
|
4729
5311
|
const {
|
|
4730
5312
|
id,
|
|
4731
5313
|
disabled,
|
|
@@ -4765,17 +5347,24 @@ const OptionalFeelTextArea = React.forwardRef((props, ref) => {
|
|
|
4765
5347
|
});
|
|
4766
5348
|
});
|
|
4767
5349
|
|
|
4768
|
-
/**
|
|
4769
|
-
* @param {Object} props
|
|
4770
|
-
* @param {Object} props.element
|
|
4771
|
-
* @param {String} props.id
|
|
4772
|
-
* @param {String} props.description
|
|
4773
|
-
* @param {Boolean} props.debounce
|
|
4774
|
-
* @param {Boolean} props.disabled
|
|
4775
|
-
* @param {
|
|
4776
|
-
* @param {
|
|
4777
|
-
* @param {Function} props.
|
|
4778
|
-
* @param {Function} props.
|
|
5350
|
+
/**
|
|
5351
|
+
* @param {Object} props
|
|
5352
|
+
* @param {Object} props.element
|
|
5353
|
+
* @param {String} props.id
|
|
5354
|
+
* @param {String} props.description
|
|
5355
|
+
* @param {Boolean} props.debounce
|
|
5356
|
+
* @param {Boolean} props.disabled
|
|
5357
|
+
* @param {Boolean} props.feel
|
|
5358
|
+
* @param {String} props.label
|
|
5359
|
+
* @param {Function} props.getValue
|
|
5360
|
+
* @param {Function} props.setValue
|
|
5361
|
+
* @param {Function} props.tooltipContainer
|
|
5362
|
+
* @param {Function} props.validate
|
|
5363
|
+
* @param {Function} props.show
|
|
5364
|
+
* @param {Function} props.example
|
|
5365
|
+
* @param {Function} props.variables
|
|
5366
|
+
* @param {Function} props.onFocus
|
|
5367
|
+
* @param {Function} props.onBlur
|
|
4779
5368
|
*/
|
|
4780
5369
|
function FeelEntry(props) {
|
|
4781
5370
|
const {
|
|
@@ -4789,8 +5378,10 @@ function FeelEntry(props) {
|
|
|
4789
5378
|
getValue,
|
|
4790
5379
|
setValue,
|
|
4791
5380
|
tooltipContainer,
|
|
5381
|
+
hostLanguage,
|
|
5382
|
+
singleLine,
|
|
4792
5383
|
validate,
|
|
4793
|
-
show = noop,
|
|
5384
|
+
show = noop$1,
|
|
4794
5385
|
example,
|
|
4795
5386
|
variables,
|
|
4796
5387
|
onFocus,
|
|
@@ -4844,6 +5435,8 @@ function FeelEntry(props) {
|
|
|
4844
5435
|
onFocus: onFocus,
|
|
4845
5436
|
onBlur: onBlur,
|
|
4846
5437
|
example: example,
|
|
5438
|
+
hostLanguage: hostLanguage,
|
|
5439
|
+
singleLine: singleLine,
|
|
4847
5440
|
show: show,
|
|
4848
5441
|
value: value,
|
|
4849
5442
|
variables: variables,
|
|
@@ -4860,28 +5453,35 @@ function FeelEntry(props) {
|
|
|
4860
5453
|
});
|
|
4861
5454
|
}
|
|
4862
5455
|
|
|
4863
|
-
/**
|
|
4864
|
-
* @param {Object} props
|
|
4865
|
-
* @param {Object} props.element
|
|
4866
|
-
* @param {String} props.id
|
|
4867
|
-
* @param {String} props.description
|
|
4868
|
-
* @param {
|
|
4869
|
-
* @param {Boolean} props.
|
|
4870
|
-
* @param {
|
|
4871
|
-
* @param {
|
|
4872
|
-
* @param {
|
|
4873
|
-
* @param {
|
|
4874
|
-
* @param {Function} props.
|
|
4875
|
-
* @param {Function} props.
|
|
5456
|
+
/**
|
|
5457
|
+
* @param {Object} props
|
|
5458
|
+
* @param {Object} props.element
|
|
5459
|
+
* @param {String} props.id
|
|
5460
|
+
* @param {String} props.description
|
|
5461
|
+
* @param {String} props.hostLanguage
|
|
5462
|
+
* @param {Boolean} props.singleLine
|
|
5463
|
+
* @param {Boolean} props.debounce
|
|
5464
|
+
* @param {Boolean} props.disabled
|
|
5465
|
+
* @param {Boolean} props.feel
|
|
5466
|
+
* @param {String} props.label
|
|
5467
|
+
* @param {Function} props.getValue
|
|
5468
|
+
* @param {Function} props.setValue
|
|
5469
|
+
* @param {Function} props.tooltipContainer
|
|
5470
|
+
* @param {Function} props.validate
|
|
5471
|
+
* @param {Function} props.show
|
|
5472
|
+
* @param {Function} props.example
|
|
5473
|
+
* @param {Function} props.variables
|
|
5474
|
+
* @param {Function} props.onFocus
|
|
5475
|
+
* @param {Function} props.onBlur
|
|
4876
5476
|
*/
|
|
4877
|
-
function
|
|
5477
|
+
function FeelTemplatingEntry(props) {
|
|
4878
5478
|
return jsxRuntime.jsx(FeelEntry, {
|
|
4879
|
-
class: "bio-properties-panel-feel-
|
|
4880
|
-
OptionalComponent:
|
|
5479
|
+
class: "bio-properties-panel-feel-templating",
|
|
5480
|
+
OptionalComponent: CodeEditor$1,
|
|
4881
5481
|
...props
|
|
4882
5482
|
});
|
|
4883
5483
|
}
|
|
4884
|
-
function isEdited$
|
|
5484
|
+
function isEdited$7(node) {
|
|
4885
5485
|
return node && (!!node.value || node.classList.contains('edited'));
|
|
4886
5486
|
}
|
|
4887
5487
|
|
|
@@ -4951,22 +5551,22 @@ function NumberField(props) {
|
|
|
4951
5551
|
});
|
|
4952
5552
|
}
|
|
4953
5553
|
|
|
4954
|
-
/**
|
|
4955
|
-
* @param {Object} props
|
|
4956
|
-
* @param {Boolean} props.debounce
|
|
4957
|
-
* @param {String} props.description
|
|
4958
|
-
* @param {Boolean} props.disabled
|
|
4959
|
-
* @param {Object} props.element
|
|
4960
|
-
* @param {Function} props.getValue
|
|
4961
|
-
* @param {String} props.id
|
|
4962
|
-
* @param {String} props.label
|
|
4963
|
-
* @param {String} props.max
|
|
4964
|
-
* @param {String} props.min
|
|
4965
|
-
* @param {Function} props.setValue
|
|
4966
|
-
* @param {Function} props.onFocus
|
|
4967
|
-
* @param {Function} props.onBlur
|
|
4968
|
-
* @param {String} props.step
|
|
4969
|
-
* @param {Function} props.validate
|
|
5554
|
+
/**
|
|
5555
|
+
* @param {Object} props
|
|
5556
|
+
* @param {Boolean} props.debounce
|
|
5557
|
+
* @param {String} props.description
|
|
5558
|
+
* @param {Boolean} props.disabled
|
|
5559
|
+
* @param {Object} props.element
|
|
5560
|
+
* @param {Function} props.getValue
|
|
5561
|
+
* @param {String} props.id
|
|
5562
|
+
* @param {String} props.label
|
|
5563
|
+
* @param {String} props.max
|
|
5564
|
+
* @param {String} props.min
|
|
5565
|
+
* @param {Function} props.setValue
|
|
5566
|
+
* @param {Function} props.onFocus
|
|
5567
|
+
* @param {Function} props.onBlur
|
|
5568
|
+
* @param {String} props.step
|
|
5569
|
+
* @param {Function} props.validate
|
|
4970
5570
|
*/
|
|
4971
5571
|
function NumberFieldEntry(props) {
|
|
4972
5572
|
const {
|
|
@@ -5091,6 +5691,16 @@ function Select(props) {
|
|
|
5091
5691
|
value: localValue,
|
|
5092
5692
|
disabled: disabled,
|
|
5093
5693
|
children: options.map((option, idx) => {
|
|
5694
|
+
if (option.children) {
|
|
5695
|
+
return jsxRuntime.jsx("optgroup", {
|
|
5696
|
+
label: option.label,
|
|
5697
|
+
children: option.children.map((child, idx) => jsxRuntime.jsx("option", {
|
|
5698
|
+
value: child.value,
|
|
5699
|
+
disabled: child.disabled,
|
|
5700
|
+
children: child.label
|
|
5701
|
+
}, idx))
|
|
5702
|
+
}, idx);
|
|
5703
|
+
}
|
|
5094
5704
|
return jsxRuntime.jsx("option", {
|
|
5095
5705
|
value: option.value,
|
|
5096
5706
|
disabled: option.disabled,
|
|
@@ -5101,18 +5711,19 @@ function Select(props) {
|
|
|
5101
5711
|
});
|
|
5102
5712
|
}
|
|
5103
5713
|
|
|
5104
|
-
/**
|
|
5105
|
-
* @param {object} props
|
|
5106
|
-
* @param {object} props.element
|
|
5107
|
-
* @param {string} props.id
|
|
5108
|
-
* @param {string} [props.description]
|
|
5109
|
-
* @param {string} props.label
|
|
5110
|
-
* @param {Function} props.getValue
|
|
5111
|
-
* @param {Function} props.setValue
|
|
5112
|
-
* @param {Function} props.onFocus
|
|
5113
|
-
* @param {Function} props.onBlur
|
|
5114
|
-
* @param {Function} props.getOptions
|
|
5115
|
-
* @param {boolean} [props.disabled]
|
|
5714
|
+
/**
|
|
5715
|
+
* @param {object} props
|
|
5716
|
+
* @param {object} props.element
|
|
5717
|
+
* @param {string} props.id
|
|
5718
|
+
* @param {string} [props.description]
|
|
5719
|
+
* @param {string} props.label
|
|
5720
|
+
* @param {Function} props.getValue
|
|
5721
|
+
* @param {Function} props.setValue
|
|
5722
|
+
* @param {Function} props.onFocus
|
|
5723
|
+
* @param {Function} props.onBlur
|
|
5724
|
+
* @param {Function} props.getOptions
|
|
5725
|
+
* @param {boolean} [props.disabled]
|
|
5726
|
+
* @param {Function} [props.validate]
|
|
5116
5727
|
*/
|
|
5117
5728
|
function SelectEntry(props) {
|
|
5118
5729
|
const {
|
|
@@ -5125,11 +5736,37 @@ function SelectEntry(props) {
|
|
|
5125
5736
|
getOptions,
|
|
5126
5737
|
disabled,
|
|
5127
5738
|
onFocus,
|
|
5128
|
-
onBlur
|
|
5739
|
+
onBlur,
|
|
5740
|
+
validate
|
|
5129
5741
|
} = props;
|
|
5130
|
-
const value = getValue(element);
|
|
5131
5742
|
const options = getOptions(element);
|
|
5132
|
-
const
|
|
5743
|
+
const [cachedInvalidValue, setCachedInvalidValue] = hooks$1.useState(null);
|
|
5744
|
+
const globalError = useError(id);
|
|
5745
|
+
const [localError, setLocalError] = hooks$1.useState(null);
|
|
5746
|
+
let value = getValue(element);
|
|
5747
|
+
const previousValue = usePrevious(value);
|
|
5748
|
+
hooks$1.useEffect(() => {
|
|
5749
|
+
if (minDash.isFunction(validate)) {
|
|
5750
|
+
const newValidationError = validate(value) || null;
|
|
5751
|
+
setLocalError(newValidationError);
|
|
5752
|
+
}
|
|
5753
|
+
}, [value]);
|
|
5754
|
+
const onChange = newValue => {
|
|
5755
|
+
let newValidationError = null;
|
|
5756
|
+
if (minDash.isFunction(validate)) {
|
|
5757
|
+
newValidationError = validate(newValue) || null;
|
|
5758
|
+
}
|
|
5759
|
+
if (newValidationError) {
|
|
5760
|
+
setCachedInvalidValue(newValue);
|
|
5761
|
+
} else {
|
|
5762
|
+
setValue(newValue);
|
|
5763
|
+
}
|
|
5764
|
+
setLocalError(newValidationError);
|
|
5765
|
+
};
|
|
5766
|
+
if (previousValue === value && localError) {
|
|
5767
|
+
value = cachedInvalidValue;
|
|
5768
|
+
}
|
|
5769
|
+
const error = globalError || localError;
|
|
5133
5770
|
return jsxRuntime.jsxs("div", {
|
|
5134
5771
|
class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
5135
5772
|
"data-entry-id": id,
|
|
@@ -5137,7 +5774,7 @@ function SelectEntry(props) {
|
|
|
5137
5774
|
id: id,
|
|
5138
5775
|
label: label,
|
|
5139
5776
|
value: value,
|
|
5140
|
-
onChange:
|
|
5777
|
+
onChange: onChange,
|
|
5141
5778
|
onFocus: onFocus,
|
|
5142
5779
|
onBlur: onBlur,
|
|
5143
5780
|
options: options,
|
|
@@ -5161,18 +5798,26 @@ function isEdited$4(node) {
|
|
|
5161
5798
|
function prefixId$4(id) {
|
|
5162
5799
|
return `bio-properties-panel-${id}`;
|
|
5163
5800
|
}
|
|
5801
|
+
function resizeToContents(element) {
|
|
5802
|
+
element.style.height = 'auto';
|
|
5803
|
+
|
|
5804
|
+
// a 2px pixel offset is required to prevent scrollbar from
|
|
5805
|
+
// appearing on OS with a full length scroll bar (Windows/Linux)
|
|
5806
|
+
element.style.height = `${element.scrollHeight + 2}px`;
|
|
5807
|
+
}
|
|
5164
5808
|
function TextArea(props) {
|
|
5165
5809
|
const {
|
|
5166
5810
|
id,
|
|
5167
5811
|
label,
|
|
5168
|
-
rows = 2,
|
|
5169
5812
|
debounce,
|
|
5170
5813
|
onInput,
|
|
5171
5814
|
value = '',
|
|
5172
5815
|
disabled,
|
|
5173
5816
|
monospace,
|
|
5174
5817
|
onFocus,
|
|
5175
|
-
onBlur
|
|
5818
|
+
onBlur,
|
|
5819
|
+
autoResize,
|
|
5820
|
+
rows = autoResize ? 1 : 2
|
|
5176
5821
|
} = props;
|
|
5177
5822
|
const [localValue, setLocalValue] = hooks$1.useState(value);
|
|
5178
5823
|
const ref = useShowEntryEvent(id);
|
|
@@ -5183,8 +5828,12 @@ function TextArea(props) {
|
|
|
5183
5828
|
}, [onInput, debounce]);
|
|
5184
5829
|
const handleInput = e => {
|
|
5185
5830
|
handleInputCallback(e);
|
|
5831
|
+
autoResize && resizeToContents(e.target);
|
|
5186
5832
|
setLocalValue(e.target.value);
|
|
5187
5833
|
};
|
|
5834
|
+
hooks$1.useLayoutEffect(() => {
|
|
5835
|
+
autoResize && resizeToContents(ref.current);
|
|
5836
|
+
}, []);
|
|
5188
5837
|
hooks$1.useEffect(() => {
|
|
5189
5838
|
if (value === localValue) {
|
|
5190
5839
|
return;
|
|
@@ -5202,7 +5851,7 @@ function TextArea(props) {
|
|
|
5202
5851
|
id: prefixId$2(id),
|
|
5203
5852
|
name: id,
|
|
5204
5853
|
spellCheck: "false",
|
|
5205
|
-
class: classnames('bio-properties-panel-input', monospace ? 'bio-properties-panel-input-monospace' : ''),
|
|
5854
|
+
class: classnames('bio-properties-panel-input', monospace ? 'bio-properties-panel-input-monospace' : '', autoResize ? 'auto-resize' : ''),
|
|
5206
5855
|
onInput: handleInput,
|
|
5207
5856
|
onFocus: onFocus,
|
|
5208
5857
|
onBlur: onBlur,
|
|
@@ -5214,20 +5863,20 @@ function TextArea(props) {
|
|
|
5214
5863
|
});
|
|
5215
5864
|
}
|
|
5216
5865
|
|
|
5217
|
-
/**
|
|
5218
|
-
* @param {object} props
|
|
5219
|
-
* @param {object} props.element
|
|
5220
|
-
* @param {string} props.id
|
|
5221
|
-
* @param {string} props.description
|
|
5222
|
-
* @param {boolean} props.debounce
|
|
5223
|
-
* @param {string} props.label
|
|
5224
|
-
* @param {Function} props.getValue
|
|
5225
|
-
* @param {Function} props.setValue
|
|
5226
|
-
* @param {Function} props.onFocus
|
|
5227
|
-
* @param {Function} props.onBlur
|
|
5228
|
-
* @param {number} props.rows
|
|
5229
|
-
* @param {boolean} props.monospace
|
|
5230
|
-
* @param {boolean} [props.disabled]
|
|
5866
|
+
/**
|
|
5867
|
+
* @param {object} props
|
|
5868
|
+
* @param {object} props.element
|
|
5869
|
+
* @param {string} props.id
|
|
5870
|
+
* @param {string} props.description
|
|
5871
|
+
* @param {boolean} props.debounce
|
|
5872
|
+
* @param {string} props.label
|
|
5873
|
+
* @param {Function} props.getValue
|
|
5874
|
+
* @param {Function} props.setValue
|
|
5875
|
+
* @param {Function} props.onFocus
|
|
5876
|
+
* @param {Function} props.onBlur
|
|
5877
|
+
* @param {number} props.rows
|
|
5878
|
+
* @param {boolean} props.monospace
|
|
5879
|
+
* @param {boolean} [props.disabled]
|
|
5231
5880
|
*/
|
|
5232
5881
|
function TextAreaEntry(props) {
|
|
5233
5882
|
const {
|
|
@@ -5242,7 +5891,8 @@ function TextAreaEntry(props) {
|
|
|
5242
5891
|
monospace,
|
|
5243
5892
|
disabled,
|
|
5244
5893
|
onFocus,
|
|
5245
|
-
onBlur
|
|
5894
|
+
onBlur,
|
|
5895
|
+
autoResize
|
|
5246
5896
|
} = props;
|
|
5247
5897
|
const value = getValue(element);
|
|
5248
5898
|
const error = useError(id);
|
|
@@ -5259,7 +5909,8 @@ function TextAreaEntry(props) {
|
|
|
5259
5909
|
rows: rows,
|
|
5260
5910
|
debounce: debounce,
|
|
5261
5911
|
monospace: monospace,
|
|
5262
|
-
disabled: disabled
|
|
5912
|
+
disabled: disabled,
|
|
5913
|
+
autoResize: autoResize
|
|
5263
5914
|
}, element), error && jsxRuntime.jsx("div", {
|
|
5264
5915
|
class: "bio-properties-panel-error",
|
|
5265
5916
|
children: error
|
|
@@ -5330,19 +5981,19 @@ function Textfield(props) {
|
|
|
5330
5981
|
});
|
|
5331
5982
|
}
|
|
5332
5983
|
|
|
5333
|
-
/**
|
|
5334
|
-
* @param {Object} props
|
|
5335
|
-
* @param {Object} props.element
|
|
5336
|
-
* @param {String} props.id
|
|
5337
|
-
* @param {String} props.description
|
|
5338
|
-
* @param {Boolean} props.debounce
|
|
5339
|
-
* @param {Boolean} props.disabled
|
|
5340
|
-
* @param {String} props.label
|
|
5341
|
-
* @param {Function} props.getValue
|
|
5342
|
-
* @param {Function} props.setValue
|
|
5343
|
-
* @param {Function} props.onFocus
|
|
5344
|
-
* @param {Function} props.onBlur
|
|
5345
|
-
* @param {Function} props.validate
|
|
5984
|
+
/**
|
|
5985
|
+
* @param {Object} props
|
|
5986
|
+
* @param {Object} props.element
|
|
5987
|
+
* @param {String} props.id
|
|
5988
|
+
* @param {String} props.description
|
|
5989
|
+
* @param {Boolean} props.debounce
|
|
5990
|
+
* @param {Boolean} props.disabled
|
|
5991
|
+
* @param {String} props.label
|
|
5992
|
+
* @param {Function} props.getValue
|
|
5993
|
+
* @param {Function} props.setValue
|
|
5994
|
+
* @param {Function} props.onFocus
|
|
5995
|
+
* @param {Function} props.onBlur
|
|
5996
|
+
* @param {Function} props.validate
|
|
5346
5997
|
*/
|
|
5347
5998
|
function TextfieldEntry(props) {
|
|
5348
5999
|
const {
|
|
@@ -5609,7 +6260,7 @@ function AltTextEntry(props) {
|
|
|
5609
6260
|
component: AltText,
|
|
5610
6261
|
editField: editField,
|
|
5611
6262
|
field: field,
|
|
5612
|
-
isEdited: isEdited$
|
|
6263
|
+
isEdited: isEdited$7
|
|
5613
6264
|
});
|
|
5614
6265
|
}
|
|
5615
6266
|
return entries;
|
|
@@ -5643,59 +6294,70 @@ function AltText(props) {
|
|
|
5643
6294
|
});
|
|
5644
6295
|
}
|
|
5645
6296
|
|
|
6297
|
+
const AUTO_OPTION_VALUE = '';
|
|
5646
6298
|
function ColumnsEntry(props) {
|
|
5647
6299
|
const {
|
|
5648
6300
|
editField,
|
|
5649
6301
|
field
|
|
5650
6302
|
} = props;
|
|
5651
|
-
const {
|
|
5652
|
-
|
|
5653
|
-
|
|
5654
|
-
|
|
5655
|
-
|
|
5656
|
-
|
|
5657
|
-
|
|
5658
|
-
component: Columns,
|
|
5659
|
-
editField: editField,
|
|
5660
|
-
field: field,
|
|
5661
|
-
isEdited: isEdited$5
|
|
5662
|
-
});
|
|
5663
|
-
}
|
|
6303
|
+
const entries = [{
|
|
6304
|
+
id: 'columns',
|
|
6305
|
+
component: Columns,
|
|
6306
|
+
field,
|
|
6307
|
+
editField,
|
|
6308
|
+
isEdited: isEdited$4
|
|
6309
|
+
}];
|
|
5664
6310
|
return entries;
|
|
5665
6311
|
}
|
|
5666
6312
|
function Columns(props) {
|
|
5667
6313
|
const {
|
|
5668
|
-
editField,
|
|
5669
6314
|
field,
|
|
6315
|
+
editField,
|
|
5670
6316
|
id
|
|
5671
6317
|
} = props;
|
|
5672
6318
|
const debounce = useService('debounce');
|
|
5673
|
-
const
|
|
5674
|
-
|
|
6319
|
+
const formLayoutValidator = useService('formLayoutValidator');
|
|
6320
|
+
const validate = value => {
|
|
6321
|
+
return formLayoutValidator.validateField(field, value ? parseInt(value) : null);
|
|
5675
6322
|
};
|
|
5676
6323
|
const setValue = value => {
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
components.push(formJsViewer.Default.create({
|
|
5681
|
-
_parent: field.id
|
|
5682
|
-
}));
|
|
5683
|
-
}
|
|
5684
|
-
} else {
|
|
5685
|
-
components = components.slice(0, value);
|
|
5686
|
-
}
|
|
5687
|
-
editField(field, 'components', components);
|
|
6324
|
+
const layout = minDash.get(field, ['layout'], {});
|
|
6325
|
+
const newValue = value ? parseInt(value) : null;
|
|
6326
|
+
editField(field, ['layout'], minDash.set(layout, ['columns'], newValue));
|
|
5688
6327
|
};
|
|
5689
|
-
|
|
6328
|
+
const getValue = () => {
|
|
6329
|
+
return minDash.get(field, ['layout', 'columns']);
|
|
6330
|
+
};
|
|
6331
|
+
const getOptions = () => {
|
|
6332
|
+
return [{
|
|
6333
|
+
label: 'Auto',
|
|
6334
|
+
value: AUTO_OPTION_VALUE
|
|
6335
|
+
},
|
|
6336
|
+
// todo(pinussilvestrus): make options dependant on field type
|
|
6337
|
+
// cf. https://github.com/bpmn-io/form-js/issues/575
|
|
6338
|
+
...[2, 4, 6, 8, 10, 12, 14, 16].map(asOption)];
|
|
6339
|
+
};
|
|
6340
|
+
return SelectEntry({
|
|
5690
6341
|
debounce,
|
|
5691
6342
|
element: field,
|
|
5692
|
-
getValue,
|
|
5693
6343
|
id,
|
|
5694
6344
|
label: 'Columns',
|
|
5695
|
-
|
|
6345
|
+
getOptions,
|
|
6346
|
+
getValue,
|
|
6347
|
+
setValue,
|
|
6348
|
+
validate
|
|
5696
6349
|
});
|
|
5697
6350
|
}
|
|
5698
6351
|
|
|
6352
|
+
// helper /////////
|
|
6353
|
+
|
|
6354
|
+
function asOption(number) {
|
|
6355
|
+
return {
|
|
6356
|
+
value: number,
|
|
6357
|
+
label: number.toString()
|
|
6358
|
+
};
|
|
6359
|
+
}
|
|
6360
|
+
|
|
5699
6361
|
function DescriptionEntry(props) {
|
|
5700
6362
|
const {
|
|
5701
6363
|
editField,
|
|
@@ -5990,7 +6652,7 @@ function DisabledEntry(props) {
|
|
|
5990
6652
|
component: Disabled,
|
|
5991
6653
|
editField: editField,
|
|
5992
6654
|
field: field,
|
|
5993
|
-
isEdited: isEdited$
|
|
6655
|
+
isEdited: isEdited$8
|
|
5994
6656
|
});
|
|
5995
6657
|
}
|
|
5996
6658
|
return entries;
|
|
@@ -6200,6 +6862,7 @@ function simpleBoolEntryFactory(options) {
|
|
|
6200
6862
|
const {
|
|
6201
6863
|
id,
|
|
6202
6864
|
label,
|
|
6865
|
+
description,
|
|
6203
6866
|
path,
|
|
6204
6867
|
props
|
|
6205
6868
|
} = options;
|
|
@@ -6213,8 +6876,9 @@ function simpleBoolEntryFactory(options) {
|
|
|
6213
6876
|
path,
|
|
6214
6877
|
field,
|
|
6215
6878
|
editField,
|
|
6879
|
+
description,
|
|
6216
6880
|
component: SimpleBoolComponent,
|
|
6217
|
-
isEdited: isEdited$
|
|
6881
|
+
isEdited: isEdited$8
|
|
6218
6882
|
};
|
|
6219
6883
|
}
|
|
6220
6884
|
const SimpleBoolComponent = props => {
|
|
@@ -6223,7 +6887,8 @@ const SimpleBoolComponent = props => {
|
|
|
6223
6887
|
label,
|
|
6224
6888
|
path,
|
|
6225
6889
|
field,
|
|
6226
|
-
editField
|
|
6890
|
+
editField,
|
|
6891
|
+
description
|
|
6227
6892
|
} = props;
|
|
6228
6893
|
const getValue = () => minDash.get(field, path, '');
|
|
6229
6894
|
const setValue = value => editField(field, path, value);
|
|
@@ -6232,7 +6897,8 @@ const SimpleBoolComponent = props => {
|
|
|
6232
6897
|
getValue,
|
|
6233
6898
|
id,
|
|
6234
6899
|
label,
|
|
6235
|
-
setValue
|
|
6900
|
+
setValue,
|
|
6901
|
+
description
|
|
6236
6902
|
});
|
|
6237
6903
|
};
|
|
6238
6904
|
|
|
@@ -6288,7 +6954,7 @@ function SourceEntry(props) {
|
|
|
6288
6954
|
component: Source,
|
|
6289
6955
|
editField: editField,
|
|
6290
6956
|
field: field,
|
|
6291
|
-
isEdited: isEdited$
|
|
6957
|
+
isEdited: isEdited$7
|
|
6292
6958
|
});
|
|
6293
6959
|
}
|
|
6294
6960
|
return entries;
|
|
@@ -6326,21 +6992,38 @@ function Source(props) {
|
|
|
6326
6992
|
function TextEntry(props) {
|
|
6327
6993
|
const {
|
|
6328
6994
|
editField,
|
|
6995
|
+
/* getService, */
|
|
6329
6996
|
field
|
|
6330
6997
|
} = props;
|
|
6331
6998
|
const {
|
|
6332
6999
|
type
|
|
6333
7000
|
} = field;
|
|
7001
|
+
|
|
7002
|
+
// const templating = getService('templating');
|
|
7003
|
+
|
|
6334
7004
|
if (type !== 'text') {
|
|
6335
7005
|
return [];
|
|
6336
7006
|
}
|
|
6337
|
-
|
|
7007
|
+
const entries = [{
|
|
6338
7008
|
id: 'text',
|
|
6339
7009
|
component: Text,
|
|
6340
7010
|
editField: editField,
|
|
6341
7011
|
field: field,
|
|
6342
|
-
isEdited: isEdited$
|
|
7012
|
+
isEdited: isEdited$7
|
|
6343
7013
|
}];
|
|
7014
|
+
|
|
7015
|
+
// todo: skipped to make the release without too much risk
|
|
7016
|
+
// if (templating.isTemplate(field.text)) {
|
|
7017
|
+
// entries.push(simpleBoolEntryFactory({
|
|
7018
|
+
// id: 'strict',
|
|
7019
|
+
// path: [ 'strict' ],
|
|
7020
|
+
// label: 'Strict templating',
|
|
7021
|
+
// description: 'Enforces types to be correct',
|
|
7022
|
+
// props
|
|
7023
|
+
// }));
|
|
7024
|
+
// }
|
|
7025
|
+
|
|
7026
|
+
return entries;
|
|
6344
7027
|
}
|
|
6345
7028
|
function Text(props) {
|
|
6346
7029
|
const {
|
|
@@ -6359,15 +7042,21 @@ function Text(props) {
|
|
|
6359
7042
|
const setValue = value => {
|
|
6360
7043
|
return editField(field, path, value);
|
|
6361
7044
|
};
|
|
6362
|
-
|
|
7045
|
+
const description = hooks$1.useMemo(() => jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
7046
|
+
children: ["Supports markdown and templating. ", jsxRuntime.jsx("a", {
|
|
7047
|
+
href: "https://docs.camunda.io/docs/components/modeler/forms/form-element-library/forms-element-library-text/",
|
|
7048
|
+
target: "_blank",
|
|
7049
|
+
children: "Learn more"
|
|
7050
|
+
})]
|
|
7051
|
+
}), []);
|
|
7052
|
+
return FeelTemplatingEntry({
|
|
6363
7053
|
debounce,
|
|
6364
|
-
description
|
|
7054
|
+
description,
|
|
6365
7055
|
element: field,
|
|
6366
|
-
feel: 'optional',
|
|
6367
7056
|
getValue,
|
|
6368
7057
|
id,
|
|
6369
7058
|
label: 'Text',
|
|
6370
|
-
|
|
7059
|
+
hostLanguage: 'markdown',
|
|
6371
7060
|
setValue,
|
|
6372
7061
|
variables
|
|
6373
7062
|
});
|
|
@@ -6483,7 +7172,7 @@ function NumberSerializationEntry(props) {
|
|
|
6483
7172
|
entries.push({
|
|
6484
7173
|
id: 'serialize-to-string',
|
|
6485
7174
|
component: SerializeToString,
|
|
6486
|
-
isEdited: isEdited$
|
|
7175
|
+
isEdited: isEdited$8,
|
|
6487
7176
|
editField,
|
|
6488
7177
|
field
|
|
6489
7178
|
});
|
|
@@ -6542,7 +7231,7 @@ function DateTimeEntry(props) {
|
|
|
6542
7231
|
entries.push({
|
|
6543
7232
|
id: 'use24h',
|
|
6544
7233
|
component: Use24h,
|
|
6545
|
-
isEdited: isEdited$
|
|
7234
|
+
isEdited: isEdited$8,
|
|
6546
7235
|
editField,
|
|
6547
7236
|
field
|
|
6548
7237
|
});
|
|
@@ -6655,7 +7344,7 @@ function DateTimeConstraintsEntry(props) {
|
|
|
6655
7344
|
entries.push({
|
|
6656
7345
|
id: id + '-disallowPassedDates',
|
|
6657
7346
|
component: DisallowPassedDates,
|
|
6658
|
-
isEdited: isEdited$
|
|
7347
|
+
isEdited: isEdited$8,
|
|
6659
7348
|
editField,
|
|
6660
7349
|
field
|
|
6661
7350
|
});
|
|
@@ -7030,11 +7719,19 @@ function InputKeyValuesSourceEntry(props) {
|
|
|
7030
7719
|
field,
|
|
7031
7720
|
id
|
|
7032
7721
|
} = props;
|
|
7722
|
+
const schema = '[\n {\n "label": "dollar",\n "value": "$"\n }\n]';
|
|
7723
|
+
const description = jsxRuntime.jsxs("div", {
|
|
7724
|
+
children: ["Define which input property to populate the values from.", jsxRuntime.jsx("br", {}), jsxRuntime.jsx("br", {}), "The input property may be an array of simple values or alternatively follow this schema:", jsxRuntime.jsx("pre", {
|
|
7725
|
+
children: jsxRuntime.jsx("code", {
|
|
7726
|
+
children: schema
|
|
7727
|
+
})
|
|
7728
|
+
})]
|
|
7729
|
+
});
|
|
7033
7730
|
return [{
|
|
7034
7731
|
id: id + '-key',
|
|
7035
7732
|
component: InputValuesKey,
|
|
7036
7733
|
label: 'Input values key',
|
|
7037
|
-
description
|
|
7734
|
+
description,
|
|
7038
7735
|
isEdited: isEdited$1,
|
|
7039
7736
|
editField,
|
|
7040
7737
|
field
|
|
@@ -7229,7 +7926,7 @@ function ConditionEntry(props) {
|
|
|
7229
7926
|
component: Condition,
|
|
7230
7927
|
editField: editField,
|
|
7231
7928
|
field: field,
|
|
7232
|
-
isEdited: isEdited$
|
|
7929
|
+
isEdited: isEdited$7
|
|
7233
7930
|
}];
|
|
7234
7931
|
}
|
|
7235
7932
|
function Condition(props) {
|
|
@@ -7267,7 +7964,7 @@ function Condition(props) {
|
|
|
7267
7964
|
});
|
|
7268
7965
|
}
|
|
7269
7966
|
|
|
7270
|
-
function GeneralGroup(field, editField) {
|
|
7967
|
+
function GeneralGroup(field, editField, getService) {
|
|
7271
7968
|
const entries = [...IdEntry({
|
|
7272
7969
|
field,
|
|
7273
7970
|
editField
|
|
@@ -7286,15 +7983,13 @@ function GeneralGroup(field, editField) {
|
|
|
7286
7983
|
}), ...ActionEntry({
|
|
7287
7984
|
field,
|
|
7288
7985
|
editField
|
|
7289
|
-
}), ...ColumnsEntry({
|
|
7290
|
-
field,
|
|
7291
|
-
editField
|
|
7292
7986
|
}), ...DateTimeEntry({
|
|
7293
7987
|
field,
|
|
7294
7988
|
editField
|
|
7295
7989
|
}), ...TextEntry({
|
|
7296
7990
|
field,
|
|
7297
|
-
editField
|
|
7991
|
+
editField,
|
|
7992
|
+
getService
|
|
7298
7993
|
}), ...NumberEntries({
|
|
7299
7994
|
field,
|
|
7300
7995
|
editField
|
|
@@ -7390,7 +8085,7 @@ function ValidationGroup(field, editField) {
|
|
|
7390
8085
|
component: Required,
|
|
7391
8086
|
getValue,
|
|
7392
8087
|
field,
|
|
7393
|
-
isEdited: isEdited$
|
|
8088
|
+
isEdited: isEdited$8,
|
|
7394
8089
|
onChange
|
|
7395
8090
|
}];
|
|
7396
8091
|
if (type === 'textfield') {
|
|
@@ -7732,6 +8427,27 @@ function AppearanceGroup(field, editField) {
|
|
|
7732
8427
|
};
|
|
7733
8428
|
}
|
|
7734
8429
|
|
|
8430
|
+
function LayoutGroup(field, editField) {
|
|
8431
|
+
const {
|
|
8432
|
+
type
|
|
8433
|
+
} = field;
|
|
8434
|
+
if (type === 'default') {
|
|
8435
|
+
return null;
|
|
8436
|
+
}
|
|
8437
|
+
const entries = [...ColumnsEntry({
|
|
8438
|
+
field,
|
|
8439
|
+
editField
|
|
8440
|
+
})];
|
|
8441
|
+
if (entries.length === 0) {
|
|
8442
|
+
return null;
|
|
8443
|
+
}
|
|
8444
|
+
return {
|
|
8445
|
+
id: 'layout',
|
|
8446
|
+
label: 'Layout',
|
|
8447
|
+
entries
|
|
8448
|
+
};
|
|
8449
|
+
}
|
|
8450
|
+
|
|
7735
8451
|
function ConditionGroup(field, editField) {
|
|
7736
8452
|
const {
|
|
7737
8453
|
type
|
|
@@ -7750,11 +8466,11 @@ function ConditionGroup(field, editField) {
|
|
|
7750
8466
|
};
|
|
7751
8467
|
}
|
|
7752
8468
|
|
|
7753
|
-
function getGroups(field, editField) {
|
|
8469
|
+
function getGroups(field, editField, getService) {
|
|
7754
8470
|
if (!field) {
|
|
7755
8471
|
return [];
|
|
7756
8472
|
}
|
|
7757
|
-
const groups = [GeneralGroup(field, editField), ConditionGroup(field, editField), AppearanceGroup(field, editField), SerializationGroup(field, editField), ...ValuesGroups(field, editField), ConstraintsGroup(field, editField), ValidationGroup(field, editField), CustomValuesGroup(field, editField)];
|
|
8473
|
+
const groups = [GeneralGroup(field, editField, getService), ConditionGroup(field, editField), LayoutGroup(field, editField), AppearanceGroup(field, editField), SerializationGroup(field, editField), ...ValuesGroups(field, editField), ConstraintsGroup(field, editField), ValidationGroup(field, editField), CustomValuesGroup(field, editField)];
|
|
7758
8474
|
|
|
7759
8475
|
// contract: if a group returns null, it should not be displayed at all
|
|
7760
8476
|
return groups.filter(group => group !== null);
|
|
@@ -7807,10 +8523,9 @@ function FormPropertiesPanel(props) {
|
|
|
7807
8523
|
};
|
|
7808
8524
|
}, []);
|
|
7809
8525
|
const selectedFormField = state.selectedFormField;
|
|
8526
|
+
const getService = (type, strict = true) => injector.get(type, strict);
|
|
7810
8527
|
const propertiesPanelContext = {
|
|
7811
|
-
getService
|
|
7812
|
-
return injector.get(type, strict);
|
|
7813
|
-
}
|
|
8528
|
+
getService
|
|
7814
8529
|
};
|
|
7815
8530
|
const onFocus = () => eventBus.fire('propertiesPanel.focusin');
|
|
7816
8531
|
const onBlur = () => eventBus.fire('propertiesPanel.focusout');
|
|
@@ -7825,7 +8540,7 @@ function FormPropertiesPanel(props) {
|
|
|
7825
8540
|
children: jsxRuntime.jsx(PropertiesPanel, {
|
|
7826
8541
|
element: selectedFormField,
|
|
7827
8542
|
eventBus: eventBus,
|
|
7828
|
-
groups: getGroups(selectedFormField, editField),
|
|
8543
|
+
groups: getGroups(selectedFormField, editField, getService),
|
|
7829
8544
|
headerProvider: PropertiesPanelHeaderProvider,
|
|
7830
8545
|
placeholderProvider: PropertiesPanelPlaceholderProvider
|
|
7831
8546
|
})
|
|
@@ -7903,6 +8618,12 @@ var PropertiesPanelModule = {
|
|
|
7903
8618
|
propertiesPanel: ['type', PropertiesPanelRenderer]
|
|
7904
8619
|
};
|
|
7905
8620
|
|
|
8621
|
+
var ExpressionLanguageModule = {
|
|
8622
|
+
__init__: ['expressionLanguage', 'templating'],
|
|
8623
|
+
expressionLanguage: ['type', formJsViewer.FeelExpressionLanguage],
|
|
8624
|
+
templating: ['type', formJsViewer.FeelersTemplating]
|
|
8625
|
+
};
|
|
8626
|
+
|
|
7906
8627
|
const ids = new Ids([32, 36, 1]);
|
|
7907
8628
|
|
|
7908
8629
|
/**
|
|
@@ -8155,7 +8876,7 @@ class FormEditor {
|
|
|
8155
8876
|
* @internal
|
|
8156
8877
|
*/
|
|
8157
8878
|
_getModules() {
|
|
8158
|
-
return [ModelingModule, EditorActionsModule, KeyboardModule, SelectionModule, PaletteModule, PropertiesPanelModule];
|
|
8879
|
+
return [ModelingModule, EditorActionsModule, DraggingModule, KeyboardModule, SelectionModule, PaletteModule, ExpressionLanguageModule, formJsViewer.MarkdownModule, PropertiesPanelModule];
|
|
8159
8880
|
}
|
|
8160
8881
|
|
|
8161
8882
|
/**
|