@bpmn-io/properties-panel 3.1.0 → 3.2.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 CHANGED
@@ -1,10 +1,10 @@
1
- import { useContext, useRef, useEffect, useMemo, useCallback, useState, useLayoutEffect } from '../preact/hooks';
1
+ import { useContext, useState, useRef, useEffect, useMemo, useCallback, useLayoutEffect } from '../preact/hooks';
2
2
  import { isFunction, isArray, get, assign, set, sortBy, find, isString, isNumber, debounce } from 'min-dash';
3
- import { useState as useState$1, useEffect as useEffect$1, forwardRef } from '../preact/compat';
3
+ import { createPortal, forwardRef } from '../preact/compat';
4
4
  import { jsx, jsxs } from '../preact/jsx-runtime';
5
+ import { createContext, createElement } from '../preact';
5
6
  import classnames from 'classnames';
6
7
  import { query } from 'min-dom';
7
- import { createContext, createElement } from '../preact';
8
8
  import { FeelersEditor } from 'feelers';
9
9
  import FeelEditor from '@bpmn-io/feel-editor';
10
10
 
@@ -141,19 +141,19 @@ const ErrorsContext = createContext({
141
141
  errors: {}
142
142
  });
143
143
 
144
- /**
145
- * @typedef {Function} <propertiesPanel.showEntry> callback
146
- *
147
- * @example
148
- *
149
- * useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
150
- * // ...
151
- * });
152
- *
153
- * @param {Object} context
154
- * @param {boolean} [context.focus]
155
- *
156
- * @returns void
144
+ /**
145
+ * @typedef {Function} <propertiesPanel.showEntry> callback
146
+ *
147
+ * @example
148
+ *
149
+ * useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
150
+ * // ...
151
+ * });
152
+ *
153
+ * @param {Object} context
154
+ * @param {boolean} [context.focus]
155
+ *
156
+ * @returns void
157
157
  */
