@bpmn-io/properties-panel 0.23.0 → 0.24.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/dist/index.esm.js +270 -288
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +270 -288
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.esm.js
CHANGED
|
@@ -8,52 +8,50 @@ import { createContext, createElement } from '../preact';
|
|
|
8
8
|
import FeelEditor from '@bpmn-io/feel-editor';
|
|
9
9
|
|
|
10
10
|
var ArrowIcon = function ArrowIcon(props) {
|
|
11
|
-
return jsx("svg", {
|
|
11
|
+
return jsx("svg", {
|
|
12
|
+
...props,
|
|
12
13
|
children: jsx("path", {
|
|
13
14
|
fillRule: "evenodd",
|
|
14
15
|
d: "m11.657 8-4.95 4.95a1 1 0 0 1-1.414-1.414L8.828 8 5.293 4.464A1 1 0 1 1 6.707 3.05L11.657 8Z"
|
|
15
16
|
})
|
|
16
17
|
});
|
|
17
18
|
};
|
|
18
|
-
|
|
19
19
|
ArrowIcon.defaultProps = {
|
|
20
20
|
xmlns: "http://www.w3.org/2000/svg",
|
|
21
21
|
width: "16",
|
|
22
22
|
height: "16"
|
|
23
23
|
};
|
|
24
|
-
|
|
25
24
|
var CreateIcon = function CreateIcon(props) {
|
|
26
|
-
return jsx("svg", {
|
|
25
|
+
return jsx("svg", {
|
|
26
|
+
...props,
|
|
27
27
|
children: jsx("path", {
|
|
28
28
|
fillRule: "evenodd",
|
|
29
29
|
d: "M9 13V9h4a1 1 0 0 0 0-2H9V3a1 1 0 1 0-2 0v4H3a1 1 0 1 0 0 2h4v4a1 1 0 0 0 2 0Z"
|
|
30
30
|
})
|
|
31
31
|
});
|
|
32
32
|
};
|
|
33
|
-
|
|
34
33
|
CreateIcon.defaultProps = {
|
|
35
34
|
xmlns: "http://www.w3.org/2000/svg",
|
|
36
35
|
width: "16",
|
|
37
36
|
height: "16"
|
|
38
37
|
};
|
|
39
|
-
|
|
40
38
|
var DeleteIcon = function DeleteIcon(props) {
|
|
41
|
-
return jsx("svg", {
|
|
39
|
+
return jsx("svg", {
|
|
40
|
+
...props,
|
|
42
41
|
children: jsx("path", {
|
|
43
42
|
fillRule: "evenodd",
|
|
44
43
|
d: "M12 6v7c0 1.1-.4 1.55-1.5 1.55h-5C4.4 14.55 4 14.1 4 13V6h8Zm-1.5 1.5h-5v4.3c0 .66.5 1.2 1.111 1.2H9.39c.611 0 1.111-.54 1.111-1.2V7.5ZM13 3h-2l-1-1H6L5 3H3v1.5h10V3Z"
|
|
45
44
|
})
|
|
46
45
|
});
|
|
47
46
|
};
|
|
48
|
-
|
|
49
47
|
DeleteIcon.defaultProps = {
|
|
50
48
|
xmlns: "http://www.w3.org/2000/svg",
|
|
51
49
|
width: "16",
|
|
52
50
|
height: "16"
|
|
53
51
|
};
|
|
54
|
-
|
|
55
52
|
var ExternalLinkIcon = function ExternalLinkIcon(props) {
|
|
56
|
-
return jsx("svg", {
|
|
53
|
+
return jsx("svg", {
|
|
54
|
+
...props,
|
|
57
55
|
children: jsx("path", {
|
|
58
56
|
fillRule: "evenodd",
|
|
59
57
|
clipRule: "evenodd",
|
|
@@ -62,16 +60,15 @@ var ExternalLinkIcon = function ExternalLinkIcon(props) {
|
|
|
62
60
|
})
|
|
63
61
|
});
|
|
64
62
|
};
|
|
65
|
-
|
|
66
63
|
ExternalLinkIcon.defaultProps = {
|
|
67
64
|
width: "16",
|
|
68
65
|
height: "16",
|
|
69
66
|
fill: "none",
|
|
70
67
|
xmlns: "http://www.w3.org/2000/svg"
|
|
71
68
|
};
|
|
72
|
-
|
|
73
69
|
var FeelRequiredIcon = function FeelRequiredIcon(props) {
|
|
74
|
-
return jsxs("svg", {
|
|
70
|
+
return jsxs("svg", {
|
|
71
|
+
...props,
|
|
75
72
|
children: [jsx("path", {
|
|
76
73
|
d: "M5.8 7.06V5.95h4.307v1.11H5.8Zm0 3.071v-1.11h4.307v1.11H5.8Z",
|
|
77
74
|
fill: "currentColor"
|
|
@@ -86,15 +83,14 @@ var FeelRequiredIcon = function FeelRequiredIcon(props) {
|
|
|
86
83
|
})]
|
|
87
84
|
});
|
|
88
85
|
};
|
|
89
|
-
|
|
90
86
|
FeelRequiredIcon.defaultProps = {
|
|
91
87
|
viewBox: "0 0 16 16",
|
|
92
88
|
fill: "none",
|
|
93
89
|
xmlns: "http://www.w3.org/2000/svg"
|
|
94
90
|
};
|
|
95
|
-
|
|
96
91
|
var FeelOptionalIcon = function FeelOptionalIcon(props) {
|
|
97
|
-
return jsxs("svg", {
|
|
92
|
+
return jsxs("svg", {
|
|
93
|
+
...props,
|
|
98
94
|
children: [jsx("path", {
|
|
99
95
|
d: "M5.845 7.04V5.93h4.307v1.11H5.845Zm0 3.07V9h4.307v1.11H5.845Z",
|
|
100
96
|
fill: "currentColor"
|
|
@@ -106,7 +102,6 @@ var FeelOptionalIcon = function FeelOptionalIcon(props) {
|
|
|
106
102
|
})]
|
|
107
103
|
});
|
|
108
104
|
};
|
|
109
|
-
|
|
110
105
|
FeelOptionalIcon.defaultProps = {
|
|
111
106
|
viewBox: "0 0 16 16",
|
|
112
107
|
fill: "none",
|
|
@@ -211,7 +206,6 @@ const LayoutContext = createContext({
|
|
|
211
206
|
*
|
|
212
207
|
* @returns {string}
|
|
213
208
|
*/
|
|
214
|
-
|
|
215
209
|
function useDescriptionContext(id, element) {
|
|
216
210
|
const {
|
|
217
211
|
getDescriptionForId
|
|
@@ -232,28 +226,25 @@ function useError(id) {
|
|
|
232
226
|
* @param {string} event
|
|
233
227
|
* @param {Function} callback
|
|
234
228
|
*/
|
|
235
|
-
|
|
236
229
|
function useEvent(event, callback, eventBus) {
|
|
237
230
|
const eventContext = useContext(EventContext);
|
|
238
|
-
|
|
239
231
|
if (!eventBus) {
|
|
240
232
|
({
|
|
241
233
|
eventBus
|
|
242
234
|
} = eventContext);
|
|
243
235
|
}
|
|
236
|
+
const didMount = useRef(false);
|
|
244
237
|
|
|
245
|
-
|
|
246
|
-
|
|
238
|
+
// (1) subscribe immediately
|
|
247
239
|
if (eventBus && !didMount.current) {
|
|
248
240
|
eventBus.on(event, callback);
|
|
249
|
-
}
|
|
250
|
-
|
|
241
|
+
}
|
|
251
242
|
|
|
243
|
+
// (2) update subscription after inputs changed
|
|
252
244
|
useEffect(() => {
|
|
253
245
|
if (eventBus && didMount.current) {
|
|
254
246
|
eventBus.on(event, callback);
|
|
255
247
|
}
|
|
256
|
-
|
|
257
248
|
didMount.current = true;
|
|
258
249
|
return () => {
|
|
259
250
|
if (eventBus) {
|
|
@@ -264,6 +255,7 @@ function useEvent(event, callback, eventBus) {
|
|
|
264
255
|
}
|
|
265
256
|
|
|
266
257
|
const KEY_LENGTH = 6;
|
|
258
|
+
|
|
267
259
|
/**
|
|
268
260
|
* Create a persistent key factory for plain objects without id.
|
|
269
261
|
*
|
|
@@ -283,21 +275,16 @@ const KEY_LENGTH = 6;
|
|
|
283
275
|
* @param {any[]} dependencies
|
|
284
276
|
* @returns {(element: object) => string}
|
|
285
277
|
*/
|
|
286
|
-
|
|
287
278
|
function useKeyFactory(dependencies = []) {
|
|
288
279
|
const map = useMemo(() => new Map(), dependencies);
|
|
289
|
-
|
|
290
280
|
const getKey = el => {
|
|
291
281
|
let key = map.get(el);
|
|
292
|
-
|
|
293
282
|
if (!key) {
|
|
294
283
|
key = Math.random().toString().slice(-KEY_LENGTH);
|
|
295
284
|
map.set(el, key);
|
|
296
285
|
}
|
|
297
|
-
|
|
298
286
|
return key;
|
|
299
287
|
};
|
|
300
|
-
|
|
301
288
|
return getKey;
|
|
302
289
|
}
|
|
303
290
|
|
|
@@ -316,7 +303,6 @@ function useKeyFactory(dependencies = []) {
|
|
|
316
303
|
*
|
|
317
304
|
* @returns {[ any, Function ]}
|
|
318
305
|
*/
|
|
319
|
-
|
|
320
306
|
function useLayoutState(path, defaultValue) {
|
|
321
307
|
const {
|
|
322
308
|
getLayoutForKey,
|
|
@@ -324,14 +310,13 @@ function useLayoutState(path, defaultValue) {
|
|
|
324
310
|
} = useContext(LayoutContext);
|
|
325
311
|
const layoutForKey = getLayoutForKey(path, defaultValue);
|
|
326
312
|
const [value, set] = useState(layoutForKey);
|
|
327
|
-
|
|
328
313
|
const setState = newValue => {
|
|
329
314
|
// (1) set component state
|
|
330
|
-
set(newValue);
|
|
315
|
+
set(newValue);
|
|
331
316
|
|
|
317
|
+
// (2) set context
|
|
332
318
|
setLayoutForKey(path, newValue);
|
|
333
319
|
};
|
|
334
|
-
|
|
335
320
|
return [value, setState];
|
|
336
321
|
}
|
|
337
322
|
|
|
@@ -357,7 +342,6 @@ function usePrevious(value) {
|
|
|
357
342
|
*
|
|
358
343
|
* @returns {import('preact').Ref}
|
|
359
344
|
*/
|
|
360
|
-
|
|
361
345
|
function useShowEntryEvent(id) {
|
|
362
346
|
const {
|
|
363
347
|
onShow
|
|
@@ -367,7 +351,6 @@ function useShowEntryEvent(id) {
|
|
|
367
351
|
const onShowEntry = useCallback(event => {
|
|
368
352
|
if (event.id === id) {
|
|
369
353
|
onShow();
|
|
370
|
-
|
|
371
354
|
if (!focus.current) {
|
|
372
355
|
focus.current = true;
|
|
373
356
|
}
|
|
@@ -378,11 +361,9 @@ function useShowEntryEvent(id) {
|
|
|
378
361
|
if (isFunction(ref.current.focus)) {
|
|
379
362
|
ref.current.focus();
|
|
380
363
|
}
|
|
381
|
-
|
|
382
364
|
if (isFunction(ref.current.select)) {
|
|
383
365
|
ref.current.select();
|
|
384
366
|
}
|
|
385
|
-
|
|
386
367
|
focus.current = false;
|
|
387
368
|
}
|
|
388
369
|
});
|
|
@@ -405,17 +386,15 @@ function useShowEntryEvent(id) {
|
|
|
405
386
|
* @param {string} scrollContainerSelector
|
|
406
387
|
* @param {setSticky} setSticky
|
|
407
388
|
*/
|
|
408
|
-
|
|
409
389
|
function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky) {
|
|
410
390
|
useEffect(() => {
|
|
411
|
-
const Observer = IntersectionObserver;
|
|
391
|
+
const Observer = IntersectionObserver;
|
|
412
392
|
|
|
393
|
+
// return early if IntersectionObserver is not available
|
|
413
394
|
if (!Observer) {
|
|
414
395
|
return;
|
|
415
396
|
}
|
|
416
|
-
|
|
417
397
|
let observer;
|
|
418
|
-
|
|
419
398
|
if (ref.current) {
|
|
420
399
|
const scrollContainer = query(scrollContainerSelector);
|
|
421
400
|
observer = new Observer(entries => {
|
|
@@ -433,9 +412,9 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
|
|
|
433
412
|
threshold: [1]
|
|
434
413
|
});
|
|
435
414
|
observer.observe(ref.current);
|
|
436
|
-
}
|
|
437
|
-
|
|
415
|
+
}
|
|
438
416
|
|
|
417
|
+
// Unobserve if unmounted
|
|
439
418
|
return () => {
|
|
440
419
|
if (ref.current && observer) {
|
|
441
420
|
observer.unobserve(ref.current);
|
|
@@ -458,7 +437,6 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
|
|
|
458
437
|
* @param {Function} callback function with changing reference
|
|
459
438
|
* @returns {Function} static function reference
|
|
460
439
|
*/
|
|
461
|
-
|
|
462
440
|
function useStaticCallback(callback) {
|
|
463
441
|
const callbackRef = useRef(callback);
|
|
464
442
|
callbackRef.current = callback;
|
|
@@ -476,12 +454,11 @@ function Group(props) {
|
|
|
476
454
|
const groupRef = useRef(null);
|
|
477
455
|
const [open, setOpen] = useLayoutState(['groups', id, 'open'], shouldOpen);
|
|
478
456
|
const onShow = useCallback(() => setOpen(true), [setOpen]);
|
|
479
|
-
|
|
480
457
|
const toggleOpen = () => setOpen(!open);
|
|
481
|
-
|
|
482
458
|
const [edited, setEdited] = useState(false);
|
|
483
|
-
const [sticky, setSticky] = useState(false);
|
|
459
|
+
const [sticky, setSticky] = useState(false);
|
|
484
460
|
|
|
461
|
+
// set edited state depending on all entries
|
|
485
462
|
useEffect(() => {
|
|
486
463
|
const hasOneEditedEntry = entries.find(entry => {
|
|
487
464
|
const {
|
|
@@ -489,19 +466,19 @@ function Group(props) {
|
|
|
489
466
|
isEdited
|
|
490
467
|
} = entry;
|
|
491
468
|
const entryNode = query(`[data-entry-id="${id}"]`);
|
|
492
|
-
|
|
493
469
|
if (!isFunction(isEdited) || !entryNode) {
|
|
494
470
|
return false;
|
|
495
471
|
}
|
|
496
|
-
|
|
497
472
|
const inputNode = query('.bio-properties-panel-input', entryNode);
|
|
498
473
|
return isEdited(inputNode);
|
|
499
474
|
});
|
|
500
475
|
setEdited(hasOneEditedEntry);
|
|
501
|
-
}, [entries]);
|
|
476
|
+
}, [entries]);
|
|
502
477
|
|
|
478
|
+
// set css class when group is sticky to top
|
|
503
479
|
useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
|
|
504
|
-
const propertiesPanelContext = {
|
|
480
|
+
const propertiesPanelContext = {
|
|
481
|
+
...useContext(LayoutContext),
|
|
505
482
|
onShow
|
|
506
483
|
};
|
|
507
484
|
return jsxs("div", {
|
|
@@ -534,7 +511,8 @@ function Group(props) {
|
|
|
534
511
|
component: Component,
|
|
535
512
|
id
|
|
536
513
|
} = entry;
|
|
537
|
-
return createElement(Component, {
|
|
514
|
+
return createElement(Component, {
|
|
515
|
+
...entry,
|
|
538
516
|
element: element,
|
|
539
517
|
key: id
|
|
540
518
|
});
|
|
@@ -543,7 +521,6 @@ function Group(props) {
|
|
|
543
521
|
})]
|
|
544
522
|
});
|
|
545
523
|
}
|
|
546
|
-
|
|
547
524
|
function DataMarker() {
|
|
548
525
|
return jsx("div", {
|
|
549
526
|
title: "Section contains data",
|
|
@@ -582,6 +559,7 @@ const DEFAULT_LAYOUT = {
|
|
|
582
559
|
open: true
|
|
583
560
|
};
|
|
584
561
|
const DEFAULT_DESCRIPTION = {};
|
|
562
|
+
|
|
585
563
|
/**
|
|
586
564
|
* @typedef { {
|
|
587
565
|
* component: import('preact').Component,
|
|
@@ -649,7 +627,6 @@ const DEFAULT_DESCRIPTION = {};
|
|
|
649
627
|
* @param {Function} [props.descriptionLoaded]
|
|
650
628
|
* @param {Object} [props.eventBus]
|
|
651
629
|
*/
|
|
652
|
-
|
|
653
630
|
function PropertiesPanel(props) {
|
|
654
631
|
const {
|
|
655
632
|
element,
|
|
@@ -661,52 +638,46 @@ function PropertiesPanel(props) {
|
|
|
661
638
|
descriptionConfig = {},
|
|
662
639
|
descriptionLoaded,
|
|
663
640
|
eventBus
|
|
664
|
-
} = props;
|
|
641
|
+
} = props;
|
|
665
642
|
|
|
643
|
+
// set-up layout context
|
|
666
644
|
const [layout, setLayout] = useState(createLayout(layoutConfig));
|
|
667
645
|
useEffect(() => {
|
|
668
646
|
if (typeof layoutChanged === 'function') {
|
|
669
647
|
layoutChanged(layout);
|
|
670
648
|
}
|
|
671
649
|
}, [layout, layoutChanged]);
|
|
672
|
-
|
|
673
650
|
const getLayoutForKey = (key, defaultValue) => {
|
|
674
651
|
return get(layout, key, defaultValue);
|
|
675
652
|
};
|
|
676
|
-
|
|
677
653
|
const setLayoutForKey = (key, config) => {
|
|
678
654
|
const newLayout = assign({}, layout);
|
|
679
655
|
set(newLayout, key, config);
|
|
680
656
|
setLayout(newLayout);
|
|
681
657
|
};
|
|
682
|
-
|
|
683
658
|
const layoutContext = {
|
|
684
659
|
layout,
|
|
685
660
|
setLayout,
|
|
686
661
|
getLayoutForKey,
|
|
687
662
|
setLayoutForKey
|
|
688
|
-
};
|
|
663
|
+
};
|
|
689
664
|
|
|
665
|
+
// set-up description context
|
|
690
666
|
const description = createDescriptionContext(descriptionConfig);
|
|
691
|
-
|
|
692
667
|
if (typeof descriptionLoaded === 'function') {
|
|
693
668
|
descriptionLoaded(description);
|
|
694
669
|
}
|
|
695
|
-
|
|
696
670
|
const getDescriptionForId = (id, element) => {
|
|
697
671
|
return description[id] && description[id](element);
|
|
698
672
|
};
|
|
699
|
-
|
|
700
673
|
const descriptionContext = {
|
|
701
674
|
description,
|
|
702
675
|
getDescriptionForId
|
|
703
676
|
};
|
|
704
677
|
const [errors, setErrors] = useState({});
|
|
705
|
-
|
|
706
678
|
const onSetErrors = ({
|
|
707
679
|
errors
|
|
708
680
|
}) => setErrors(errors);
|
|
709
|
-
|
|
710
681
|
useEvent('propertiesPanel.setErrors', onSetErrors, eventBus);
|
|
711
682
|
const errorsContext = {
|
|
712
683
|
errors
|
|
@@ -716,19 +687,21 @@ function PropertiesPanel(props) {
|
|
|
716
687
|
};
|
|
717
688
|
const propertiesPanelContext = {
|
|
718
689
|
element
|
|
719
|
-
};
|
|
690
|
+
};
|
|
720
691
|
|
|
692
|
+
// empty state
|
|
721
693
|
if (placeholderProvider && !element) {
|
|
722
|
-
return jsx(Placeholder, {
|
|
694
|
+
return jsx(Placeholder, {
|
|
695
|
+
...placeholderProvider.getEmpty()
|
|
723
696
|
});
|
|
724
|
-
}
|
|
725
|
-
|
|
697
|
+
}
|
|
726
698
|
|
|
699
|
+
// multiple state
|
|
727
700
|
if (placeholderProvider && isArray(element)) {
|
|
728
|
-
return jsx(Placeholder, {
|
|
701
|
+
return jsx(Placeholder, {
|
|
702
|
+
...placeholderProvider.getMultiple()
|
|
729
703
|
});
|
|
730
704
|
}
|
|
731
|
-
|
|
732
705
|
return jsx(LayoutContext.Provider, {
|
|
733
706
|
value: propertiesPanelContext,
|
|
734
707
|
children: jsx(ErrorsContext.Provider, {
|
|
@@ -751,7 +724,8 @@ function PropertiesPanel(props) {
|
|
|
751
724
|
component: Component = Group,
|
|
752
725
|
id
|
|
753
726
|
} = group;
|
|
754
|
-
return createElement(Component, {
|
|
727
|
+
return createElement(Component, {
|
|
728
|
+
...group,
|
|
755
729
|
key: id,
|
|
756
730
|
element: element
|
|
757
731
|
});
|
|
@@ -763,16 +737,19 @@ function PropertiesPanel(props) {
|
|
|
763
737
|
})
|
|
764
738
|
})
|
|
765
739
|
});
|
|
766
|
-
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
// helpers //////////////////
|
|
767
743
|
|
|
768
744
|
function createLayout(overrides) {
|
|
769
|
-
return {
|
|
745
|
+
return {
|
|
746
|
+
...DEFAULT_LAYOUT,
|
|
770
747
|
...overrides
|
|
771
748
|
};
|
|
772
749
|
}
|
|
773
|
-
|
|
774
750
|
function createDescriptionContext(overrides) {
|
|
775
|
-
return {
|
|
751
|
+
return {
|
|
752
|
+
...DEFAULT_DESCRIPTION,
|
|
776
753
|
...overrides
|
|
777
754
|
};
|
|
778
755
|
}
|
|
@@ -786,24 +763,19 @@ function DropdownButton(props) {
|
|
|
786
763
|
const dropdownRef = useRef(null);
|
|
787
764
|
const menuRef = useRef(null);
|
|
788
765
|
const [open, setOpen] = useState(false);
|
|
789
|
-
|
|
790
766
|
const close = () => setOpen(false);
|
|
791
|
-
|
|
792
767
|
function onDropdownToggle(event) {
|
|
793
768
|
if (menuRef.current && menuRef.current.contains(event.target)) {
|
|
794
769
|
return;
|
|
795
770
|
}
|
|
796
|
-
|
|
797
771
|
event.stopPropagation();
|
|
798
772
|
setOpen(open => !open);
|
|
799
773
|
}
|
|
800
|
-
|
|
801
774
|
function onActionClick(event, action) {
|
|
802
775
|
event.stopPropagation();
|
|
803
776
|
close();
|
|
804
777
|
action();
|
|
805
778
|
}
|
|
806
|
-
|
|
807
779
|
useGlobalClick([dropdownRef.current], () => close());
|
|
808
780
|
return jsxs("div", {
|
|
809
781
|
class: classnames('bio-properties-panel-dropdown-button', {
|
|
@@ -821,7 +793,6 @@ function DropdownButton(props) {
|
|
|
821
793
|
})]
|
|
822
794
|
});
|
|
823
795
|
}
|
|
824
|
-
|
|
825
796
|
function MenuItem({
|
|
826
797
|
item,
|
|
827
798
|
onClick
|
|
@@ -831,7 +802,6 @@ function MenuItem({
|
|
|
831
802
|
class: "bio-properties-panel-dropdown-button__menu-item bio-properties-panel-dropdown-button__menu-item--separator"
|
|
832
803
|
});
|
|
833
804
|
}
|
|
834
|
-
|
|
835
805
|
if (item.action) {
|
|
836
806
|
return jsx("button", {
|
|
837
807
|
class: "bio-properties-panel-dropdown-button__menu-item bio-properties-panel-dropdown-button__menu-item--actionable",
|
|
@@ -839,19 +809,17 @@ function MenuItem({
|
|
|
839
809
|
children: item.entry
|
|
840
810
|
});
|
|
841
811
|
}
|
|
842
|
-
|
|
843
812
|
return jsx("div", {
|
|
844
813
|
class: "bio-properties-panel-dropdown-button__menu-item",
|
|
845
814
|
children: item.entry
|
|
846
815
|
});
|
|
847
816
|
}
|
|
817
|
+
|
|
848
818
|
/**
|
|
849
819
|
*
|
|
850
820
|
* @param {Array<null | Element>} ignoredElements
|
|
851
821
|
* @param {Function} callback
|
|
852
822
|
*/
|
|
853
|
-
|
|
854
|
-
|
|
855
823
|
function useGlobalClick(ignoredElements, callback) {
|
|
856
824
|
useEffect(() => {
|
|
857
825
|
/**
|
|
@@ -861,10 +829,8 @@ function useGlobalClick(ignoredElements, callback) {
|
|
|
861
829
|
if (ignoredElements.some(element => element && element.contains(event.target))) {
|
|
862
830
|
return;
|
|
863
831
|
}
|
|
864
|
-
|
|
865
832
|
callback();
|
|
866
833
|
}
|
|
867
|
-
|
|
868
834
|
document.addEventListener('click', listener, {
|
|
869
835
|
capture: true
|
|
870
836
|
});
|
|
@@ -881,7 +847,8 @@ function HeaderButton(props) {
|
|
|
881
847
|
onClick = () => {},
|
|
882
848
|
...otherProps
|
|
883
849
|
} = props;
|
|
884
|
-
return jsx("button", {
|
|
850
|
+
return jsx("button", {
|
|
851
|
+
...otherProps,
|
|
885
852
|
onClick: onClick,
|
|
886
853
|
class: classnames('bio-properties-panel-group-header-button', classname),
|
|
887
854
|
children: children
|
|
@@ -898,22 +865,21 @@ function CollapsibleEntry(props) {
|
|
|
898
865
|
remove
|
|
899
866
|
} = props;
|
|
900
867
|
const [open, setOpen] = useState(shouldOpen);
|
|
901
|
-
|
|
902
868
|
const toggleOpen = () => setOpen(!open);
|
|
903
|
-
|
|
904
869
|
const {
|
|
905
870
|
onShow
|
|
906
871
|
} = useContext(LayoutContext);
|
|
907
|
-
const propertiesPanelContext = {
|
|
872
|
+
const propertiesPanelContext = {
|
|
873
|
+
...useContext(LayoutContext),
|
|
908
874
|
onShow: useCallback(() => {
|
|
909
875
|
setOpen(true);
|
|
910
|
-
|
|
911
876
|
if (isFunction(onShow)) {
|
|
912
877
|
onShow();
|
|
913
878
|
}
|
|
914
879
|
}, [onShow, setOpen])
|
|
915
|
-
};
|
|
880
|
+
};
|
|
916
881
|
|
|
882
|
+
// todo(pinussilvestrus): translate once we have a translate mechanism for the core
|
|
917
883
|
const placeholderLabel = '<empty>';
|
|
918
884
|
return jsxs("div", {
|
|
919
885
|
"data-entry-id": id,
|
|
@@ -946,7 +912,8 @@ function CollapsibleEntry(props) {
|
|
|
946
912
|
component: Component,
|
|
947
913
|
id
|
|
948
914
|
} = entry;
|
|
949
|
-
return createElement(Component, {
|
|
915
|
+
return createElement(Component, {
|
|
916
|
+
...entry,
|
|
950
917
|
element: element,
|
|
951
918
|
key: id
|
|
952
919
|
});
|
|
@@ -960,13 +927,13 @@ function ListItem(props) {
|
|
|
960
927
|
const {
|
|
961
928
|
autoFocusEntry,
|
|
962
929
|
autoOpen
|
|
963
|
-
} = props;
|
|
930
|
+
} = props;
|
|
964
931
|
|
|
932
|
+
// focus specified entry on auto open
|
|
965
933
|
useEffect(() => {
|
|
966
934
|
if (autoOpen && autoFocusEntry) {
|
|
967
935
|
const entry = query(`[data-entry-id="${autoFocusEntry}"]`);
|
|
968
936
|
const focusableInput = query('.bio-properties-panel-input', entry);
|
|
969
|
-
|
|
970
937
|
if (focusableInput) {
|
|
971
938
|
if (isFunction(focusableInput.select)) {
|
|
972
939
|
focusableInput.select();
|
|
@@ -978,18 +945,18 @@ function ListItem(props) {
|
|
|
978
945
|
}, [autoOpen, autoFocusEntry]);
|
|
979
946
|
return jsx("div", {
|
|
980
947
|
class: "bio-properties-panel-list-item",
|
|
981
|
-
children: jsx(CollapsibleEntry, {
|
|
948
|
+
children: jsx(CollapsibleEntry, {
|
|
949
|
+
...props,
|
|
982
950
|
open: autoOpen
|
|
983
951
|
})
|
|
984
952
|
});
|
|
985
953
|
}
|
|
986
954
|
|
|
987
955
|
const noop$2 = () => {};
|
|
956
|
+
|
|
988
957
|
/**
|
|
989
958
|
* @param {import('../PropertiesPanel').ListGroupDefinition} props
|
|
990
959
|
*/
|
|
991
|
-
|
|
992
|
-
|
|
993
960
|
function ListGroup(props) {
|
|
994
961
|
const {
|
|
995
962
|
add,
|
|
@@ -1009,20 +976,23 @@ function ListGroup(props) {
|
|
|
1009
976
|
const prevItems = usePrevious(items);
|
|
1010
977
|
const prevElement = usePrevious(element);
|
|
1011
978
|
const elementChanged = element !== prevElement;
|
|
1012
|
-
const shouldHandleEffects = !elementChanged && (shouldSort || shouldOpen);
|
|
979
|
+
const shouldHandleEffects = !elementChanged && (shouldSort || shouldOpen);
|
|
1013
980
|
|
|
981
|
+
// reset initial ordering when element changes (before first render)
|
|
1014
982
|
if (elementChanged) {
|
|
1015
983
|
setOrdering(createOrdering(shouldSort ? sortItems(items) : items));
|
|
1016
|
-
}
|
|
1017
|
-
// (0) set initial ordering from given items
|
|
984
|
+
}
|
|
1018
985
|
|
|
986
|
+
// keep ordering in sync to items - and open changes
|
|
1019
987
|
|
|
988
|
+
// (0) set initial ordering from given items
|
|
1020
989
|
useEffect(() => {
|
|
1021
990
|
if (!prevItems || !shouldSort) {
|
|
1022
991
|
setOrdering(createOrdering(items));
|
|
1023
992
|
}
|
|
1024
|
-
}, [items, element]);
|
|
993
|
+
}, [items, element]);
|
|
1025
994
|
|
|
995
|
+
// (1) items were added
|
|
1026
996
|
useEffect(() => {
|
|
1027
997
|
if (shouldHandleEffects && prevItems && items.length > prevItems.length) {
|
|
1028
998
|
let add = [];
|
|
@@ -1031,38 +1001,40 @@ function ListGroup(props) {
|
|
|
1031
1001
|
add.push(item.id);
|
|
1032
1002
|
}
|
|
1033
1003
|
});
|
|
1034
|
-
let newOrdering = ordering;
|
|
1004
|
+
let newOrdering = ordering;
|
|
1035
1005
|
|
|
1006
|
+
// open if not open and configured
|
|
1036
1007
|
if (!open && shouldOpen) {
|
|
1037
|
-
toggleOpen();
|
|
1008
|
+
toggleOpen();
|
|
1038
1009
|
|
|
1010
|
+
// if I opened and I should sort, then sort items
|
|
1039
1011
|
if (shouldSort) {
|
|
1040
1012
|
newOrdering = createOrdering(sortItems(items));
|
|
1041
1013
|
}
|
|
1042
|
-
}
|
|
1043
|
-
|
|
1014
|
+
}
|
|
1044
1015
|
|
|
1016
|
+
// add new items on top or bottom depending on sorting behavior
|
|
1045
1017
|
newOrdering = newOrdering.filter(item => !add.includes(item));
|
|
1046
|
-
|
|
1047
1018
|
if (shouldSort) {
|
|
1048
1019
|
newOrdering.unshift(...add);
|
|
1049
1020
|
} else {
|
|
1050
1021
|
newOrdering.push(...add);
|
|
1051
1022
|
}
|
|
1052
|
-
|
|
1053
1023
|
setOrdering(newOrdering);
|
|
1054
1024
|
setNewItemAdded(true);
|
|
1055
1025
|
} else {
|
|
1056
1026
|
setNewItemAdded(false);
|
|
1057
1027
|
}
|
|
1058
|
-
}, [items, open, shouldHandleEffects]);
|
|
1028
|
+
}, [items, open, shouldHandleEffects]);
|
|
1059
1029
|
|
|
1030
|
+
// (2) sort items on open if shouldSort is set
|
|
1060
1031
|
useEffect(() => {
|
|
1061
1032
|
if (shouldSort && open && !newItemAdded) {
|
|
1062
1033
|
setOrdering(createOrdering(sortItems(items)));
|
|
1063
1034
|
}
|
|
1064
|
-
}, [open, shouldSort]);
|
|
1035
|
+
}, [open, shouldSort]);
|
|
1065
1036
|
|
|
1037
|
+
// (3) items were deleted
|
|
1066
1038
|
useEffect(() => {
|
|
1067
1039
|
if (shouldHandleEffects && prevItems && items.length < prevItems.length) {
|
|
1068
1040
|
let keep = [];
|
|
@@ -1073,14 +1045,14 @@ function ListGroup(props) {
|
|
|
1073
1045
|
});
|
|
1074
1046
|
setOrdering(keep);
|
|
1075
1047
|
}
|
|
1076
|
-
}, [items, shouldHandleEffects]);
|
|
1048
|
+
}, [items, shouldHandleEffects]);
|
|
1077
1049
|
|
|
1050
|
+
// set css class when group is sticky to top
|
|
1078
1051
|
useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
|
|
1079
|
-
|
|
1080
1052
|
const toggleOpen = () => setOpen(!open);
|
|
1081
|
-
|
|
1082
1053
|
const hasItems = !!items.length;
|
|
1083
|
-
const propertiesPanelContext = {
|
|
1054
|
+
const propertiesPanelContext = {
|
|
1055
|
+
...useContext(LayoutContext),
|
|
1084
1056
|
onShow
|
|
1085
1057
|
};
|
|
1086
1058
|
return jsxs("div", {
|
|
@@ -1122,17 +1094,17 @@ function ListGroup(props) {
|
|
|
1122
1094
|
value: propertiesPanelContext,
|
|
1123
1095
|
children: ordering.map((o, index) => {
|
|
1124
1096
|
const item = getItem(items, o);
|
|
1125
|
-
|
|
1126
1097
|
if (!item) {
|
|
1127
1098
|
return;
|
|
1128
1099
|
}
|
|
1129
|
-
|
|
1130
1100
|
const {
|
|
1131
1101
|
id
|
|
1132
|
-
} = item;
|
|
1102
|
+
} = item;
|
|
1133
1103
|
|
|
1104
|
+
// if item was added, open first or last item based on ordering
|
|
1134
1105
|
const autoOpen = newItemAdded && (shouldSort ? index === 0 : index === ordering.length - 1);
|
|
1135
|
-
return createElement(ListItem, {
|
|
1106
|
+
return createElement(ListItem, {
|
|
1107
|
+
...item,
|
|
1136
1108
|
autoOpen: autoOpen,
|
|
1137
1109
|
element: element,
|
|
1138
1110
|
index: index,
|
|
@@ -1142,20 +1114,19 @@ function ListGroup(props) {
|
|
|
1142
1114
|
})
|
|
1143
1115
|
})]
|
|
1144
1116
|
});
|
|
1145
|
-
}
|
|
1117
|
+
}
|
|
1118
|
+
|
|
1119
|
+
// helpers ////////////////////
|
|
1146
1120
|
|
|
1147
1121
|
/**
|
|
1148
1122
|
* Sorts given items alphanumeric by label
|
|
1149
1123
|
*/
|
|
1150
|
-
|
|
1151
1124
|
function sortItems(items) {
|
|
1152
1125
|
return sortBy(items, i => i.label.toLowerCase());
|
|
1153
1126
|
}
|
|
1154
|
-
|
|
1155
1127
|
function getItem(items, id) {
|
|
1156
1128
|
return find(items, i => i.id === id);
|
|
1157
1129
|
}
|
|
1158
|
-
|
|
1159
1130
|
function createOrdering(items) {
|
|
1160
1131
|
return items.map(i => i.id);
|
|
1161
1132
|
}
|
|
@@ -1168,7 +1139,6 @@ function Description(props) {
|
|
|
1168
1139
|
} = props;
|
|
1169
1140
|
const contextDescription = useDescriptionContext(forId, element);
|
|
1170
1141
|
const description = value || contextDescription;
|
|
1171
|
-
|
|
1172
1142
|
if (description) {
|
|
1173
1143
|
return jsx("div", {
|
|
1174
1144
|
class: "bio-properties-panel-description",
|
|
@@ -1183,26 +1153,24 @@ function Checkbox(props) {
|
|
|
1183
1153
|
label,
|
|
1184
1154
|
onChange,
|
|
1185
1155
|
disabled,
|
|
1186
|
-
value = false
|
|
1156
|
+
value = false,
|
|
1157
|
+
onFocus,
|
|
1158
|
+
onBlur
|
|
1187
1159
|
} = props;
|
|
1188
1160
|
const [localValue, setLocalValue] = useState(value);
|
|
1189
|
-
|
|
1190
1161
|
const handleChangeCallback = ({
|
|
1191
1162
|
target
|
|
1192
1163
|
}) => {
|
|
1193
1164
|
onChange(target.checked);
|
|
1194
1165
|
};
|
|
1195
|
-
|
|
1196
1166
|
const handleChange = e => {
|
|
1197
1167
|
handleChangeCallback(e);
|
|
1198
1168
|
setLocalValue(e.target.value);
|
|
1199
1169
|
};
|
|
1200
|
-
|
|
1201
1170
|
useEffect(() => {
|
|
1202
1171
|
if (value === localValue) {
|
|
1203
1172
|
return;
|
|
1204
1173
|
}
|
|
1205
|
-
|
|
1206
1174
|
setLocalValue(value);
|
|
1207
1175
|
}, [value]);
|
|
1208
1176
|
const ref = useShowEntryEvent(id);
|
|
@@ -1212,6 +1180,8 @@ function Checkbox(props) {
|
|
|
1212
1180
|
ref: ref,
|
|
1213
1181
|
id: prefixId$7(id),
|
|
1214
1182
|
name: id,
|
|
1183
|
+
onFocus: onFocus,
|
|
1184
|
+
onBlur: onBlur,
|
|
1215
1185
|
type: "checkbox",
|
|
1216
1186
|
class: "bio-properties-panel-input",
|
|
1217
1187
|
onChange: handleChange,
|
|
@@ -1224,6 +1194,7 @@ function Checkbox(props) {
|
|
|
1224
1194
|
})]
|
|
1225
1195
|
});
|
|
1226
1196
|
}
|
|
1197
|
+
|
|
1227
1198
|
/**
|
|
1228
1199
|
* @param {Object} props
|
|
1229
1200
|
* @param {Object} props.element
|
|
@@ -1232,10 +1203,10 @@ function Checkbox(props) {
|
|
|
1232
1203
|
* @param {String} props.label
|
|
1233
1204
|
* @param {Function} props.getValue
|
|
1234
1205
|
* @param {Function} props.setValue
|
|
1206
|
+
* @param {Function} props.onFocus
|
|
1207
|
+
* @param {Function} props.onBlur
|
|
1235
1208
|
* @param {boolean} [props.disabled]
|
|
1236
1209
|
*/
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
1210
|
function CheckboxEntry(props) {
|
|
1240
1211
|
const {
|
|
1241
1212
|
element,
|
|
@@ -1244,7 +1215,9 @@ function CheckboxEntry(props) {
|
|
|
1244
1215
|
label,
|
|
1245
1216
|
getValue,
|
|
1246
1217
|
setValue,
|
|
1247
|
-
disabled
|
|
1218
|
+
disabled,
|
|
1219
|
+
onFocus,
|
|
1220
|
+
onBlur
|
|
1248
1221
|
} = props;
|
|
1249
1222
|
const value = getValue(element);
|
|
1250
1223
|
const error = useError(id);
|
|
@@ -1256,6 +1229,8 @@ function CheckboxEntry(props) {
|
|
|
1256
1229
|
id: id,
|
|
1257
1230
|
label: label,
|
|
1258
1231
|
onChange: setValue,
|
|
1232
|
+
onFocus: onFocus,
|
|
1233
|
+
onBlur: onBlur,
|
|
1259
1234
|
value: value
|
|
1260
1235
|
}, element), error && jsx("div", {
|
|
1261
1236
|
class: "bio-properties-panel-error",
|
|
@@ -1269,7 +1244,9 @@ function CheckboxEntry(props) {
|
|
|
1269
1244
|
}
|
|
1270
1245
|
function isEdited$7(node) {
|
|
1271
1246
|
return node && !!node.checked;
|
|
1272
|
-
}
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
// helpers /////////////////
|
|
1273
1250
|
|
|
1274
1251
|
function prefixId$7(id) {
|
|
1275
1252
|
return `bio-properties-panel-${id}`;
|
|
@@ -1278,11 +1255,14 @@ function prefixId$7(id) {
|
|
|
1278
1255
|
const useBufferedFocus = function (editor, ref) {
|
|
1279
1256
|
const [buffer, setBuffer] = useState(undefined);
|
|
1280
1257
|
ref.current = useMemo(() => ({
|
|
1281
|
-
focus:
|
|
1258
|
+
focus: offset => {
|
|
1282
1259
|
if (editor) {
|
|
1283
|
-
editor.focus(
|
|
1260
|
+
editor.focus(offset);
|
|
1284
1261
|
} else {
|
|
1285
|
-
|
|
1262
|
+
if (typeof offset === 'undefined') {
|
|
1263
|
+
offset = Infinity;
|
|
1264
|
+
}
|
|
1265
|
+
setBuffer(offset);
|
|
1286
1266
|
}
|
|
1287
1267
|
}
|
|
1288
1268
|
}), [editor]);
|
|
@@ -1293,7 +1273,6 @@ const useBufferedFocus = function (editor, ref) {
|
|
|
1293
1273
|
}
|
|
1294
1274
|
}, [editor, buffer]);
|
|
1295
1275
|
};
|
|
1296
|
-
|
|
1297
1276
|
const CodeEditor = forwardRef((props, ref) => {
|
|
1298
1277
|
const {
|
|
1299
1278
|
value,
|
|
@@ -1313,25 +1292,22 @@ const CodeEditor = forwardRef((props, ref) => {
|
|
|
1313
1292
|
});
|
|
1314
1293
|
useEffect(() => {
|
|
1315
1294
|
let editor;
|
|
1295
|
+
|
|
1316
1296
|
/* Trigger FEEL toggle when
|
|
1317
1297
|
*
|
|
1318
1298
|
* - `backspace` is pressed
|
|
1319
1299
|
* - AND the cursor is at the beginning of the input
|
|
1320
1300
|
*/
|
|
1321
|
-
|
|
1322
1301
|
const onKeyDown = e => {
|
|
1323
1302
|
if (e.key !== 'Backspace' || !editor) {
|
|
1324
1303
|
return;
|
|
1325
1304
|
}
|
|
1326
|
-
|
|
1327
1305
|
const selection = editor.getSelection();
|
|
1328
1306
|
const range = selection.ranges[selection.mainIndex];
|
|
1329
|
-
|
|
1330
1307
|
if (range.from === 0 && range.to === 0) {
|
|
1331
1308
|
onFeelToggle();
|
|
1332
1309
|
}
|
|
1333
1310
|
};
|
|
1334
|
-
|
|
1335
1311
|
editor = new FeelEditor({
|
|
1336
1312
|
container: inputRef.current,
|
|
1337
1313
|
onChange: handleInput,
|
|
@@ -1346,24 +1322,26 @@ const CodeEditor = forwardRef((props, ref) => {
|
|
|
1346
1322
|
inputRef.current.innerHTML = '';
|
|
1347
1323
|
setEditor(null);
|
|
1348
1324
|
};
|
|
1349
|
-
}, [
|
|
1325
|
+
}, []);
|
|
1350
1326
|
useEffect(() => {
|
|
1351
1327
|
if (!editor) {
|
|
1352
1328
|
return;
|
|
1353
1329
|
}
|
|
1354
|
-
|
|
1355
1330
|
if (value === localValue) {
|
|
1356
1331
|
return;
|
|
1357
1332
|
}
|
|
1358
|
-
|
|
1359
1333
|
editor.setValue(value);
|
|
1360
1334
|
setLocalValue(value);
|
|
1361
1335
|
}, [value]);
|
|
1362
|
-
|
|
1336
|
+
useEffect(() => {
|
|
1337
|
+
if (!editor) {
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1340
|
+
editor.setVariables(variables);
|
|
1341
|
+
}, [variables]);
|
|
1363
1342
|
const handleClick = () => {
|
|
1364
1343
|
ref.current.focus();
|
|
1365
1344
|
};
|
|
1366
|
-
|
|
1367
1345
|
return jsx("div", {
|
|
1368
1346
|
class: classnames('bio-properties-panel-feel-editor-container', disabled ? 'disabled' : null),
|
|
1369
1347
|
children: jsx("div", {
|
|
@@ -1379,11 +1357,9 @@ function FeelIndicator(props) {
|
|
|
1379
1357
|
const {
|
|
1380
1358
|
active
|
|
1381
1359
|
} = props;
|
|
1382
|
-
|
|
1383
1360
|
if (!active) {
|
|
1384
1361
|
return null;
|
|
1385
1362
|
}
|
|
1386
|
-
|
|
1387
1363
|
return jsx("span", {
|
|
1388
1364
|
class: "bio-properties-panel-feel-indicator",
|
|
1389
1365
|
children: "="
|
|
@@ -1391,13 +1367,12 @@ function FeelIndicator(props) {
|
|
|
1391
1367
|
}
|
|
1392
1368
|
|
|
1393
1369
|
const noop$1 = () => {};
|
|
1370
|
+
|
|
1394
1371
|
/**
|
|
1395
1372
|
* @param {Object} props
|
|
1396
1373
|
* @param {Object} props.label
|
|
1397
1374
|
* @param {String} props.feel
|
|
1398
1375
|
*/
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
1376
|
function FeelIcon(props) {
|
|
1402
1377
|
const {
|
|
1403
1378
|
label,
|
|
@@ -1408,15 +1383,14 @@ function FeelIcon(props) {
|
|
|
1408
1383
|
} = props;
|
|
1409
1384
|
const feelRequiredLabel = ' must be a FEEL expression';
|
|
1410
1385
|
const feelOptionalLabel = ' can optionally be a FEEL expression';
|
|
1411
|
-
|
|
1412
1386
|
const handleClick = e => {
|
|
1413
|
-
onClick(e);
|
|
1387
|
+
onClick(e);
|
|
1414
1388
|
|
|
1389
|
+
// when pointer event was created from keyboard, keep focus on button
|
|
1415
1390
|
if (!e.pointerType) {
|
|
1416
1391
|
e.stopPropagation();
|
|
1417
1392
|
}
|
|
1418
1393
|
};
|
|
1419
|
-
|
|
1420
1394
|
return jsx("button", {
|
|
1421
1395
|
class: classnames('bio-properties-panel-feel-icon', active ? 'active' : null, feel === 'required' ? 'required' : 'optional'),
|
|
1422
1396
|
onClick: handleClick,
|
|
@@ -1427,7 +1401,6 @@ function FeelIcon(props) {
|
|
|
1427
1401
|
}
|
|
1428
1402
|
|
|
1429
1403
|
const noop = () => {};
|
|
1430
|
-
|
|
1431
1404
|
function FeelTextfield(props) {
|
|
1432
1405
|
const {
|
|
1433
1406
|
debounce,
|
|
@@ -1438,6 +1411,7 @@ function FeelTextfield(props) {
|
|
|
1438
1411
|
feel,
|
|
1439
1412
|
value = '',
|
|
1440
1413
|
disabled = false,
|
|
1414
|
+
variables,
|
|
1441
1415
|
OptionalComponent = OptionalFeelInput
|
|
1442
1416
|
} = props;
|
|
1443
1417
|
const [localValue, _setLocalValue] = useState(value);
|
|
@@ -1446,66 +1420,54 @@ function FeelTextfield(props) {
|
|
|
1446
1420
|
const feelActive = localValue.startsWith('=') || feel === 'required';
|
|
1447
1421
|
const feelOnlyValue = localValue.startsWith('=') ? localValue.substring(1) : localValue;
|
|
1448
1422
|
const [focus, _setFocus] = useState(undefined);
|
|
1449
|
-
|
|
1450
1423
|
const setFocus = (offset = 0) => {
|
|
1451
|
-
const hasFocus = containerRef.current.contains(document.activeElement);
|
|
1424
|
+
const hasFocus = containerRef.current.contains(document.activeElement);
|
|
1452
1425
|
|
|
1426
|
+
// Keep caret position if it is already focused, otherwise focus at the end
|
|
1453
1427
|
const position = hasFocus ? document.activeElement.selectionStart : Infinity;
|
|
1454
|
-
|
|
1455
1428
|
_setFocus(position + offset);
|
|
1456
1429
|
};
|
|
1457
|
-
|
|
1458
1430
|
const handleInputCallback = useMemo(() => {
|
|
1459
1431
|
return debounce(newValue => {
|
|
1460
1432
|
onInput(newValue);
|
|
1461
1433
|
});
|
|
1462
1434
|
}, [onInput, debounce]);
|
|
1463
|
-
|
|
1464
1435
|
const setLocalValue = newValue => {
|
|
1465
1436
|
_setLocalValue(newValue);
|
|
1466
|
-
|
|
1467
1437
|
if (!newValue || newValue === '=') {
|
|
1468
1438
|
handleInputCallback(undefined);
|
|
1469
1439
|
} else {
|
|
1470
1440
|
handleInputCallback(newValue);
|
|
1471
1441
|
}
|
|
1472
1442
|
};
|
|
1473
|
-
|
|
1474
1443
|
const handleFeelToggle = useStaticCallback(() => {
|
|
1475
1444
|
if (feel === 'required') {
|
|
1476
1445
|
return;
|
|
1477
1446
|
}
|
|
1478
|
-
|
|
1479
1447
|
if (!feelActive) {
|
|
1480
1448
|
setLocalValue('=' + localValue);
|
|
1481
1449
|
} else {
|
|
1482
1450
|
setLocalValue(feelOnlyValue);
|
|
1483
1451
|
}
|
|
1484
1452
|
});
|
|
1485
|
-
|
|
1486
1453
|
const handleLocalInput = newValue => {
|
|
1487
1454
|
if (feelActive) {
|
|
1488
1455
|
newValue = '=' + newValue;
|
|
1489
1456
|
}
|
|
1490
|
-
|
|
1491
1457
|
if (newValue === localValue) {
|
|
1492
1458
|
return;
|
|
1493
1459
|
}
|
|
1494
|
-
|
|
1495
1460
|
setLocalValue(newValue);
|
|
1496
|
-
|
|
1497
1461
|
if (!feelActive && newValue.startsWith('=')) {
|
|
1498
1462
|
// focus is behind `=` sign that will be removed
|
|
1499
1463
|
setFocus(-1);
|
|
1500
1464
|
}
|
|
1501
1465
|
};
|
|
1502
|
-
|
|
1503
1466
|
const handleLint = useStaticCallback(lint => {
|
|
1504
1467
|
if (!(lint && lint.length)) {
|
|
1505
1468
|
onError(undefined);
|
|
1506
1469
|
return;
|
|
1507
1470
|
}
|
|
1508
|
-
|
|
1509
1471
|
const error = lint[0];
|
|
1510
1472
|
const message = `${error.source}: ${error.message}`;
|
|
1511
1473
|
onError(message);
|
|
@@ -1513,40 +1475,35 @@ function FeelTextfield(props) {
|
|
|
1513
1475
|
useEffect(() => {
|
|
1514
1476
|
if (typeof focus !== 'undefined') {
|
|
1515
1477
|
editorRef.current.focus(focus);
|
|
1516
|
-
|
|
1517
1478
|
_setFocus(undefined);
|
|
1518
1479
|
}
|
|
1519
1480
|
}, [focus]);
|
|
1520
1481
|
useEffect(() => {
|
|
1521
1482
|
if (value === localValue) {
|
|
1522
1483
|
return;
|
|
1523
|
-
}
|
|
1524
|
-
|
|
1484
|
+
}
|
|
1525
1485
|
|
|
1486
|
+
// External value change removed content => keep FEEL configuration
|
|
1526
1487
|
if (!value) {
|
|
1527
1488
|
setLocalValue(feelActive ? '=' : '');
|
|
1528
1489
|
return;
|
|
1529
1490
|
}
|
|
1530
|
-
|
|
1531
1491
|
setLocalValue(value);
|
|
1532
|
-
}, [value]);
|
|
1492
|
+
}, [value]);
|
|
1533
1493
|
|
|
1494
|
+
// copy-paste integration
|
|
1534
1495
|
useEffect(() => {
|
|
1535
1496
|
const copyHandler = event => {
|
|
1536
1497
|
if (!feelActive) {
|
|
1537
1498
|
return;
|
|
1538
1499
|
}
|
|
1539
|
-
|
|
1540
1500
|
event.clipboardData.setData('application/FEEL', event.clipboardData.getData('text'));
|
|
1541
1501
|
};
|
|
1542
|
-
|
|
1543
1502
|
const pasteHandler = event => {
|
|
1544
1503
|
if (feelActive) {
|
|
1545
1504
|
return;
|
|
1546
1505
|
}
|
|
1547
|
-
|
|
1548
1506
|
const data = event.clipboardData.getData('application/FEEL');
|
|
1549
|
-
|
|
1550
1507
|
if (data) {
|
|
1551
1508
|
setTimeout(() => {
|
|
1552
1509
|
handleFeelToggle();
|
|
@@ -1554,7 +1511,6 @@ function FeelTextfield(props) {
|
|
|
1554
1511
|
});
|
|
1555
1512
|
}
|
|
1556
1513
|
};
|
|
1557
|
-
|
|
1558
1514
|
containerRef.current.addEventListener('copy', copyHandler);
|
|
1559
1515
|
containerRef.current.addEventListener('cut', copyHandler);
|
|
1560
1516
|
containerRef.current.addEventListener('paste', pasteHandler);
|
|
@@ -1594,9 +1550,10 @@ function FeelTextfield(props) {
|
|
|
1594
1550
|
},
|
|
1595
1551
|
onLint: handleLint,
|
|
1596
1552
|
value: feelOnlyValue,
|
|
1597
|
-
variables:
|
|
1553
|
+
variables: variables,
|
|
1598
1554
|
ref: editorRef
|
|
1599
|
-
}) : jsx(OptionalComponent, {
|
|
1555
|
+
}) : jsx(OptionalComponent, {
|
|
1556
|
+
...props,
|
|
1600
1557
|
onInput: handleLocalInput,
|
|
1601
1558
|
value: localValue,
|
|
1602
1559
|
ref: editorRef
|
|
@@ -1604,32 +1561,30 @@ function FeelTextfield(props) {
|
|
|
1604
1561
|
})]
|
|
1605
1562
|
});
|
|
1606
1563
|
}
|
|
1607
|
-
|
|
1608
1564
|
const OptionalFeelInput = forwardRef((props, ref) => {
|
|
1609
1565
|
const {
|
|
1610
1566
|
id,
|
|
1611
1567
|
disabled,
|
|
1612
1568
|
onInput,
|
|
1613
|
-
value
|
|
1569
|
+
value,
|
|
1570
|
+
onFocus,
|
|
1571
|
+
onBlur
|
|
1614
1572
|
} = props;
|
|
1615
|
-
const inputRef = useRef();
|
|
1616
|
-
// this ensures clean editing experience when switching with the keyboard
|
|
1573
|
+
const inputRef = useRef();
|
|
1617
1574
|
|
|
1575
|
+
// To be consistent with the FEEL editor, set focus at start of input
|
|
1576
|
+
// this ensures clean editing experience when switching with the keyboard
|
|
1618
1577
|
ref.current = {
|
|
1619
1578
|
focus: position => {
|
|
1620
1579
|
const input = inputRef.current;
|
|
1621
|
-
|
|
1622
1580
|
if (!input) {
|
|
1623
1581
|
return;
|
|
1624
1582
|
}
|
|
1625
|
-
|
|
1626
1583
|
input.focus();
|
|
1627
|
-
|
|
1628
1584
|
if (typeof position === 'number') {
|
|
1629
1585
|
if (position > value.length) {
|
|
1630
1586
|
position = value.length;
|
|
1631
1587
|
}
|
|
1632
|
-
|
|
1633
1588
|
input.setSelectionRange(position, position);
|
|
1634
1589
|
}
|
|
1635
1590
|
}
|
|
@@ -1644,8 +1599,8 @@ const OptionalFeelInput = forwardRef((props, ref) => {
|
|
|
1644
1599
|
disabled: disabled,
|
|
1645
1600
|
class: "bio-properties-panel-input",
|
|
1646
1601
|
onInput: e => onInput(e.target.value),
|
|
1647
|
-
onFocus:
|
|
1648
|
-
onBlur:
|
|
1602
|
+
onFocus: onFocus,
|
|
1603
|
+
onBlur: onBlur,
|
|
1649
1604
|
value: value || ''
|
|
1650
1605
|
});
|
|
1651
1606
|
});
|
|
@@ -1654,19 +1609,20 @@ const OptionalFeelTextArea = forwardRef((props, ref) => {
|
|
|
1654
1609
|
id,
|
|
1655
1610
|
disabled,
|
|
1656
1611
|
onInput,
|
|
1657
|
-
value
|
|
1612
|
+
value,
|
|
1613
|
+
onFocus,
|
|
1614
|
+
onBlur
|
|
1658
1615
|
} = props;
|
|
1659
|
-
const inputRef = useRef();
|
|
1660
|
-
// this ensures clean editing experience when switching with the keyboard
|
|
1616
|
+
const inputRef = useRef();
|
|
1661
1617
|
|
|
1618
|
+
// To be consistent with the FEEL editor, set focus at start of input
|
|
1619
|
+
// this ensures clean editing experience when switching with the keyboard
|
|
1662
1620
|
ref.current = {
|
|
1663
1621
|
focus: () => {
|
|
1664
1622
|
const input = inputRef.current;
|
|
1665
|
-
|
|
1666
1623
|
if (!input) {
|
|
1667
1624
|
return;
|
|
1668
1625
|
}
|
|
1669
|
-
|
|
1670
1626
|
input.focus();
|
|
1671
1627
|
input.setSelectionRange(0, 0);
|
|
1672
1628
|
}
|
|
@@ -1681,11 +1637,12 @@ const OptionalFeelTextArea = forwardRef((props, ref) => {
|
|
|
1681
1637
|
disabled: disabled,
|
|
1682
1638
|
class: "bio-properties-panel-input",
|
|
1683
1639
|
onInput: e => onInput(e.target.value),
|
|
1684
|
-
onFocus:
|
|
1685
|
-
onBlur:
|
|
1640
|
+
onFocus: onFocus,
|
|
1641
|
+
onBlur: onBlur,
|
|
1686
1642
|
value: value || ''
|
|
1687
1643
|
});
|
|
1688
1644
|
});
|
|
1645
|
+
|
|
1689
1646
|
/**
|
|
1690
1647
|
* @param {Object} props
|
|
1691
1648
|
* @param {Object} props.element
|
|
@@ -1698,7 +1655,6 @@ const OptionalFeelTextArea = forwardRef((props, ref) => {
|
|
|
1698
1655
|
* @param {Function} props.setValue
|
|
1699
1656
|
* @param {Function} props.validate
|
|
1700
1657
|
*/
|
|
1701
|
-
|
|
1702
1658
|
function FeelEntry(props) {
|
|
1703
1659
|
const {
|
|
1704
1660
|
element,
|
|
@@ -1711,7 +1667,11 @@ function FeelEntry(props) {
|
|
|
1711
1667
|
getValue,
|
|
1712
1668
|
setValue,
|
|
1713
1669
|
validate,
|
|
1714
|
-
show = noop
|
|
1670
|
+
show = noop,
|
|
1671
|
+
example,
|
|
1672
|
+
variables,
|
|
1673
|
+
onFocus,
|
|
1674
|
+
onBlur
|
|
1715
1675
|
} = props;
|
|
1716
1676
|
const [cachedInvalidValue, setCachedInvalidValue] = useState(null);
|
|
1717
1677
|
const [validationError, setValidationError] = useState(null);
|
|
@@ -1726,11 +1686,9 @@ function FeelEntry(props) {
|
|
|
1726
1686
|
}, [value]);
|
|
1727
1687
|
const onInput = useStaticCallback(newValue => {
|
|
1728
1688
|
let newValidationError = null;
|
|
1729
|
-
|
|
1730
1689
|
if (isFunction(validate)) {
|
|
1731
1690
|
newValidationError = validate(newValue) || null;
|
|
1732
1691
|
}
|
|
1733
|
-
|
|
1734
1692
|
if (newValidationError) {
|
|
1735
1693
|
setCachedInvalidValue(newValue);
|
|
1736
1694
|
} else {
|
|
@@ -1739,19 +1697,16 @@ function FeelEntry(props) {
|
|
|
1739
1697
|
setValue(newValue);
|
|
1740
1698
|
}
|
|
1741
1699
|
}
|
|
1742
|
-
|
|
1743
1700
|
setValidationError(newValidationError);
|
|
1744
1701
|
});
|
|
1745
1702
|
const onError = useCallback(err => {
|
|
1746
1703
|
setLocalError(err);
|
|
1747
1704
|
}, []);
|
|
1748
|
-
|
|
1749
1705
|
if (previousValue === value && validationError) {
|
|
1750
1706
|
value = cachedInvalidValue;
|
|
1751
1707
|
}
|
|
1752
|
-
|
|
1753
1708
|
const temporaryError = useError(id);
|
|
1754
|
-
const error =
|
|
1709
|
+
const error = localError || temporaryError || validationError;
|
|
1755
1710
|
return jsxs("div", {
|
|
1756
1711
|
class: classnames(props.class, 'bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
1757
1712
|
"data-entry-id": id,
|
|
@@ -1763,10 +1718,12 @@ function FeelEntry(props) {
|
|
|
1763
1718
|
label: label,
|
|
1764
1719
|
onInput: onInput,
|
|
1765
1720
|
onError: onError,
|
|
1766
|
-
|
|
1721
|
+
onFocus: onFocus,
|
|
1722
|
+
onBlur: onBlur,
|
|
1723
|
+
example: example,
|
|
1767
1724
|
show: show,
|
|
1768
1725
|
value: value,
|
|
1769
|
-
variables:
|
|
1726
|
+
variables: variables,
|
|
1770
1727
|
OptionalComponent: props.OptionalComponent
|
|
1771
1728
|
}, element), error && jsx("div", {
|
|
1772
1729
|
class: "bio-properties-panel-error",
|
|
@@ -1778,6 +1735,7 @@ function FeelEntry(props) {
|
|
|
1778
1735
|
})]
|
|
1779
1736
|
});
|
|
1780
1737
|
}
|
|
1738
|
+
|
|
1781
1739
|
/**
|
|
1782
1740
|
* @param {Object} props
|
|
1783
1741
|
* @param {Object} props.element
|
|
@@ -1788,9 +1746,10 @@ function FeelEntry(props) {
|
|
|
1788
1746
|
* @param {String} props.label
|
|
1789
1747
|
* @param {Function} props.getValue
|
|
1790
1748
|
* @param {Function} props.setValue
|
|
1749
|
+
* @param {Function} props.onFocus
|
|
1750
|
+
* @param {Function} props.onBlur
|
|
1791
1751
|
* @param {Function} props.validate
|
|
1792
1752
|
*/
|
|
1793
|
-
|
|
1794
1753
|
function FeelTextArea(props) {
|
|
1795
1754
|
return jsx(FeelEntry, {
|
|
1796
1755
|
class: "bio-properties-panel-feel-textarea",
|
|
@@ -1800,7 +1759,9 @@ function FeelTextArea(props) {
|
|
|
1800
1759
|
}
|
|
1801
1760
|
function isEdited$6(node) {
|
|
1802
1761
|
return node && (!!node.value || node.classList.contains('edited'));
|
|
1803
|
-
}
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
// helpers /////////////////
|
|
1804
1765
|
|
|
1805
1766
|
function prefixId$6(id) {
|
|
1806
1767
|
return `bio-properties-panel-${id}`;
|
|
@@ -1822,9 +1783,7 @@ function List(props) {
|
|
|
1822
1783
|
} = props;
|
|
1823
1784
|
const [open, setOpen] = useState(!!shouldOpen);
|
|
1824
1785
|
const hasItems = !!items.length;
|
|
1825
|
-
|
|
1826
1786
|
const toggleOpen = () => hasItems && setOpen(!open);
|
|
1827
|
-
|
|
1828
1787
|
const opening = !usePrevious(open) && open;
|
|
1829
1788
|
const elementChanged = usePrevious(element) !== element;
|
|
1830
1789
|
const shouldReset = opening || elementChanged;
|
|
@@ -1835,19 +1794,17 @@ function List(props) {
|
|
|
1835
1794
|
setOpen(false);
|
|
1836
1795
|
}
|
|
1837
1796
|
}, [open, hasItems]);
|
|
1797
|
+
|
|
1838
1798
|
/**
|
|
1839
1799
|
* @param {MouseEvent} event
|
|
1840
1800
|
*/
|
|
1841
|
-
|
|
1842
1801
|
function addItem(event) {
|
|
1843
1802
|
event.stopPropagation();
|
|
1844
1803
|
onAdd();
|
|
1845
|
-
|
|
1846
1804
|
if (!open) {
|
|
1847
1805
|
setOpen(true);
|
|
1848
1806
|
}
|
|
1849
1807
|
}
|
|
1850
|
-
|
|
1851
1808
|
return jsxs("div", {
|
|
1852
1809
|
"data-entry-id": id,
|
|
1853
1810
|
class: classnames('bio-properties-panel-entry', 'bio-properties-panel-list-entry', hasItems ? '' : 'empty', open ? 'open' : ''),
|
|
@@ -1880,7 +1837,8 @@ function List(props) {
|
|
|
1880
1837
|
})
|
|
1881
1838
|
})]
|
|
1882
1839
|
})]
|
|
1883
|
-
}), hasItems && jsx(ItemsList, {
|
|
1840
|
+
}), hasItems && jsx(ItemsList, {
|
|
1841
|
+
...restProps,
|
|
1884
1842
|
autoFocusEntry: autoFocusEntry,
|
|
1885
1843
|
component: component,
|
|
1886
1844
|
element: element,
|
|
@@ -1892,7 +1850,6 @@ function List(props) {
|
|
|
1892
1850
|
})]
|
|
1893
1851
|
});
|
|
1894
1852
|
}
|
|
1895
|
-
|
|
1896
1853
|
function ItemsList(props) {
|
|
1897
1854
|
const {
|
|
1898
1855
|
autoFocusEntry,
|
|
@@ -1910,11 +1867,13 @@ function ItemsList(props) {
|
|
|
1910
1867
|
useEffect(() => {
|
|
1911
1868
|
if (newItem && autoFocusEntry) {
|
|
1912
1869
|
// (0) select the parent entry (containing all list items)
|
|
1913
|
-
const entry = query(`[data-entry-id="${id}"]`);
|
|
1870
|
+
const entry = query(`[data-entry-id="${id}"]`);
|
|
1914
1871
|
|
|
1872
|
+
// (1) select the first input or a custom element to be focussed
|
|
1915
1873
|
const selector = typeof autoFocusEntry === 'boolean' ? '.bio-properties-panel-input' : autoFocusEntry;
|
|
1916
|
-
const focusableInput = query(selector, entry);
|
|
1874
|
+
const focusableInput = query(selector, entry);
|
|
1917
1875
|
|
|
1876
|
+
// (2) set focus
|
|
1918
1877
|
if (focusableInput) {
|
|
1919
1878
|
if (isFunction(focusableInput.select)) {
|
|
1920
1879
|
focusableInput.select();
|
|
@@ -1930,7 +1889,8 @@ function ItemsList(props) {
|
|
|
1930
1889
|
const key = getKey(item);
|
|
1931
1890
|
return jsxs("li", {
|
|
1932
1891
|
class: "bio-properties-panel-list-entry-item",
|
|
1933
|
-
children: [jsx(Component, {
|
|
1892
|
+
children: [jsx(Component, {
|
|
1893
|
+
...restProps,
|
|
1934
1894
|
element: element,
|
|
1935
1895
|
id: id,
|
|
1936
1896
|
index: index,
|
|
@@ -1947,6 +1907,7 @@ function ItemsList(props) {
|
|
|
1947
1907
|
})
|
|
1948
1908
|
});
|
|
1949
1909
|
}
|
|
1910
|
+
|
|
1950
1911
|
/**
|
|
1951
1912
|
* Place new items in the beginning of the list and sort the rest with provided function.
|
|
1952
1913
|
*
|
|
@@ -1956,41 +1917,36 @@ function ItemsList(props) {
|
|
|
1956
1917
|
* @param {boolean} [shouldReset=false] set to `true` to reset state of the hook
|
|
1957
1918
|
* @returns {Item[]}
|
|
1958
1919
|
*/
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
1920
|
function useSortedItems(currentItems, compareFn, shouldReset = false) {
|
|
1962
|
-
const itemsRef = useRef(currentItems.slice());
|
|
1921
|
+
const itemsRef = useRef(currentItems.slice());
|
|
1963
1922
|
|
|
1923
|
+
// (1) Reset and optionally sort.
|
|
1964
1924
|
if (shouldReset) {
|
|
1965
1925
|
itemsRef.current = currentItems.slice();
|
|
1966
|
-
|
|
1967
1926
|
if (compareFn) {
|
|
1968
1927
|
itemsRef.current.sort(compareFn);
|
|
1969
1928
|
}
|
|
1970
1929
|
} else {
|
|
1971
|
-
const items = itemsRef.current;
|
|
1930
|
+
const items = itemsRef.current;
|
|
1972
1931
|
|
|
1932
|
+
// (2) Add new item to the list.
|
|
1973
1933
|
for (const item of currentItems) {
|
|
1974
1934
|
if (!items.includes(item)) {
|
|
1975
1935
|
// Unshift or push depending on whether we have a compareFn
|
|
1976
1936
|
compareFn ? items.unshift(item) : items.push(item);
|
|
1977
1937
|
}
|
|
1978
|
-
}
|
|
1979
|
-
|
|
1938
|
+
}
|
|
1980
1939
|
|
|
1940
|
+
// (3) Filter out removed items.
|
|
1981
1941
|
itemsRef.current = items.filter(item => currentItems.includes(item));
|
|
1982
1942
|
}
|
|
1983
|
-
|
|
1984
1943
|
return itemsRef.current;
|
|
1985
1944
|
}
|
|
1986
|
-
|
|
1987
1945
|
function useNewItems(items = [], shouldReset) {
|
|
1988
1946
|
const previousItems = usePrevious(items.slice()) || [];
|
|
1989
|
-
|
|
1990
1947
|
if (shouldReset) {
|
|
1991
1948
|
return [];
|
|
1992
1949
|
}
|
|
1993
|
-
|
|
1994
1950
|
return previousItems ? items.filter(item => !previousItems.includes(item)) : [];
|
|
1995
1951
|
}
|
|
1996
1952
|
|
|
@@ -2004,7 +1960,9 @@ function NumberField(props) {
|
|
|
2004
1960
|
min,
|
|
2005
1961
|
onInput,
|
|
2006
1962
|
step,
|
|
2007
|
-
value = ''
|
|
1963
|
+
value = '',
|
|
1964
|
+
onFocus,
|
|
1965
|
+
onBlur
|
|
2008
1966
|
} = props;
|
|
2009
1967
|
const [localValue, setLocalValue] = useState(value);
|
|
2010
1968
|
const handleInputCallback = useMemo(() => {
|
|
@@ -2013,23 +1971,19 @@ function NumberField(props) {
|
|
|
2013
1971
|
validity,
|
|
2014
1972
|
value
|
|
2015
1973
|
} = event.target;
|
|
2016
|
-
|
|
2017
1974
|
if (validity.valid) {
|
|
2018
1975
|
onInput(value ? parseFloat(value) : undefined);
|
|
2019
1976
|
}
|
|
2020
1977
|
});
|
|
2021
1978
|
}, [onInput, debounce]);
|
|
2022
|
-
|
|
2023
1979
|
const handleInput = e => {
|
|
2024
1980
|
handleInputCallback(e);
|
|
2025
1981
|
setLocalValue(e.target.value);
|
|
2026
1982
|
};
|
|
2027
|
-
|
|
2028
1983
|
useEffect(() => {
|
|
2029
1984
|
if (value === localValue) {
|
|
2030
1985
|
return;
|
|
2031
1986
|
}
|
|
2032
|
-
|
|
2033
1987
|
setLocalValue(value);
|
|
2034
1988
|
}, [value]);
|
|
2035
1989
|
return jsxs("div", {
|
|
@@ -2049,11 +2003,14 @@ function NumberField(props) {
|
|
|
2049
2003
|
max: max,
|
|
2050
2004
|
min: min,
|
|
2051
2005
|
onInput: handleInput,
|
|
2006
|
+
onFocus: onFocus,
|
|
2007
|
+
onBlur: onBlur,
|
|
2052
2008
|
step: step,
|
|
2053
2009
|
value: localValue
|
|
2054
2010
|
})]
|
|
2055
2011
|
});
|
|
2056
2012
|
}
|
|
2013
|
+
|
|
2057
2014
|
/**
|
|
2058
2015
|
* @param {Object} props
|
|
2059
2016
|
* @param {Boolean} props.debounce
|
|
@@ -2066,10 +2023,10 @@ function NumberField(props) {
|
|
|
2066
2023
|
* @param {String} props.max
|
|
2067
2024
|
* @param {String} props.min
|
|
2068
2025
|
* @param {Function} props.setValue
|
|
2026
|
+
* @param {Function} props.onFocus
|
|
2027
|
+
* @param {Function} props.onBlur
|
|
2069
2028
|
* @param {String} props.step
|
|
2070
2029
|
*/
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
2030
|
function NumberFieldEntry(props) {
|
|
2074
2031
|
const {
|
|
2075
2032
|
debounce,
|
|
@@ -2082,7 +2039,9 @@ function NumberFieldEntry(props) {
|
|
|
2082
2039
|
max,
|
|
2083
2040
|
min,
|
|
2084
2041
|
setValue,
|
|
2085
|
-
step
|
|
2042
|
+
step,
|
|
2043
|
+
onFocus,
|
|
2044
|
+
onBlur
|
|
2086
2045
|
} = props;
|
|
2087
2046
|
const value = getValue(element);
|
|
2088
2047
|
return jsxs("div", {
|
|
@@ -2094,6 +2053,8 @@ function NumberFieldEntry(props) {
|
|
|
2094
2053
|
id: id,
|
|
2095
2054
|
label: label,
|
|
2096
2055
|
onInput: setValue,
|
|
2056
|
+
onFocus: onFocus,
|
|
2057
|
+
onBlur: onBlur,
|
|
2097
2058
|
max: max,
|
|
2098
2059
|
min: min,
|
|
2099
2060
|
step: step,
|
|
@@ -2107,7 +2068,9 @@ function NumberFieldEntry(props) {
|
|
|
2107
2068
|
}
|
|
2108
2069
|
function isEdited$5(node) {
|
|
2109
2070
|
return node && !!node.value;
|
|
2110
|
-
}
|
|
2071
|
+
}
|
|
2072
|
+
|
|
2073
|
+
// helpers /////////////////
|
|
2111
2074
|
|
|
2112
2075
|
function prefixId$5(id) {
|
|
2113
2076
|
return `bio-properties-panel-${id}`;
|
|
@@ -2120,27 +2083,25 @@ function Select(props) {
|
|
|
2120
2083
|
onChange,
|
|
2121
2084
|
options = [],
|
|
2122
2085
|
value,
|
|
2123
|
-
disabled
|
|
2086
|
+
disabled,
|
|
2087
|
+
onFocus,
|
|
2088
|
+
onBlur
|
|
2124
2089
|
} = props;
|
|
2125
2090
|
const ref = useShowEntryEvent(id);
|
|
2126
2091
|
const [localValue, setLocalValue] = useState(value);
|
|
2127
|
-
|
|
2128
2092
|
const handleChangeCallback = ({
|
|
2129
2093
|
target
|
|
2130
2094
|
}) => {
|
|
2131
2095
|
onChange(target.value);
|
|
2132
2096
|
};
|
|
2133
|
-
|
|
2134
2097
|
const handleChange = e => {
|
|
2135
2098
|
handleChangeCallback(e);
|
|
2136
2099
|
setLocalValue(e.target.value);
|
|
2137
2100
|
};
|
|
2138
|
-
|
|
2139
2101
|
useEffect(() => {
|
|
2140
2102
|
if (value === localValue) {
|
|
2141
2103
|
return;
|
|
2142
2104
|
}
|
|
2143
|
-
|
|
2144
2105
|
setLocalValue(value);
|
|
2145
2106
|
}, [value]);
|
|
2146
2107
|
return jsxs("div", {
|
|
@@ -2155,6 +2116,8 @@ function Select(props) {
|
|
|
2155
2116
|
name: id,
|
|
2156
2117
|
class: "bio-properties-panel-input",
|
|
2157
2118
|
onInput: handleChange,
|
|
2119
|
+
onFocus: onFocus,
|
|
2120
|
+
onBlur: onBlur,
|
|
2158
2121
|
value: localValue,
|
|
2159
2122
|
disabled: disabled,
|
|
2160
2123
|
children: options.map((option, idx) => {
|
|
@@ -2167,6 +2130,7 @@ function Select(props) {
|
|
|
2167
2130
|
})]
|
|
2168
2131
|
});
|
|
2169
2132
|
}
|
|
2133
|
+
|
|
2170
2134
|
/**
|
|
2171
2135
|
* @param {object} props
|
|
2172
2136
|
* @param {object} props.element
|
|
@@ -2175,11 +2139,11 @@ function Select(props) {
|
|
|
2175
2139
|
* @param {string} props.label
|
|
2176
2140
|
* @param {Function} props.getValue
|
|
2177
2141
|
* @param {Function} props.setValue
|
|
2142
|
+
* @param {Function} props.onFocus
|
|
2143
|
+
* @param {Function} props.onBlur
|
|
2178
2144
|
* @param {Function} props.getOptions
|
|
2179
2145
|
* @param {boolean} [props.disabled]
|
|
2180
2146
|
*/
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
2147
|
function SelectEntry(props) {
|
|
2184
2148
|
const {
|
|
2185
2149
|
element,
|
|
@@ -2189,7 +2153,9 @@ function SelectEntry(props) {
|
|
|
2189
2153
|
getValue,
|
|
2190
2154
|
setValue,
|
|
2191
2155
|
getOptions,
|
|
2192
|
-
disabled
|
|
2156
|
+
disabled,
|
|
2157
|
+
onFocus,
|
|
2158
|
+
onBlur
|
|
2193
2159
|
} = props;
|
|
2194
2160
|
const value = getValue(element);
|
|
2195
2161
|
const options = getOptions(element);
|
|
@@ -2202,6 +2168,8 @@ function SelectEntry(props) {
|
|
|
2202
2168
|
label: label,
|
|
2203
2169
|
value: value,
|
|
2204
2170
|
onChange: setValue,
|
|
2171
|
+
onFocus: onFocus,
|
|
2172
|
+
onBlur: onBlur,
|
|
2205
2173
|
options: options,
|
|
2206
2174
|
disabled: disabled
|
|
2207
2175
|
}, element), error && jsx("div", {
|
|
@@ -2216,7 +2184,9 @@ function SelectEntry(props) {
|
|
|
2216
2184
|
}
|
|
2217
2185
|
function isEdited$4(node) {
|
|
2218
2186
|
return node && !!node.value;
|
|
2219
|
-
}
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
// helpers /////////////////
|
|
2220
2190
|
|
|
2221
2191
|
function prefixId$4(id) {
|
|
2222
2192
|
return `bio-properties-panel-${id}`;
|
|
@@ -2240,17 +2210,14 @@ function Simple(props) {
|
|
|
2240
2210
|
target
|
|
2241
2211
|
}) => setValue(target.value.length ? target.value : undefined));
|
|
2242
2212
|
}, [setValue, debounce]);
|
|
2243
|
-
|
|
2244
2213
|
const handleInput = e => {
|
|
2245
2214
|
handleInputCallback(e);
|
|
2246
2215
|
setLocalValue(e.target.value);
|
|
2247
2216
|
};
|
|
2248
|
-
|
|
2249
2217
|
useEffect(() => {
|
|
2250
2218
|
if (value === localValue) {
|
|
2251
2219
|
return;
|
|
2252
2220
|
}
|
|
2253
|
-
|
|
2254
2221
|
setLocalValue(value);
|
|
2255
2222
|
}, [value]);
|
|
2256
2223
|
return jsx("div", {
|
|
@@ -2273,7 +2240,9 @@ function Simple(props) {
|
|
|
2273
2240
|
}
|
|
2274
2241
|
function isEdited$3(node) {
|
|
2275
2242
|
return node && !!node.value;
|
|
2276
|
-
}
|
|
2243
|
+
}
|
|
2244
|
+
|
|
2245
|
+
// helpers /////////////////
|
|
2277
2246
|
|
|
2278
2247
|
function prefixId$3(id) {
|
|
2279
2248
|
return `bio-properties-panel-${id}`;
|
|
@@ -2288,7 +2257,9 @@ function TextArea(props) {
|
|
|
2288
2257
|
onInput,
|
|
2289
2258
|
value = '',
|
|
2290
2259
|
disabled,
|
|
2291
|
-
monospace
|
|
2260
|
+
monospace,
|
|
2261
|
+
onFocus,
|
|
2262
|
+
onBlur
|
|
2292
2263
|
} = props;
|
|
2293
2264
|
const [localValue, setLocalValue] = useState(value);
|
|
2294
2265
|
const ref = useShowEntryEvent(id);
|
|
@@ -2297,17 +2268,14 @@ function TextArea(props) {
|
|
|
2297
2268
|
target
|
|
2298
2269
|
}) => onInput(target.value.length ? target.value : undefined));
|
|
2299
2270
|
}, [onInput, debounce]);
|
|
2300
|
-
|
|
2301
2271
|
const handleInput = e => {
|
|
2302
2272
|
handleInputCallback(e);
|
|
2303
2273
|
setLocalValue(e.target.value);
|
|
2304
2274
|
};
|
|
2305
|
-
|
|
2306
2275
|
useEffect(() => {
|
|
2307
2276
|
if (value === localValue) {
|
|
2308
2277
|
return;
|
|
2309
2278
|
}
|
|
2310
|
-
|
|
2311
2279
|
setLocalValue(value);
|
|
2312
2280
|
}, [value]);
|
|
2313
2281
|
return jsxs("div", {
|
|
@@ -2323,14 +2291,15 @@ function TextArea(props) {
|
|
|
2323
2291
|
spellCheck: "false",
|
|
2324
2292
|
class: classnames('bio-properties-panel-input', monospace ? 'bio-properties-panel-input-monospace' : ''),
|
|
2325
2293
|
onInput: handleInput,
|
|
2326
|
-
onFocus:
|
|
2327
|
-
onBlur:
|
|
2294
|
+
onFocus: onFocus,
|
|
2295
|
+
onBlur: onBlur,
|
|
2328
2296
|
rows: rows,
|
|
2329
2297
|
value: localValue,
|
|
2330
2298
|
disabled: disabled
|
|
2331
2299
|
})]
|
|
2332
2300
|
});
|
|
2333
2301
|
}
|
|
2302
|
+
|
|
2334
2303
|
/**
|
|
2335
2304
|
* @param {object} props
|
|
2336
2305
|
* @param {object} props.element
|
|
@@ -2340,12 +2309,12 @@ function TextArea(props) {
|
|
|
2340
2309
|
* @param {string} props.label
|
|
2341
2310
|
* @param {Function} props.getValue
|
|
2342
2311
|
* @param {Function} props.setValue
|
|
2312
|
+
* @param {Function} props.onFocus
|
|
2313
|
+
* @param {Function} props.onBlur
|
|
2343
2314
|
* @param {number} props.rows
|
|
2344
2315
|
* @param {boolean} props.monospace
|
|
2345
2316
|
* @param {boolean} [props.disabled]
|
|
2346
2317
|
*/
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
2318
|
function TextAreaEntry(props) {
|
|
2350
2319
|
const {
|
|
2351
2320
|
element,
|
|
@@ -2357,7 +2326,9 @@ function TextAreaEntry(props) {
|
|
|
2357
2326
|
setValue,
|
|
2358
2327
|
rows,
|
|
2359
2328
|
monospace,
|
|
2360
|
-
disabled
|
|
2329
|
+
disabled,
|
|
2330
|
+
onFocus,
|
|
2331
|
+
onBlur
|
|
2361
2332
|
} = props;
|
|
2362
2333
|
const value = getValue(element);
|
|
2363
2334
|
const error = useError(id);
|
|
@@ -2369,6 +2340,8 @@ function TextAreaEntry(props) {
|
|
|
2369
2340
|
label: label,
|
|
2370
2341
|
value: value,
|
|
2371
2342
|
onInput: setValue,
|
|
2343
|
+
onFocus: onFocus,
|
|
2344
|
+
onBlur: onBlur,
|
|
2372
2345
|
rows: rows,
|
|
2373
2346
|
debounce: debounce,
|
|
2374
2347
|
monospace: monospace,
|
|
@@ -2385,7 +2358,9 @@ function TextAreaEntry(props) {
|
|
|
2385
2358
|
}
|
|
2386
2359
|
function isEdited$2(node) {
|
|
2387
2360
|
return node && !!node.value;
|
|
2388
|
-
}
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2363
|
+
// helpers /////////////////
|
|
2389
2364
|
|
|
2390
2365
|
function prefixId$2(id) {
|
|
2391
2366
|
return `bio-properties-panel-${id}`;
|
|
@@ -2398,6 +2373,8 @@ function Textfield(props) {
|
|
|
2398
2373
|
id,
|
|
2399
2374
|
label,
|
|
2400
2375
|
onInput,
|
|
2376
|
+
onFocus,
|
|
2377
|
+
onBlur,
|
|
2401
2378
|
value = ''
|
|
2402
2379
|
} = props;
|
|
2403
2380
|
const [localValue, setLocalValue] = useState(value || '');
|
|
@@ -2407,17 +2384,14 @@ function Textfield(props) {
|
|
|
2407
2384
|
target
|
|
2408
2385
|
}) => onInput(target.value.length ? target.value : undefined));
|
|
2409
2386
|
}, [onInput, debounce]);
|
|
2410
|
-
|
|
2411
2387
|
const handleInput = e => {
|
|
2412
2388
|
handleInputCallback(e);
|
|
2413
2389
|
setLocalValue(e.target.value);
|
|
2414
2390
|
};
|
|
2415
|
-
|
|
2416
2391
|
useEffect(() => {
|
|
2417
2392
|
if (value === localValue) {
|
|
2418
2393
|
return;
|
|
2419
2394
|
}
|
|
2420
|
-
|
|
2421
2395
|
setLocalValue(value);
|
|
2422
2396
|
}, [value]);
|
|
2423
2397
|
return jsxs("div", {
|
|
@@ -2436,12 +2410,13 @@ function Textfield(props) {
|
|
|
2436
2410
|
disabled: disabled,
|
|
2437
2411
|
class: "bio-properties-panel-input",
|
|
2438
2412
|
onInput: handleInput,
|
|
2439
|
-
onFocus:
|
|
2440
|
-
onBlur:
|
|
2413
|
+
onFocus: onFocus,
|
|
2414
|
+
onBlur: onBlur,
|
|
2441
2415
|
value: localValue
|
|
2442
2416
|
})]
|
|
2443
2417
|
});
|
|
2444
2418
|
}
|
|
2419
|
+
|
|
2445
2420
|
/**
|
|
2446
2421
|
* @param {Object} props
|
|
2447
2422
|
* @param {Object} props.element
|
|
@@ -2452,10 +2427,10 @@ function Textfield(props) {
|
|
|
2452
2427
|
* @param {String} props.label
|
|
2453
2428
|
* @param {Function} props.getValue
|
|
2454
2429
|
* @param {Function} props.setValue
|
|
2430
|
+
* @param {Function} props.onFocus
|
|
2431
|
+
* @param {Function} props.onBlur
|
|
2455
2432
|
* @param {Function} props.validate
|
|
2456
2433
|
*/
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
2434
|
function TextfieldEntry(props) {
|
|
2460
2435
|
const {
|
|
2461
2436
|
element,
|
|
@@ -2466,7 +2441,9 @@ function TextfieldEntry(props) {
|
|
|
2466
2441
|
label,
|
|
2467
2442
|
getValue,
|
|
2468
2443
|
setValue,
|
|
2469
|
-
validate
|
|
2444
|
+
validate,
|
|
2445
|
+
onFocus,
|
|
2446
|
+
onBlur
|
|
2470
2447
|
} = props;
|
|
2471
2448
|
const [cachedInvalidValue, setCachedInvalidValue] = useState(null);
|
|
2472
2449
|
const globalError = useError(id);
|
|
@@ -2479,27 +2456,21 @@ function TextfieldEntry(props) {
|
|
|
2479
2456
|
setLocalError(newValidationError);
|
|
2480
2457
|
}
|
|
2481
2458
|
}, [value]);
|
|
2482
|
-
|
|
2483
2459
|
const onInput = newValue => {
|
|
2484
2460
|
let newValidationError = null;
|
|
2485
|
-
|
|
2486
2461
|
if (isFunction(validate)) {
|
|
2487
2462
|
newValidationError = validate(newValue) || null;
|
|
2488
2463
|
}
|
|
2489
|
-
|
|
2490
2464
|
if (newValidationError) {
|
|
2491
2465
|
setCachedInvalidValue(newValue);
|
|
2492
2466
|
} else {
|
|
2493
2467
|
setValue(newValue);
|
|
2494
2468
|
}
|
|
2495
|
-
|
|
2496
2469
|
setLocalError(newValidationError);
|
|
2497
2470
|
};
|
|
2498
|
-
|
|
2499
2471
|
if (previousValue === value && localError) {
|
|
2500
2472
|
value = cachedInvalidValue;
|
|
2501
2473
|
}
|
|
2502
|
-
|
|
2503
2474
|
const error = globalError || localError;
|
|
2504
2475
|
return jsxs("div", {
|
|
2505
2476
|
class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
@@ -2510,6 +2481,8 @@ function TextfieldEntry(props) {
|
|
|
2510
2481
|
id: id,
|
|
2511
2482
|
label: label,
|
|
2512
2483
|
onInput: onInput,
|
|
2484
|
+
onFocus: onFocus,
|
|
2485
|
+
onBlur: onBlur,
|
|
2513
2486
|
value: value
|
|
2514
2487
|
}, element), error && jsx("div", {
|
|
2515
2488
|
class: "bio-properties-panel-error",
|
|
@@ -2523,7 +2496,9 @@ function TextfieldEntry(props) {
|
|
|
2523
2496
|
}
|
|
2524
2497
|
function isEdited$1(node) {
|
|
2525
2498
|
return node && !!node.value;
|
|
2526
|
-
}
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2501
|
+
// helpers /////////////////
|
|
2527
2502
|
|
|
2528
2503
|
function prefixId$1(id) {
|
|
2529
2504
|
return `bio-properties-panel-${id}`;
|
|
@@ -2535,24 +2510,22 @@ function ToggleSwitch(props) {
|
|
|
2535
2510
|
label,
|
|
2536
2511
|
onInput,
|
|
2537
2512
|
value,
|
|
2538
|
-
switcherLabel
|
|
2513
|
+
switcherLabel,
|
|
2514
|
+
onFocus,
|
|
2515
|
+
onBlur
|
|
2539
2516
|
} = props;
|
|
2540
2517
|
const [localValue, setLocalValue] = useState(value);
|
|
2541
|
-
|
|
2542
2518
|
const handleInputCallback = async () => {
|
|
2543
2519
|
onInput(!value);
|
|
2544
2520
|
};
|
|
2545
|
-
|
|
2546
2521
|
const handleInput = e => {
|
|
2547
2522
|
handleInputCallback();
|
|
2548
2523
|
setLocalValue(e.target.value);
|
|
2549
2524
|
};
|
|
2550
|
-
|
|
2551
2525
|
useEffect(() => {
|
|
2552
2526
|
if (value === localValue) {
|
|
2553
2527
|
return;
|
|
2554
2528
|
}
|
|
2555
|
-
|
|
2556
2529
|
setLocalValue(value);
|
|
2557
2530
|
}, [value]);
|
|
2558
2531
|
return jsxs("div", {
|
|
@@ -2569,9 +2542,11 @@ function ToggleSwitch(props) {
|
|
|
2569
2542
|
id: prefixId(id),
|
|
2570
2543
|
class: "bio-properties-panel-input",
|
|
2571
2544
|
type: "checkbox",
|
|
2545
|
+
onFocus: onFocus,
|
|
2546
|
+
onBlur: onBlur,
|
|
2572
2547
|
name: id,
|
|
2573
2548
|
onInput: handleInput,
|
|
2574
|
-
checked: localValue
|
|
2549
|
+
checked: !!localValue
|
|
2575
2550
|
}), jsx("span", {
|
|
2576
2551
|
class: "bio-properties-panel-toggle-switch__slider"
|
|
2577
2552
|
})]
|
|
@@ -2582,6 +2557,7 @@ function ToggleSwitch(props) {
|
|
|
2582
2557
|
})]
|
|
2583
2558
|
});
|
|
2584
2559
|
}
|
|
2560
|
+
|
|
2585
2561
|
/**
|
|
2586
2562
|
* @param {Object} props
|
|
2587
2563
|
* @param {Object} props.element
|
|
@@ -2591,9 +2567,9 @@ function ToggleSwitch(props) {
|
|
|
2591
2567
|
* @param {String} props.switcherLabel
|
|
2592
2568
|
* @param {Function} props.getValue
|
|
2593
2569
|
* @param {Function} props.setValue
|
|
2570
|
+
* @param {Function} props.onFocus
|
|
2571
|
+
* @param {Function} props.onBlur
|
|
2594
2572
|
*/
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
2573
|
function ToggleSwitchEntry(props) {
|
|
2598
2574
|
const {
|
|
2599
2575
|
element,
|
|
@@ -2602,7 +2578,9 @@ function ToggleSwitchEntry(props) {
|
|
|
2602
2578
|
label,
|
|
2603
2579
|
switcherLabel,
|
|
2604
2580
|
getValue,
|
|
2605
|
-
setValue
|
|
2581
|
+
setValue,
|
|
2582
|
+
onFocus,
|
|
2583
|
+
onBlur
|
|
2606
2584
|
} = props;
|
|
2607
2585
|
const value = getValue(element);
|
|
2608
2586
|
return jsxs("div", {
|
|
@@ -2613,6 +2591,8 @@ function ToggleSwitchEntry(props) {
|
|
|
2613
2591
|
label: label,
|
|
2614
2592
|
value: value,
|
|
2615
2593
|
onInput: setValue,
|
|
2594
|
+
onFocus: onFocus,
|
|
2595
|
+
onBlur: onBlur,
|
|
2616
2596
|
switcherLabel: switcherLabel
|
|
2617
2597
|
}), jsx(Description, {
|
|
2618
2598
|
forId: id,
|
|
@@ -2623,7 +2603,9 @@ function ToggleSwitchEntry(props) {
|
|
|
2623
2603
|
}
|
|
2624
2604
|
function isEdited(node) {
|
|
2625
2605
|
return node && !!node.checked;
|
|
2626
|
-
}
|
|
2606
|
+
}
|
|
2607
|
+
|
|
2608
|
+
// helpers /////////////////
|
|
2627
2609
|
|
|
2628
2610
|
function prefixId(id) {
|
|
2629
2611
|
return `bio-properties-panel-${id}`;
|