@bpmn-io/form-js-editor 1.17.0 → 1.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/form-js-editor.css +13 -1
- package/dist/assets/properties-panel.css +13 -1
- package/dist/index.cjs +400 -77
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +401 -78
- package/dist/index.es.js.map +1 -1
- package/package.json +7 -7
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var ids$1 = require('ids');
|
|
4
4
|
var formJsViewer = require('@bpmn-io/form-js-viewer');
|
|
5
5
|
var minDash = require('min-dash');
|
|
6
6
|
var classnames = require('classnames');
|
|
@@ -2890,11 +2890,35 @@ EditorActions.prototype._registerDefaultActions = function (injector) {
|
|
|
2890
2890
|
}
|
|
2891
2891
|
});
|
|
2892
2892
|
}
|
|
2893
|
+
if (copyPaste && selection) {
|
|
2894
|
+
this.register('duplicate', function () {
|
|
2895
|
+
var selectedElements = selection.get();
|
|
2896
|
+
if (selectedElements.length) {
|
|
2897
|
+
return copyPaste.duplicate(selectedElements);
|
|
2898
|
+
}
|
|
2899
|
+
});
|
|
2900
|
+
}
|
|
2893
2901
|
if (copyPaste) {
|
|
2894
2902
|
this.register('paste', function () {
|
|
2895
2903
|
copyPaste.paste();
|
|
2896
2904
|
});
|
|
2897
2905
|
}
|
|
2906
|
+
if (copyPaste && selection && rules) {
|
|
2907
|
+
this.register('cut', function () {
|
|
2908
|
+
var selectedElements = selection.get();
|
|
2909
|
+
if (!selectedElements.length) {
|
|
2910
|
+
return;
|
|
2911
|
+
}
|
|
2912
|
+
var allowed = rules.allowed('elements.delete', {
|
|
2913
|
+
elements: selectedElements
|
|
2914
|
+
});
|
|
2915
|
+
if (allowed === false) {
|
|
2916
|
+
return;
|
|
2917
|
+
}
|
|
2918
|
+
var cuttableElements = minDash.isArray(allowed) ? allowed : selectedElements;
|
|
2919
|
+
return copyPaste.cut(cuttableElements.slice());
|
|
2920
|
+
});
|
|
2921
|
+
}
|
|
2898
2922
|
if (zoomScroll) {
|
|
2899
2923
|
this.register('stepZoom', function (opts) {
|
|
2900
2924
|
zoomScroll.stepZoom(opts.value);
|
|
@@ -3113,6 +3137,8 @@ const EditorExpressionLanguageModule = {
|
|
|
3113
3137
|
|
|
3114
3138
|
var KEYS_COPY = ['c', 'C'];
|
|
3115
3139
|
var KEYS_PASTE = ['v', 'V'];
|
|
3140
|
+
var KEYS_DUPLICATE = ['d', 'D'];
|
|
3141
|
+
var KEYS_CUT = ['x', 'X'];
|
|
3116
3142
|
var KEYS_REDO = ['y', 'Y'];
|
|
3117
3143
|
var KEYS_UNDO = ['z', 'Z'];
|
|
3118
3144
|
|
|
@@ -3128,7 +3154,7 @@ function hasModifier(event) {
|
|
|
3128
3154
|
* @param {KeyboardEvent} event
|
|
3129
3155
|
* @return {boolean}
|
|
3130
3156
|
*/
|
|
3131
|
-
function isCmd(event) {
|
|
3157
|
+
function isCmd$1(event) {
|
|
3132
3158
|
// ensure we don't react to AltGr
|
|
3133
3159
|
// (mapped to CTRL + ALT)
|
|
3134
3160
|
if (event.altKey) {
|
|
@@ -3160,28 +3186,42 @@ function isShift(event) {
|
|
|
3160
3186
|
* @param {KeyboardEvent} event
|
|
3161
3187
|
*/
|
|
3162
3188
|
function isCopy(event) {
|
|
3163
|
-
return isCmd(event) && isKey(KEYS_COPY, event);
|
|
3189
|
+
return isCmd$1(event) && isKey(KEYS_COPY, event);
|
|
3164
3190
|
}
|
|
3165
3191
|
|
|
3166
3192
|
/**
|
|
3167
3193
|
* @param {KeyboardEvent} event
|
|
3168
3194
|
*/
|
|
3169
3195
|
function isPaste(event) {
|
|
3170
|
-
return isCmd(event) && isKey(KEYS_PASTE, event);
|
|
3196
|
+
return isCmd$1(event) && isKey(KEYS_PASTE, event);
|
|
3197
|
+
}
|
|
3198
|
+
|
|
3199
|
+
/**
|
|
3200
|
+
* @param {KeyboardEvent} event
|
|
3201
|
+
*/
|
|
3202
|
+
function isDuplicate(event) {
|
|
3203
|
+
return isCmd$1(event) && isKey(KEYS_DUPLICATE, event);
|
|
3204
|
+
}
|
|
3205
|
+
|
|
3206
|
+
/**
|
|
3207
|
+
* @param {KeyboardEvent} event
|
|
3208
|
+
*/
|
|
3209
|
+
function isCut(event) {
|
|
3210
|
+
return isCmd$1(event) && isKey(KEYS_CUT, event);
|
|
3171
3211
|
}
|
|
3172
3212
|
|
|
3173
3213
|
/**
|
|
3174
3214
|
* @param {KeyboardEvent} event
|
|
3175
3215
|
*/
|
|
3176
3216
|
function isUndo(event) {
|
|
3177
|
-
return isCmd(event) && !isShift(event) && isKey(KEYS_UNDO, event);
|
|
3217
|
+
return isCmd$1(event) && !isShift(event) && isKey(KEYS_UNDO, event);
|
|
3178
3218
|
}
|
|
3179
3219
|
|
|
3180
3220
|
/**
|
|
3181
3221
|
* @param {KeyboardEvent} event
|
|
3182
3222
|
*/
|
|
3183
3223
|
function isRedo(event) {
|
|
3184
|
-
return isCmd(event) && (isKey(KEYS_REDO, event) || isKey(KEYS_UNDO, event) && isShift(event));
|
|
3224
|
+
return isCmd$1(event) && (isKey(KEYS_REDO, event) || isKey(KEYS_UNDO, event) && isShift(event));
|
|
3185
3225
|
}
|
|
3186
3226
|
|
|
3187
3227
|
/**
|
|
@@ -3350,7 +3390,7 @@ Keyboard.prototype.removeListener = function (listener, type) {
|
|
|
3350
3390
|
this._eventBus.off(type || KEYDOWN_EVENT, listener);
|
|
3351
3391
|
};
|
|
3352
3392
|
Keyboard.prototype.hasModifier = hasModifier;
|
|
3353
|
-
Keyboard.prototype.isCmd = isCmd;
|
|
3393
|
+
Keyboard.prototype.isCmd = isCmd$1;
|
|
3354
3394
|
Keyboard.prototype.isShift = isShift;
|
|
3355
3395
|
Keyboard.prototype.isKey = isKey;
|
|
3356
3396
|
|
|
@@ -3435,6 +3475,26 @@ KeyboardBindings.prototype.registerBindings = function (keyboard, editorActions)
|
|
|
3435
3475
|
}
|
|
3436
3476
|
});
|
|
3437
3477
|
|
|
3478
|
+
// duplicate
|
|
3479
|
+
// CTRL/CMD + D
|
|
3480
|
+
addListener('duplicate', function (context) {
|
|
3481
|
+
var event = context.keyEvent;
|
|
3482
|
+
if (isDuplicate(event)) {
|
|
3483
|
+
editorActions.trigger('duplicate');
|
|
3484
|
+
return true;
|
|
3485
|
+
}
|
|
3486
|
+
});
|
|
3487
|
+
|
|
3488
|
+
// cut
|
|
3489
|
+
// CTRL/CMD + X
|
|
3490
|
+
addListener('cut', function (context) {
|
|
3491
|
+
var event = context.keyEvent;
|
|
3492
|
+
if (isCut(event)) {
|
|
3493
|
+
editorActions.trigger('cut');
|
|
3494
|
+
return true;
|
|
3495
|
+
}
|
|
3496
|
+
});
|
|
3497
|
+
|
|
3438
3498
|
// zoom in one step
|
|
3439
3499
|
// CTRL/CMD + +
|
|
3440
3500
|
addListener('stepZoom', function (context) {
|
|
@@ -3442,7 +3502,7 @@ KeyboardBindings.prototype.registerBindings = function (keyboard, editorActions)
|
|
|
3442
3502
|
|
|
3443
3503
|
// quirk: it has to be triggered by `=` as well to work on international keyboard layout
|
|
3444
3504
|
// cf: https://github.com/bpmn-io/bpmn-js/issues/1362#issuecomment-722989754
|
|
3445
|
-
if (isKey(['+', 'Add', '='], event) && isCmd(event)) {
|
|
3505
|
+
if (isKey(['+', 'Add', '='], event) && isCmd$1(event)) {
|
|
3446
3506
|
editorActions.trigger('stepZoom', {
|
|
3447
3507
|
value: 1
|
|
3448
3508
|
});
|
|
@@ -3454,7 +3514,7 @@ KeyboardBindings.prototype.registerBindings = function (keyboard, editorActions)
|
|
|
3454
3514
|
// CTRL + -
|
|
3455
3515
|
addListener('stepZoom', function (context) {
|
|
3456
3516
|
var event = context.keyEvent;
|
|
3457
|
-
if (isKey(['-', 'Subtract'], event) && isCmd(event)) {
|
|
3517
|
+
if (isKey(['-', 'Subtract'], event) && isCmd$1(event)) {
|
|
3458
3518
|
editorActions.trigger('stepZoom', {
|
|
3459
3519
|
value: -1
|
|
3460
3520
|
});
|
|
@@ -3466,7 +3526,7 @@ KeyboardBindings.prototype.registerBindings = function (keyboard, editorActions)
|
|
|
3466
3526
|
// CTRL + 0
|
|
3467
3527
|
addListener('zoom', function (context) {
|
|
3468
3528
|
var event = context.keyEvent;
|
|
3469
|
-
if (isKey('0', event) && isCmd(event)) {
|
|
3529
|
+
if (isKey('0', event) && isCmd$1(event)) {
|
|
3470
3530
|
editorActions.trigger('zoom', {
|
|
3471
3531
|
value: 1
|
|
3472
3532
|
});
|
|
@@ -5462,23 +5522,32 @@ LaunchIcon.defaultProps = {
|
|
|
5462
5522
|
viewBox: "0 0 32 32"
|
|
5463
5523
|
};
|
|
5464
5524
|
var OpenPopupIcon = function OpenPopupIcon(props) {
|
|
5465
|
-
return jsxRuntime.
|
|
5525
|
+
return jsxRuntime.jsx("svg", {
|
|
5466
5526
|
...props,
|
|
5467
|
-
children:
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
}), jsxRuntime.jsx("path", {
|
|
5471
|
-
fill: "currentColor",
|
|
5472
|
-
d: "M18 26H4V16h2v-2H4a2.006 2.006 0 0 0-2 2v10a2.006 2.006 0 0 0 2 2h14a2.006 2.006 0 0 0 2-2v-2h-2Z"
|
|
5473
|
-
})]
|
|
5527
|
+
children: jsxRuntime.jsx("path", {
|
|
5528
|
+
d: "M6 15v-1H2.7L7 9.7 6.3 9 2 13.3V10H1v5zm4-14v1h3.3L9 6.3l.7.7L14 2.7V6h1V1z"
|
|
5529
|
+
})
|
|
5474
5530
|
});
|
|
5475
5531
|
};
|
|
5476
5532
|
OpenPopupIcon.defaultProps = {
|
|
5477
5533
|
xmlns: "http://www.w3.org/2000/svg",
|
|
5478
|
-
|
|
5479
|
-
height: "16",
|
|
5480
|
-
viewBox: "0 0 32 32"
|
|
5534
|
+
viewBox: "0 0 16 16"
|
|
5481
5535
|
};
|
|
5536
|
+
|
|
5537
|
+
/**
|
|
5538
|
+
* @typedef { {
|
|
5539
|
+
* getElementLabel: (element: object) => string,
|
|
5540
|
+
* getTypeLabel: (element: object) => string,
|
|
5541
|
+
* getElementIcon: (element: object) => import('preact').Component,
|
|
5542
|
+
* getDocumentationRef: (element: object) => string
|
|
5543
|
+
* } } HeaderProvider
|
|
5544
|
+
*/
|
|
5545
|
+
|
|
5546
|
+
/**
|
|
5547
|
+
* @param {Object} props
|
|
5548
|
+
* @param {Object} props.element,
|
|
5549
|
+
* @param {HeaderProvider} props.headerProvider
|
|
5550
|
+
*/
|
|
5482
5551
|
function Header(props) {
|
|
5483
5552
|
const {
|
|
5484
5553
|
element,
|
|
@@ -5506,11 +5575,9 @@ function Header(props) {
|
|
|
5506
5575
|
}), jsxRuntime.jsxs("div", {
|
|
5507
5576
|
class: "bio-properties-panel-header-labels",
|
|
5508
5577
|
children: [jsxRuntime.jsx("div", {
|
|
5509
|
-
title: type,
|
|
5510
5578
|
class: "bio-properties-panel-header-type",
|
|
5511
5579
|
children: type
|
|
5512
5580
|
}), label ? jsxRuntime.jsx("div", {
|
|
5513
|
-
title: label,
|
|
5514
5581
|
class: "bio-properties-panel-header-label",
|
|
5515
5582
|
children: label
|
|
5516
5583
|
}) : null]
|
|
@@ -5598,6 +5665,27 @@ function useTooltipContext(id, element) {
|
|
|
5598
5665
|
} = hooks.useContext(TooltipContext);
|
|
5599
5666
|
return getTooltipForId(id, element);
|
|
5600
5667
|
}
|
|
5668
|
+
|
|
5669
|
+
/**
|
|
5670
|
+
* @typedef {Object} TooltipProps
|
|
5671
|
+
* @property {Object} [parent] - Parent element ref for portal rendering
|
|
5672
|
+
* @property {String} [direction='right'] - Tooltip direction ( 'right', 'top')
|
|
5673
|
+
* @property {String} [position] - Custom CSS position override
|
|
5674
|
+
* @property {Number} [showDelay=250] - Delay in ms before showing tooltip on hover
|
|
5675
|
+
* @property {Number} [hideDelay=250] - Delay in ms before hiding tooltip when mouse leaves, to avoid multiple tooltips from being opened, this should be the same as showDelay
|
|
5676
|
+
* @property {*} [children] - Child elements to render inside the tooltip wrapper
|
|
5677
|
+
*/
|
|
5678
|
+
|
|
5679
|
+
/**
|
|
5680
|
+
* Tooltip wrapper that provides context-based tooltip content lookup.
|
|
5681
|
+
* All props are forwarded to the underlying Tooltip component.
|
|
5682
|
+
*
|
|
5683
|
+
* @param {TooltipProps & {
|
|
5684
|
+
* forId: String,
|
|
5685
|
+
* value?: String|Object,
|
|
5686
|
+
* element?: Object
|
|
5687
|
+
* }} props - Shared tooltip props plus wrapper-specific ones
|
|
5688
|
+
*/
|
|
5601
5689
|
function TooltipWrapper(props) {
|
|
5602
5690
|
const {
|
|
5603
5691
|
forId,
|
|
@@ -5614,35 +5702,77 @@ function TooltipWrapper(props) {
|
|
|
5614
5702
|
forId: `bio-properties-panel-${forId}`
|
|
5615
5703
|
});
|
|
5616
5704
|
}
|
|
5705
|
+
|
|
5706
|
+
/**
|
|
5707
|
+
* @param {TooltipProps & {
|
|
5708
|
+
* forId: String,
|
|
5709
|
+
* value: String|Object
|
|
5710
|
+
* }} props
|
|
5711
|
+
*/
|
|
5617
5712
|
function Tooltip(props) {
|
|
5618
5713
|
const {
|
|
5619
5714
|
forId,
|
|
5620
5715
|
value,
|
|
5621
5716
|
parent,
|
|
5622
5717
|
direction = 'right',
|
|
5623
|
-
position
|
|
5718
|
+
position,
|
|
5719
|
+
showDelay = 250,
|
|
5720
|
+
hideDelay = 250
|
|
5624
5721
|
} = props;
|
|
5625
5722
|
const [visible, setVisible] = hooks.useState(false);
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
const SHOW_DELAY = 200;
|
|
5629
|
-
let timeout = null;
|
|
5723
|
+
const showTimeoutRef = hooks.useRef(null);
|
|
5724
|
+
const hideTimeoutRef = hooks.useRef(null);
|
|
5630
5725
|
const wrapperRef = hooks.useRef(null);
|
|
5631
5726
|
const tooltipRef = hooks.useRef(null);
|
|
5632
5727
|
const show = (_, delay) => {
|
|
5728
|
+
clearTimeout(showTimeoutRef.current);
|
|
5729
|
+
clearTimeout(hideTimeoutRef.current);
|
|
5633
5730
|
if (visible) return;
|
|
5634
5731
|
if (delay) {
|
|
5635
|
-
|
|
5732
|
+
showTimeoutRef.current = setTimeout(() => {
|
|
5636
5733
|
setVisible(true);
|
|
5637
|
-
},
|
|
5734
|
+
}, showDelay);
|
|
5638
5735
|
} else {
|
|
5639
5736
|
setVisible(true);
|
|
5640
5737
|
}
|
|
5641
5738
|
};
|
|
5642
|
-
const
|
|
5643
|
-
|
|
5644
|
-
|
|
5739
|
+
const handleWrapperMouseEnter = e => {
|
|
5740
|
+
show(e, true);
|
|
5741
|
+
};
|
|
5742
|
+
const hide = (delay = false) => {
|
|
5743
|
+
clearTimeout(showTimeoutRef.current);
|
|
5744
|
+
clearTimeout(hideTimeoutRef.current);
|
|
5745
|
+
if (delay) {
|
|
5746
|
+
hideTimeoutRef.current = setTimeout(() => {
|
|
5747
|
+
setVisible(false);
|
|
5748
|
+
}, hideDelay);
|
|
5749
|
+
} else {
|
|
5750
|
+
setVisible(false);
|
|
5751
|
+
}
|
|
5645
5752
|
};
|
|
5753
|
+
|
|
5754
|
+
// Cleanup timeouts on unmount
|
|
5755
|
+
hooks.useEffect(() => {
|
|
5756
|
+
return () => {
|
|
5757
|
+
clearTimeout(showTimeoutRef.current);
|
|
5758
|
+
clearTimeout(hideTimeoutRef.current);
|
|
5759
|
+
};
|
|
5760
|
+
}, []);
|
|
5761
|
+
|
|
5762
|
+
// Handle click outside to close tooltip for non-focusable elements
|
|
5763
|
+
hooks.useEffect(() => {
|
|
5764
|
+
if (!visible) return;
|
|
5765
|
+
const handleClickOutside = e => {
|
|
5766
|
+
// If clicking outside both the wrapper and tooltip, hide it
|
|
5767
|
+
if (wrapperRef.current && !wrapperRef.current.contains(e.target) && tooltipRef.current && !tooltipRef.current.contains(e.target)) {
|
|
5768
|
+
hide(false);
|
|
5769
|
+
}
|
|
5770
|
+
};
|
|
5771
|
+
document.addEventListener('mousedown', handleClickOutside);
|
|
5772
|
+
return () => {
|
|
5773
|
+
document.removeEventListener('mousedown', handleClickOutside);
|
|
5774
|
+
};
|
|
5775
|
+
}, [visible, hide]);
|
|
5646
5776
|
const handleMouseLeave = ({
|
|
5647
5777
|
relatedTarget
|
|
5648
5778
|
}) => {
|
|
@@ -5650,23 +5780,32 @@ function Tooltip(props) {
|
|
|
5650
5780
|
if (relatedTarget === wrapperRef.current || relatedTarget === tooltipRef.current || relatedTarget?.parentElement === tooltipRef.current) {
|
|
5651
5781
|
return;
|
|
5652
5782
|
}
|
|
5653
|
-
|
|
5783
|
+
const selection = window.getSelection();
|
|
5784
|
+
if (selection && selection.toString().length > 0) {
|
|
5785
|
+
// Check if selection is within tooltip content
|
|
5786
|
+
const selectionRange = selection.getRangeAt(0);
|
|
5787
|
+
if (tooltipRef.current?.contains(selectionRange.commonAncestorContainer) || tooltipRef.current?.contains(selection.anchorNode) || tooltipRef.current?.contains(selection.focusNode)) {
|
|
5788
|
+
return; // Keep tooltip open during text selection
|
|
5789
|
+
}
|
|
5790
|
+
}
|
|
5791
|
+
hide(true);
|
|
5792
|
+
};
|
|
5793
|
+
const handleTooltipMouseEnter = () => {
|
|
5794
|
+
clearTimeout(hideTimeoutRef.current);
|
|
5654
5795
|
};
|
|
5655
5796
|
const handleFocusOut = e => {
|
|
5656
5797
|
const {
|
|
5657
|
-
|
|
5798
|
+
relatedTarget
|
|
5658
5799
|
} = e;
|
|
5659
5800
|
|
|
5660
|
-
// Don't hide
|
|
5661
|
-
|
|
5662
|
-
if (target === wrapperRef.current && isHovered) {
|
|
5663
|
-
e.stopPropagation();
|
|
5801
|
+
// Don't hide if focus moved to the tooltip or another element within the wrapper
|
|
5802
|
+
if (tooltipRef.current?.contains(relatedTarget) || wrapperRef.current?.contains(relatedTarget)) {
|
|
5664
5803
|
return;
|
|
5665
5804
|
}
|
|
5666
|
-
hide();
|
|
5805
|
+
hide(false);
|
|
5667
5806
|
};
|
|
5668
5807
|
const hideTooltipViaEscape = e => {
|
|
5669
|
-
e.code === 'Escape' && hide();
|
|
5808
|
+
e.code === 'Escape' && hide(false);
|
|
5670
5809
|
};
|
|
5671
5810
|
const renderTooltip = () => {
|
|
5672
5811
|
return jsxRuntime.jsxs("div", {
|
|
@@ -5677,6 +5816,7 @@ function Tooltip(props) {
|
|
|
5677
5816
|
style: position || getTooltipPosition(wrapperRef.current),
|
|
5678
5817
|
ref: tooltipRef,
|
|
5679
5818
|
onClick: e => e.stopPropagation(),
|
|
5819
|
+
onMouseEnter: handleTooltipMouseEnter,
|
|
5680
5820
|
onMouseLeave: handleMouseLeave,
|
|
5681
5821
|
children: [jsxRuntime.jsx("div", {
|
|
5682
5822
|
class: "bio-properties-panel-tooltip-content",
|
|
@@ -5690,7 +5830,7 @@ function Tooltip(props) {
|
|
|
5690
5830
|
class: "bio-properties-panel-tooltip-wrapper",
|
|
5691
5831
|
tabIndex: "0",
|
|
5692
5832
|
ref: wrapperRef,
|
|
5693
|
-
onMouseEnter:
|
|
5833
|
+
onMouseEnter: handleWrapperMouseEnter,
|
|
5694
5834
|
onMouseLeave: handleMouseLeave,
|
|
5695
5835
|
onFocus: show,
|
|
5696
5836
|
onBlur: handleFocusOut,
|
|
@@ -5968,6 +6108,10 @@ function useElementVisible(element) {
|
|
|
5968
6108
|
}, [element, visible]);
|
|
5969
6109
|
return visible;
|
|
5970
6110
|
}
|
|
6111
|
+
|
|
6112
|
+
/**
|
|
6113
|
+
* @param {import('../PropertiesPanel').GroupDefinition} props
|
|
6114
|
+
*/
|
|
5971
6115
|
function Group(props) {
|
|
5972
6116
|
const {
|
|
5973
6117
|
element,
|
|
@@ -6022,8 +6166,6 @@ function Group(props) {
|
|
|
6022
6166
|
class: classnames('bio-properties-panel-group-header', edited ? '' : 'empty', open ? 'open' : '', sticky && open ? 'sticky' : ''),
|
|
6023
6167
|
onClick: toggleOpen,
|
|
6024
6168
|
children: [jsxRuntime.jsx("div", {
|
|
6025
|
-
title: props.tooltip ? null : label,
|
|
6026
|
-
"data-title": label,
|
|
6027
6169
|
class: "bio-properties-panel-group-header-title",
|
|
6028
6170
|
children: jsxRuntime.jsx(TooltipWrapper, {
|
|
6029
6171
|
value: props.tooltip,
|
|
@@ -6227,9 +6369,11 @@ function PropertiesPanel$1(props) {
|
|
|
6227
6369
|
return minDash.get(layout, key, defaultValue);
|
|
6228
6370
|
};
|
|
6229
6371
|
const setLayoutForKey = (key, config) => {
|
|
6230
|
-
|
|
6231
|
-
|
|
6232
|
-
|
|
6372
|
+
setLayout(prevLayout => {
|
|
6373
|
+
const newLayout = minDash.assign({}, prevLayout);
|
|
6374
|
+
minDash.set(newLayout, key, config);
|
|
6375
|
+
return newLayout;
|
|
6376
|
+
});
|
|
6233
6377
|
};
|
|
6234
6378
|
const layoutContext = {
|
|
6235
6379
|
layout,
|
|
@@ -6428,7 +6572,6 @@ function CollapsibleEntry(props) {
|
|
|
6428
6572
|
class: "bio-properties-panel-collapsible-entry-header",
|
|
6429
6573
|
onClick: toggleOpen,
|
|
6430
6574
|
children: [jsxRuntime.jsx("div", {
|
|
6431
|
-
title: label || placeholderLabel,
|
|
6432
6575
|
class: classnames('bio-properties-panel-collapsible-entry-header-title', !label && 'empty'),
|
|
6433
6576
|
children: label || placeholderLabel
|
|
6434
6577
|
}), jsxRuntime.jsx("button", {
|
|
@@ -6464,6 +6607,10 @@ function CollapsibleEntry(props) {
|
|
|
6464
6607
|
})]
|
|
6465
6608
|
});
|
|
6466
6609
|
}
|
|
6610
|
+
|
|
6611
|
+
/**
|
|
6612
|
+
* @param {import('../PropertiesPanel').ListItemDefinition} props
|
|
6613
|
+
*/
|
|
6467
6614
|
function ListItem(props) {
|
|
6468
6615
|
const {
|
|
6469
6616
|
autoFocusEntry,
|
|
@@ -6565,8 +6712,6 @@ function ListGroup(props) {
|
|
|
6565
6712
|
class: classnames('bio-properties-panel-group-header', hasItems ? '' : 'empty', hasItems && open ? 'open' : '', sticky && open ? 'sticky' : ''),
|
|
6566
6713
|
onClick: hasItems ? toggleOpen : noop$6,
|
|
6567
6714
|
children: [jsxRuntime.jsx("div", {
|
|
6568
|
-
title: props.tooltip ? null : label,
|
|
6569
|
-
"data-title": label,
|
|
6570
6715
|
class: "bio-properties-panel-group-header-title",
|
|
6571
6716
|
children: jsxRuntime.jsx(TooltipWrapper, {
|
|
6572
6717
|
value: props.tooltip,
|
|
@@ -6635,6 +6780,13 @@ function getNewItemIds(newItems, oldItems) {
|
|
|
6635
6780
|
const oldIds = oldItems.map(item => item.id);
|
|
6636
6781
|
return newIds.filter(itemId => !oldIds.includes(itemId));
|
|
6637
6782
|
}
|
|
6783
|
+
|
|
6784
|
+
/**
|
|
6785
|
+
* @param {Object} props
|
|
6786
|
+
* @param {Object} props.element
|
|
6787
|
+
* @param {String} props.forId - id of the entry the description is used for
|
|
6788
|
+
* @param {String} props.value
|
|
6789
|
+
*/
|
|
6638
6790
|
function Description$1(props) {
|
|
6639
6791
|
const {
|
|
6640
6792
|
element,
|
|
@@ -6764,6 +6916,16 @@ function isEdited$8(node) {
|
|
|
6764
6916
|
function prefixId$8(id) {
|
|
6765
6917
|
return `bio-properties-panel-${id}`;
|
|
6766
6918
|
}
|
|
6919
|
+
|
|
6920
|
+
/**
|
|
6921
|
+
* Button to open popups.
|
|
6922
|
+
*
|
|
6923
|
+
* @param {Object} props
|
|
6924
|
+
* @param {Function} props.onClick - Callback to trigger when the button is clicked.
|
|
6925
|
+
* @param {string} [props.title] - Tooltip text for the button.
|
|
6926
|
+
* @param {boolean} [props.disabled] - Whether the button is disabled.
|
|
6927
|
+
* @param {string} [props.className] - Additional class names for the button.
|
|
6928
|
+
*/
|
|
6767
6929
|
function OpenPopupButton({
|
|
6768
6930
|
onClick,
|
|
6769
6931
|
title = 'Open pop-up editor'
|
|
@@ -6907,6 +7069,7 @@ const FeelEditor = React.forwardRef((props, ref) => {
|
|
|
6907
7069
|
enableGutters,
|
|
6908
7070
|
value,
|
|
6909
7071
|
onInput,
|
|
7072
|
+
onKeyDown: onKeyDownProp = noop$4,
|
|
6910
7073
|
onFeelToggle = noop$4,
|
|
6911
7074
|
onLint = noop$4,
|
|
6912
7075
|
onOpenPopup = noop$4,
|
|
@@ -6939,6 +7102,8 @@ const FeelEditor = React.forwardRef((props, ref) => {
|
|
|
6939
7102
|
* - AND the cursor is at the beginning of the input
|
|
6940
7103
|
*/
|
|
6941
7104
|
const onKeyDown = e => {
|
|
7105
|
+
// Call parent onKeyDown handler first
|
|
7106
|
+
onKeyDownProp(e);
|
|
6942
7107
|
if (e.key !== 'Backspace' || !editor) {
|
|
6943
7108
|
return;
|
|
6944
7109
|
}
|
|
@@ -7055,6 +7220,22 @@ function FeelIcon(props) {
|
|
|
7055
7220
|
children: jsxRuntime.jsx(FeelIcon$1, {})
|
|
7056
7221
|
});
|
|
7057
7222
|
}
|
|
7223
|
+
|
|
7224
|
+
/**
|
|
7225
|
+
* @param {KeyboardEvent} event
|
|
7226
|
+
* @return {boolean}
|
|
7227
|
+
*/
|
|
7228
|
+
function isCmd(event) {
|
|
7229
|
+
// ensure we don't react to AltGr
|
|
7230
|
+
// (mapped to CTRL + ALT)
|
|
7231
|
+
if (event.altKey) {
|
|
7232
|
+
return false;
|
|
7233
|
+
}
|
|
7234
|
+
return event.ctrlKey || event.metaKey;
|
|
7235
|
+
}
|
|
7236
|
+
function isCmdWithChar(event) {
|
|
7237
|
+
return isCmd(event) && event.key.length === 1 && /^[a-zA-Z]$/.test(event.key);
|
|
7238
|
+
}
|
|
7058
7239
|
function ToggleSwitch(props) {
|
|
7059
7240
|
const {
|
|
7060
7241
|
id,
|
|
@@ -7366,7 +7547,7 @@ function FeelTextfield(props) {
|
|
|
7366
7547
|
element,
|
|
7367
7548
|
label,
|
|
7368
7549
|
hostLanguage,
|
|
7369
|
-
onInput,
|
|
7550
|
+
onInput: commitValue,
|
|
7370
7551
|
onBlur,
|
|
7371
7552
|
onError,
|
|
7372
7553
|
placeholder,
|
|
@@ -7382,6 +7563,12 @@ function FeelTextfield(props) {
|
|
|
7382
7563
|
const [localValue, setLocalValue] = hooks.useState(value);
|
|
7383
7564
|
const editorRef = useShowEntryEvent(id);
|
|
7384
7565
|
const containerRef = hooks.useRef();
|
|
7566
|
+
const onInput = hooks.useCallback(newValue => {
|
|
7567
|
+
// we don't commit empty FEEL expressions,
|
|
7568
|
+
// but instead serialize them as <undefined>
|
|
7569
|
+
const newModelValue = newValue === '' || newValue === '=' ? undefined : newValue;
|
|
7570
|
+
commitValue(newModelValue);
|
|
7571
|
+
}, [commitValue]);
|
|
7385
7572
|
const feelActive = minDash.isString(localValue) && localValue.startsWith('=') || feel === 'required';
|
|
7386
7573
|
const feelOnlyValue = minDash.isString(localValue) && localValue.startsWith('=') ? localValue.substring(1) : localValue;
|
|
7387
7574
|
const feelLanguageContext = hooks.useContext(FeelLanguageContext);
|
|
@@ -7401,13 +7588,7 @@ function FeelTextfield(props) {
|
|
|
7401
7588
|
/**
|
|
7402
7589
|
* @type { import('min-dash').DebouncedFunction }
|
|
7403
7590
|
*/
|
|
7404
|
-
const
|
|
7405
|
-
const handleInput = newValue => {
|
|
7406
|
-
// we don't commit empty FEEL expressions,
|
|
7407
|
-
// but instead serialize them as <undefined>
|
|
7408
|
-
const newModelValue = newValue === '' || newValue === '=' ? undefined : newValue;
|
|
7409
|
-
handleInputCallback(newModelValue);
|
|
7410
|
-
};
|
|
7591
|
+
const handleInput = useDebounce(onInput, debounce);
|
|
7411
7592
|
const handleFeelToggle = useStaticCallback(() => {
|
|
7412
7593
|
if (feel === 'required') {
|
|
7413
7594
|
return;
|
|
@@ -7420,7 +7601,7 @@ function FeelTextfield(props) {
|
|
|
7420
7601
|
handleInput(feelOnlyValue);
|
|
7421
7602
|
}
|
|
7422
7603
|
});
|
|
7423
|
-
const handleLocalInput = newValue => {
|
|
7604
|
+
const handleLocalInput = (newValue, useDebounce = true) => {
|
|
7424
7605
|
if (feelActive) {
|
|
7425
7606
|
newValue = '=' + newValue;
|
|
7426
7607
|
}
|
|
@@ -7428,23 +7609,33 @@ function FeelTextfield(props) {
|
|
|
7428
7609
|
return;
|
|
7429
7610
|
}
|
|
7430
7611
|
setLocalValue(newValue);
|
|
7431
|
-
|
|
7612
|
+
if (useDebounce) {
|
|
7613
|
+
handleInput(newValue);
|
|
7614
|
+
} else {
|
|
7615
|
+
onInput(newValue);
|
|
7616
|
+
}
|
|
7432
7617
|
if (!feelActive && minDash.isString(newValue) && newValue.startsWith('=')) {
|
|
7433
7618
|
// focus is behind `=` sign that will be removed
|
|
7434
7619
|
setFocus(-1);
|
|
7435
7620
|
}
|
|
7436
7621
|
};
|
|
7437
7622
|
const handleOnBlur = e => {
|
|
7623
|
+
handleInput.cancel?.();
|
|
7438
7624
|
if (e.target.type === 'checkbox') {
|
|
7439
7625
|
onInput(e.target.checked);
|
|
7440
7626
|
} else {
|
|
7441
7627
|
const trimmedValue = e.target.value.trim();
|
|
7442
|
-
|
|
7628
|
+
handleLocalInput(trimmedValue, false);
|
|
7443
7629
|
}
|
|
7444
7630
|
if (onBlur) {
|
|
7445
7631
|
onBlur(e);
|
|
7446
7632
|
}
|
|
7447
7633
|
};
|
|
7634
|
+
const handleOnKeyDown = e => {
|
|
7635
|
+
if (isCmdWithChar(e)) {
|
|
7636
|
+
handleInput.flush();
|
|
7637
|
+
}
|
|
7638
|
+
};
|
|
7448
7639
|
const handleLint = useStaticCallback((lint = []) => {
|
|
7449
7640
|
const syntaxError = lint.some(report => report.type === 'Syntax Error');
|
|
7450
7641
|
if (syntaxError) {
|
|
@@ -7511,12 +7702,26 @@ function FeelTextfield(props) {
|
|
|
7511
7702
|
if (feelActive || isPopupOpen) {
|
|
7512
7703
|
return;
|
|
7513
7704
|
}
|
|
7514
|
-
const
|
|
7515
|
-
if (
|
|
7705
|
+
const feelData = event.clipboardData.getData('application/FEEL');
|
|
7706
|
+
if (feelData) {
|
|
7516
7707
|
setTimeout(() => {
|
|
7517
7708
|
handleFeelToggle();
|
|
7518
7709
|
setFocus();
|
|
7519
7710
|
});
|
|
7711
|
+
return;
|
|
7712
|
+
}
|
|
7713
|
+
const input = event.target;
|
|
7714
|
+
const isFieldEmpty = !input.value;
|
|
7715
|
+
const isAllSelected = input.selectionStart === 0 && input.selectionEnd === input.value.length;
|
|
7716
|
+
if (isFieldEmpty || isAllSelected) {
|
|
7717
|
+
const textData = event.clipboardData.getData('text');
|
|
7718
|
+
const trimmedValue = textData.trim();
|
|
7719
|
+
setLocalValue(trimmedValue);
|
|
7720
|
+
handleInput(trimmedValue);
|
|
7721
|
+
if (!feelActive && minDash.isString(trimmedValue) && trimmedValue.startsWith('=')) {
|
|
7722
|
+
setFocus(trimmedValue.length - 1);
|
|
7723
|
+
}
|
|
7724
|
+
event.preventDefault();
|
|
7520
7725
|
}
|
|
7521
7726
|
};
|
|
7522
7727
|
containerRef.current.addEventListener('copy', copyHandler);
|
|
@@ -7557,6 +7762,7 @@ function FeelTextfield(props) {
|
|
|
7557
7762
|
}), feelActive ? jsxRuntime.jsx(FeelEditor, {
|
|
7558
7763
|
name: id,
|
|
7559
7764
|
onInput: handleLocalInput,
|
|
7765
|
+
onKeyDown: handleOnKeyDown,
|
|
7560
7766
|
contentAttributes: {
|
|
7561
7767
|
'id': prefixId$5(id),
|
|
7562
7768
|
'aria-label': label
|
|
@@ -7579,6 +7785,7 @@ function FeelTextfield(props) {
|
|
|
7579
7785
|
...props,
|
|
7580
7786
|
popupOpen: isPopupOpen,
|
|
7581
7787
|
onInput: handleLocalInput,
|
|
7788
|
+
onKeyDown: handleOnKeyDown,
|
|
7582
7789
|
onBlur: handleOnBlur,
|
|
7583
7790
|
contentAttributes: {
|
|
7584
7791
|
'id': prefixId$5(id),
|
|
@@ -7597,6 +7804,7 @@ const OptionalFeelInput = React.forwardRef((props, ref) => {
|
|
|
7597
7804
|
id,
|
|
7598
7805
|
disabled,
|
|
7599
7806
|
onInput,
|
|
7807
|
+
onKeyDown,
|
|
7600
7808
|
value,
|
|
7601
7809
|
onFocus,
|
|
7602
7810
|
onBlur,
|
|
@@ -7632,6 +7840,7 @@ const OptionalFeelInput = React.forwardRef((props, ref) => {
|
|
|
7632
7840
|
class: "bio-properties-panel-input",
|
|
7633
7841
|
onInput: e => onInput(e.target.value),
|
|
7634
7842
|
onFocus: onFocus,
|
|
7843
|
+
onKeyDown: onKeyDown,
|
|
7635
7844
|
onBlur: onBlur,
|
|
7636
7845
|
placeholder: placeholder,
|
|
7637
7846
|
value: value || ''
|
|
@@ -8005,6 +8214,25 @@ function isEdited$5(node) {
|
|
|
8005
8214
|
function prefixId$5(id) {
|
|
8006
8215
|
return `bio-properties-panel-${id}`;
|
|
8007
8216
|
}
|
|
8217
|
+
|
|
8218
|
+
/**
|
|
8219
|
+
* @typedef { { value: string, label: string, disabled: boolean, children: { value: string, label: string, disabled: boolean } } } Option
|
|
8220
|
+
*/
|
|
8221
|
+
|
|
8222
|
+
/**
|
|
8223
|
+
* Provides basic select input.
|
|
8224
|
+
*
|
|
8225
|
+
* @param {object} props
|
|
8226
|
+
* @param {string} props.id
|
|
8227
|
+
* @param {string[]} props.path
|
|
8228
|
+
* @param {string} props.label
|
|
8229
|
+
* @param {Function} props.onChange
|
|
8230
|
+
* @param {Function} props.onFocus
|
|
8231
|
+
* @param {Function} props.onBlur
|
|
8232
|
+
* @param {Array<Option>} [props.options]
|
|
8233
|
+
* @param {string} props.value
|
|
8234
|
+
* @param {boolean} [props.disabled]
|
|
8235
|
+
*/
|
|
8008
8236
|
function Select(props) {
|
|
8009
8237
|
const {
|
|
8010
8238
|
id,
|
|
@@ -8170,12 +8398,13 @@ function TextArea(props) {
|
|
|
8170
8398
|
id,
|
|
8171
8399
|
label,
|
|
8172
8400
|
debounce,
|
|
8173
|
-
onInput,
|
|
8401
|
+
onInput: commitValue,
|
|
8174
8402
|
value = '',
|
|
8175
8403
|
disabled,
|
|
8176
8404
|
monospace,
|
|
8177
8405
|
onFocus,
|
|
8178
8406
|
onBlur,
|
|
8407
|
+
onPaste,
|
|
8179
8408
|
autoResize = true,
|
|
8180
8409
|
placeholder,
|
|
8181
8410
|
rows = autoResize ? 1 : 2,
|
|
@@ -8183,16 +8412,16 @@ function TextArea(props) {
|
|
|
8183
8412
|
} = props;
|
|
8184
8413
|
const [localValue, setLocalValue] = hooks.useState(value);
|
|
8185
8414
|
const ref = useShowEntryEvent(id);
|
|
8415
|
+
const onInput = hooks.useCallback(newValue => {
|
|
8416
|
+
const newModelValue = newValue === '' ? undefined : newValue;
|
|
8417
|
+
commitValue(newModelValue);
|
|
8418
|
+
}, [commitValue]);
|
|
8186
8419
|
const visible = useElementVisible(ref.current);
|
|
8187
8420
|
|
|
8188
8421
|
/**
|
|
8189
8422
|
* @type { import('min-dash').DebouncedFunction }
|
|
8190
8423
|
*/
|
|
8191
|
-
const
|
|
8192
|
-
const handleInput = newValue => {
|
|
8193
|
-
const newModelValue = newValue === '' ? undefined : newValue;
|
|
8194
|
-
handleInputCallback(newModelValue);
|
|
8195
|
-
};
|
|
8424
|
+
const handleInput = useDebounce(onInput, debounce);
|
|
8196
8425
|
const handleLocalInput = e => {
|
|
8197
8426
|
autoResize && resizeToContents(e.target);
|
|
8198
8427
|
if (e.target.value === localValue) {
|
|
@@ -8205,11 +8434,40 @@ function TextArea(props) {
|
|
|
8205
8434
|
const trimmedValue = e.target.value.trim();
|
|
8206
8435
|
|
|
8207
8436
|
// trim and commit on blur
|
|
8437
|
+
handleInput.cancel?.();
|
|
8208
8438
|
onInput(trimmedValue);
|
|
8439
|
+
setLocalValue(trimmedValue);
|
|
8209
8440
|
if (onBlur) {
|
|
8210
8441
|
onBlur(e);
|
|
8211
8442
|
}
|
|
8212
8443
|
};
|
|
8444
|
+
const handleOnPaste = e => {
|
|
8445
|
+
const input = e.target;
|
|
8446
|
+
const isFieldEmpty = !input.value;
|
|
8447
|
+
const isAllSelected = input.selectionStart === 0 && input.selectionEnd === input.value.length;
|
|
8448
|
+
|
|
8449
|
+
// Trim and handle paste if field is empty or all content is selected
|
|
8450
|
+
if (isFieldEmpty || isAllSelected) {
|
|
8451
|
+
const trimmedValue = e.clipboardData.getData('text').trim();
|
|
8452
|
+
setLocalValue(trimmedValue);
|
|
8453
|
+
handleInput(trimmedValue);
|
|
8454
|
+
if (onPaste) {
|
|
8455
|
+
onPaste(e);
|
|
8456
|
+
}
|
|
8457
|
+
e.preventDefault();
|
|
8458
|
+
return;
|
|
8459
|
+
}
|
|
8460
|
+
|
|
8461
|
+
// Allow default paste behavior for normal text editing
|
|
8462
|
+
if (onPaste) {
|
|
8463
|
+
onPaste(e);
|
|
8464
|
+
}
|
|
8465
|
+
};
|
|
8466
|
+
const handleOnKeyDown = e => {
|
|
8467
|
+
if (isCmdWithChar(e)) {
|
|
8468
|
+
handleInput.flush();
|
|
8469
|
+
}
|
|
8470
|
+
};
|
|
8213
8471
|
hooks.useLayoutEffect(() => {
|
|
8214
8472
|
autoResize && resizeToContents(ref.current);
|
|
8215
8473
|
}, []);
|
|
@@ -8241,7 +8499,9 @@ function TextArea(props) {
|
|
|
8241
8499
|
class: classnames('bio-properties-panel-input', monospace ? 'bio-properties-panel-input-monospace' : '', autoResize ? 'auto-resize' : ''),
|
|
8242
8500
|
onInput: handleLocalInput,
|
|
8243
8501
|
onFocus: onFocus,
|
|
8502
|
+
onKeyDown: handleOnKeyDown,
|
|
8244
8503
|
onBlur: handleOnBlur,
|
|
8504
|
+
onPaste: handleOnPaste,
|
|
8245
8505
|
placeholder: placeholder,
|
|
8246
8506
|
rows: rows,
|
|
8247
8507
|
value: localValue,
|
|
@@ -8262,6 +8522,7 @@ function TextArea(props) {
|
|
|
8262
8522
|
* @param {Function} props.setValue
|
|
8263
8523
|
* @param {Function} props.onFocus
|
|
8264
8524
|
* @param {Function} props.onBlur
|
|
8525
|
+
* @param {Function} props.onPaste
|
|
8265
8526
|
* @param {number} props.rows
|
|
8266
8527
|
* @param {boolean} props.monospace
|
|
8267
8528
|
* @param {Function} [props.validate]
|
|
@@ -8282,6 +8543,7 @@ function TextAreaEntry(props) {
|
|
|
8282
8543
|
validate,
|
|
8283
8544
|
onFocus,
|
|
8284
8545
|
onBlur,
|
|
8546
|
+
onPaste,
|
|
8285
8547
|
placeholder,
|
|
8286
8548
|
autoResize,
|
|
8287
8549
|
tooltip
|
|
@@ -8317,6 +8579,7 @@ function TextAreaEntry(props) {
|
|
|
8317
8579
|
onInput: onInput,
|
|
8318
8580
|
onFocus: onFocus,
|
|
8319
8581
|
onBlur: onBlur,
|
|
8582
|
+
onPaste: onPaste,
|
|
8320
8583
|
rows: rows,
|
|
8321
8584
|
debounce: debounce,
|
|
8322
8585
|
monospace: monospace,
|
|
@@ -8350,32 +8613,57 @@ function Textfield(props) {
|
|
|
8350
8613
|
disabled = false,
|
|
8351
8614
|
id,
|
|
8352
8615
|
label,
|
|
8353
|
-
onInput,
|
|
8616
|
+
onInput: commitValue,
|
|
8354
8617
|
onFocus,
|
|
8355
8618
|
onBlur,
|
|
8619
|
+
onPaste,
|
|
8356
8620
|
placeholder,
|
|
8357
8621
|
value = '',
|
|
8358
8622
|
tooltip
|
|
8359
8623
|
} = props;
|
|
8360
8624
|
const [localValue, setLocalValue] = hooks.useState(value || '');
|
|
8361
8625
|
const ref = useShowEntryEvent(id);
|
|
8626
|
+
const onInput = hooks.useCallback(newValue => {
|
|
8627
|
+
const newModelValue = newValue === '' ? undefined : newValue;
|
|
8628
|
+
commitValue(newModelValue);
|
|
8629
|
+
}, [commitValue]);
|
|
8362
8630
|
|
|
8363
8631
|
/**
|
|
8364
8632
|
* @type { import('min-dash').DebouncedFunction }
|
|
8365
8633
|
*/
|
|
8366
|
-
const
|
|
8634
|
+
const handleInput = useDebounce(onInput, debounce);
|
|
8367
8635
|
const handleOnBlur = e => {
|
|
8368
8636
|
const trimmedValue = e.target.value.trim();
|
|
8369
8637
|
|
|
8370
8638
|
// trim and commit on blur
|
|
8639
|
+
handleInput.cancel?.();
|
|
8371
8640
|
onInput(trimmedValue);
|
|
8641
|
+
setLocalValue(trimmedValue);
|
|
8372
8642
|
if (onBlur) {
|
|
8373
8643
|
onBlur(e);
|
|
8374
8644
|
}
|
|
8375
8645
|
};
|
|
8376
|
-
const
|
|
8377
|
-
const
|
|
8378
|
-
|
|
8646
|
+
const handleOnPaste = e => {
|
|
8647
|
+
const input = e.target;
|
|
8648
|
+
const isFieldEmpty = !input.value;
|
|
8649
|
+
const isAllSelected = input.selectionStart === 0 && input.selectionEnd === input.value.length;
|
|
8650
|
+
|
|
8651
|
+
// Trim and handle paste if field is empty or all content is selected (overwrite)
|
|
8652
|
+
if (isFieldEmpty || isAllSelected) {
|
|
8653
|
+
const trimmedValue = e.clipboardData.getData('text').trim();
|
|
8654
|
+
setLocalValue(trimmedValue);
|
|
8655
|
+
handleInput(trimmedValue);
|
|
8656
|
+
if (onPaste) {
|
|
8657
|
+
onPaste(e);
|
|
8658
|
+
}
|
|
8659
|
+
e.preventDefault();
|
|
8660
|
+
return;
|
|
8661
|
+
}
|
|
8662
|
+
|
|
8663
|
+
// Allow default paste behavior for normal text editing
|
|
8664
|
+
if (onPaste) {
|
|
8665
|
+
onPaste(e);
|
|
8666
|
+
}
|
|
8379
8667
|
};
|
|
8380
8668
|
const handleLocalInput = e => {
|
|
8381
8669
|
if (e.target.value === localValue) {
|
|
@@ -8390,6 +8678,11 @@ function Textfield(props) {
|
|
|
8390
8678
|
}
|
|
8391
8679
|
setLocalValue(value);
|
|
8392
8680
|
}, [value]);
|
|
8681
|
+
const handleOnKeyDown = e => {
|
|
8682
|
+
if (isCmdWithChar(e)) {
|
|
8683
|
+
handleInput.flush();
|
|
8684
|
+
}
|
|
8685
|
+
};
|
|
8393
8686
|
return jsxRuntime.jsxs("div", {
|
|
8394
8687
|
class: "bio-properties-panel-textfield",
|
|
8395
8688
|
children: [jsxRuntime.jsx("label", {
|
|
@@ -8412,7 +8705,9 @@ function Textfield(props) {
|
|
|
8412
8705
|
class: "bio-properties-panel-input",
|
|
8413
8706
|
onInput: handleLocalInput,
|
|
8414
8707
|
onFocus: onFocus,
|
|
8708
|
+
onKeyDown: handleOnKeyDown,
|
|
8415
8709
|
onBlur: handleOnBlur,
|
|
8710
|
+
onPaste: handleOnPaste,
|
|
8416
8711
|
placeholder: placeholder,
|
|
8417
8712
|
value: localValue
|
|
8418
8713
|
})]
|
|
@@ -8447,6 +8742,7 @@ function TextfieldEntry(props) {
|
|
|
8447
8742
|
validate,
|
|
8448
8743
|
onFocus,
|
|
8449
8744
|
onBlur,
|
|
8745
|
+
onPaste,
|
|
8450
8746
|
placeholder,
|
|
8451
8747
|
tooltip
|
|
8452
8748
|
} = props;
|
|
@@ -8482,6 +8778,7 @@ function TextfieldEntry(props) {
|
|
|
8482
8778
|
onInput: onInput,
|
|
8483
8779
|
onFocus: onFocus,
|
|
8484
8780
|
onBlur: onBlur,
|
|
8781
|
+
onPaste: onPaste,
|
|
8485
8782
|
placeholder: placeholder,
|
|
8486
8783
|
value: value,
|
|
8487
8784
|
tooltip: tooltip,
|
|
@@ -8792,6 +9089,25 @@ function cancel(event) {
|
|
|
8792
9089
|
event.preventDefault();
|
|
8793
9090
|
event.stopPropagation();
|
|
8794
9091
|
}
|
|
9092
|
+
|
|
9093
|
+
/**
|
|
9094
|
+
* @typedef {Object} FeelPopupProps
|
|
9095
|
+
* @property {string} entryId
|
|
9096
|
+
* @property {Function} onInput
|
|
9097
|
+
* @property {Function} onClose
|
|
9098
|
+
* @property {string} title
|
|
9099
|
+
* @property {'feel'|'feelers'} type
|
|
9100
|
+
* @property {string} value
|
|
9101
|
+
* @property {Array} [links]
|
|
9102
|
+
* @property {Array|Object} [variables]
|
|
9103
|
+
* @property {Object} [position]
|
|
9104
|
+
* @property {string} [hostLanguage]
|
|
9105
|
+
* @property {boolean} [singleLine]
|
|
9106
|
+
* @property {HTMLElement} [sourceElement]
|
|
9107
|
+
* @property {HTMLElement|string} [tooltipContainer]
|
|
9108
|
+
* @property {Object} [eventBus]
|
|
9109
|
+
*/
|
|
9110
|
+
|
|
8795
9111
|
const FEEL_POPUP_WIDTH = 700;
|
|
8796
9112
|
const FEEL_POPUP_HEIGHT = 250;
|
|
8797
9113
|
|
|
@@ -11475,7 +11791,14 @@ function Value$1(props) {
|
|
|
11475
11791
|
if (error) {
|
|
11476
11792
|
return;
|
|
11477
11793
|
}
|
|
11794
|
+
const {
|
|
11795
|
+
defaultValue
|
|
11796
|
+
} = field;
|
|
11478
11797
|
const values = minDash.get(field, ['values']);
|
|
11798
|
+
const previousValue = minDash.get(field, ['values', index, 'value']);
|
|
11799
|
+
if (!minDash.isNil(defaultValue) && defaultValue === previousValue) {
|
|
11800
|
+
minDash.set(field, ['defaultValue'], value);
|
|
11801
|
+
}
|
|
11479
11802
|
return editField(field, 'values', minDash.set(values, [index, 'value'], value));
|
|
11480
11803
|
};
|
|
11481
11804
|
const getValue = () => {
|
|
@@ -12885,7 +13208,7 @@ function DocumentsDataSource(props) {
|
|
|
12885
13208
|
children: "When using Camunda Tasklist UI, additional document reference attributes are automatically handled. Modifying the document reference may affect the document preview functionality."
|
|
12886
13209
|
}), jsxRuntime.jsxs("p", {
|
|
12887
13210
|
children: ["Learn more in our", ' ', jsxRuntime.jsx("a", {
|
|
12888
|
-
href: "https://docs.camunda.io/docs/
|
|
13211
|
+
href: "https://docs.camunda.io/docs/components/modeler/forms/form-element-library/forms-element-library-document-preview/",
|
|
12889
13212
|
target: "_blank",
|
|
12890
13213
|
rel: "noopener noreferrer",
|
|
12891
13214
|
children: "documentation"
|
|
@@ -13497,7 +13820,7 @@ function CustomPropertiesGroup(field, editField) {
|
|
|
13497
13820
|
event.stopPropagation();
|
|
13498
13821
|
return editField(field, ['properties'], removeKey(properties, key));
|
|
13499
13822
|
};
|
|
13500
|
-
const id = `property-${index}`;
|
|
13823
|
+
const id = `property-${field.id}-${index}`;
|
|
13501
13824
|
return {
|
|
13502
13825
|
autoFocusEntry: id + '-key',
|
|
13503
13826
|
entries: CustomValueEntry({
|
|
@@ -13879,7 +14202,7 @@ const RepeatRenderModule = {
|
|
|
13879
14202
|
repeatRenderManager: ['type', EditorRepeatRenderManager]
|
|
13880
14203
|
};
|
|
13881
14204
|
|
|
13882
|
-
const ids = new Ids([32, 36, 1]);
|
|
14205
|
+
const ids = new ids$1.Ids([32, 36, 1]);
|
|
13883
14206
|
|
|
13884
14207
|
/**
|
|
13885
14208
|
* @typedef { import('./types').Injector } Injector
|