@bpmn-io/properties-panel 0.24.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -17,52 +17,50 @@ var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
17
17
  var FeelEditor__default = /*#__PURE__*/_interopDefaultLegacy(FeelEditor);
18
18
 
19
19
  var ArrowIcon = function ArrowIcon(props) {
20
- return jsxRuntime.jsx("svg", { ...props,
20
+ return jsxRuntime.jsx("svg", {
21
+ ...props,
21
22
  children: jsxRuntime.jsx("path", {
22
23
  fillRule: "evenodd",
23
24
  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"
24
25
  })
25
26
  });
26
27
  };
27
-
28
28
  ArrowIcon.defaultProps = {
29
29
  xmlns: "http://www.w3.org/2000/svg",
30
30
  width: "16",
31
31
  height: "16"
32
32
  };
33
-
34
33
  var CreateIcon = function CreateIcon(props) {
35
- return jsxRuntime.jsx("svg", { ...props,
34
+ return jsxRuntime.jsx("svg", {
35
+ ...props,
36
36
  children: jsxRuntime.jsx("path", {
37
37
  fillRule: "evenodd",
38
38
  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"
39
39
  })
40
40
  });
41
41
  };
42
-
43
42
  CreateIcon.defaultProps = {
44
43
  xmlns: "http://www.w3.org/2000/svg",
45
44
  width: "16",
46
45
  height: "16"
47
46
  };
48
-
49
47
  var DeleteIcon = function DeleteIcon(props) {
50
- return jsxRuntime.jsx("svg", { ...props,
48
+ return jsxRuntime.jsx("svg", {
49
+ ...props,
51
50
  children: jsxRuntime.jsx("path", {
52
51
  fillRule: "evenodd",
53
52
  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"
54
53
  })
55
54
  });
56
55
  };
57
-
58
56
  DeleteIcon.defaultProps = {
59
57
  xmlns: "http://www.w3.org/2000/svg",
60
58
  width: "16",
61
59
  height: "16"
62
60
  };
63
-
64
61
  var ExternalLinkIcon = function ExternalLinkIcon(props) {
65
- return jsxRuntime.jsx("svg", { ...props,
62
+ return jsxRuntime.jsx("svg", {
63
+ ...props,
66
64
  children: jsxRuntime.jsx("path", {
67
65
  fillRule: "evenodd",
68
66
  clipRule: "evenodd",
@@ -71,16 +69,15 @@ var ExternalLinkIcon = function ExternalLinkIcon(props) {
71
69
  })
72
70
  });
73
71
  };
74
-
75
72
  ExternalLinkIcon.defaultProps = {
76
73
  width: "16",
77
74
  height: "16",
78
75
  fill: "none",
79
76
  xmlns: "http://www.w3.org/2000/svg"
80
77
  };
81
-
82
78
  var FeelRequiredIcon = function FeelRequiredIcon(props) {
83
- return jsxRuntime.jsxs("svg", { ...props,
79
+ return jsxRuntime.jsxs("svg", {
80
+ ...props,
84
81
  children: [jsxRuntime.jsx("path", {
85
82
  d: "M5.8 7.06V5.95h4.307v1.11H5.8Zm0 3.071v-1.11h4.307v1.11H5.8Z",
86
83
  fill: "currentColor"
@@ -95,15 +92,14 @@ var FeelRequiredIcon = function FeelRequiredIcon(props) {
95
92
  })]
96
93
  });
97
94
  };
98
-
99
95
  FeelRequiredIcon.defaultProps = {
100
96
  viewBox: "0 0 16 16",
101
97
  fill: "none",
102
98
  xmlns: "http://www.w3.org/2000/svg"
103
99
  };
104
-
105
100
  var FeelOptionalIcon = function FeelOptionalIcon(props) {
106
- return jsxRuntime.jsxs("svg", { ...props,
101
+ return jsxRuntime.jsxs("svg", {
102
+ ...props,
107
103
  children: [jsxRuntime.jsx("path", {
108
104
  d: "M5.845 7.04V5.93h4.307v1.11H5.845Zm0 3.07V9h4.307v1.11H5.845Z",
109
105
  fill: "currentColor"
@@ -115,7 +111,6 @@ var FeelOptionalIcon = function FeelOptionalIcon(props) {
115
111
  })]
116
112
  });
117
113
  };
118
-
119
114
  FeelOptionalIcon.defaultProps = {
120
115
  viewBox: "0 0 16 16",
121
116
  fill: "none",
@@ -220,7 +215,6 @@ const LayoutContext = preact.createContext({
220
215
  *
221
216
  * @returns {string}
222
217
  */
223
-
224
218
  function useDescriptionContext(id, element) {
225
219
  const {
226
220
  getDescriptionForId
@@ -241,28 +235,25 @@ function useError(id) {
241
235
  * @param {string} event
242
236
  * @param {Function} callback
243
237
  */
244
-
245
238
  function useEvent(event, callback, eventBus) {
246
239
  const eventContext = hooks.useContext(EventContext);
247
-
248
240
  if (!eventBus) {
249
241
  ({
250
242
  eventBus
251
243
  } = eventContext);
252
244
  }
245
+ const didMount = hooks.useRef(false);
253
246
 
254
- const didMount = hooks.useRef(false); // (1) subscribe immediately
255
-
247
+ // (1) subscribe immediately
256
248
  if (eventBus && !didMount.current) {
257
249
  eventBus.on(event, callback);
258
- } // (2) update subscription after inputs changed
259
-
250
+ }
260
251
 
252
+ // (2) update subscription after inputs changed
261
253
  hooks.useEffect(() => {
262
254
  if (eventBus && didMount.current) {
263
255
  eventBus.on(event, callback);
264
256
  }
265
-
266
257
  didMount.current = true;
267
258
  return () => {
268
259
  if (eventBus) {
@@ -273,6 +264,7 @@ function useEvent(event, callback, eventBus) {
273
264
  }
274
265
 
275
266
  const KEY_LENGTH = 6;
267
+
276
268
  /**
277
269
  * Create a persistent key factory for plain objects without id.
278
270
  *
@@ -292,21 +284,16 @@ const KEY_LENGTH = 6;
292
284
  * @param {any[]} dependencies
293
285
  * @returns {(element: object) => string}
294
286
  */
295
-
296
287
  function useKeyFactory(dependencies = []) {
297
288
  const map = hooks.useMemo(() => new Map(), dependencies);
298
-
299
289
  const getKey = el => {
300
290
  let key = map.get(el);
301
-
302
291
  if (!key) {
303
292
  key = Math.random().toString().slice(-KEY_LENGTH);
304
293
  map.set(el, key);
305
294
  }
306
-
307
295
  return key;
308
296
  };
309
-
310
297
  return getKey;
311
298
  }
312
299
 
@@ -325,7 +312,6 @@ function useKeyFactory(dependencies = []) {
325
312
  *
326
313
  * @returns {[ any, Function ]}
327
314
  */
328
-
329
315
  function useLayoutState(path, defaultValue) {
330
316
  const {
331
317
  getLayoutForKey,
@@ -333,14 +319,13 @@ function useLayoutState(path, defaultValue) {
333
319
  } = hooks.useContext(LayoutContext);
334
320
  const layoutForKey = getLayoutForKey(path, defaultValue);
335
321
  const [value, set] = hooks.useState(layoutForKey);
336
-
337
322
  const setState = newValue => {
338
323
  // (1) set component state
339
- set(newValue); // (2) set context
324
+ set(newValue);
340
325
 
326
+ // (2) set context
341
327
  setLayoutForKey(path, newValue);
342
328
  };
343
-
344
329
  return [value, setState];
345
330
  }
346
331
 
@@ -366,7 +351,6 @@ function usePrevious(value) {
366
351
  *
367
352
  * @returns {import('preact').Ref}
368
353
  */
369
-
370
354
  function useShowEntryEvent(id) {
371
355
  const {
372
356
  onShow
@@ -376,7 +360,6 @@ function useShowEntryEvent(id) {
376
360
  const onShowEntry = hooks.useCallback(event => {
377
361
  if (event.id === id) {
378
362
  onShow();
379
-
380
363
  if (!focus.current) {
381
364
  focus.current = true;
382
365
  }
@@ -387,11 +370,9 @@ function useShowEntryEvent(id) {
387
370
  if (minDash.isFunction(ref.current.focus)) {
388
371
  ref.current.focus();
389
372
  }
390
-
391
373
  if (minDash.isFunction(ref.current.select)) {
392
374
  ref.current.select();
393
375
  }
394
-
395
376
  focus.current = false;
396
377
  }
397
378
  });
@@ -414,17 +395,15 @@ function useShowEntryEvent(id) {
414
395
  * @param {string} scrollContainerSelector
415
396
  * @param {setSticky} setSticky
416
397
  */
417
-
418
398
  function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky) {
419
399
  hooks.useEffect(() => {
420
- const Observer = IntersectionObserver; // return early if IntersectionObserver is not available
400
+ const Observer = IntersectionObserver;
421
401
 
402
+ // return early if IntersectionObserver is not available
422
403
  if (!Observer) {
423
404
  return;
424
405
  }
425
-
426
406
  let observer;
427
-
428
407
  if (ref.current) {
429
408
  const scrollContainer = minDom.query(scrollContainerSelector);
430
409
  observer = new Observer(entries => {
@@ -442,9 +421,9 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
442
421
  threshold: [1]
443
422
  });
444
423
  observer.observe(ref.current);
445
- } // Unobserve if unmounted
446
-
424
+ }
447
425
 
426
+ // Unobserve if unmounted
448
427
  return () => {
449
428
  if (ref.current && observer) {
450
429
  observer.unobserve(ref.current);
@@ -467,7 +446,6 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
467
446
  * @param {Function} callback function with changing reference
468
447
  * @returns {Function} static function reference
469
448
  */
470
-
471
449
  function useStaticCallback(callback) {
472
450
  const callbackRef = hooks.useRef(callback);
473
451
  callbackRef.current = callback;
@@ -485,12 +463,11 @@ function Group(props) {
485
463
  const groupRef = hooks.useRef(null);
486
464
  const [open, setOpen] = useLayoutState(['groups', id, 'open'], shouldOpen);
487
465
  const onShow = hooks.useCallback(() => setOpen(true), [setOpen]);
488
-
489
466
  const toggleOpen = () => setOpen(!open);
490
-
491
467
  const [edited, setEdited] = hooks.useState(false);
492
- const [sticky, setSticky] = hooks.useState(false); // set edited state depending on all entries
468
+ const [sticky, setSticky] = hooks.useState(false);
493
469
 
470
+ // set edited state depending on all entries
494
471
  hooks.useEffect(() => {
495
472
  const hasOneEditedEntry = entries.find(entry => {
496
473
  const {
@@ -498,19 +475,19 @@ function Group(props) {
498
475
  isEdited
499
476
  } = entry;
500
477
  const entryNode = minDom.query(`[data-entry-id="${id}"]`);
501
-
502
478
  if (!minDash.isFunction(isEdited) || !entryNode) {
503
479
  return false;
504
480
  }
505
-
506
481
  const inputNode = minDom.query('.bio-properties-panel-input', entryNode);
507
482
  return isEdited(inputNode);
508
483
  });
509
484
  setEdited(hasOneEditedEntry);
510
- }, [entries]); // set css class when group is sticky to top
485
+ }, [entries]);
511
486
 
487
+ // set css class when group is sticky to top
512
488
  useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
513
- const propertiesPanelContext = { ...hooks.useContext(LayoutContext),
489
+ const propertiesPanelContext = {
490
+ ...hooks.useContext(LayoutContext),
514
491
  onShow
515
492
  };
516
493
  return jsxRuntime.jsxs("div", {
@@ -543,7 +520,8 @@ function Group(props) {
543
520
  component: Component,
544
521
  id
545
522
  } = entry;
546
- return preact.createElement(Component, { ...entry,
523
+ return preact.createElement(Component, {
524
+ ...entry,
547
525
  element: element,
548
526
  key: id
549
527
  });
@@ -552,7 +530,6 @@ function Group(props) {
552
530
  })]
553
531
  });
554
532
  }
555
-
556
533
  function DataMarker() {
557
534
  return jsxRuntime.jsx("div", {
558
535
  title: "Section contains data",
@@ -591,6 +568,7 @@ const DEFAULT_LAYOUT = {
591
568
  open: true
592
569
  };
593
570
  const DEFAULT_DESCRIPTION = {};
571
+
594
572
  /**
595
573
  * @typedef { {
596
574
  * component: import('preact').Component,
@@ -658,7 +636,6 @@ const DEFAULT_DESCRIPTION = {};
658
636
  * @param {Function} [props.descriptionLoaded]
659
637
  * @param {Object} [props.eventBus]
660
638
  */
661
-
662
639
  function PropertiesPanel(props) {
663
640
  const {
664
641
  element,
@@ -670,52 +647,46 @@ function PropertiesPanel(props) {
670
647
  descriptionConfig = {},
671
648
  descriptionLoaded,
672
649
  eventBus
673
- } = props; // set-up layout context
650
+ } = props;
674
651
 
652
+ // set-up layout context
675
653
  const [layout, setLayout] = hooks.useState(createLayout(layoutConfig));
676
654
  hooks.useEffect(() => {
677
655
  if (typeof layoutChanged === 'function') {
678
656
  layoutChanged(layout);
679
657
  }
680
658
  }, [layout, layoutChanged]);
681
-
682
659
  const getLayoutForKey = (key, defaultValue) => {
683
660
  return minDash.get(layout, key, defaultValue);
684
661
  };
685
-
686
662
  const setLayoutForKey = (key, config) => {
687
663
  const newLayout = minDash.assign({}, layout);
688
664
  minDash.set(newLayout, key, config);
689
665
  setLayout(newLayout);
690
666
  };
691
-
692
667
  const layoutContext = {
693
668
  layout,
694
669
  setLayout,
695
670
  getLayoutForKey,
696
671
  setLayoutForKey
697
- }; // set-up description context
672
+ };
698
673
 
674
+ // set-up description context
699
675
  const description = createDescriptionContext(descriptionConfig);
700
-
701
676
  if (typeof descriptionLoaded === 'function') {
702
677
  descriptionLoaded(description);
703
678
  }
704
-
705
679
  const getDescriptionForId = (id, element) => {
706
680
  return description[id] && description[id](element);
707
681
  };
708
-
709
682
  const descriptionContext = {
710
683
  description,
711
684
  getDescriptionForId
712
685
  };
713
686
  const [errors, setErrors] = hooks.useState({});
714
-
715
687
  const onSetErrors = ({
716
688
  errors
717
689
  }) => setErrors(errors);
718
-
719
690
  useEvent('propertiesPanel.setErrors', onSetErrors, eventBus);
720
691
  const errorsContext = {
721
692
  errors
@@ -725,19 +696,21 @@ function PropertiesPanel(props) {
725
696
  };
726
697
  const propertiesPanelContext = {
727
698
  element
728
- }; // empty state
699
+ };
729
700
 
701
+ // empty state
730
702
  if (placeholderProvider && !element) {
731
- return jsxRuntime.jsx(Placeholder, { ...placeholderProvider.getEmpty()
703
+ return jsxRuntime.jsx(Placeholder, {
704
+ ...placeholderProvider.getEmpty()
732
705
  });
733
- } // multiple state
734
-
706
+ }
735
707
 
708
+ // multiple state
736
709
  if (placeholderProvider && minDash.isArray(element)) {
737
- return jsxRuntime.jsx(Placeholder, { ...placeholderProvider.getMultiple()
710
+ return jsxRuntime.jsx(Placeholder, {
711
+ ...placeholderProvider.getMultiple()
738
712
  });
739
713
  }
740
-
741
714
  return jsxRuntime.jsx(LayoutContext.Provider, {
742
715
  value: propertiesPanelContext,
743
716
  children: jsxRuntime.jsx(ErrorsContext.Provider, {
@@ -760,7 +733,8 @@ function PropertiesPanel(props) {
760
733
  component: Component = Group,
761
734
  id
762
735
  } = group;
763
- return preact.createElement(Component, { ...group,
736
+ return preact.createElement(Component, {
737
+ ...group,
764
738
  key: id,
765
739
  element: element
766
740
  });
@@ -772,16 +746,19 @@ function PropertiesPanel(props) {
772
746
  })
773
747
  })
774
748
  });
775
- } // helpers //////////////////
749
+ }
750
+
751
+ // helpers //////////////////
776
752
 
777
753
  function createLayout(overrides) {
778
- return { ...DEFAULT_LAYOUT,
754
+ return {
755
+ ...DEFAULT_LAYOUT,
779
756
  ...overrides
780
757
  };
781
758
  }
782
-
783
759
  function createDescriptionContext(overrides) {
784
- return { ...DEFAULT_DESCRIPTION,
760
+ return {
761
+ ...DEFAULT_DESCRIPTION,
785
762
  ...overrides
786
763
  };
787
764
  }
@@ -795,24 +772,19 @@ function DropdownButton(props) {
795
772
  const dropdownRef = hooks.useRef(null);
796
773
  const menuRef = hooks.useRef(null);
797
774
  const [open, setOpen] = hooks.useState(false);
798
-
799
775
  const close = () => setOpen(false);
800
-
801
776
  function onDropdownToggle(event) {
802
777
  if (menuRef.current && menuRef.current.contains(event.target)) {
803
778
  return;
804
779
  }
805
-
806
780
  event.stopPropagation();
807
781
  setOpen(open => !open);
808
782
  }
809
-
810
783
  function onActionClick(event, action) {
811
784
  event.stopPropagation();
812
785
  close();
813
786
  action();
814
787
  }
815
-
816
788
  useGlobalClick([dropdownRef.current], () => close());
817
789
  return jsxRuntime.jsxs("div", {
818
790
  class: classnames__default["default"]('bio-properties-panel-dropdown-button', {
@@ -830,7 +802,6 @@ function DropdownButton(props) {
830
802
  })]
831
803
  });
832
804
  }
833
-
834
805
  function MenuItem({
835
806
  item,
836
807
  onClick
@@ -840,7 +811,6 @@ function MenuItem({
840
811
  class: "bio-properties-panel-dropdown-button__menu-item bio-properties-panel-dropdown-button__menu-item--separator"
841
812
  });
842
813
  }
843
-
844
814
  if (item.action) {
845
815
  return jsxRuntime.jsx("button", {
846
816
  class: "bio-properties-panel-dropdown-button__menu-item bio-properties-panel-dropdown-button__menu-item--actionable",
@@ -848,19 +818,17 @@ function MenuItem({
848
818
  children: item.entry
849
819
  });
850
820
  }
851
-
852
821
  return jsxRuntime.jsx("div", {
853
822
  class: "bio-properties-panel-dropdown-button__menu-item",
854
823
  children: item.entry
855
824
  });
856
825
  }
826
+
857
827
  /**
858
828
  *
859
829
  * @param {Array<null | Element>} ignoredElements
860
830
  * @param {Function} callback
861
831
  */
862
-
863
-
864
832
  function useGlobalClick(ignoredElements, callback) {
865
833
  hooks.useEffect(() => {
866
834
  /**
@@ -870,10 +838,8 @@ function useGlobalClick(ignoredElements, callback) {
870
838
  if (ignoredElements.some(element => element && element.contains(event.target))) {
871
839
  return;
872
840
  }
873
-
874
841
  callback();
875
842
  }
876
-
877
843
  document.addEventListener('click', listener, {
878
844
  capture: true
879
845
  });
@@ -890,7 +856,8 @@ function HeaderButton(props) {
890
856
  onClick = () => {},
891
857
  ...otherProps
892
858
  } = props;
893
- return jsxRuntime.jsx("button", { ...otherProps,
859
+ return jsxRuntime.jsx("button", {
860
+ ...otherProps,
894
861
  onClick: onClick,
895
862
  class: classnames__default["default"]('bio-properties-panel-group-header-button', classname),
896
863
  children: children
@@ -907,22 +874,21 @@ function CollapsibleEntry(props) {
907
874
  remove
908
875
  } = props;
909
876
  const [open, setOpen] = hooks.useState(shouldOpen);
910
-
911
877
  const toggleOpen = () => setOpen(!open);
912
-
913
878
  const {
914
879
  onShow
915
880
  } = hooks.useContext(LayoutContext);
916
- const propertiesPanelContext = { ...hooks.useContext(LayoutContext),
881
+ const propertiesPanelContext = {
882
+ ...hooks.useContext(LayoutContext),
917
883
  onShow: hooks.useCallback(() => {
918
884
  setOpen(true);
919
-
920
885
  if (minDash.isFunction(onShow)) {
921
886
  onShow();
922
887
  }
923
888
  }, [onShow, setOpen])
924
- }; // todo(pinussilvestrus): translate once we have a translate mechanism for the core
889
+ };
925
890
 
891
+ // todo(pinussilvestrus): translate once we have a translate mechanism for the core
926
892
  const placeholderLabel = '<empty>';
927
893
  return jsxRuntime.jsxs("div", {
928
894
  "data-entry-id": id,
@@ -955,7 +921,8 @@ function CollapsibleEntry(props) {
955
921
  component: Component,
956
922
  id
957
923
  } = entry;
958
- return preact.createElement(Component, { ...entry,
924
+ return preact.createElement(Component, {
925
+ ...entry,
959
926
  element: element,
960
927
  key: id
961
928
  });
@@ -969,13 +936,13 @@ function ListItem(props) {
969
936
  const {
970
937
  autoFocusEntry,
971
938
  autoOpen
972
- } = props; // focus specified entry on auto open
939
+ } = props;
973
940
 
941
+ // focus specified entry on auto open
974
942
  hooks.useEffect(() => {
975
943
  if (autoOpen && autoFocusEntry) {
976
944
  const entry = minDom.query(`[data-entry-id="${autoFocusEntry}"]`);
977
945
  const focusableInput = minDom.query('.bio-properties-panel-input', entry);
978
-
979
946
  if (focusableInput) {
980
947
  if (minDash.isFunction(focusableInput.select)) {
981
948
  focusableInput.select();
@@ -987,18 +954,18 @@ function ListItem(props) {
987
954
  }, [autoOpen, autoFocusEntry]);
988
955
  return jsxRuntime.jsx("div", {
989
956
  class: "bio-properties-panel-list-item",
990
- children: jsxRuntime.jsx(CollapsibleEntry, { ...props,
957
+ children: jsxRuntime.jsx(CollapsibleEntry, {
958
+ ...props,
991
959
  open: autoOpen
992
960
  })
993
961
  });
994
962
  }
995
963
 
996
964
  const noop$2 = () => {};
965
+
997
966
  /**
998
967
  * @param {import('../PropertiesPanel').ListGroupDefinition} props
999
968
  */
1000
-
1001
-
1002
969
  function ListGroup(props) {
1003
970
  const {
1004
971
  add,
@@ -1018,20 +985,23 @@ function ListGroup(props) {
1018
985
  const prevItems = usePrevious(items);
1019
986
  const prevElement = usePrevious(element);
1020
987
  const elementChanged = element !== prevElement;
1021
- const shouldHandleEffects = !elementChanged && (shouldSort || shouldOpen); // reset initial ordering when element changes (before first render)
988
+ const shouldHandleEffects = !elementChanged && (shouldSort || shouldOpen);
1022
989
 
990
+ // reset initial ordering when element changes (before first render)
1023
991
  if (elementChanged) {
1024
992
  setOrdering(createOrdering(shouldSort ? sortItems(items) : items));
1025
- } // keep ordering in sync to items - and open changes
1026
- // (0) set initial ordering from given items
993
+ }
1027
994
 
995
+ // keep ordering in sync to items - and open changes
1028
996
 
997
+ // (0) set initial ordering from given items
1029
998
  hooks.useEffect(() => {
1030
999
  if (!prevItems || !shouldSort) {
1031
1000
  setOrdering(createOrdering(items));
1032
1001
  }
1033
- }, [items, element]); // (1) items were added
1002
+ }, [items, element]);
1034
1003
 
1004
+ // (1) items were added
1035
1005
  hooks.useEffect(() => {
1036
1006
  if (shouldHandleEffects && prevItems && items.length > prevItems.length) {
1037
1007
  let add = [];
@@ -1040,38 +1010,40 @@ function ListGroup(props) {
1040
1010
  add.push(item.id);
1041
1011
  }
1042
1012
  });
1043
- let newOrdering = ordering; // open if not open and configured
1013
+ let newOrdering = ordering;
1044
1014
 
1015
+ // open if not open and configured
1045
1016
  if (!open && shouldOpen) {
1046
- toggleOpen(); // if I opened and I should sort, then sort items
1017
+ toggleOpen();
1047
1018
 
1019
+ // if I opened and I should sort, then sort items
1048
1020
  if (shouldSort) {
1049
1021
  newOrdering = createOrdering(sortItems(items));
1050
1022
  }
1051
- } // add new items on top or bottom depending on sorting behavior
1052
-
1023
+ }
1053
1024
 
1025
+ // add new items on top or bottom depending on sorting behavior
1054
1026
  newOrdering = newOrdering.filter(item => !add.includes(item));
1055
-
1056
1027
  if (shouldSort) {
1057
1028
  newOrdering.unshift(...add);
1058
1029
  } else {
1059
1030
  newOrdering.push(...add);
1060
1031
  }
1061
-
1062
1032
  setOrdering(newOrdering);
1063
1033
  setNewItemAdded(true);
1064
1034
  } else {
1065
1035
  setNewItemAdded(false);
1066
1036
  }
1067
- }, [items, open, shouldHandleEffects]); // (2) sort items on open if shouldSort is set
1037
+ }, [items, open, shouldHandleEffects]);
1068
1038
 
1039
+ // (2) sort items on open if shouldSort is set
1069
1040
  hooks.useEffect(() => {
1070
1041
  if (shouldSort && open && !newItemAdded) {
1071
1042
  setOrdering(createOrdering(sortItems(items)));
1072
1043
  }
1073
- }, [open, shouldSort]); // (3) items were deleted
1044
+ }, [open, shouldSort]);
1074
1045
 
1046
+ // (3) items were deleted
1075
1047
  hooks.useEffect(() => {
1076
1048
  if (shouldHandleEffects && prevItems && items.length < prevItems.length) {
1077
1049
  let keep = [];
@@ -1082,14 +1054,14 @@ function ListGroup(props) {
1082
1054
  });
1083
1055
  setOrdering(keep);
1084
1056
  }
1085
- }, [items, shouldHandleEffects]); // set css class when group is sticky to top
1057
+ }, [items, shouldHandleEffects]);
1086
1058
 
1059
+ // set css class when group is sticky to top
1087
1060
  useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
1088
-
1089
1061
  const toggleOpen = () => setOpen(!open);
1090
-
1091
1062
  const hasItems = !!items.length;
1092
- const propertiesPanelContext = { ...hooks.useContext(LayoutContext),
1063
+ const propertiesPanelContext = {
1064
+ ...hooks.useContext(LayoutContext),
1093
1065
  onShow
1094
1066
  };
1095
1067
  return jsxRuntime.jsxs("div", {
@@ -1131,17 +1103,17 @@ function ListGroup(props) {
1131
1103
  value: propertiesPanelContext,
1132
1104
  children: ordering.map((o, index) => {
1133
1105
  const item = getItem(items, o);
1134
-
1135
1106
  if (!item) {
1136
1107
  return;
1137
1108
  }
1138
-
1139
1109
  const {
1140
1110
  id
1141
- } = item; // if item was added, open first or last item based on ordering
1111
+ } = item;
1142
1112
 
1113
+ // if item was added, open first or last item based on ordering
1143
1114
  const autoOpen = newItemAdded && (shouldSort ? index === 0 : index === ordering.length - 1);
1144
- return preact.createElement(ListItem, { ...item,
1115
+ return preact.createElement(ListItem, {
1116
+ ...item,
1145
1117
  autoOpen: autoOpen,
1146
1118
  element: element,
1147
1119
  index: index,
@@ -1151,20 +1123,19 @@ function ListGroup(props) {
1151
1123
  })
1152
1124
  })]
1153
1125
  });
1154
- } // helpers ////////////////////
1126
+ }
1127
+
1128
+ // helpers ////////////////////
1155
1129
 
1156
1130
  /**
1157
1131
  * Sorts given items alphanumeric by label
1158
1132
  */
1159
-
1160
1133
  function sortItems(items) {
1161
1134
  return minDash.sortBy(items, i => i.label.toLowerCase());
1162
1135
  }
1163
-
1164
1136
  function getItem(items, id) {
1165
1137
  return minDash.find(items, i => i.id === id);
1166
1138
  }
1167
-
1168
1139
  function createOrdering(items) {
1169
1140
  return items.map(i => i.id);
1170
1141
  }
@@ -1177,7 +1148,6 @@ function Description(props) {
1177
1148
  } = props;
1178
1149
  const contextDescription = useDescriptionContext(forId, element);
1179
1150
  const description = value || contextDescription;
1180
-
1181
1151
  if (description) {
1182
1152
  return jsxRuntime.jsx("div", {
1183
1153
  class: "bio-properties-panel-description",
@@ -1197,23 +1167,19 @@ function Checkbox(props) {
1197
1167
  onBlur
1198
1168
  } = props;
1199
1169
  const [localValue, setLocalValue] = hooks.useState(value);
1200
-
1201
1170
  const handleChangeCallback = ({
1202
1171
  target
1203
1172
  }) => {
1204
1173
  onChange(target.checked);
1205
1174
  };
1206
-
1207
1175
  const handleChange = e => {
1208
1176
  handleChangeCallback(e);
1209
1177
  setLocalValue(e.target.value);
1210
1178
  };
1211
-
1212
1179
  hooks.useEffect(() => {
1213
1180
  if (value === localValue) {
1214
1181
  return;
1215
1182
  }
1216
-
1217
1183
  setLocalValue(value);
1218
1184
  }, [value]);
1219
1185
  const ref = useShowEntryEvent(id);
@@ -1237,6 +1203,7 @@ function Checkbox(props) {
1237
1203
  })]
1238
1204
  });
1239
1205
  }
1206
+
1240
1207
  /**
1241
1208
  * @param {Object} props
1242
1209
  * @param {Object} props.element
@@ -1249,8 +1216,6 @@ function Checkbox(props) {
1249
1216
  * @param {Function} props.onBlur
1250
1217
  * @param {boolean} [props.disabled]
1251
1218
  */
1252
-
1253
-
1254
1219
  function CheckboxEntry(props) {
1255
1220
  const {
1256
1221
  element,
@@ -1288,7 +1253,9 @@ function CheckboxEntry(props) {
1288
1253
  }
1289
1254
  function isEdited$7(node) {
1290
1255
  return node && !!node.checked;
1291
- } // helpers /////////////////
1256
+ }
1257
+
1258
+ // helpers /////////////////
1292
1259
 
1293
1260
  function prefixId$7(id) {
1294
1261
  return `bio-properties-panel-${id}`;
@@ -1297,11 +1264,14 @@ function prefixId$7(id) {
1297
1264
  const useBufferedFocus = function (editor, ref) {
1298
1265
  const [buffer, setBuffer] = hooks.useState(undefined);
1299
1266
  ref.current = hooks.useMemo(() => ({
1300
- focus: argument => {
1267
+ focus: offset => {
1301
1268
  if (editor) {
1302
- editor.focus(argument);
1269
+ editor.focus(offset);
1303
1270
  } else {
1304
- setBuffer(argument);
1271
+ if (typeof offset === 'undefined') {
1272
+ offset = Infinity;
1273
+ }
1274
+ setBuffer(offset);
1305
1275
  }
1306
1276
  }
1307
1277
  }), [editor]);
@@ -1312,7 +1282,6 @@ const useBufferedFocus = function (editor, ref) {
1312
1282
  }
1313
1283
  }, [editor, buffer]);
1314
1284
  };
1315
-
1316
1285
  const CodeEditor = compat.forwardRef((props, ref) => {
1317
1286
  const {
1318
1287
  value,
@@ -1320,6 +1289,7 @@ const CodeEditor = compat.forwardRef((props, ref) => {
1320
1289
  onFeelToggle,
1321
1290
  onLint = () => {},
1322
1291
  disabled,
1292
+ tooltipContainer,
1323
1293
  variables
1324
1294
  } = props;
1325
1295
  const inputRef = hooks.useRef();
@@ -1332,30 +1302,28 @@ const CodeEditor = compat.forwardRef((props, ref) => {
1332
1302
  });
1333
1303
  hooks.useEffect(() => {
1334
1304
  let editor;
1305
+
1335
1306
  /* Trigger FEEL toggle when
1336
1307
  *
1337
1308
  * - `backspace` is pressed
1338
1309
  * - AND the cursor is at the beginning of the input
1339
1310
  */
1340
-
1341
1311
  const onKeyDown = e => {
1342
1312
  if (e.key !== 'Backspace' || !editor) {
1343
1313
  return;
1344
1314
  }
1345
-
1346
1315
  const selection = editor.getSelection();
1347
1316
  const range = selection.ranges[selection.mainIndex];
1348
-
1349
1317
  if (range.from === 0 && range.to === 0) {
1350
1318
  onFeelToggle();
1351
1319
  }
1352
1320
  };
1353
-
1354
1321
  editor = new FeelEditor__default["default"]({
1355
1322
  container: inputRef.current,
1356
1323
  onChange: handleInput,
1357
1324
  onKeyDown: onKeyDown,
1358
1325
  onLint: onLint,
1326
+ tooltipContainer: tooltipContainer,
1359
1327
  value: localValue,
1360
1328
  variables: variables
1361
1329
  });
@@ -1365,24 +1333,26 @@ const CodeEditor = compat.forwardRef((props, ref) => {
1365
1333
  inputRef.current.innerHTML = '';
1366
1334
  setEditor(null);
1367
1335
  };
1368
- }, [variables]);
1336
+ }, []);
1369
1337
  hooks.useEffect(() => {
1370
1338
  if (!editor) {
1371
1339
  return;
1372
1340
  }
1373
-
1374
1341
  if (value === localValue) {
1375
1342
  return;
1376
1343
  }
1377
-
1378
1344
  editor.setValue(value);
1379
1345
  setLocalValue(value);
1380
1346
  }, [value]);
1381
-
1347
+ hooks.useEffect(() => {
1348
+ if (!editor) {
1349
+ return;
1350
+ }
1351
+ editor.setVariables(variables);
1352
+ }, [variables]);
1382
1353
  const handleClick = () => {
1383
1354
  ref.current.focus();
1384
1355
  };
1385
-
1386
1356
  return jsxRuntime.jsx("div", {
1387
1357
  class: classnames__default["default"]('bio-properties-panel-feel-editor-container', disabled ? 'disabled' : null),
1388
1358
  children: jsxRuntime.jsx("div", {
@@ -1398,11 +1368,9 @@ function FeelIndicator(props) {
1398
1368
  const {
1399
1369
  active
1400
1370
  } = props;
1401
-
1402
1371
  if (!active) {
1403
1372
  return null;
1404
1373
  }
1405
-
1406
1374
  return jsxRuntime.jsx("span", {
1407
1375
  class: "bio-properties-panel-feel-indicator",
1408
1376
  children: "="
@@ -1410,13 +1378,12 @@ function FeelIndicator(props) {
1410
1378
  }
1411
1379
 
1412
1380
  const noop$1 = () => {};
1381
+
1413
1382
  /**
1414
1383
  * @param {Object} props
1415
1384
  * @param {Object} props.label
1416
1385
  * @param {String} props.feel
1417
1386
  */
1418
-
1419
-
1420
1387
  function FeelIcon(props) {
1421
1388
  const {
1422
1389
  label,
@@ -1427,15 +1394,14 @@ function FeelIcon(props) {
1427
1394
  } = props;
1428
1395
  const feelRequiredLabel = ' must be a FEEL expression';
1429
1396
  const feelOptionalLabel = ' can optionally be a FEEL expression';
1430
-
1431
1397
  const handleClick = e => {
1432
- onClick(e); // when pointer event was created from keyboard, keep focus on button
1398
+ onClick(e);
1433
1399
 
1400
+ // when pointer event was created from keyboard, keep focus on button
1434
1401
  if (!e.pointerType) {
1435
1402
  e.stopPropagation();
1436
1403
  }
1437
1404
  };
1438
-
1439
1405
  return jsxRuntime.jsx("button", {
1440
1406
  class: classnames__default["default"]('bio-properties-panel-feel-icon', active ? 'active' : null, feel === 'required' ? 'required' : 'optional'),
1441
1407
  onClick: handleClick,
@@ -1446,7 +1412,6 @@ function FeelIcon(props) {
1446
1412
  }
1447
1413
 
1448
1414
  const noop = () => {};
1449
-
1450
1415
  function FeelTextfield(props) {
1451
1416
  const {
1452
1417
  debounce,
@@ -1458,6 +1423,7 @@ function FeelTextfield(props) {
1458
1423
  value = '',
1459
1424
  disabled = false,
1460
1425
  variables,
1426
+ tooltipContainer,
1461
1427
  OptionalComponent = OptionalFeelInput
1462
1428
  } = props;
1463
1429
  const [localValue, _setLocalValue] = hooks.useState(value);
@@ -1466,66 +1432,54 @@ function FeelTextfield(props) {
1466
1432
  const feelActive = localValue.startsWith('=') || feel === 'required';
1467
1433
  const feelOnlyValue = localValue.startsWith('=') ? localValue.substring(1) : localValue;
1468
1434
  const [focus, _setFocus] = hooks.useState(undefined);
1469
-
1470
1435
  const setFocus = (offset = 0) => {
1471
- const hasFocus = containerRef.current.contains(document.activeElement); // Keep caret position if it is already focused, otherwise focus at the end
1436
+ const hasFocus = containerRef.current.contains(document.activeElement);
1472
1437
 
1438
+ // Keep caret position if it is already focused, otherwise focus at the end
1473
1439
  const position = hasFocus ? document.activeElement.selectionStart : Infinity;
1474
-
1475
1440
  _setFocus(position + offset);
1476
1441
  };
1477
-
1478
1442
  const handleInputCallback = hooks.useMemo(() => {
1479
1443
  return debounce(newValue => {
1480
1444
  onInput(newValue);
1481
1445
  });
1482
1446
  }, [onInput, debounce]);
1483
-
1484
1447
  const setLocalValue = newValue => {
1485
1448
  _setLocalValue(newValue);
1486
-
1487
1449
  if (!newValue || newValue === '=') {
1488
1450
  handleInputCallback(undefined);
1489
1451
  } else {
1490
1452
  handleInputCallback(newValue);
1491
1453
  }
1492
1454
  };
1493
-
1494
1455
  const handleFeelToggle = useStaticCallback(() => {
1495
1456
  if (feel === 'required') {
1496
1457
  return;
1497
1458
  }
1498
-
1499
1459
  if (!feelActive) {
1500
1460
  setLocalValue('=' + localValue);
1501
1461
  } else {
1502
1462
  setLocalValue(feelOnlyValue);
1503
1463
  }
1504
1464
  });
1505
-
1506
1465
  const handleLocalInput = newValue => {
1507
1466
  if (feelActive) {
1508
1467
  newValue = '=' + newValue;
1509
1468
  }
1510
-
1511
1469
  if (newValue === localValue) {
1512
1470
  return;
1513
1471
  }
1514
-
1515
1472
  setLocalValue(newValue);
1516
-
1517
1473
  if (!feelActive && newValue.startsWith('=')) {
1518
1474
  // focus is behind `=` sign that will be removed
1519
1475
  setFocus(-1);
1520
1476
  }
1521
1477
  };
1522
-
1523
1478
  const handleLint = useStaticCallback(lint => {
1524
1479
  if (!(lint && lint.length)) {
1525
1480
  onError(undefined);
1526
1481
  return;
1527
1482
  }
1528
-
1529
1483
  const error = lint[0];
1530
1484
  const message = `${error.source}: ${error.message}`;
1531
1485
  onError(message);
@@ -1533,40 +1487,35 @@ function FeelTextfield(props) {
1533
1487
  hooks.useEffect(() => {
1534
1488
  if (typeof focus !== 'undefined') {
1535
1489
  editorRef.current.focus(focus);
1536
-
1537
1490
  _setFocus(undefined);
1538
1491
  }
1539
1492
  }, [focus]);
1540
1493
  hooks.useEffect(() => {
1541
1494
  if (value === localValue) {
1542
1495
  return;
1543
- } // External value change removed content => keep FEEL configuration
1544
-
1496
+ }
1545
1497
 
1498
+ // External value change removed content => keep FEEL configuration
1546
1499
  if (!value) {
1547
1500
  setLocalValue(feelActive ? '=' : '');
1548
1501
  return;
1549
1502
  }
1550
-
1551
1503
  setLocalValue(value);
1552
- }, [value]); // copy-paste integration
1504
+ }, [value]);
1553
1505
 
1506
+ // copy-paste integration
1554
1507
  hooks.useEffect(() => {
1555
1508
  const copyHandler = event => {
1556
1509
  if (!feelActive) {
1557
1510
  return;
1558
1511
  }
1559
-
1560
1512
  event.clipboardData.setData('application/FEEL', event.clipboardData.getData('text'));
1561
1513
  };
1562
-
1563
1514
  const pasteHandler = event => {
1564
1515
  if (feelActive) {
1565
1516
  return;
1566
1517
  }
1567
-
1568
1518
  const data = event.clipboardData.getData('application/FEEL');
1569
-
1570
1519
  if (data) {
1571
1520
  setTimeout(() => {
1572
1521
  handleFeelToggle();
@@ -1574,7 +1523,6 @@ function FeelTextfield(props) {
1574
1523
  });
1575
1524
  }
1576
1525
  };
1577
-
1578
1526
  containerRef.current.addEventListener('copy', copyHandler);
1579
1527
  containerRef.current.addEventListener('cut', copyHandler);
1580
1528
  containerRef.current.addEventListener('paste', pasteHandler);
@@ -1615,8 +1563,10 @@ function FeelTextfield(props) {
1615
1563
  onLint: handleLint,
1616
1564
  value: feelOnlyValue,
1617
1565
  variables: variables,
1618
- ref: editorRef
1619
- }) : jsxRuntime.jsx(OptionalComponent, { ...props,
1566
+ ref: editorRef,
1567
+ tooltipContainer: tooltipContainer
1568
+ }) : jsxRuntime.jsx(OptionalComponent, {
1569
+ ...props,
1620
1570
  onInput: handleLocalInput,
1621
1571
  value: localValue,
1622
1572
  ref: editorRef
@@ -1624,7 +1574,6 @@ function FeelTextfield(props) {
1624
1574
  })]
1625
1575
  });
1626
1576
  }
1627
-
1628
1577
  const OptionalFeelInput = compat.forwardRef((props, ref) => {
1629
1578
  const {
1630
1579
  id,
@@ -1634,24 +1583,21 @@ const OptionalFeelInput = compat.forwardRef((props, ref) => {
1634
1583
  onFocus,
1635
1584
  onBlur
1636
1585
  } = props;
1637
- const inputRef = hooks.useRef(); // To be consistent with the FEEL editor, set focus at start of input
1638
- // this ensures clean editing experience when switching with the keyboard
1586
+ const inputRef = hooks.useRef();
1639
1587
 
1588
+ // To be consistent with the FEEL editor, set focus at start of input
1589
+ // this ensures clean editing experience when switching with the keyboard
1640
1590
  ref.current = {
1641
1591
  focus: position => {
1642
1592
  const input = inputRef.current;
1643
-
1644
1593
  if (!input) {
1645
1594
  return;
1646
1595
  }
1647
-
1648
1596
  input.focus();
1649
-
1650
1597
  if (typeof position === 'number') {
1651
1598
  if (position > value.length) {
1652
1599
  position = value.length;
1653
1600
  }
1654
-
1655
1601
  input.setSelectionRange(position, position);
1656
1602
  }
1657
1603
  }
@@ -1680,17 +1626,16 @@ const OptionalFeelTextArea = compat.forwardRef((props, ref) => {
1680
1626
  onFocus,
1681
1627
  onBlur
1682
1628
  } = props;
1683
- const inputRef = hooks.useRef(); // To be consistent with the FEEL editor, set focus at start of input
1684
- // this ensures clean editing experience when switching with the keyboard
1629
+ const inputRef = hooks.useRef();
1685
1630
 
1631
+ // To be consistent with the FEEL editor, set focus at start of input
1632
+ // this ensures clean editing experience when switching with the keyboard
1686
1633
  ref.current = {
1687
1634
  focus: () => {
1688
1635
  const input = inputRef.current;
1689
-
1690
1636
  if (!input) {
1691
1637
  return;
1692
1638
  }
1693
-
1694
1639
  input.focus();
1695
1640
  input.setSelectionRange(0, 0);
1696
1641
  }
@@ -1710,6 +1655,7 @@ const OptionalFeelTextArea = compat.forwardRef((props, ref) => {
1710
1655
  value: value || ''
1711
1656
  });
1712
1657
  });
1658
+
1713
1659
  /**
1714
1660
  * @param {Object} props
1715
1661
  * @param {Object} props.element
@@ -1722,7 +1668,6 @@ const OptionalFeelTextArea = compat.forwardRef((props, ref) => {
1722
1668
  * @param {Function} props.setValue
1723
1669
  * @param {Function} props.validate
1724
1670
  */
1725
-
1726
1671
  function FeelEntry(props) {
1727
1672
  const {
1728
1673
  element,
@@ -1734,6 +1679,7 @@ function FeelEntry(props) {
1734
1679
  label,
1735
1680
  getValue,
1736
1681
  setValue,
1682
+ tooltipContainer,
1737
1683
  validate,
1738
1684
  show = noop,
1739
1685
  example,
@@ -1754,11 +1700,9 @@ function FeelEntry(props) {
1754
1700
  }, [value]);
1755
1701
  const onInput = useStaticCallback(newValue => {
1756
1702
  let newValidationError = null;
1757
-
1758
1703
  if (minDash.isFunction(validate)) {
1759
1704
  newValidationError = validate(newValue) || null;
1760
1705
  }
1761
-
1762
1706
  if (newValidationError) {
1763
1707
  setCachedInvalidValue(newValue);
1764
1708
  } else {
@@ -1767,17 +1711,14 @@ function FeelEntry(props) {
1767
1711
  setValue(newValue);
1768
1712
  }
1769
1713
  }
1770
-
1771
1714
  setValidationError(newValidationError);
1772
1715
  });
1773
1716
  const onError = hooks.useCallback(err => {
1774
1717
  setLocalError(err);
1775
1718
  }, []);
1776
-
1777
1719
  if (previousValue === value && validationError) {
1778
1720
  value = cachedInvalidValue;
1779
1721
  }
1780
-
1781
1722
  const temporaryError = useError(id);
1782
1723
  const error = localError || temporaryError || validationError;
1783
1724
  return jsxRuntime.jsxs("div", {
@@ -1797,6 +1738,7 @@ function FeelEntry(props) {
1797
1738
  show: show,
1798
1739
  value: value,
1799
1740
  variables: variables,
1741
+ tooltipContainer: tooltipContainer,
1800
1742
  OptionalComponent: props.OptionalComponent
1801
1743
  }, element), error && jsxRuntime.jsx("div", {
1802
1744
  class: "bio-properties-panel-error",
@@ -1808,6 +1750,7 @@ function FeelEntry(props) {
1808
1750
  })]
1809
1751
  });
1810
1752
  }
1753
+
1811
1754
  /**
1812
1755
  * @param {Object} props
1813
1756
  * @param {Object} props.element
@@ -1822,7 +1765,6 @@ function FeelEntry(props) {
1822
1765
  * @param {Function} props.onBlur
1823
1766
  * @param {Function} props.validate
1824
1767
  */
1825
-
1826
1768
  function FeelTextArea(props) {
1827
1769
  return jsxRuntime.jsx(FeelEntry, {
1828
1770
  class: "bio-properties-panel-feel-textarea",
@@ -1832,7 +1774,9 @@ function FeelTextArea(props) {
1832
1774
  }
1833
1775
  function isEdited$6(node) {
1834
1776
  return node && (!!node.value || node.classList.contains('edited'));
1835
- } // helpers /////////////////
1777
+ }
1778
+
1779
+ // helpers /////////////////
1836
1780
 
1837
1781
  function prefixId$6(id) {
1838
1782
  return `bio-properties-panel-${id}`;
@@ -1854,9 +1798,7 @@ function List(props) {
1854
1798
  } = props;
1855
1799
  const [open, setOpen] = hooks.useState(!!shouldOpen);
1856
1800
  const hasItems = !!items.length;
1857
-
1858
1801
  const toggleOpen = () => hasItems && setOpen(!open);
1859
-
1860
1802
  const opening = !usePrevious(open) && open;
1861
1803
  const elementChanged = usePrevious(element) !== element;
1862
1804
  const shouldReset = opening || elementChanged;
@@ -1867,19 +1809,17 @@ function List(props) {
1867
1809
  setOpen(false);
1868
1810
  }
1869
1811
  }, [open, hasItems]);
1812
+
1870
1813
  /**
1871
1814
  * @param {MouseEvent} event
1872
1815
  */
1873
-
1874
1816
  function addItem(event) {
1875
1817
  event.stopPropagation();
1876
1818
  onAdd();
1877
-
1878
1819
  if (!open) {
1879
1820
  setOpen(true);
1880
1821
  }
1881
1822
  }
1882
-
1883
1823
  return jsxRuntime.jsxs("div", {
1884
1824
  "data-entry-id": id,
1885
1825
  class: classnames__default["default"]('bio-properties-panel-entry', 'bio-properties-panel-list-entry', hasItems ? '' : 'empty', open ? 'open' : ''),
@@ -1912,7 +1852,8 @@ function List(props) {
1912
1852
  })
1913
1853
  })]
1914
1854
  })]
1915
- }), hasItems && jsxRuntime.jsx(ItemsList, { ...restProps,
1855
+ }), hasItems && jsxRuntime.jsx(ItemsList, {
1856
+ ...restProps,
1916
1857
  autoFocusEntry: autoFocusEntry,
1917
1858
  component: component,
1918
1859
  element: element,
@@ -1924,7 +1865,6 @@ function List(props) {
1924
1865
  })]
1925
1866
  });
1926
1867
  }
1927
-
1928
1868
  function ItemsList(props) {
1929
1869
  const {
1930
1870
  autoFocusEntry,
@@ -1942,11 +1882,13 @@ function ItemsList(props) {
1942
1882
  hooks.useEffect(() => {
1943
1883
  if (newItem && autoFocusEntry) {
1944
1884
  // (0) select the parent entry (containing all list items)
1945
- const entry = minDom.query(`[data-entry-id="${id}"]`); // (1) select the first input or a custom element to be focussed
1885
+ const entry = minDom.query(`[data-entry-id="${id}"]`);
1946
1886
 
1887
+ // (1) select the first input or a custom element to be focussed
1947
1888
  const selector = typeof autoFocusEntry === 'boolean' ? '.bio-properties-panel-input' : autoFocusEntry;
1948
- const focusableInput = minDom.query(selector, entry); // (2) set focus
1889
+ const focusableInput = minDom.query(selector, entry);
1949
1890
 
1891
+ // (2) set focus
1950
1892
  if (focusableInput) {
1951
1893
  if (minDash.isFunction(focusableInput.select)) {
1952
1894
  focusableInput.select();
@@ -1962,7 +1904,8 @@ function ItemsList(props) {
1962
1904
  const key = getKey(item);
1963
1905
  return jsxRuntime.jsxs("li", {
1964
1906
  class: "bio-properties-panel-list-entry-item",
1965
- children: [jsxRuntime.jsx(Component, { ...restProps,
1907
+ children: [jsxRuntime.jsx(Component, {
1908
+ ...restProps,
1966
1909
  element: element,
1967
1910
  id: id,
1968
1911
  index: index,
@@ -1979,6 +1922,7 @@ function ItemsList(props) {
1979
1922
  })
1980
1923
  });
1981
1924
  }
1925
+
1982
1926
  /**
1983
1927
  * Place new items in the beginning of the list and sort the rest with provided function.
1984
1928
  *
@@ -1988,41 +1932,36 @@ function ItemsList(props) {
1988
1932
  * @param {boolean} [shouldReset=false] set to `true` to reset state of the hook
1989
1933
  * @returns {Item[]}
1990
1934
  */
1991
-
1992
-
1993
1935
  function useSortedItems(currentItems, compareFn, shouldReset = false) {
1994
- const itemsRef = hooks.useRef(currentItems.slice()); // (1) Reset and optionally sort.
1936
+ const itemsRef = hooks.useRef(currentItems.slice());
1995
1937
 
1938
+ // (1) Reset and optionally sort.
1996
1939
  if (shouldReset) {
1997
1940
  itemsRef.current = currentItems.slice();
1998
-
1999
1941
  if (compareFn) {
2000
1942
  itemsRef.current.sort(compareFn);
2001
1943
  }
2002
1944
  } else {
2003
- const items = itemsRef.current; // (2) Add new item to the list.
1945
+ const items = itemsRef.current;
2004
1946
 
1947
+ // (2) Add new item to the list.
2005
1948
  for (const item of currentItems) {
2006
1949
  if (!items.includes(item)) {
2007
1950
  // Unshift or push depending on whether we have a compareFn
2008
1951
  compareFn ? items.unshift(item) : items.push(item);
2009
1952
  }
2010
- } // (3) Filter out removed items.
2011
-
1953
+ }
2012
1954
 
1955
+ // (3) Filter out removed items.
2013
1956
  itemsRef.current = items.filter(item => currentItems.includes(item));
2014
1957
  }
2015
-
2016
1958
  return itemsRef.current;
2017
1959
  }
2018
-
2019
1960
  function useNewItems(items = [], shouldReset) {
2020
1961
  const previousItems = usePrevious(items.slice()) || [];
2021
-
2022
1962
  if (shouldReset) {
2023
1963
  return [];
2024
1964
  }
2025
-
2026
1965
  return previousItems ? items.filter(item => !previousItems.includes(item)) : [];
2027
1966
  }
2028
1967
 
@@ -2047,23 +1986,19 @@ function NumberField(props) {
2047
1986
  validity,
2048
1987
  value
2049
1988
  } = event.target;
2050
-
2051
1989
  if (validity.valid) {
2052
1990
  onInput(value ? parseFloat(value) : undefined);
2053
1991
  }
2054
1992
  });
2055
1993
  }, [onInput, debounce]);
2056
-
2057
1994
  const handleInput = e => {
2058
1995
  handleInputCallback(e);
2059
1996
  setLocalValue(e.target.value);
2060
1997
  };
2061
-
2062
1998
  hooks.useEffect(() => {
2063
1999
  if (value === localValue) {
2064
2000
  return;
2065
2001
  }
2066
-
2067
2002
  setLocalValue(value);
2068
2003
  }, [value]);
2069
2004
  return jsxRuntime.jsxs("div", {
@@ -2090,6 +2025,7 @@ function NumberField(props) {
2090
2025
  })]
2091
2026
  });
2092
2027
  }
2028
+
2093
2029
  /**
2094
2030
  * @param {Object} props
2095
2031
  * @param {Boolean} props.debounce
@@ -2106,8 +2042,6 @@ function NumberField(props) {
2106
2042
  * @param {Function} props.onBlur
2107
2043
  * @param {String} props.step
2108
2044
  */
2109
-
2110
-
2111
2045
  function NumberFieldEntry(props) {
2112
2046
  const {
2113
2047
  debounce,
@@ -2149,7 +2083,9 @@ function NumberFieldEntry(props) {
2149
2083
  }
2150
2084
  function isEdited$5(node) {
2151
2085
  return node && !!node.value;
2152
- } // helpers /////////////////
2086
+ }
2087
+
2088
+ // helpers /////////////////
2153
2089
 
2154
2090
  function prefixId$5(id) {
2155
2091
  return `bio-properties-panel-${id}`;
@@ -2168,23 +2104,19 @@ function Select(props) {
2168
2104
  } = props;
2169
2105
  const ref = useShowEntryEvent(id);
2170
2106
  const [localValue, setLocalValue] = hooks.useState(value);
2171
-
2172
2107
  const handleChangeCallback = ({
2173
2108
  target
2174
2109
  }) => {
2175
2110
  onChange(target.value);
2176
2111
  };
2177
-
2178
2112
  const handleChange = e => {
2179
2113
  handleChangeCallback(e);
2180
2114
  setLocalValue(e.target.value);
2181
2115
  };
2182
-
2183
2116
  hooks.useEffect(() => {
2184
2117
  if (value === localValue) {
2185
2118
  return;
2186
2119
  }
2187
-
2188
2120
  setLocalValue(value);
2189
2121
  }, [value]);
2190
2122
  return jsxRuntime.jsxs("div", {
@@ -2213,6 +2145,7 @@ function Select(props) {
2213
2145
  })]
2214
2146
  });
2215
2147
  }
2148
+
2216
2149
  /**
2217
2150
  * @param {object} props
2218
2151
  * @param {object} props.element
@@ -2226,8 +2159,6 @@ function Select(props) {
2226
2159
  * @param {Function} props.getOptions
2227
2160
  * @param {boolean} [props.disabled]
2228
2161
  */
2229
-
2230
-
2231
2162
  function SelectEntry(props) {
2232
2163
  const {
2233
2164
  element,
@@ -2268,7 +2199,9 @@ function SelectEntry(props) {
2268
2199
  }
2269
2200
  function isEdited$4(node) {
2270
2201
  return node && !!node.value;
2271
- } // helpers /////////////////
2202
+ }
2203
+
2204
+ // helpers /////////////////
2272
2205
 
2273
2206
  function prefixId$4(id) {
2274
2207
  return `bio-properties-panel-${id}`;
@@ -2292,17 +2225,14 @@ function Simple(props) {
2292
2225
  target
2293
2226
  }) => setValue(target.value.length ? target.value : undefined));
2294
2227
  }, [setValue, debounce]);
2295
-
2296
2228
  const handleInput = e => {
2297
2229
  handleInputCallback(e);
2298
2230
  setLocalValue(e.target.value);
2299
2231
  };
2300
-
2301
2232
  hooks.useEffect(() => {
2302
2233
  if (value === localValue) {
2303
2234
  return;
2304
2235
  }
2305
-
2306
2236
  setLocalValue(value);
2307
2237
  }, [value]);
2308
2238
  return jsxRuntime.jsx("div", {
@@ -2325,7 +2255,9 @@ function Simple(props) {
2325
2255
  }
2326
2256
  function isEdited$3(node) {
2327
2257
  return node && !!node.value;
2328
- } // helpers /////////////////
2258
+ }
2259
+
2260
+ // helpers /////////////////
2329
2261
 
2330
2262
  function prefixId$3(id) {
2331
2263
  return `bio-properties-panel-${id}`;
@@ -2351,17 +2283,14 @@ function TextArea(props) {
2351
2283
  target
2352
2284
  }) => onInput(target.value.length ? target.value : undefined));
2353
2285
  }, [onInput, debounce]);
2354
-
2355
2286
  const handleInput = e => {
2356
2287
  handleInputCallback(e);
2357
2288
  setLocalValue(e.target.value);
2358
2289
  };
2359
-
2360
2290
  hooks.useEffect(() => {
2361
2291
  if (value === localValue) {
2362
2292
  return;
2363
2293
  }
2364
-
2365
2294
  setLocalValue(value);
2366
2295
  }, [value]);
2367
2296
  return jsxRuntime.jsxs("div", {
@@ -2385,6 +2314,7 @@ function TextArea(props) {
2385
2314
  })]
2386
2315
  });
2387
2316
  }
2317
+
2388
2318
  /**
2389
2319
  * @param {object} props
2390
2320
  * @param {object} props.element
@@ -2400,8 +2330,6 @@ function TextArea(props) {
2400
2330
  * @param {boolean} props.monospace
2401
2331
  * @param {boolean} [props.disabled]
2402
2332
  */
2403
-
2404
-
2405
2333
  function TextAreaEntry(props) {
2406
2334
  const {
2407
2335
  element,
@@ -2445,7 +2373,9 @@ function TextAreaEntry(props) {
2445
2373
  }
2446
2374
  function isEdited$2(node) {
2447
2375
  return node && !!node.value;
2448
- } // helpers /////////////////
2376
+ }
2377
+
2378
+ // helpers /////////////////
2449
2379
 
2450
2380
  function prefixId$2(id) {
2451
2381
  return `bio-properties-panel-${id}`;
@@ -2469,17 +2399,14 @@ function Textfield(props) {
2469
2399
  target
2470
2400
  }) => onInput(target.value.length ? target.value : undefined));
2471
2401
  }, [onInput, debounce]);
2472
-
2473
2402
  const handleInput = e => {
2474
2403
  handleInputCallback(e);
2475
2404
  setLocalValue(e.target.value);
2476
2405
  };
2477
-
2478
2406
  hooks.useEffect(() => {
2479
2407
  if (value === localValue) {
2480
2408
  return;
2481
2409
  }
2482
-
2483
2410
  setLocalValue(value);
2484
2411
  }, [value]);
2485
2412
  return jsxRuntime.jsxs("div", {
@@ -2504,6 +2431,7 @@ function Textfield(props) {
2504
2431
  })]
2505
2432
  });
2506
2433
  }
2434
+
2507
2435
  /**
2508
2436
  * @param {Object} props
2509
2437
  * @param {Object} props.element
@@ -2518,8 +2446,6 @@ function Textfield(props) {
2518
2446
  * @param {Function} props.onBlur
2519
2447
  * @param {Function} props.validate
2520
2448
  */
2521
-
2522
-
2523
2449
  function TextfieldEntry(props) {
2524
2450
  const {
2525
2451
  element,
@@ -2545,27 +2471,21 @@ function TextfieldEntry(props) {
2545
2471
  setLocalError(newValidationError);
2546
2472
  }
2547
2473
  }, [value]);
2548
-
2549
2474
  const onInput = newValue => {
2550
2475
  let newValidationError = null;
2551
-
2552
2476
  if (minDash.isFunction(validate)) {
2553
2477
  newValidationError = validate(newValue) || null;
2554
2478
  }
2555
-
2556
2479
  if (newValidationError) {
2557
2480
  setCachedInvalidValue(newValue);
2558
2481
  } else {
2559
2482
  setValue(newValue);
2560
2483
  }
2561
-
2562
2484
  setLocalError(newValidationError);
2563
2485
  };
2564
-
2565
2486
  if (previousValue === value && localError) {
2566
2487
  value = cachedInvalidValue;
2567
2488
  }
2568
-
2569
2489
  const error = globalError || localError;
2570
2490
  return jsxRuntime.jsxs("div", {
2571
2491
  class: classnames__default["default"]('bio-properties-panel-entry', error ? 'has-error' : ''),
@@ -2591,7 +2511,9 @@ function TextfieldEntry(props) {
2591
2511
  }
2592
2512
  function isEdited$1(node) {
2593
2513
  return node && !!node.value;
2594
- } // helpers /////////////////
2514
+ }
2515
+
2516
+ // helpers /////////////////
2595
2517
 
2596
2518
  function prefixId$1(id) {
2597
2519
  return `bio-properties-panel-${id}`;
@@ -2608,21 +2530,17 @@ function ToggleSwitch(props) {
2608
2530
  onBlur
2609
2531
  } = props;
2610
2532
  const [localValue, setLocalValue] = hooks.useState(value);
2611
-
2612
2533
  const handleInputCallback = async () => {
2613
2534
  onInput(!value);
2614
2535
  };
2615
-
2616
2536
  const handleInput = e => {
2617
2537
  handleInputCallback();
2618
2538
  setLocalValue(e.target.value);
2619
2539
  };
2620
-
2621
2540
  hooks.useEffect(() => {
2622
2541
  if (value === localValue) {
2623
2542
  return;
2624
2543
  }
2625
-
2626
2544
  setLocalValue(value);
2627
2545
  }, [value]);
2628
2546
  return jsxRuntime.jsxs("div", {
@@ -2654,6 +2572,7 @@ function ToggleSwitch(props) {
2654
2572
  })]
2655
2573
  });
2656
2574
  }
2575
+
2657
2576
  /**
2658
2577
  * @param {Object} props
2659
2578
  * @param {Object} props.element
@@ -2666,8 +2585,6 @@ function ToggleSwitch(props) {
2666
2585
  * @param {Function} props.onFocus
2667
2586
  * @param {Function} props.onBlur
2668
2587
  */
2669
-
2670
-
2671
2588
  function ToggleSwitchEntry(props) {
2672
2589
  const {
2673
2590
  element,
@@ -2701,7 +2618,9 @@ function ToggleSwitchEntry(props) {
2701
2618
  }
2702
2619
  function isEdited(node) {
2703
2620
  return node && !!node.checked;
2704
- } // helpers /////////////////
2621
+ }
2622
+
2623
+ // helpers /////////////////
2705
2624
 
2706
2625
  function prefixId(id) {
2707
2626
  return `bio-properties-panel-${id}`;