158
158
  const EventContext = createContext({
159
159
  eventBus: null
@@ -166,20 +166,182 @@ const LayoutContext = createContext({
166
166
  setLayoutForKey: () => {}
167
167
  });
168
168
 
169
- /**
170
- * Accesses the global DescriptionContext and returns a description for a given id and element.
171
- *
172
- * @example
173
- * ```jsx
174
- * function TextField(props) {
175
- * const description = useDescriptionContext('input1', element);
176
- * }
177
- * ```
178
- *
179
- * @param {string} id
180
- * @param {object} element
181
- *
182
- * @returns {string}
169
+ const TooltipContext = createContext({
170
+ tooltip: {},
171
+ getTooltipForId: () => {}
172
+ });
173
+
174
+ /**
175
+ * Accesses the global TooltipContext and returns a tooltip for a given id and element.
176
+ *
177
+ * @example
178
+ * ```jsx
179
+ * function TextField(props) {
180
+ * const tooltip = useTooltipContext('input1', element);
181
+ * }
182
+ * ```
183
+ *
184
+ * @param {string} id
185
+ * @param {object} element
186
+ *
187
+ * @returns {string}
188
+ */
189
+ function useTooltipContext(id, element) {
190
+ const {
191
+ getTooltipForId
192
+ } = useContext(TooltipContext);
193
+ return getTooltipForId(id, element);
194
+ }
195
+
196
+ function TooltipWrapper(props) {
197
+ const {
198
+ forId,
199
+ element
200
+ } = props;
201
+ const contextDescription = useTooltipContext(forId, element);
202
+ const value = props.value || contextDescription;
203
+ if (!value) {
204
+ return props.children;
205
+ }
206
+ return jsx(Tooltip, {
207
+ ...props,
208
+ value: value,
209
+ forId: prefixId$8(forId)
210
+ });
211
+ }
212
+ function Tooltip(props) {
213
+ const {
214
+ forId,
215
+ value,
216
+ parent
217
+ } = props;
218
+ const [visible, setShow] = useState(false);
219
+ let timeout = null;
220
+ const wrapperRef = useRef(null);
221
+ const tooltipRef = useRef(null);
222
+ const showTooltip = async event => {
223
+ const show = () => !visible && setShow(true);
224
+ if (event instanceof MouseEvent) {
225
+ timeout = setTimeout(show, 200);
226
+ } else {
227
+ show();
228
+ }
229
+ };
230
+ const hideTooltip = () => setShow(false);
231
+ const hideTooltipViaEscape = e => {
232
+ e.code === 'Escape' && hideTooltip();
233
+ };
234
+ const isTooltipHovered = ({
235
+ x,
236
+ y
237
+ }) => {
238
+ const tooltip = tooltipRef.current;
239
+ const wrapper = wrapperRef.current;
240
+ return tooltip && (inBounds(x, y, wrapper.getBoundingClientRect()) || inBounds(x, y, tooltip.getBoundingClientRect()));
241
+ };
242
+ useEffect(() => {
243
+ const {
244
+ current
245
+ } = wrapperRef;
246
+ if (!current) {
247
+ return;
248
+ }
249
+ const hideHoveredTooltip = e => {
250
+ const isFocused = document.activeElement === wrapperRef.current || document.activeElement.closest('.bio-properties-panel-tooltip');
251
+ if (visible && !isTooltipHovered({
252
+ x: e.x,
253
+ y: e.y
254
+ }) && !isFocused) {
255
+ hideTooltip();
256
+ }
257
+ };
258
+ const hideFocusedTooltip = e => {
259
+ const {
260
+ relatedTarget
261
+ } = e;
262
+ const isTooltipChild = el => el && !!el.closest('.bio-properties-panel-tooltip');
263
+ if (visible && !isHovered(wrapperRef.current) && !isTooltipChild(relatedTarget)) {
264
+ hideTooltip();
265
+ }
266
+ };
267
+ document.addEventListener('wheel', hideHoveredTooltip);
268
+ document.addEventListener('focusout', hideFocusedTooltip);
269
+ document.addEventListener('mousemove', hideHoveredTooltip);
270
+ return () => {
271
+ document.removeEventListener('wheel', hideHoveredTooltip);
272
+ document.removeEventListener('mousemove', hideHoveredTooltip);
273
+ document.removeEventListener('focusout', hideFocusedTooltip);
274
+ };
275
+ }, [wrapperRef.current, visible]);
276
+ const renderTooltip = () => {
277
+ return jsxs("div", {
278
+ class: "bio-properties-panel-tooltip",
279
+ role: "tooltip",
280
+ id: "bio-properties-panel-tooltip",
281
+ "aria-labelledby": forId,
282
+ style: getTooltipPosition(wrapperRef.current),
283
+ ref: tooltipRef,
284
+ onClick: e => e.stopPropagation(),
285
+ children: [jsx("div", {
286
+ class: "bio-properties-panel-tooltip-content",
287
+ children: value
288
+ }), jsx("div", {
289
+ class: "bio-properties-panel-tooltip-arrow"
290
+ })]
291
+ });
292
+ };
293
+ return jsxs("div", {
294
+ class: "bio-properties-panel-tooltip-wrapper",
295
+ tabIndex: "0",
296
+ ref: wrapperRef,
297
+ onMouseEnter: showTooltip,
298
+ onMouseLeave: () => clearTimeout(timeout),
299
+ onFocus: showTooltip,
300
+ onKeyDown: hideTooltipViaEscape,
301
+ onMouseDown: e => {
302
+ e.preventDefault();
303
+ },
304
+ children: [props.children, visible ? parent ? createPortal(renderTooltip(), parent.current) : renderTooltip() : null]
305
+ });
306
+ }
307
+
308
+ // helper
309
+ function inBounds(x, y, bounds) {
310
+ const {
311
+ top,
312
+ right,
313
+ bottom,
314
+ left
315
+ } = bounds;
316
+ return x >= left && x <= right && y >= top && y <= bottom;
317
+ }
318
+ function getTooltipPosition(refElement) {
319
+ const refPosition = refElement.getBoundingClientRect();
320
+ const right = `calc(100% - ${refPosition.x}px)`;
321
+ const top = `${refPosition.top - 10}px`;
322
+ return `right: ${right}; top: ${top};`;
323
+ }
324
+ function isHovered(element) {
325
+ return element.matches(':hover');
326
+ }
327
+ function prefixId$8(id) {
328
+ return `bio-properties-panel-${id}`;
329
+ }
330
+
331
+ /**
332
+ * Accesses the global DescriptionContext and returns a description for a given id and element.
333
+ *
334
+ * @example
335
+ * ```jsx
336
+ * function TextField(props) {
337
+ * const description = useDescriptionContext('input1', element);
338
+ * }
339
+ * ```
340
+ *
341
+ * @param {string} id
342
+ * @param {object} element
343
+ *
344
+ * @returns {string}
183
345
  */
184
346
  function useDescriptionContext(id, element) {
185
347
  const {
@@ -201,11 +363,11 @@ function useErrors() {
201
363
  return errors;
202
364
  }
203
365
 
204
- /**
205
- * Subscribe to an event immediately. Update subscription after inputs changed.
206
- *
207
- * @param {string} event
208
- * @param {Function} callback
366
+ /**
367
+ * Subscribe to an event immediately. Update subscription after inputs changed.
368
+ *
369
+ * @param {string} event
370
+ * @param {Function} callback
209
371
  */
210
372
  function useEvent(event, callback, eventBus) {
211
373
  const eventContext = useContext(EventContext);
@@ -237,24 +399,24 @@ function useEvent(event, callback, eventBus) {
237
399
 
238
400
  const KEY_LENGTH = 6;
239
401
 
240
- /**
241
- * Create a persistent key factory for plain objects without id.
242
- *
243
- * @example
244
- * ```jsx
245
- * function List({ objects }) {
246
- * const getKey = useKeyFactory();
247
- * return (<ol>{
248
- * objects.map(obj => {
249
- * const key = getKey(obj);
250
- * return <li key={key}>obj.name</li>
251
- * })
252
- * }</ol>);
253
- * }
254
- * ```
255
- *
256
- * @param {any[]} dependencies
257
- * @returns {(element: object) => string}
402
+ /**
403
+ * Create a persistent key factory for plain objects without id.
404
+ *
405
+ * @example
406
+ * ```jsx
407
+ * function List({ objects }) {
408
+ * const getKey = useKeyFactory();
409
+ * return (<ol>{
410
+ * objects.map(obj => {
411
+ * const key = getKey(obj);
412
+ * return <li key={key}>obj.name</li>
413
+ * })
414
+ * }</ol>);
415
+ * }
416
+ * ```
417
+ *
418
+ * @param {any[]} dependencies
419
+ * @returns {(element: object) => string}
258
420
  */
259
421
  function useKeyFactory(dependencies = []) {
260
422
  const map = useMemo(() => new Map(), dependencies);
@@ -269,20 +431,20 @@ function useKeyFactory(dependencies = []) {
269
431
  return getKey;
270
432
  }
271
433
 
272
- /**
273
- * Creates a state that persists in the global LayoutContext.
274
- *
275
- * @example
276
- * ```jsx
277
- * function Group(props) {
278
- * const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
279
- * }
280
- * ```
281
- *
282
- * @param {(string|number)[]} path
283
- * @param {any} [defaultValue]
284
- *
285
- * @returns {[ any, Function ]}
434
+ /**
435
+ * Creates a state that persists in the global LayoutContext.
436
+ *
437
+ * @example
438
+ * ```jsx
439
+ * function Group(props) {
440
+ * const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
441
+ * }
442
+ * ```
443
+ *
444
+ * @param {(string|number)[]} path
445
+ * @param {any} [defaultValue]
446
+ *
447
+ * @returns {[ any, Function ]}
286
448
  */
287
449
  function useLayoutState(path, defaultValue) {
288
450
  const {
@@ -296,11 +458,11 @@ function useLayoutState(path, defaultValue) {
296
458
  return [layoutForKey, setState];
297
459
  }
298
460
 
299
- /**
300
- * @pinussilvestrus: we need to introduce our own hook to persist the previous
301
- * state on updates.
302
- *
303
- * cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
461
+ /**
462
+ * @pinussilvestrus: we need to introduce our own hook to persist the previous
463
+ * state on updates.
464
+ *
465
+ * cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
304
466
  */
305
467
 
306
468
  function usePrevious(value) {
@@ -311,12 +473,12 @@ function usePrevious(value) {
311
473
  return ref.current;
312
474
  }
313
475
 
314
- /**
315
- * Subscribe to `propertiesPanel.showEntry`.
316
- *
317
- * @param {string} id
318
- *
319
- * @returns {import('preact').Ref}
476
+ /**
477
+ * Subscribe to `propertiesPanel.showEntry`.
478
+ *
479
+ * @param {string} id
480
+ *
481
+ * @returns {import('preact').Ref}
320
482
  */
321
483
  function useShowEntryEvent(id) {
322
484
  const {
@@ -347,20 +509,20 @@ function useShowEntryEvent(id) {
347
509
  return ref;
348
510
  }
349
511
 
350
- /**
351
- * @callback setSticky
352
- * @param {boolean} value
512
+ /**
513
+ * @callback setSticky
514
+ * @param {boolean} value
353
515
  */
354
516
 
355
- /**
356
- * Use IntersectionObserver to identify when DOM element is in sticky mode.
357
- * If sticky is observered setSticky(true) will be called.
358
- * If sticky mode is left, setSticky(false) will be called.
359
- *
360
- *
361
- * @param {Object} ref
362
- * @param {string} scrollContainerSelector
363
- * @param {setSticky} setSticky
517
+ /**
518
+ * Use IntersectionObserver to identify when DOM element is in sticky mode.
519
+ * If sticky is observered setSticky(true) will be called.
520
+ * If sticky mode is left, setSticky(false) will be called.
521
+ *
522
+ *
523
+ * @param {Object} ref
524
+ * @param {string} scrollContainerSelector
525
+ * @param {setSticky} setSticky
364
526
  */
365
527
  function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky) {
366
528
  const [scrollContainer, setScrollContainer] = useState(query(scrollContainerSelector));
@@ -414,19 +576,19 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
414
576
  }, [ref.current, scrollContainer, setSticky]);
415
577
  }
416
578
 
417
- /**
418
- * Creates a static function reference with changing body.
419
- * This is necessary when external libraries require a callback function
420
- * that has references to state variables.
421
- *
422
- * Usage:
423
- * const callback = useStaticCallback((val) => {val === currentState});
424
- *
425
- * The `callback` reference is static and can be safely used in external
426
- * libraries or as a prop that does not cause rerendering of children.
427
- *
428
- * @param {Function} callback function with changing reference
429
- * @returns {Function} static function reference
579
+ /**
580
+ * Creates a static function reference with changing body.
581
+ * This is necessary when external libraries require a callback function
582
+ * that has references to state variables.
583
+ *
584
+ * Usage:
585
+ * const callback = useStaticCallback((val) => {val === currentState});
586
+ *
587
+ * The `callback` reference is static and can be safely used in external
588
+ * libraries or as a prop that does not cause rerendering of children.
589
+ *
590
+ * @param {Function} callback function with changing reference
591
+ * @returns {Function} static function reference
430
592
  */
431
593
  function useStaticCallback(callback) {
432
594
  const callbackRef = useRef(callback);
@@ -486,7 +648,13 @@ function Group(props) {
486
648
  children: [jsx("div", {
487
649
  title: label,
488
650
  class: "bio-properties-panel-group-header-title",
489
- children: label
651
+ children: jsx(TooltipWrapper, {
652
+ value: props.tooltip,
653
+ forId: 'group-' + id,
654
+ element: element,
655
+ parent: groupRef,
656
+ children: label
657
+ })
490
658
  }), jsxs("div", {
491
659
  class: "bio-properties-panel-group-header-buttons",
492
660
  children: [jsx(DataMarker, {
@@ -539,13 +707,13 @@ function DataMarker(props) {
539
707
  return null;
540
708
  }
541
709
 
542
- /**
543
- * @typedef { {
544
- * text: (element: object) => string,
545
- * icon?: (element: Object) => import('preact').Component
546
- * } } PlaceholderDefinition
547
- *
548
- * @param { PlaceholderDefinition } props
710
+ /**
711
+ * @typedef { {
712
+ * text: (element: object) => string,
713
+ * icon?: (element: Object) => import('preact').Component
714
+ * } } PlaceholderDefinition
715
+ *
716
+ * @param { PlaceholderDefinition } props
549
717
  */
550
718
  function Placeholder(props) {
551
719
  const {
@@ -568,73 +736,86 @@ function Placeholder(props) {
568
736
 
569
737
  const DEFAULT_LAYOUT = {};
570
738
  const DEFAULT_DESCRIPTION = {};
571
-
572
- /**
573
- * @typedef { {
574
- * component: import('preact').Component,
575
- * id: String,
576
- * isEdited?: Function
577
- * } } EntryDefinition
578
- *
579
- * @typedef { {
580
- * autoFocusEntry: String,
581
- * autoOpen?: Boolean,
582
- * entries: Array<EntryDefinition>,
583
- * id: String,
584
- * label: String,
585
- * remove: (event: MouseEvent) => void
586
- * } } ListItemDefinition
587
- *
588
- * @typedef { {
589
- * add: (event: MouseEvent) => void,
590
- * component: import('preact').Component,
591
- * element: Object,
592
- * id: String,
593
- * items: Array<ListItemDefinition>,
594
- * label: String,
595
- * shouldSort?: Boolean,
596
- * shouldOpen?: Boolean
597
- * } } ListGroupDefinition
598
- *
599
- * @typedef { {
600
- * component?: import('preact').Component,
601
- * entries: Array<EntryDefinition>,
602
- * id: String,
603
- * label: String,
604
- * shouldOpen?: Boolean
605
- * } } GroupDefinition
606
- *
607
- * @typedef { {
608
- * [id: String]: GetDescriptionFunction
609
- * } } DescriptionConfig
610
- *
611
- * @callback { {
612
- * @param {string} id
613
- * @param {Object} element
614
- * @returns {string}
615
- * } } GetDescriptionFunction
616
- *
617
- * @typedef { {
618
- * getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
619
- * getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
620
- * } } PlaceholderProvider
621
- *
739
+ const DEFAULT_TOOLTIP = {};
740
+
741
+ /**
742
+ * @typedef { {
743
+ * component: import('preact').Component,
744
+ * id: String,
745
+ * isEdited?: Function
746
+ * } } EntryDefinition
747
+ *
748
+ * @typedef { {
749
+ * autoFocusEntry: String,
750
+ * autoOpen?: Boolean,
751
+ * entries: Array<EntryDefinition>,
752
+ * id: String,
753
+ * label: String,
754
+ * remove: (event: MouseEvent) => void
755
+ * } } ListItemDefinition
756
+ *
757
+ * @typedef { {
758
+ * add: (event: MouseEvent) => void,
759
+ * component: import('preact').Component,
760
+ * element: Object,
761
+ * id: String,
762
+ * items: Array<ListItemDefinition>,
763
+ * label: String,
764
+ * shouldSort?: Boolean,
765
+ * shouldOpen?: Boolean
766
+ * } } ListGroupDefinition
767
+ *
768
+ * @typedef { {
769
+ * component?: import('preact').Component,
770
+ * entries: Array<EntryDefinition>,
771
+ * id: String,
772
+ * label: String,
773
+ * shouldOpen?: Boolean
774
+ * } } GroupDefinition
775
+ *
776
+ * @typedef { {
777
+ * [id: String]: GetDescriptionFunction
778
+ * } } DescriptionConfig
779
+ *
780
+ * @typedef { {
781
+ * [id: String]: GetTooltipFunction
782
+ * } } TooltipConfig
783
+ *
784
+ * @callback { {
785
+ * @param {string} id
786
+ * @param {Object} element
787
+ * @returns {string}
788
+ * } } GetDescriptionFunction
789
+ *
790
+ * @callback { {
791
+ * @param {string} id
792
+ * @param {Object} element
793
+ * @returns {string}
794
+ * } } GetTooltipFunction
795
+ *
796
+ * @typedef { {
797
+ * getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
798
+ * getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
799
+ * } } PlaceholderProvider
800
+ *
622
801
  */
623
802
 
624
- /**
625
- * A basic properties panel component. Describes *how* content will be rendered, accepts
626
- * data from implementor to describe *what* will be rendered.
627
- *
628
- * @param {Object} props
629
- * @param {Object|Array} props.element
630
- * @param {import('./components/Header').HeaderProvider} props.headerProvider
631
- * @param {PlaceholderProvider} [props.placeholderProvider]
632
- * @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
633
- * @param {Object} [props.layoutConfig]
634
- * @param {Function} [props.layoutChanged]
635
- * @param {DescriptionConfig} [props.descriptionConfig]
636
- * @param {Function} [props.descriptionLoaded]
637
- * @param {Object} [props.eventBus]
803
+ /**
804
+ * A basic properties panel component. Describes *how* content will be rendered, accepts
805
+ * data from implementor to describe *what* will be rendered.
806
+ *
807
+ * @param {Object} props
808
+ * @param {Object|Array} props.element
809
+ * @param {import('./components/Header').HeaderProvider} props.headerProvider
810
+ * @param {PlaceholderProvider} [props.placeholderProvider]
811
+ * @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
812
+ * @param {Object} [props.layoutConfig]
813
+ * @param {Function} [props.layoutChanged]
814
+ * @param {DescriptionConfig} [props.descriptionConfig]
815
+ * @param {Function} [props.descriptionLoaded]
816
+ * @param {TooltipConfig} [props.tooltipConfig]
817
+ * @param {Function} [props.tooltipLoaded]
818
+ * @param {Object} [props.eventBus]
638
819
  */
639
820
  function PropertiesPanel(props) {
640
821
  const {
@@ -646,6 +827,8 @@ function PropertiesPanel(props) {
646
827
  layoutChanged,
647
828
  descriptionConfig,
648
829
  descriptionLoaded,
830
+ tooltipConfig,
831
+ tooltipLoaded,
649
832
  eventBus
650
833
  } = props;
651
834
 
@@ -691,6 +874,21 @@ function PropertiesPanel(props) {
691
874
  description,
692
875
  getDescriptionForId
693
876
  };
877
+
878
+ // set-up tooltip context
879
+ const tooltip = useMemo(() => createTooltipContext(tooltipConfig), [tooltipConfig]);
880
+ useEffect(() => {
881
+ if (typeof tooltipLoaded === 'function') {
882
+ tooltipLoaded(tooltip);
883
+ }
884
+ }, [tooltip, tooltipLoaded]);
885
+ const getTooltipForId = (id, element) => {
886
+ return tooltip[id] && tooltip[id](element);
887
+ };
888
+ const tooltipContext = {
889
+ tooltip,
890
+ getTooltipForId
891
+ };
694
892
  const [errors, setErrors] = useState({});
695
893
  const onSetErrors = ({
696
894
  errors
@@ -725,29 +923,32 @@ function PropertiesPanel(props) {
725
923
  value: errorsContext,
726
924
  children: jsx(DescriptionContext.Provider, {
727
925
  value: descriptionContext,
728
- children: jsx(LayoutContext.Provider, {
729
- value: layoutContext,
730
- children: jsx(EventContext.Provider, {
731
- value: eventContext,
732
- children: jsxs("div", {
733
- class: "bio-properties-panel",
734
- children: [jsx(Header, {
735
- element: element,
736
- headerProvider: headerProvider
737
- }), jsx("div", {
738
- class: "bio-properties-panel-scroll-container",
739
- children: groups.map(group => {
740
- const {
741
- component: Component = Group,
742
- id
743
- } = group;
744
- return createElement(Component, {
745
- ...group,
746
- key: id,
747
- element: element
748
- });
749
- })
750
- })]
926
+ children: jsx(TooltipContext.Provider, {
927
+ value: tooltipContext,
928
+ children: jsx(LayoutContext.Provider, {
929
+ value: layoutContext,
930
+ children: jsx(EventContext.Provider, {
931
+ value: eventContext,
932
+ children: jsxs("div", {
933
+ class: "bio-properties-panel",
934
+ children: [jsx(Header, {
935
+ element: element,
936
+ headerProvider: headerProvider
937
+ }), jsx("div", {
938
+ class: "bio-properties-panel-scroll-container",
939
+ children: groups.map(group => {
940
+ const {
941
+ component: Component = Group,
942
+ id
943
+ } = group;
944
+ return createElement(Component, {
945
+ ...group,
946
+ key: id,
947
+ element: element
948
+ });
949
+ })
950
+ })]
951
+ })
751
952
  })
752
953
  })
753
954
  })
@@ -770,14 +971,20 @@ function createDescriptionContext(overrides = {}) {
770
971
  ...overrides
771
972
  };
772
973
  }
974
+ function createTooltipContext(overrides = {}) {
975
+ return {
976
+ ...DEFAULT_TOOLTIP,
977
+ ...overrides
978
+ };
979
+ }
773
980
 
774
981
  // hooks //////////////////
775
982
 
776
- /**
777
- * This hook behaves like useLayoutEffect, but does not trigger on the first render.
778
- *
779
- * @param {Function} effect
780
- * @param {Array} deps
983
+ /**
984
+ * This hook behaves like useLayoutEffect, but does not trigger on the first render.
985
+ *
986
+ * @param {Function} effect
987
+ * @param {Array} deps
781
988
  */
782
989
  function useUpdateLayoutEffect(effect, deps) {
783
990
  const isMounted = useRef(false);
@@ -851,15 +1058,15 @@ function MenuItem({
851
1058
  });
852
1059
  }
853
1060
 
854
- /**
855
- *
856
- * @param {Array<null | Element>} ignoredElements
857
- * @param {Function} callback
1061
+ /**
1062
+ *
1063
+ * @param {Array<null | Element>} ignoredElements
1064
+ * @param {Function} callback
858
1065
  */
859
1066
  function useGlobalClick(ignoredElements, callback) {
860
1067
  useEffect(() => {
861
- /**
862
- * @param {MouseEvent} event
1068
+ /**
1069
+ * @param {MouseEvent} event
863
1070
  */
864
1071
  function listener(event) {
865
1072
  if (ignoredElements.some(element => element && element.contains(event.target))) {
@@ -990,8 +1197,8 @@ function ListItem(props) {
990
1197
 
991
1198
  const noop$3 = () => {};
992
1199
 
993
- /**
994
- * @param {import('../PropertiesPanel').ListGroupDefinition} props
1200
+ /**
1201
+ * @param {import('../PropertiesPanel').ListGroupDefinition} props
995
1202
  */
996
1203
  function ListGroup(props) {
997
1204
  const {
@@ -1126,7 +1333,13 @@ function ListGroup(props) {
1126
1333
  children: [jsx("div", {
1127
1334
  title: label,
1128
1335
  class: "bio-properties-panel-group-header-title",
1129
- children: label
1336
+ children: jsx(TooltipWrapper, {
1337
+ value: props.tooltip,
1338
+ forId: 'group-' + id,
1339
+ element: element,
1340
+ parent: groupRef,
1341
+ children: label
1342
+ })
1130
1343
  }), jsxs("div", {
1131
1344
  class: "bio-properties-panel-group-header-buttons",
1132
1345
  children: [add ? jsxs("button", {
@@ -1180,8 +1393,8 @@ function ListGroup(props) {
1180
1393
 
1181
1394
  // helpers ////////////////////
1182
1395
 
1183
- /**
1184
- * Sorts given items alphanumeric by label
1396
+ /**
1397
+ * Sorts given items alphanumeric by label
1185
1398
  */
1186
1399
  function sortItems(items) {
1187
1400
  return sortBy(items, i => i.label.toLowerCase());
@@ -1209,121 +1422,6 @@ function Description(props) {
1209
1422
  }
1210
1423
  }
1211
1424
 
1212
- function TooltipWrapper(props) {
1213
- if (!props.value) {
1214
- return props.children;
1215
- }
1216
- return jsx(Tooltip, {
1217
- ...props
1218
- });
1219
- }
1220
- function Tooltip(props) {
1221
- const {
1222
- value,
1223
- labelId
1224
- } = props;
1225
- const [visible, setShow] = useState$1(false);
1226
- let timeout = null;
1227
- const wrapperRef = useRef(null);
1228
- const tooltipRef = useRef(null);
1229
- const showTooltip = async event => {
1230
- const show = () => !visible && setShow(true);
1231
- if (event instanceof MouseEvent) {
1232
- timeout = setTimeout(show, 200);
1233
- } else {
1234
- show();
1235
- }
1236
- };
1237
- const hideTooltip = () => setShow(false);
1238
- const hideTooltipViaEscape = e => {
1239
- e.code === 'Escape' && hideTooltip();
1240
- };
1241
- const isTooltipHovered = ({
1242
- x,
1243
- y
1244
- }) => {
1245
- const tooltip = tooltipRef.current;
1246
- const wrapper = wrapperRef.current;
1247
- return tooltip && (inBounds(x, y, wrapper.getBoundingClientRect()) || inBounds(x, y, tooltip.getBoundingClientRect()));
1248
- };
1249
- useEffect$1(() => {
1250
- const {
1251
- current
1252
- } = wrapperRef;
1253
- if (!current) {
1254
- return;
1255
- }
1256
- const hideHoveredTooltip = e => {
1257
- const isFocused = document.activeElement === wrapperRef.current || document.activeElement.closest('.bio-properties-panel-tooltip');
1258
- if (visible && !isTooltipHovered({
1259
- x: e.x,
1260
- y: e.y
1261
- }) && !isFocused) {
1262
- hideTooltip();
1263
- }
1264
- };
1265
- const hideFocusedTooltip = e => {
1266
- const {
1267
- relatedTarget
1268
- } = e;
1269
- const isTooltipChild = el => el && !!el.closest('.bio-properties-panel-tooltip');
1270
- if (visible && !isHovered(wrapperRef.current) && !isTooltipChild(relatedTarget)) {
1271
- hideTooltip();
1272
- }
1273
- };
1274
- document.addEventListener('focusout', hideFocusedTooltip);
1275
- document.addEventListener('mousemove', hideHoveredTooltip);
1276
- return () => {
1277
- document.removeEventListener('mousemove', hideHoveredTooltip);
1278
- document.removeEventListener('focusout', hideFocusedTooltip);
1279
- };
1280
- }, [wrapperRef.current, visible]);
1281
- return jsxs("div", {
1282
- class: "bio-properties-panel-tooltip-wrapper",
1283
- tabIndex: "0",
1284
- ref: wrapperRef,
1285
- onMouseEnter: showTooltip,
1286
- onMouseLeave: () => clearTimeout(timeout),
1287
- onFocus: showTooltip,
1288
- onKeyDown: hideTooltipViaEscape,
1289
- children: [props.children, visible ? jsxs("div", {
1290
- class: "bio-properties-panel-tooltip",
1291
- role: "tooltip",
1292
- id: "bio-properties-panel-tooltip",
1293
- "aria-labelledby": labelId,
1294
- style: getTooltipPosition(wrapperRef.current),
1295
- ref: tooltipRef,
1296
- onClick: e => e.stopPropagation(),
1297
- children: [jsx("div", {
1298
- class: "bio-properties-panel-tooltip-content",
1299
- children: value
1300
- }), jsx("div", {
1301
- class: "bio-properties-panel-tooltip-arrow"
1302
- })]
1303
- }) : null]
1304
- });
1305
- }
1306
-
1307
- // helper
1308
- function inBounds(x, y, bounds) {
1309
- const {
1310
- top,
1311
- right,
1312
- bottom,
1313
- left
1314
- } = bounds;
1315
- return x >= left && x <= right && y >= top && y <= bottom;
1316
- }
1317
- function getTooltipPosition(refElement) {
1318
- const refPosition = refElement.getBoundingClientRect();
1319
- const right = `calc(100% - ${refPosition.x}px)`;
1320
- const top = `${refPosition.top - 10}px`;
1321
- return `right: ${right}; top: ${top};`;
1322
- }
1323
- function isHovered(element) {
1324
- return element.matches(':hover');
1325
- }
1326
-
1327
1425
  function Checkbox(props) {
1328
1426
  const {
1329
1427
  id,
@@ -1370,25 +1468,26 @@ function Checkbox(props) {
1370
1468
  class: "bio-properties-panel-label",
1371
1469
  children: jsx(TooltipWrapper, {
1372
1470
  value: tooltip,
1373
- labelId: prefixId$7(id),
1471
+ forId: id,
1472
+ element: props.element,
1374
1473
  children: label
1375
1474
  })
1376
1475
  })]
1377
1476
  });
1378
1477
  }
1379
1478
 
1380
- /**
1381
- * @param {Object} props
1382
- * @param {Object} props.element
1383
- * @param {String} props.id
1384
- * @param {String} props.description
1385
- * @param {String} props.label
1386
- * @param {Function} props.getValue
1387
- * @param {Function} props.setValue
1388
- * @param {Function} props.onFocus
1389
- * @param {Function} props.onBlur
1390
- * @param {string|import('preact').Component} props.tooltip
1391
- * @param {boolean} [props.disabled]
1479
+ /**
1480
+ * @param {Object} props
1481
+ * @param {Object} props.element
1482
+ * @param {String} props.id
1483
+ * @param {String} props.description
1484
+ * @param {String} props.label
1485
+ * @param {Function} props.getValue
1486
+ * @param {Function} props.setValue
1487
+ * @param {Function} props.onFocus
1488
+ * @param {Function} props.onBlur
1489
+ * @param {string|import('preact').Component} props.tooltip
1490
+ * @param {boolean} [props.disabled]
1392
1491
  */
1393
1492
  function CheckboxEntry(props) {
1394
1493
  const {
@@ -1416,7 +1515,8 @@ function CheckboxEntry(props) {
1416
1515
  onFocus: onFocus,
1417
1516
  onBlur: onBlur,
1418
1517
  value: value,
1419
- tooltip: tooltip
1518
+ tooltip: tooltip,
1519
+ element: element
1420
1520
  }, element), error && jsx("div", {
1421
1521
  class: "bio-properties-panel-error",
1422
1522
  children: error
@@ -1561,10 +1661,10 @@ const CodeEditor = forwardRef((props, ref) => {
1561
1661
  useEffect(() => {
1562
1662
  let editor;
1563
1663
 
1564
- /* Trigger FEEL toggle when
1565
- *
1566
- * - `backspace` is pressed
1567
- * - AND the cursor is at the beginning of the input
1664
+ /* Trigger FEEL toggle when
1665
+ *
1666
+ * - `backspace` is pressed
1667
+ * - AND the cursor is at the beginning of the input
1568
1668
  */
1569
1669
  const onKeyDown = e => {
1570
1670
  if (e.key !== 'Backspace' || !editor) {
@@ -1637,10 +1737,10 @@ function FeelIndicator(props) {
1637
1737
 
1638
1738
  const noop$2 = () => {};
1639
1739
 
1640
- /**
1641
- * @param {Object} props
1642
- * @param {Object} props.label
1643
- * @param {String} props.feel
1740
+ /**
1741
+ * @param {Object} props
1742
+ * @param {Object} props.label
1743
+ * @param {String} props.feel
1644
1744
  */
1645
1745
  function FeelIcon(props) {
1646
1746
  const {
@@ -1704,7 +1804,8 @@ function ToggleSwitch(props) {
1704
1804
  for: prefixId$6(id),
1705
1805
  children: jsx(TooltipWrapper, {
1706
1806
  value: tooltip,
1707
- labelId: prefixId$6(id),
1807
+ forId: id,
1808
+ element: props.element,
1708
1809
  children: label
1709
1810
  })
1710
1811
  }), jsxs("div", {
@@ -1732,19 +1833,19 @@ function ToggleSwitch(props) {
1732
1833
  });
1733
1834
  }
1734
1835
 
1735
- /**
1736
- * @param {Object} props
1737
- * @param {Object} props.element
1738
- * @param {String} props.id
1739
- * @param {String} props.description
1740
- * @param {String} props.label
1741
- * @param {String} props.switcherLabel
1742
- * @param {Boolean} props.inline
1743
- * @param {Function} props.getValue
1744
- * @param {Function} props.setValue
1745
- * @param {Function} props.onFocus
1746
- * @param {Function} props.onBlur
1747
- * @param {string|import('preact').Component} props.tooltip
1836
+ /**
1837
+ * @param {Object} props
1838
+ * @param {Object} props.element
1839
+ * @param {String} props.id
1840
+ * @param {String} props.description
1841
+ * @param {String} props.label
1842
+ * @param {String} props.switcherLabel
1843
+ * @param {Boolean} props.inline
1844
+ * @param {Function} props.getValue
1845
+ * @param {Function} props.setValue
1846
+ * @param {Function} props.onFocus
1847
+ * @param {Function} props.onBlur
1848
+ * @param {string|import('preact').Component} props.tooltip
1748
1849
  */
1749
1850
  function ToggleSwitchEntry(props) {
1750
1851
  const {
@@ -1773,7 +1874,8 @@ function ToggleSwitchEntry(props) {
1773
1874
  onBlur: onBlur,
1774
1875
  switcherLabel: switcherLabel,
1775
1876
  inline: inline,
1776
- tooltip: tooltip
1877
+ tooltip: tooltip,
1878
+ element: element
1777
1879
  }), jsx(Description, {
1778
1880
  forId: id,
1779
1881
  element: element,
@@ -1855,22 +1957,22 @@ function NumberField(props) {
1855
1957
  });
1856
1958
  }
1857
1959
 
1858
- /**
1859
- * @param {Object} props
1860
- * @param {Boolean} props.debounce
1861
- * @param {String} props.description
1862
- * @param {Boolean} props.disabled
1863
- * @param {Object} props.element
1864
- * @param {Function} props.getValue
1865
- * @param {String} props.id
1866
- * @param {String} props.label
1867
- * @param {String} props.max
1868
- * @param {String} props.min
1869
- * @param {Function} props.setValue
1870
- * @param {Function} props.onFocus
1871
- * @param {Function} props.onBlur
1872
- * @param {String} props.step
1873
- * @param {Function} props.validate
1960
+ /**
1961
+ * @param {Object} props
1962
+ * @param {Boolean} props.debounce
1963
+ * @param {String} props.description
1964
+ * @param {Boolean} props.disabled
1965
+ * @param {Object} props.element
1966
+ * @param {Function} props.getValue
1967
+ * @param {String} props.id
1968
+ * @param {String} props.label
1969
+ * @param {String} props.max
1970
+ * @param {String} props.min
1971
+ * @param {Function} props.setValue
1972
+ * @param {Function} props.onFocus
1973
+ * @param {Function} props.onBlur
1974
+ * @param {String} props.step
1975
+ * @param {Function} props.validate
1874
1976
  */
1875
1977
  function NumberFieldEntry(props) {
1876
1978
  const {
@@ -2074,7 +2176,8 @@ function FeelTextfield(props) {
2074
2176
  onClick: () => setFocus(),
2075
2177
  children: [jsx(TooltipWrapper, {
2076
2178
  value: tooltip,
2077
- labelId: prefixId$4(id),
2179
+ forId: id,
2180
+ element: props.element,
2078
2181
  children: label
2079
2182
  }), jsx(FeelIcon, {
2080
2183
  label: label,
@@ -2318,25 +2421,25 @@ const OptionalFeelCheckbox = forwardRef((props, ref) => {
2318
2421
  });
2319
2422
  });
2320
2423
 
2321
- /**
2322
- * @param {Object} props
2323
- * @param {Object} props.element
2324
- * @param {String} props.id
2325
- * @param {String} props.description
2326
- * @param {Boolean} props.debounce
2327
- * @param {Boolean} props.disabled
2328
- * @param {Boolean} props.feel
2329
- * @param {String} props.label
2330
- * @param {Function} props.getValue
2331
- * @param {Function} props.setValue
2332
- * @param {Function} props.tooltipContainer
2333
- * @param {Function} props.validate
2334
- * @param {Function} props.show
2335
- * @param {Function} props.example
2336
- * @param {Function} props.variables
2337
- * @param {Function} props.onFocus
2338
- * @param {Function} props.onBlur
2339
- * @param {string|import('preact').Component} props.tooltip
2424
+ /**
2425
+ * @param {Object} props
2426
+ * @param {Object} props.element
2427
+ * @param {String} props.id
2428
+ * @param {String} props.description
2429
+ * @param {Boolean} props.debounce
2430
+ * @param {Boolean} props.disabled
2431
+ * @param {Boolean} props.feel
2432
+ * @param {String} props.label
2433
+ * @param {Function} props.getValue
2434
+ * @param {Function} props.setValue
2435
+ * @param {Function} props.tooltipContainer
2436
+ * @param {Function} props.validate
2437
+ * @param {Function} props.show
2438
+ * @param {Function} props.example
2439
+ * @param {Function} props.variables
2440
+ * @param {Function} props.onFocus
2441
+ * @param {Function} props.onBlur
2442
+ * @param {string|import('preact').Component} props.tooltip
2340
2443
  */
2341
2444
  function FeelEntry(props) {
2342
2445
  const {
@@ -2421,27 +2524,27 @@ function FeelEntry(props) {
2421
2524
  });
2422
2525
  }
2423
2526
 
2424
- /**
2425
- * @param {Object} props
2426
- * @param {Object} props.element
2427
- * @param {String} props.id
2428
- * @param {String} props.description
2429
- * @param {Boolean} props.debounce
2430
- * @param {Boolean} props.disabled
2431
- * @param {String} props.max
2432
- * @param {String} props.min
2433
- * @param {String} props.step
2434
- * @param {Boolean} props.feel
2435
- * @param {String} props.label
2436
- * @param {Function} props.getValue
2437
- * @param {Function} props.setValue
2438
- * @param {Function} props.tooltipContainer
2439
- * @param {Function} props.validate
2440
- * @param {Function} props.show
2441
- * @param {Function} props.example
2442
- * @param {Function} props.variables
2443
- * @param {Function} props.onFocus
2444
- * @param {Function} props.onBlur
2527
+ /**
2528
+ * @param {Object} props
2529
+ * @param {Object} props.element
2530
+ * @param {String} props.id
2531
+ * @param {String} props.description
2532
+ * @param {Boolean} props.debounce
2533
+ * @param {Boolean} props.disabled
2534
+ * @param {String} props.max
2535
+ * @param {String} props.min
2536
+ * @param {String} props.step
2537
+ * @param {Boolean} props.feel
2538
+ * @param {String} props.label
2539
+ * @param {Function} props.getValue
2540
+ * @param {Function} props.setValue
2541
+ * @param {Function} props.tooltipContainer
2542
+ * @param {Function} props.validate
2543
+ * @param {Function} props.show
2544
+ * @param {Function} props.example
2545
+ * @param {Function} props.variables
2546
+ * @param {Function} props.onFocus
2547
+ * @param {Function} props.onBlur
2445
2548
  */
2446
2549
  function FeelNumberEntry(props) {
2447
2550
  return jsx(FeelEntry, {
@@ -2451,24 +2554,24 @@ function FeelNumberEntry(props) {
2451
2554
  });
2452
2555
  }
2453
2556
 
2454
- /**
2455
- * @param {Object} props
2456
- * @param {Object} props.element
2457
- * @param {String} props.id
2458
- * @param {String} props.description
2459
- * @param {Boolean} props.debounce
2460
- * @param {Boolean} props.disabled
2461
- * @param {Boolean} props.feel
2462
- * @param {String} props.label
2463
- * @param {Function} props.getValue
2464
- * @param {Function} props.setValue
2465
- * @param {Function} props.tooltipContainer
2466
- * @param {Function} props.validate
2467
- * @param {Function} props.show
2468
- * @param {Function} props.example
2469
- * @param {Function} props.variables
2470
- * @param {Function} props.onFocus
2471
- * @param {Function} props.onBlur
2557
+ /**
2558
+ * @param {Object} props
2559
+ * @param {Object} props.element
2560
+ * @param {String} props.id
2561
+ * @param {String} props.description
2562
+ * @param {Boolean} props.debounce
2563
+ * @param {Boolean} props.disabled
2564
+ * @param {Boolean} props.feel
2565
+ * @param {String} props.label
2566
+ * @param {Function} props.getValue
2567
+ * @param {Function} props.setValue
2568
+ * @param {Function} props.tooltipContainer
2569
+ * @param {Function} props.validate
2570
+ * @param {Function} props.show
2571
+ * @param {Function} props.example
2572
+ * @param {Function} props.variables
2573
+ * @param {Function} props.onFocus
2574
+ * @param {Function} props.onBlur
2472
2575
  */
2473
2576
  function FeelTextAreaEntry(props) {
2474
2577
  return jsx(FeelEntry, {
@@ -2478,24 +2581,24 @@ function FeelTextAreaEntry(props) {
2478
2581
  });
2479
2582
  }
2480
2583
 
2481
- /**
2482
- * @param {Object} props
2483
- * @param {Object} props.element
2484
- * @param {String} props.id
2485
- * @param {String} props.description
2486
- * @param {Boolean} props.debounce
2487
- * @param {Boolean} props.disabled
2488
- * @param {Boolean} props.feel
2489
- * @param {String} props.label
2490
- * @param {Function} props.getValue
2491
- * @param {Function} props.setValue
2492
- * @param {Function} props.tooltipContainer
2493
- * @param {Function} props.validate
2494
- * @param {Function} props.show
2495
- * @param {Function} props.example
2496
- * @param {Function} props.variables
2497
- * @param {Function} props.onFocus
2498
- * @param {Function} props.onBlur
2584
+ /**
2585
+ * @param {Object} props
2586
+ * @param {Object} props.element
2587
+ * @param {String} props.id
2588
+ * @param {String} props.description
2589
+ * @param {Boolean} props.debounce
2590
+ * @param {Boolean} props.disabled
2591
+ * @param {Boolean} props.feel
2592
+ * @param {String} props.label
2593
+ * @param {Function} props.getValue
2594
+ * @param {Function} props.setValue
2595
+ * @param {Function} props.tooltipContainer
2596
+ * @param {Function} props.validate
2597
+ * @param {Function} props.show
2598
+ * @param {Function} props.example
2599
+ * @param {Function} props.variables
2600
+ * @param {Function} props.onFocus
2601
+ * @param {Function} props.onBlur
2499
2602
  */
2500
2603
  function FeelToggleSwitchEntry(props) {
2501
2604
  return jsx(FeelEntry, {
@@ -2505,24 +2608,24 @@ function FeelToggleSwitchEntry(props) {
2505
2608
  });
2506
2609
  }
2507
2610
 
2508
- /**
2509
- * @param {Object} props
2510
- * @param {Object} props.element
2511
- * @param {String} props.id
2512
- * @param {String} props.description
2513
- * @param {Boolean} props.debounce
2514
- * @param {Boolean} props.disabled
2515
- * @param {Boolean} props.feel
2516
- * @param {String} props.label
2517
- * @param {Function} props.getValue
2518
- * @param {Function} props.setValue
2519
- * @param {Function} props.tooltipContainer
2520
- * @param {Function} props.validate
2521
- * @param {Function} props.show
2522
- * @param {Function} props.example
2523
- * @param {Function} props.variables
2524
- * @param {Function} props.onFocus
2525
- * @param {Function} props.onBlur
2611
+ /**
2612
+ * @param {Object} props
2613
+ * @param {Object} props.element
2614
+ * @param {String} props.id
2615
+ * @param {String} props.description
2616
+ * @param {Boolean} props.debounce
2617
+ * @param {Boolean} props.disabled
2618
+ * @param {Boolean} props.feel
2619
+ * @param {String} props.label
2620
+ * @param {Function} props.getValue
2621
+ * @param {Function} props.setValue
2622
+ * @param {Function} props.tooltipContainer
2623
+ * @param {Function} props.validate
2624
+ * @param {Function} props.show
2625
+ * @param {Function} props.example
2626
+ * @param {Function} props.variables
2627
+ * @param {Function} props.onFocus
2628
+ * @param {Function} props.onBlur
2526
2629
  */
2527
2630
  function FeelCheckboxEntry(props) {
2528
2631
  return jsx(FeelEntry, {
@@ -2532,26 +2635,26 @@ function FeelCheckboxEntry(props) {
2532
2635
  });
2533
2636
  }
2534
2637
 
2535
- /**
2536
- * @param {Object} props
2537
- * @param {Object} props.element
2538
- * @param {String} props.id
2539
- * @param {String} props.description
2540
- * @param {String} props.hostLanguage
2541
- * @param {Boolean} props.singleLine
2542
- * @param {Boolean} props.debounce
2543
- * @param {Boolean} props.disabled
2544
- * @param {Boolean} props.feel
2545
- * @param {String} props.label
2546
- * @param {Function} props.getValue
2547
- * @param {Function} props.setValue
2548
- * @param {Function} props.tooltipContainer
2549
- * @param {Function} props.validate
2550
- * @param {Function} props.show
2551
- * @param {Function} props.example
2552
- * @param {Function} props.variables
2553
- * @param {Function} props.onFocus
2554
- * @param {Function} props.onBlur
2638
+ /**
2639
+ * @param {Object} props
2640
+ * @param {Object} props.element
2641
+ * @param {String} props.id
2642
+ * @param {String} props.description
2643
+ * @param {String} props.hostLanguage
2644
+ * @param {Boolean} props.singleLine
2645
+ * @param {Boolean} props.debounce
2646
+ * @param {Boolean} props.disabled
2647
+ * @param {Boolean} props.feel
2648
+ * @param {String} props.label
2649
+ * @param {Function} props.getValue
2650
+ * @param {Function} props.setValue
2651
+ * @param {Function} props.tooltipContainer
2652
+ * @param {Function} props.validate
2653
+ * @param {Function} props.show
2654
+ * @param {Function} props.example
2655
+ * @param {Function} props.variables
2656
+ * @param {Function} props.onFocus
2657
+ * @param {Function} props.onBlur
2555
2658
  */
2556
2659
  function FeelTemplatingEntry(props) {
2557
2660
  return jsx(FeelEntry, {
@@ -2578,19 +2681,19 @@ function prefixId$4(id) {
2578
2681
 
2579
2682
  const noop = () => {};
2580
2683
 
2581
- /**
2582
- * @param {Object} props
2583
- * @param {Object} props.element
2584
- * @param {String} props.id
2585
- * @param {String} props.description
2586
- * @param {Boolean} props.debounce
2587
- * @param {Boolean} props.disabled
2588
- * @param {String} props.label
2589
- * @param {Function} props.getValue
2590
- * @param {Function} props.setValue
2591
- * @param {Function} props.tooltipContainer
2592
- * @param {Function} props.validate
2593
- * @param {Function} props.show
2684
+ /**
2685
+ * @param {Object} props
2686
+ * @param {Object} props.element
2687
+ * @param {String} props.id
2688
+ * @param {String} props.description
2689
+ * @param {Boolean} props.debounce
2690
+ * @param {Boolean} props.disabled
2691
+ * @param {String} props.label
2692
+ * @param {Function} props.getValue
2693
+ * @param {Function} props.setValue
2694
+ * @param {Function} props.tooltipContainer
2695
+ * @param {Function} props.validate
2696
+ * @param {Function} props.show
2594
2697
  */
2595
2698
  function TemplatingEntry(props) {
2596
2699
  const {
@@ -2769,8 +2872,8 @@ function List(props) {
2769
2872
  }
2770
2873
  }, [open, hasItems]);
2771
2874
 
2772
- /**
2773
- * @param {MouseEvent} event
2875
+ /**
2876
+ * @param {MouseEvent} event
2774
2877
  */
2775
2878
  function addItem(event) {
2776
2879
  event.stopPropagation();
@@ -2882,14 +2985,14 @@ function ItemsList(props) {
2882
2985
  });
2883
2986
  }
2884
2987
 
2885
- /**
2886
- * Place new items in the beginning of the list and sort the rest with provided function.
2887
- *
2888
- * @template Item
2889
- * @param {Item[]} currentItems
2890
- * @param {(a: Item, b: Item) => 0 | 1 | -1} [compareFn] function used to sort items
2891
- * @param {boolean} [shouldReset=false] set to `true` to reset state of the hook
2892
- * @returns {Item[]}
2988
+ /**
2989
+ * Place new items in the beginning of the list and sort the rest with provided function.
2990
+ *
2991
+ * @template Item
2992
+ * @param {Item[]} currentItems
2993
+ * @param {(a: Item, b: Item) => 0 | 1 | -1} [compareFn] function used to sort items
2994
+ * @param {boolean} [shouldReset=false] set to `true` to reset state of the hook
2995
+ * @returns {Item[]}
2893
2996
  */
2894
2997
  function useSortedItems(currentItems, compareFn, shouldReset = false) {
2895
2998
  const itemsRef = useRef(currentItems.slice());
@@ -2960,7 +3063,8 @@ function Select(props) {
2960
3063
  class: "bio-properties-panel-label",
2961
3064
  children: jsx(TooltipWrapper, {
2962
3065
  value: tooltip,
2963
- labelId: prefixId$3(id),
3066
+ forId: id,
3067
+ element: props.element,
2964
3068
  children: label
2965
3069
  })
2966
3070
  }), jsx("select", {
@@ -2994,20 +3098,20 @@ function Select(props) {
2994
3098
  });
2995
3099
  }
2996
3100
 
2997
- /**
2998
- * @param {object} props
2999
- * @param {object} props.element
3000
- * @param {string} props.id
3001
- * @param {string} [props.description]
3002
- * @param {string} props.label
3003
- * @param {Function} props.getValue
3004
- * @param {Function} props.setValue
3005
- * @param {Function} props.onFocus
3006
- * @param {Function} props.onBlur
3007
- * @param {Function} props.getOptions
3008
- * @param {boolean} [props.disabled]
3009
- * @param {Function} [props.validate]
3010
- * @param {string|import('preact').Component} props.tooltip
3101
+ /**
3102
+ * @param {object} props
3103
+ * @param {object} props.element
3104
+ * @param {string} props.id
3105
+ * @param {string} [props.description]
3106
+ * @param {string} props.label
3107
+ * @param {Function} props.getValue
3108
+ * @param {Function} props.setValue
3109
+ * @param {Function} props.onFocus
3110
+ * @param {Function} props.onBlur
3111
+ * @param {Function} props.getOptions
3112
+ * @param {boolean} [props.disabled]
3113
+ * @param {Function} [props.validate]
3114
+ * @param {string|import('preact').Component} props.tooltip
3011
3115
  */
3012
3116
  function SelectEntry(props) {
3013
3117
  const {
@@ -3055,7 +3159,8 @@ function SelectEntry(props) {
3055
3159
  onBlur: onBlur,
3056
3160
  options: options,
3057
3161
  disabled: disabled,
3058
- tooltip: tooltip
3162
+ tooltip: tooltip,
3163
+ element: element
3059
3164
  }, element), error && jsx("div", {
3060
3165
  class: "bio-properties-panel-error",
3061
3166
  children: error
@@ -3182,7 +3287,8 @@ function TextArea(props) {
3182
3287
  class: "bio-properties-panel-label",
3183
3288
  children: jsx(TooltipWrapper, {
3184
3289
  value: tooltip,
3185
- labelId: prefixId$1(id),
3290
+ forId: id,
3291
+ element: props.element,
3186
3292
  children: label
3187
3293
  })
3188
3294
  }), jsx("textarea", {
@@ -3202,21 +3308,21 @@ function TextArea(props) {
3202
3308
  });
3203
3309
  }
3204
3310
 
3205
- /**
3206
- * @param {object} props
3207
- * @param {object} props.element
3208
- * @param {string} props.id
3209
- * @param {string} props.description
3210
- * @param {boolean} props.debounce
3211
- * @param {string} props.label
3212
- * @param {Function} props.getValue
3213
- * @param {Function} props.setValue
3214
- * @param {Function} props.onFocus
3215
- * @param {Function} props.onBlur
3216
- * @param {number} props.rows
3217
- * @param {boolean} props.monospace
3218
- * @param {Function} [props.validate]
3219
- * @param {boolean} [props.disabled]
3311
+ /**
3312
+ * @param {object} props
3313
+ * @param {object} props.element
3314
+ * @param {string} props.id
3315
+ * @param {string} props.description
3316
+ * @param {boolean} props.debounce
3317
+ * @param {string} props.label
3318
+ * @param {Function} props.getValue
3319
+ * @param {Function} props.setValue
3320
+ * @param {Function} props.onFocus
3321
+ * @param {Function} props.onBlur
3322
+ * @param {number} props.rows
3323
+ * @param {boolean} props.monospace
3324
+ * @param {Function} [props.validate]
3325
+ * @param {boolean} [props.disabled]
3220
3326
  */
3221
3327
  function TextAreaEntry(props) {
3222
3328
  const {
@@ -3269,7 +3375,8 @@ function TextAreaEntry(props) {
3269
3375
  monospace: monospace,
3270
3376
  disabled: disabled,
3271
3377
  autoResize: autoResize,
3272
- tooltip: tooltip
3378
+ tooltip: tooltip,
3379
+ element: element
3273
3380
  }, element), error && jsx("div", {
3274
3381
  class: "bio-properties-panel-error",
3275
3382
  children: error
@@ -3304,7 +3411,6 @@ function Textfield(props) {
3304
3411
  } = props;
3305
3412
  const [localValue, setLocalValue] = useState(value || '');
3306
3413
  const ref = useShowEntryEvent(id);
3307
- const labelRef = useRef(null);
3308
3414
  const handleInputCallback = useMemo(() => {
3309
3415
  return debounce(({
3310
3416
  target
@@ -3327,8 +3433,8 @@ function Textfield(props) {
3327
3433
  class: "bio-properties-panel-label",
3328
3434
  children: jsx(TooltipWrapper, {
3329
3435
  value: tooltip,
3330
- refElement: labelRef,
3331
- labelId: prefixId(id),
3436
+ forId: id,
3437
+ element: props.element,
3332
3438
  children: label
3333
3439
  })
3334
3440
  }), jsx("input", {
@@ -3348,20 +3454,20 @@ function Textfield(props) {
3348
3454
  });
3349
3455
  }
3350
3456
 
3351
- /**
3352
- * @param {Object} props
3353
- * @param {Object} props.element
3354
- * @param {String} props.id
3355
- * @param {String} props.description
3356
- * @param {Boolean} props.debounce
3357
- * @param {Boolean} props.disabled
3358
- * @param {String} props.label
3359
- * @param {Function} props.getValue
3360
- * @param {Function} props.setValue
3361
- * @param {Function} props.onFocus
3362
- * @param {Function} props.onBlur
3363
- * @param {string|import('preact').Component} props.tooltip
3364
- * @param {Function} props.validate
3457
+ /**
3458
+ * @param {Object} props
3459
+ * @param {Object} props.element
3460
+ * @param {String} props.id
3461
+ * @param {String} props.description
3462
+ * @param {Boolean} props.debounce
3463
+ * @param {Boolean} props.disabled
3464
+ * @param {String} props.label
3465
+ * @param {Function} props.getValue
3466
+ * @param {Function} props.setValue
3467
+ * @param {Function} props.onFocus
3468
+ * @param {Function} props.onBlur
3469
+ * @param {string|import('preact').Component} props.tooltip
3470
+ * @param {Function} props.validate
3365
3471
  */
3366
3472
  function TextfieldEntry(props) {
3367
3473
  const {
@@ -3408,7 +3514,8 @@ function TextfieldEntry(props) {
3408
3514
  onFocus: onFocus,
3409
3515
  onBlur: onBlur,
3410
3516
  value: value,
3411
- tooltip: tooltip
3517
+ tooltip: tooltip,
3518
+ element: element
3412
3519
  }, element), error && jsx("div", {
3413
3520
  class: "bio-properties-panel-error",
3414
3521
  children: error
@@ -3446,5 +3553,5 @@ var index = {
3446
3553
  debounceInput: ['factory', debounceInput]
3447
3554
  };
3448
3555
 
3449
- export { ArrowIcon, CheckboxEntry, CollapsibleEntry, CreateIcon, index as DebounceInputModule, DeleteIcon, DescriptionContext, Description as DescriptionEntry, DropdownButton, ErrorsContext, EventContext, ExternalLinkIcon, FeelCheckboxEntry, FeelEntry, FeelIcon$1 as FeelIcon, FeelNumberEntry, FeelTemplatingEntry, FeelTextAreaEntry, FeelToggleSwitchEntry, Group, Header, HeaderButton, LayoutContext, List as ListEntry, ListGroup, ListItem, NumberFieldEntry, Placeholder, PropertiesPanel, LayoutContext as PropertiesPanelContext, SelectEntry, Simple as SimpleEntry, TemplatingEntry, TextAreaEntry, TextfieldEntry as TextFieldEntry, ToggleSwitchEntry, isEdited$8 as isCheckboxEntryEdited, isEdited$5 as isFeelEntryEdited, isEdited$6 as isNumberFieldEntryEdited, isEdited$3 as isSelectEntryEdited, isEdited$2 as isSimpleEntryEdited, isEdited$4 as isTemplatingEntryEdited, isEdited$1 as isTextAreaEntryEdited, isEdited as isTextFieldEntryEdited, isEdited$7 as isToggleSwitchEntryEdited, useDescriptionContext, useError, useErrors, useEvent, useKeyFactory, useLayoutState, usePrevious, useShowEntryEvent, useStaticCallback, useStickyIntersectionObserver };
3556
+ export { ArrowIcon, CheckboxEntry, CollapsibleEntry, CreateIcon, index as DebounceInputModule, DeleteIcon, DescriptionContext, Description as DescriptionEntry, DropdownButton, ErrorsContext, EventContext, ExternalLinkIcon, FeelCheckboxEntry, FeelEntry, FeelIcon$1 as FeelIcon, FeelNumberEntry, FeelTemplatingEntry, FeelTextAreaEntry, FeelToggleSwitchEntry, Group, Header, HeaderButton, LayoutContext, List as ListEntry, ListGroup, ListItem, NumberFieldEntry, Placeholder, PropertiesPanel, LayoutContext as PropertiesPanelContext, SelectEntry, Simple as SimpleEntry, TemplatingEntry, TextAreaEntry, TextfieldEntry as TextFieldEntry, ToggleSwitchEntry, TooltipContext, isEdited$8 as isCheckboxEntryEdited, isEdited$5 as isFeelEntryEdited, isEdited$6 as isNumberFieldEntryEdited, isEdited$3 as isSelectEntryEdited, isEdited$2 as isSimpleEntryEdited, isEdited$4 as isTemplatingEntryEdited, isEdited$1 as isTextAreaEntryEdited, isEdited as isTextFieldEntryEdited, isEdited$7 as isToggleSwitchEntryEdited, useDescriptionContext, useError, useErrors, useEvent, useKeyFactory, useLayoutState, usePrevious, useShowEntryEvent, useStaticCallback, useStickyIntersectionObserver, useTooltipContext };
3450
3557
  //# sourceMappingURL=index.esm.js.map