@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.js CHANGED
@@ -6,9 +6,9 @@ var hooks = require('../preact/hooks');
6
6
  var minDash = require('min-dash');
7
7
  var compat = require('../preact/compat');
8
8
  var jsxRuntime = require('../preact/jsx-runtime');
9
+ var preact = require('../preact');
9
10
  var classnames = require('classnames');
10
11
  var minDom = require('min-dom');
11
- var preact = require('../preact');
12
12
  var feelers = require('feelers');
13
13
  var FeelEditor = require('@bpmn-io/feel-editor');
14
14
 
@@ -150,19 +150,19 @@ const ErrorsContext = preact.createContext({
150
150
  errors: {}
151
151
  });
152
152
 
153
- /**
154
- * @typedef {Function} <propertiesPanel.showEntry> callback
155
- *
156
- * @example
157
- *
158
- * useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
159
- * // ...
160
- * });
161
- *
162
- * @param {Object} context
163
- * @param {boolean} [context.focus]
164
- *
165
- * @returns void
153
+ /**
154
+ * @typedef {Function} <propertiesPanel.showEntry> callback
155
+ *
156
+ * @example
157
+ *
158
+ * useEvent('propertiesPanel.showEntry', ({ focus = false, ...rest }) => {
159
+ * // ...
160
+ * });
161
+ *
162
+ * @param {Object} context
163
+ * @param {boolean} [context.focus]
164
+ *
165
+ * @returns void
166
166
  */
167
167
  const EventContext = preact.createContext({
168
168
  eventBus: null
@@ -175,20 +175,182 @@ const LayoutContext = preact.createContext({
175
175
  setLayoutForKey: () => {}
176
176
  });
177
177
 
178
- /**
179
- * Accesses the global DescriptionContext and returns a description for a given id and element.
180
- *
181
- * @example
182
- * ```jsx
183
- * function TextField(props) {
184
- * const description = useDescriptionContext('input1', element);
185
- * }
186
- * ```
187
- *
188
- * @param {string} id
189
- * @param {object} element
190
- *
191
- * @returns {string}
178
+ const TooltipContext = preact.createContext({
179
+ tooltip: {},
180
+ getTooltipForId: () => {}
181
+ });
182
+
183
+ /**
184
+ * Accesses the global TooltipContext and returns a tooltip for a given id and element.
185
+ *
186
+ * @example
187
+ * ```jsx
188
+ * function TextField(props) {
189
+ * const tooltip = useTooltipContext('input1', element);
190
+ * }
191
+ * ```
192
+ *
193
+ * @param {string} id
194
+ * @param {object} element
195
+ *
196
+ * @returns {string}
197
+ */
198
+ function useTooltipContext(id, element) {
199
+ const {
200
+ getTooltipForId
201
+ } = hooks.useContext(TooltipContext);
202
+ return getTooltipForId(id, element);
203
+ }
204
+
205
+ function TooltipWrapper(props) {
206
+ const {
207
+ forId,
208
+ element
209
+ } = props;
210
+ const contextDescription = useTooltipContext(forId, element);
211
+ const value = props.value || contextDescription;
212
+ if (!value) {
213
+ return props.children;
214
+ }
215
+ return jsxRuntime.jsx(Tooltip, {
216
+ ...props,
217
+ value: value,
218
+ forId: prefixId$8(forId)
219
+ });
220
+ }
221
+ function Tooltip(props) {
222
+ const {
223
+ forId,
224
+ value,
225
+ parent
226
+ } = props;
227
+ const [visible, setShow] = hooks.useState(false);
228
+ let timeout = null;
229
+ const wrapperRef = hooks.useRef(null);
230
+ const tooltipRef = hooks.useRef(null);
231
+ const showTooltip = async event => {
232
+ const show = () => !visible && setShow(true);
233
+ if (event instanceof MouseEvent) {
234
+ timeout = setTimeout(show, 200);
235
+ } else {
236
+ show();
237
+ }
238
+ };
239
+ const hideTooltip = () => setShow(false);
240
+ const hideTooltipViaEscape = e => {
241
+ e.code === 'Escape' && hideTooltip();
242
+ };
243
+ const isTooltipHovered = ({
244
+ x,
245
+ y
246
+ }) => {
247
+ const tooltip = tooltipRef.current;
248
+ const wrapper = wrapperRef.current;
249
+ return tooltip && (inBounds(x, y, wrapper.getBoundingClientRect()) || inBounds(x, y, tooltip.getBoundingClientRect()));
250
+ };
251
+ hooks.useEffect(() => {
252
+ const {
253
+ current
254
+ } = wrapperRef;
255
+ if (!current) {
256
+ return;
257
+ }
258
+ const hideHoveredTooltip = e => {
259
+ const isFocused = document.activeElement === wrapperRef.current || document.activeElement.closest('.bio-properties-panel-tooltip');
260
+ if (visible && !isTooltipHovered({
261
+ x: e.x,
262
+ y: e.y
263
+ }) && !isFocused) {
264
+ hideTooltip();
265
+ }
266
+ };
267
+ const hideFocusedTooltip = e => {
268
+ const {
269
+ relatedTarget
270
+ } = e;
271
+ const isTooltipChild = el => el && !!el.closest('.bio-properties-panel-tooltip');
272
+ if (visible && !isHovered(wrapperRef.current) && !isTooltipChild(relatedTarget)) {
273
+ hideTooltip();
274
+ }
275
+ };
276
+ document.addEventListener('wheel', hideHoveredTooltip);
277
+ document.addEventListener('focusout', hideFocusedTooltip);
278
+ document.addEventListener('mousemove', hideHoveredTooltip);
279
+ return () => {
280
+ document.removeEventListener('wheel', hideHoveredTooltip);
281
+ document.removeEventListener('mousemove', hideHoveredTooltip);
282
+ document.removeEventListener('focusout', hideFocusedTooltip);
283
+ };
284
+ }, [wrapperRef.current, visible]);
285
+ const renderTooltip = () => {
286
+ return jsxRuntime.jsxs("div", {
287
+ class: "bio-properties-panel-tooltip",
288
+ role: "tooltip",
289
+ id: "bio-properties-panel-tooltip",
290
+ "aria-labelledby": forId,
291
+ style: getTooltipPosition(wrapperRef.current),
292
+ ref: tooltipRef,
293
+ onClick: e => e.stopPropagation(),
294
+ children: [jsxRuntime.jsx("div", {
295
+ class: "bio-properties-panel-tooltip-content",
296
+ children: value
297
+ }), jsxRuntime.jsx("div", {
298
+ class: "bio-properties-panel-tooltip-arrow"
299
+ })]
300
+ });
301
+ };
302
+ return jsxRuntime.jsxs("div", {
303
+ class: "bio-properties-panel-tooltip-wrapper",
304
+ tabIndex: "0",
305
+ ref: wrapperRef,
306
+ onMouseEnter: showTooltip,
307
+ onMouseLeave: () => clearTimeout(timeout),
308
+ onFocus: showTooltip,
309
+ onKeyDown: hideTooltipViaEscape,
310
+ onMouseDown: e => {
311
+ e.preventDefault();
312
+ },
313
+ children: [props.children, visible ? parent ? compat.createPortal(renderTooltip(), parent.current) : renderTooltip() : null]
314
+ });
315
+ }
316
+
317
+ // helper
318
+ function inBounds(x, y, bounds) {
319
+ const {
320
+ top,
321
+ right,
322
+ bottom,
323
+ left
324
+ } = bounds;
325
+ return x >= left && x <= right && y >= top && y <= bottom;
326
+ }
327
+ function getTooltipPosition(refElement) {
328
+ const refPosition = refElement.getBoundingClientRect();
329
+ const right = `calc(100% - ${refPosition.x}px)`;
330
+ const top = `${refPosition.top - 10}px`;
331
+ return `right: ${right}; top: ${top};`;
332
+ }
333
+ function isHovered(element) {
334
+ return element.matches(':hover');
335
+ }
336
+ function prefixId$8(id) {
337
+ return `bio-properties-panel-${id}`;
338
+ }
339
+
340
+ /**
341
+ * Accesses the global DescriptionContext and returns a description for a given id and element.
342
+ *
343
+ * @example
344
+ * ```jsx
345
+ * function TextField(props) {
346
+ * const description = useDescriptionContext('input1', element);
347
+ * }
348
+ * ```
349
+ *
350
+ * @param {string} id
351
+ * @param {object} element
352
+ *
353
+ * @returns {string}
192
354
  */
193
355
  function useDescriptionContext(id, element) {
194
356
  const {
@@ -210,11 +372,11 @@ function useErrors() {
210
372
  return errors;
211
373
  }
212
374
 
213
- /**
214
- * Subscribe to an event immediately. Update subscription after inputs changed.
215
- *
216
- * @param {string} event
217
- * @param {Function} callback
375
+ /**
376
+ * Subscribe to an event immediately. Update subscription after inputs changed.
377
+ *
378
+ * @param {string} event
379
+ * @param {Function} callback
218
380
  */
219
381
  function useEvent(event, callback, eventBus) {
220
382
  const eventContext = hooks.useContext(EventContext);
@@ -246,24 +408,24 @@ function useEvent(event, callback, eventBus) {
246
408
 
247
409
  const KEY_LENGTH = 6;
248
410
 
249
- /**
250
- * Create a persistent key factory for plain objects without id.
251
- *
252
- * @example
253
- * ```jsx
254
- * function List({ objects }) {
255
- * const getKey = useKeyFactory();
256
- * return (<ol>{
257
- * objects.map(obj => {
258
- * const key = getKey(obj);
259
- * return <li key={key}>obj.name</li>
260
- * })
261
- * }</ol>);
262
- * }
263
- * ```
264
- *
265
- * @param {any[]} dependencies
266
- * @returns {(element: object) => string}
411
+ /**
412
+ * Create a persistent key factory for plain objects without id.
413
+ *
414
+ * @example
415
+ * ```jsx
416
+ * function List({ objects }) {
417
+ * const getKey = useKeyFactory();
418
+ * return (<ol>{
419
+ * objects.map(obj => {
420
+ * const key = getKey(obj);
421
+ * return <li key={key}>obj.name</li>
422
+ * })
423
+ * }</ol>);
424
+ * }
425
+ * ```
426
+ *
427
+ * @param {any[]} dependencies
428
+ * @returns {(element: object) => string}
267
429
  */
268
430
  function useKeyFactory(dependencies = []) {
269
431
  const map = hooks.useMemo(() => new Map(), dependencies);
@@ -278,20 +440,20 @@ function useKeyFactory(dependencies = []) {
278
440
  return getKey;
279
441
  }
280
442
 
281
- /**
282
- * Creates a state that persists in the global LayoutContext.
283
- *
284
- * @example
285
- * ```jsx
286
- * function Group(props) {
287
- * const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
288
- * }
289
- * ```
290
- *
291
- * @param {(string|number)[]} path
292
- * @param {any} [defaultValue]
293
- *
294
- * @returns {[ any, Function ]}
443
+ /**
444
+ * Creates a state that persists in the global LayoutContext.
445
+ *
446
+ * @example
447
+ * ```jsx
448
+ * function Group(props) {
449
+ * const [ open, setOpen ] = useLayoutState([ 'groups', 'foo', 'open' ], false);
450
+ * }
451
+ * ```
452
+ *
453
+ * @param {(string|number)[]} path
454
+ * @param {any} [defaultValue]
455
+ *
456
+ * @returns {[ any, Function ]}
295
457
  */
296
458
  function useLayoutState(path, defaultValue) {
297
459
  const {
@@ -305,11 +467,11 @@ function useLayoutState(path, defaultValue) {
305
467
  return [layoutForKey, setState];
306
468
  }
307
469
 
308
- /**
309
- * @pinussilvestrus: we need to introduce our own hook to persist the previous
310
- * state on updates.
311
- *
312
- * cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
470
+ /**
471
+ * @pinussilvestrus: we need to introduce our own hook to persist the previous
472
+ * state on updates.
473
+ *
474
+ * cf. https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
313
475
  */
314
476
 
315
477
  function usePrevious(value) {
@@ -320,12 +482,12 @@ function usePrevious(value) {
320
482
  return ref.current;
321
483
  }
322
484
 
323
- /**
324
- * Subscribe to `propertiesPanel.showEntry`.
325
- *
326
- * @param {string} id
327
- *
328
- * @returns {import('preact').Ref}
485
+ /**
486
+ * Subscribe to `propertiesPanel.showEntry`.
487
+ *
488
+ * @param {string} id
489
+ *
490
+ * @returns {import('preact').Ref}
329
491
  */
330
492
  function useShowEntryEvent(id) {
331
493
  const {
@@ -356,20 +518,20 @@ function useShowEntryEvent(id) {
356
518
  return ref;
357
519
  }
358
520
 
359
- /**
360
- * @callback setSticky
361
- * @param {boolean} value
521
+ /**
522
+ * @callback setSticky
523
+ * @param {boolean} value
362
524
  */
363
525
 
364
- /**
365
- * Use IntersectionObserver to identify when DOM element is in sticky mode.
366
- * If sticky is observered setSticky(true) will be called.
367
- * If sticky mode is left, setSticky(false) will be called.
368
- *
369
- *
370
- * @param {Object} ref
371
- * @param {string} scrollContainerSelector
372
- * @param {setSticky} setSticky
526
+ /**
527
+ * Use IntersectionObserver to identify when DOM element is in sticky mode.
528
+ * If sticky is observered setSticky(true) will be called.
529
+ * If sticky mode is left, setSticky(false) will be called.
530
+ *
531
+ *
532
+ * @param {Object} ref
533
+ * @param {string} scrollContainerSelector
534
+ * @param {setSticky} setSticky
373
535
  */
374
536
  function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky) {
375
537
  const [scrollContainer, setScrollContainer] = hooks.useState(minDom.query(scrollContainerSelector));
@@ -423,19 +585,19 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
423
585
  }, [ref.current, scrollContainer, setSticky]);
424
586
  }
425
587
 
426
- /**
427
- * Creates a static function reference with changing body.
428
- * This is necessary when external libraries require a callback function
429
- * that has references to state variables.
430
- *
431
- * Usage:
432
- * const callback = useStaticCallback((val) => {val === currentState});
433
- *
434
- * The `callback` reference is static and can be safely used in external
435
- * libraries or as a prop that does not cause rerendering of children.
436
- *
437
- * @param {Function} callback function with changing reference
438
- * @returns {Function} static function reference
588
+ /**
589
+ * Creates a static function reference with changing body.
590
+ * This is necessary when external libraries require a callback function
591
+ * that has references to state variables.
592
+ *
593
+ * Usage:
594
+ * const callback = useStaticCallback((val) => {val === currentState});
595
+ *
596
+ * The `callback` reference is static and can be safely used in external
597
+ * libraries or as a prop that does not cause rerendering of children.
598
+ *
599
+ * @param {Function} callback function with changing reference
600
+ * @returns {Function} static function reference
439
601
  */
440
602
  function useStaticCallback(callback) {
441
603
  const callbackRef = hooks.useRef(callback);
@@ -495,7 +657,13 @@ function Group(props) {
495
657
  children: [jsxRuntime.jsx("div", {
496
658
  title: label,
497
659
  class: "bio-properties-panel-group-header-title",
498
- children: label
660
+ children: jsxRuntime.jsx(TooltipWrapper, {
661
+ value: props.tooltip,
662
+ forId: 'group-' + id,
663
+ element: element,
664
+ parent: groupRef,
665
+ children: label
666
+ })
499
667
  }), jsxRuntime.jsxs("div", {
500
668
  class: "bio-properties-panel-group-header-buttons",
501
669
  children: [jsxRuntime.jsx(DataMarker, {
@@ -548,13 +716,13 @@ function DataMarker(props) {
548
716
  return null;
549
717
  }
550
718
 
551
- /**
552
- * @typedef { {
553
- * text: (element: object) => string,
554
- * icon?: (element: Object) => import('preact').Component
555
- * } } PlaceholderDefinition
556
- *
557
- * @param { PlaceholderDefinition } props
719
+ /**
720
+ * @typedef { {
721
+ * text: (element: object) => string,
722
+ * icon?: (element: Object) => import('preact').Component
723
+ * } } PlaceholderDefinition
724
+ *
725
+ * @param { PlaceholderDefinition } props
558
726
  */
559
727
  function Placeholder(props) {
560
728
  const {
@@ -577,73 +745,86 @@ function Placeholder(props) {
577
745
 
578
746
  const DEFAULT_LAYOUT = {};
579
747
  const DEFAULT_DESCRIPTION = {};
580
-
581
- /**
582
- * @typedef { {
583
- * component: import('preact').Component,
584
- * id: String,
585
- * isEdited?: Function
586
- * } } EntryDefinition
587
- *
588
- * @typedef { {
589
- * autoFocusEntry: String,
590
- * autoOpen?: Boolean,
591
- * entries: Array<EntryDefinition>,
592
- * id: String,
593
- * label: String,
594
- * remove: (event: MouseEvent) => void
595
- * } } ListItemDefinition
596
- *
597
- * @typedef { {
598
- * add: (event: MouseEvent) => void,
599
- * component: import('preact').Component,
600
- * element: Object,
601
- * id: String,
602
- * items: Array<ListItemDefinition>,
603
- * label: String,
604
- * shouldSort?: Boolean,
605
- * shouldOpen?: Boolean
606
- * } } ListGroupDefinition
607
- *
608
- * @typedef { {
609
- * component?: import('preact').Component,
610
- * entries: Array<EntryDefinition>,
611
- * id: String,
612
- * label: String,
613
- * shouldOpen?: Boolean
614
- * } } GroupDefinition
615
- *
616
- * @typedef { {
617
- * [id: String]: GetDescriptionFunction
618
- * } } DescriptionConfig
619
- *
620
- * @callback { {
621
- * @param {string} id
622
- * @param {Object} element
623
- * @returns {string}
624
- * } } GetDescriptionFunction
625
- *
626
- * @typedef { {
627
- * getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
628
- * getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
629
- * } } PlaceholderProvider
630
- *
748
+ const DEFAULT_TOOLTIP = {};
749
+
750
+ /**
751
+ * @typedef { {
752
+ * component: import('preact').Component,
753
+ * id: String,
754
+ * isEdited?: Function
755
+ * } } EntryDefinition
756
+ *
757
+ * @typedef { {
758
+ * autoFocusEntry: String,
759
+ * autoOpen?: Boolean,
760
+ * entries: Array<EntryDefinition>,
761
+ * id: String,
762
+ * label: String,
763
+ * remove: (event: MouseEvent) => void
764
+ * } } ListItemDefinition
765
+ *
766
+ * @typedef { {
767
+ * add: (event: MouseEvent) => void,
768
+ * component: import('preact').Component,
769
+ * element: Object,
770
+ * id: String,
771
+ * items: Array<ListItemDefinition>,
772
+ * label: String,
773
+ * shouldSort?: Boolean,
774
+ * shouldOpen?: Boolean
775
+ * } } ListGroupDefinition
776
+ *
777
+ * @typedef { {
778
+ * component?: import('preact').Component,
779
+ * entries: Array<EntryDefinition>,
780
+ * id: String,
781
+ * label: String,
782
+ * shouldOpen?: Boolean
783
+ * } } GroupDefinition
784
+ *
785
+ * @typedef { {
786
+ * [id: String]: GetDescriptionFunction
787
+ * } } DescriptionConfig
788
+ *
789
+ * @typedef { {
790
+ * [id: String]: GetTooltipFunction
791
+ * } } TooltipConfig
792
+ *
793
+ * @callback { {
794
+ * @param {string} id
795
+ * @param {Object} element
796
+ * @returns {string}
797
+ * } } GetDescriptionFunction
798
+ *
799
+ * @callback { {
800
+ * @param {string} id
801
+ * @param {Object} element
802
+ * @returns {string}
803
+ * } } GetTooltipFunction
804
+ *
805
+ * @typedef { {
806
+ * getEmpty: (element: object) => import('./components/Placeholder').PlaceholderDefinition,
807
+ * getMultiple: (element: Object) => import('./components/Placeholder').PlaceholderDefinition
808
+ * } } PlaceholderProvider
809
+ *
631
810
  */
632
811
 
633
- /**
634
- * A basic properties panel component. Describes *how* content will be rendered, accepts
635
- * data from implementor to describe *what* will be rendered.
636
- *
637
- * @param {Object} props
638
- * @param {Object|Array} props.element
639
- * @param {import('./components/Header').HeaderProvider} props.headerProvider
640
- * @param {PlaceholderProvider} [props.placeholderProvider]
641
- * @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
642
- * @param {Object} [props.layoutConfig]
643
- * @param {Function} [props.layoutChanged]
644
- * @param {DescriptionConfig} [props.descriptionConfig]
645
- * @param {Function} [props.descriptionLoaded]
646
- * @param {Object} [props.eventBus]
812
+ /**
813
+ * A basic properties panel component. Describes *how* content will be rendered, accepts
814
+ * data from implementor to describe *what* will be rendered.
815
+ *
816
+ * @param {Object} props
817
+ * @param {Object|Array} props.element
818
+ * @param {import('./components/Header').HeaderProvider} props.headerProvider
819
+ * @param {PlaceholderProvider} [props.placeholderProvider]
820
+ * @param {Array<GroupDefinition|ListGroupDefinition>} props.groups
821
+ * @param {Object} [props.layoutConfig]
822
+ * @param {Function} [props.layoutChanged]
823
+ * @param {DescriptionConfig} [props.descriptionConfig]
824
+ * @param {Function} [props.descriptionLoaded]
825
+ * @param {TooltipConfig} [props.tooltipConfig]
826
+ * @param {Function} [props.tooltipLoaded]
827
+ * @param {Object} [props.eventBus]
647
828
  */
648
829
  function PropertiesPanel(props) {
649
830
  const {
@@ -655,6 +836,8 @@ function PropertiesPanel(props) {
655
836
  layoutChanged,
656
837
  descriptionConfig,
657
838
  descriptionLoaded,
839
+ tooltipConfig,
840
+ tooltipLoaded,
658
841
  eventBus
659
842
  } = props;
660
843
 
@@ -700,6 +883,21 @@ function PropertiesPanel(props) {
700
883
  description,
701
884
  getDescriptionForId
702
885
  };
886
+
887
+ // set-up tooltip context
888
+ const tooltip = hooks.useMemo(() => createTooltipContext(tooltipConfig), [tooltipConfig]);
889
+ hooks.useEffect(() => {
890
+ if (typeof tooltipLoaded === 'function') {
891
+ tooltipLoaded(tooltip);
892
+ }
893
+ }, [tooltip, tooltipLoaded]);
894
+ const getTooltipForId = (id, element) => {
895
+ return tooltip[id] && tooltip[id](element);
896
+ };
897
+ const tooltipContext = {
898
+ tooltip,
899
+ getTooltipForId
900
+ };
703
901
  const [errors, setErrors] = hooks.useState({});
704
902
  const onSetErrors = ({
705
903
  errors
@@ -734,29 +932,32 @@ function PropertiesPanel(props) {
734
932
  value: errorsContext,
735
933
  children: jsxRuntime.jsx(DescriptionContext.Provider, {
736
934
  value: descriptionContext,
737
- children: jsxRuntime.jsx(LayoutContext.Provider, {
738
- value: layoutContext,
739
- children: jsxRuntime.jsx(EventContext.Provider, {
740
- value: eventContext,
741
- children: jsxRuntime.jsxs("div", {
742
- class: "bio-properties-panel",
743
- children: [jsxRuntime.jsx(Header, {
744
- element: element,
745
- headerProvider: headerProvider
746
- }), jsxRuntime.jsx("div", {
747
- class: "bio-properties-panel-scroll-container",
748
- children: groups.map(group => {
749
- const {
750
- component: Component = Group,
751
- id
752
- } = group;
753
- return preact.createElement(Component, {
754
- ...group,
755
- key: id,
756
- element: element
757
- });
758
- })
759
- })]
935
+ children: jsxRuntime.jsx(TooltipContext.Provider, {
936
+ value: tooltipContext,
937
+ children: jsxRuntime.jsx(LayoutContext.Provider, {
938
+ value: layoutContext,
939
+ children: jsxRuntime.jsx(EventContext.Provider, {
940
+ value: eventContext,
941
+ children: jsxRuntime.jsxs("div", {
942
+ class: "bio-properties-panel",
943
+ children: [jsxRuntime.jsx(Header, {
944
+ element: element,
945
+ headerProvider: headerProvider
946
+ }), jsxRuntime.jsx("div", {
947
+ class: "bio-properties-panel-scroll-container",
948
+ children: groups.map(group => {
949
+ const {
950
+ component: Component = Group,
951
+ id
952
+ } = group;
953
+ return preact.createElement(Component, {
954
+ ...group,
955
+ key: id,
956
+ element: element
957
+ });
958
+ })
959
+ })]
960
+ })
760
961
  })
761
962
  })
762
963
  })
@@ -779,14 +980,20 @@ function createDescriptionContext(overrides = {}) {
779
980
  ...overrides
780
981
  };
781
982
  }
983
+ function createTooltipContext(overrides = {}) {
984
+ return {
985
+ ...DEFAULT_TOOLTIP,
986
+ ...overrides
987
+ };
988
+ }
782
989
 
783
990
  // hooks //////////////////
784
991
 
785
- /**
786
- * This hook behaves like useLayoutEffect, but does not trigger on the first render.
787
- *
788
- * @param {Function} effect
789
- * @param {Array} deps
992
+ /**
993
+ * This hook behaves like useLayoutEffect, but does not trigger on the first render.
994
+ *
995
+ * @param {Function} effect
996
+ * @param {Array} deps
790
997
  */
791
998
  function useUpdateLayoutEffect(effect, deps) {
792
999
  const isMounted = hooks.useRef(false);
@@ -860,15 +1067,15 @@ function MenuItem({
860
1067
  });
861
1068
  }
862
1069
 
863
- /**
864
- *
865
- * @param {Array<null | Element>} ignoredElements
866
- * @param {Function} callback
1070
+ /**
1071
+ *
1072
+ * @param {Array<null | Element>} ignoredElements
1073
+ * @param {Function} callback
867
1074
  */
868
1075
  function useGlobalClick(ignoredElements, callback) {
869
1076
  hooks.useEffect(() => {
870
- /**
871
- * @param {MouseEvent} event
1077
+ /**
1078
+ * @param {MouseEvent} event
872
1079
  */
873
1080
  function listener(event) {
874
1081
  if (ignoredElements.some(element => element && element.contains(event.target))) {
@@ -999,8 +1206,8 @@ function ListItem(props) {
999
1206
 
1000
1207
  const noop$3 = () => {};
1001
1208
 
1002
- /**
1003
- * @param {import('../PropertiesPanel').ListGroupDefinition} props
1209
+ /**
1210
+ * @param {import('../PropertiesPanel').ListGroupDefinition} props
1004
1211
  */
1005
1212
  function ListGroup(props) {
1006
1213
  const {
@@ -1135,7 +1342,13 @@ function ListGroup(props) {
1135
1342
  children: [jsxRuntime.jsx("div", {
1136
1343
  title: label,
1137
1344
  class: "bio-properties-panel-group-header-title",
1138
- children: label
1345
+ children: jsxRuntime.jsx(TooltipWrapper, {
1346
+ value: props.tooltip,
1347
+ forId: 'group-' + id,
1348
+ element: element,
1349
+ parent: groupRef,
1350
+ children: label
1351
+ })
1139
1352
  }), jsxRuntime.jsxs("div", {
1140
1353
  class: "bio-properties-panel-group-header-buttons",
1141
1354
  children: [add ? jsxRuntime.jsxs("button", {
@@ -1189,8 +1402,8 @@ function ListGroup(props) {
1189
1402
 
1190
1403
  // helpers ////////////////////
1191
1404
 
1192
- /**
1193
- * Sorts given items alphanumeric by label
1405
+ /**
1406
+ * Sorts given items alphanumeric by label
1194
1407
  */
1195
1408
  function sortItems(items) {
1196
1409
  return minDash.sortBy(items, i => i.label.toLowerCase());
@@ -1218,121 +1431,6 @@ function Description(props) {
1218
1431
  }
1219
1432
  }
1220
1433
 
1221
- function TooltipWrapper(props) {
1222
- if (!props.value) {
1223
- return props.children;
1224
- }
1225
- return jsxRuntime.jsx(Tooltip, {
1226
- ...props
1227
- });
1228
- }
1229
- function Tooltip(props) {
1230
- const {
1231
- value,
1232
- labelId
1233
- } = props;
1234
- const [visible, setShow] = compat.useState(false);
1235
- let timeout = null;
1236
- const wrapperRef = hooks.useRef(null);
1237
- const tooltipRef = hooks.useRef(null);
1238
- const showTooltip = async event => {
1239
- const show = () => !visible && setShow(true);
1240
- if (event instanceof MouseEvent) {
1241
- timeout = setTimeout(show, 200);
1242
- } else {
1243
- show();
1244
- }
1245
- };
1246
- const hideTooltip = () => setShow(false);
1247
- const hideTooltipViaEscape = e => {
1248
- e.code === 'Escape' && hideTooltip();
1249
- };
1250
- const isTooltipHovered = ({
1251
- x,
1252
- y
1253
- }) => {
1254
- const tooltip = tooltipRef.current;
1255
- const wrapper = wrapperRef.current;
1256
- return tooltip && (inBounds(x, y, wrapper.getBoundingClientRect()) || inBounds(x, y, tooltip.getBoundingClientRect()));
1257
- };
1258
- compat.useEffect(() => {
1259
- const {
1260
- current
1261
- } = wrapperRef;
1262
- if (!current) {
1263
- return;
1264
- }
1265
- const hideHoveredTooltip = e => {
1266
- const isFocused = document.activeElement === wrapperRef.current || document.activeElement.closest('.bio-properties-panel-tooltip');
1267
- if (visible && !isTooltipHovered({
1268
- x: e.x,
1269
- y: e.y
1270
- }) && !isFocused) {
1271
- hideTooltip();
1272
- }
1273
- };
1274
- const hideFocusedTooltip = e => {
1275
- const {
1276
- relatedTarget
1277
- } = e;
1278
- const isTooltipChild = el => el && !!el.closest('.bio-properties-panel-tooltip');
1279
- if (visible && !isHovered(wrapperRef.current) && !isTooltipChild(relatedTarget)) {
1280
- hideTooltip();
1281
- }
1282
- };
1283
- document.addEventListener('focusout', hideFocusedTooltip);
1284
- document.addEventListener('mousemove', hideHoveredTooltip);
1285
- return () => {
1286
- document.removeEventListener('mousemove', hideHoveredTooltip);
1287
- document.removeEventListener('focusout', hideFocusedTooltip);
1288
- };
1289
- }, [wrapperRef.current, visible]);
1290
- return jsxRuntime.jsxs("div", {
1291
- class: "bio-properties-panel-tooltip-wrapper",
1292
- tabIndex: "0",
1293
- ref: wrapperRef,
1294
- onMouseEnter: showTooltip,
1295
- onMouseLeave: () => clearTimeout(timeout),
1296
- onFocus: showTooltip,
1297
- onKeyDown: hideTooltipViaEscape,
1298
- children: [props.children, visible ? jsxRuntime.jsxs("div", {
1299
- class: "bio-properties-panel-tooltip",
1300
- role: "tooltip",
1301
- id: "bio-properties-panel-tooltip",
1302
- "aria-labelledby": labelId,
1303
- style: getTooltipPosition(wrapperRef.current),
1304
- ref: tooltipRef,
1305
- onClick: e => e.stopPropagation(),
1306
- children: [jsxRuntime.jsx("div", {
1307
- class: "bio-properties-panel-tooltip-content",
1308
- children: value
1309
- }), jsxRuntime.jsx("div", {
1310
- class: "bio-properties-panel-tooltip-arrow"
1311
- })]
1312
- }) : null]
1313
- });
1314
- }
1315
-
1316
- // helper
1317
- function inBounds(x, y, bounds) {
1318
- const {
1319
- top,
1320
- right,
1321
- bottom,
1322
- left
1323
- } = bounds;
1324
- return x >= left && x <= right && y >= top && y <= bottom;
1325
- }
1326
- function getTooltipPosition(refElement) {
1327
- const refPosition = refElement.getBoundingClientRect();
1328
- const right = `calc(100% - ${refPosition.x}px)`;
1329
- const top = `${refPosition.top - 10}px`;
1330
- return `right: ${right}; top: ${top};`;
1331
- }
1332
- function isHovered(element) {
1333
- return element.matches(':hover');
1334
- }
1335
-
1336
1434
  function Checkbox(props) {
1337
1435
  const {
1338
1436
  id,
@@ -1379,25 +1477,26 @@ function Checkbox(props) {
1379
1477
  class: "bio-properties-panel-label",
1380
1478
  children: jsxRuntime.jsx(TooltipWrapper, {
1381
1479
  value: tooltip,
1382
- labelId: prefixId$7(id),
1480
+ forId: id,
1481
+ element: props.element,
1383
1482
  children: label
1384
1483
  })
1385
1484
  })]
1386
1485
  });
1387
1486
  }
1388
1487
 
1389
- /**
1390
- * @param {Object} props
1391
- * @param {Object} props.element
1392
- * @param {String} props.id
1393
- * @param {String} props.description
1394
- * @param {String} props.label
1395
- * @param {Function} props.getValue
1396
- * @param {Function} props.setValue
1397
- * @param {Function} props.onFocus
1398
- * @param {Function} props.onBlur
1399
- * @param {string|import('preact').Component} props.tooltip
1400
- * @param {boolean} [props.disabled]
1488
+ /**
1489
+ * @param {Object} props
1490
+ * @param {Object} props.element
1491
+ * @param {String} props.id
1492
+ * @param {String} props.description
1493
+ * @param {String} props.label
1494
+ * @param {Function} props.getValue
1495
+ * @param {Function} props.setValue
1496
+ * @param {Function} props.onFocus
1497
+ * @param {Function} props.onBlur
1498
+ * @param {string|import('preact').Component} props.tooltip
1499
+ * @param {boolean} [props.disabled]
1401
1500
  */
1402
1501
  function CheckboxEntry(props) {
1403
1502
  const {
@@ -1425,7 +1524,8 @@ function CheckboxEntry(props) {
1425
1524
  onFocus: onFocus,
1426
1525
  onBlur: onBlur,
1427
1526
  value: value,
1428
- tooltip: tooltip
1527
+ tooltip: tooltip,
1528
+ element: element
1429
1529
  }, element), error && jsxRuntime.jsx("div", {
1430
1530
  class: "bio-properties-panel-error",
1431
1531
  children: error
@@ -1570,10 +1670,10 @@ const CodeEditor = compat.forwardRef((props, ref) => {
1570
1670
  hooks.useEffect(() => {
1571
1671
  let editor;
1572
1672
 
1573
- /* Trigger FEEL toggle when
1574
- *
1575
- * - `backspace` is pressed
1576
- * - AND the cursor is at the beginning of the input
1673
+ /* Trigger FEEL toggle when
1674
+ *
1675
+ * - `backspace` is pressed
1676
+ * - AND the cursor is at the beginning of the input
1577
1677
  */
1578
1678
  const onKeyDown = e => {
1579
1679
  if (e.key !== 'Backspace' || !editor) {
@@ -1646,10 +1746,10 @@ function FeelIndicator(props) {
1646
1746
 
1647
1747
  const noop$2 = () => {};
1648
1748
 
1649
- /**
1650
- * @param {Object} props
1651
- * @param {Object} props.label
1652
- * @param {String} props.feel
1749
+ /**
1750
+ * @param {Object} props
1751
+ * @param {Object} props.label
1752
+ * @param {String} props.feel
1653
1753
  */
1654
1754
  function FeelIcon(props) {
1655
1755
  const {
@@ -1713,7 +1813,8 @@ function ToggleSwitch(props) {
1713
1813
  for: prefixId$6(id),
1714
1814
  children: jsxRuntime.jsx(TooltipWrapper, {
1715
1815
  value: tooltip,
1716
- labelId: prefixId$6(id),
1816
+ forId: id,
1817
+ element: props.element,
1717
1818
  children: label
1718
1819
  })
1719
1820
  }), jsxRuntime.jsxs("div", {
@@ -1741,19 +1842,19 @@ function ToggleSwitch(props) {
1741
1842
  });
1742
1843
  }
1743
1844
 
1744
- /**
1745
- * @param {Object} props
1746
- * @param {Object} props.element
1747
- * @param {String} props.id
1748
- * @param {String} props.description
1749
- * @param {String} props.label
1750
- * @param {String} props.switcherLabel
1751
- * @param {Boolean} props.inline
1752
- * @param {Function} props.getValue
1753
- * @param {Function} props.setValue
1754
- * @param {Function} props.onFocus
1755
- * @param {Function} props.onBlur
1756
- * @param {string|import('preact').Component} props.tooltip
1845
+ /**
1846
+ * @param {Object} props
1847
+ * @param {Object} props.element
1848
+ * @param {String} props.id
1849
+ * @param {String} props.description
1850
+ * @param {String} props.label
1851
+ * @param {String} props.switcherLabel
1852
+ * @param {Boolean} props.inline
1853
+ * @param {Function} props.getValue
1854
+ * @param {Function} props.setValue
1855
+ * @param {Function} props.onFocus
1856
+ * @param {Function} props.onBlur
1857
+ * @param {string|import('preact').Component} props.tooltip
1757
1858
  */
1758
1859
  function ToggleSwitchEntry(props) {
1759
1860
  const {
@@ -1782,7 +1883,8 @@ function ToggleSwitchEntry(props) {
1782
1883
  onBlur: onBlur,
1783
1884
  switcherLabel: switcherLabel,
1784
1885
  inline: inline,
1785
- tooltip: tooltip
1886
+ tooltip: tooltip,
1887
+ element: element
1786
1888
  }), jsxRuntime.jsx(Description, {
1787
1889
  forId: id,
1788
1890
  element: element,
@@ -1864,22 +1966,22 @@ function NumberField(props) {
1864
1966
  });
1865
1967
  }
1866
1968
 
1867
- /**
1868
- * @param {Object} props
1869
- * @param {Boolean} props.debounce
1870
- * @param {String} props.description
1871
- * @param {Boolean} props.disabled
1872
- * @param {Object} props.element
1873
- * @param {Function} props.getValue
1874
- * @param {String} props.id
1875
- * @param {String} props.label
1876
- * @param {String} props.max
1877
- * @param {String} props.min
1878
- * @param {Function} props.setValue
1879
- * @param {Function} props.onFocus
1880
- * @param {Function} props.onBlur
1881
- * @param {String} props.step
1882
- * @param {Function} props.validate
1969
+ /**
1970
+ * @param {Object} props
1971
+ * @param {Boolean} props.debounce
1972
+ * @param {String} props.description
1973
+ * @param {Boolean} props.disabled
1974
+ * @param {Object} props.element
1975
+ * @param {Function} props.getValue
1976
+ * @param {String} props.id
1977
+ * @param {String} props.label
1978
+ * @param {String} props.max
1979
+ * @param {String} props.min
1980
+ * @param {Function} props.setValue
1981
+ * @param {Function} props.onFocus
1982
+ * @param {Function} props.onBlur
1983
+ * @param {String} props.step
1984
+ * @param {Function} props.validate
1883
1985
  */
1884
1986
  function NumberFieldEntry(props) {
1885
1987
  const {
@@ -2083,7 +2185,8 @@ function FeelTextfield(props) {
2083
2185
  onClick: () => setFocus(),
2084
2186
  children: [jsxRuntime.jsx(TooltipWrapper, {
2085
2187
  value: tooltip,
2086
- labelId: prefixId$4(id),
2188
+ forId: id,
2189
+ element: props.element,
2087
2190
  children: label
2088
2191
  }), jsxRuntime.jsx(FeelIcon, {
2089
2192
  label: label,
@@ -2327,25 +2430,25 @@ const OptionalFeelCheckbox = compat.forwardRef((props, ref) => {
2327
2430
  });
2328
2431
  });
2329
2432
 
2330
- /**
2331
- * @param {Object} props
2332
- * @param {Object} props.element
2333
- * @param {String} props.id
2334
- * @param {String} props.description
2335
- * @param {Boolean} props.debounce
2336
- * @param {Boolean} props.disabled
2337
- * @param {Boolean} props.feel
2338
- * @param {String} props.label
2339
- * @param {Function} props.getValue
2340
- * @param {Function} props.setValue
2341
- * @param {Function} props.tooltipContainer
2342
- * @param {Function} props.validate
2343
- * @param {Function} props.show
2344
- * @param {Function} props.example
2345
- * @param {Function} props.variables
2346
- * @param {Function} props.onFocus
2347
- * @param {Function} props.onBlur
2348
- * @param {string|import('preact').Component} props.tooltip
2433
+ /**
2434
+ * @param {Object} props
2435
+ * @param {Object} props.element
2436
+ * @param {String} props.id
2437
+ * @param {String} props.description
2438
+ * @param {Boolean} props.debounce
2439
+ * @param {Boolean} props.disabled
2440
+ * @param {Boolean} props.feel
2441
+ * @param {String} props.label
2442
+ * @param {Function} props.getValue
2443
+ * @param {Function} props.setValue
2444
+ * @param {Function} props.tooltipContainer
2445
+ * @param {Function} props.validate
2446
+ * @param {Function} props.show
2447
+ * @param {Function} props.example
2448
+ * @param {Function} props.variables
2449
+ * @param {Function} props.onFocus
2450
+ * @param {Function} props.onBlur
2451
+ * @param {string|import('preact').Component} props.tooltip
2349
2452
  */
2350
2453
  function FeelEntry(props) {
2351
2454
  const {
@@ -2430,27 +2533,27 @@ function FeelEntry(props) {
2430
2533
  });
2431
2534
  }
2432
2535
 
2433
- /**
2434
- * @param {Object} props
2435
- * @param {Object} props.element
2436
- * @param {String} props.id
2437
- * @param {String} props.description
2438
- * @param {Boolean} props.debounce
2439
- * @param {Boolean} props.disabled
2440
- * @param {String} props.max
2441
- * @param {String} props.min
2442
- * @param {String} props.step
2443
- * @param {Boolean} props.feel
2444
- * @param {String} props.label
2445
- * @param {Function} props.getValue
2446
- * @param {Function} props.setValue
2447
- * @param {Function} props.tooltipContainer
2448
- * @param {Function} props.validate
2449
- * @param {Function} props.show
2450
- * @param {Function} props.example
2451
- * @param {Function} props.variables
2452
- * @param {Function} props.onFocus
2453
- * @param {Function} props.onBlur
2536
+ /**
2537
+ * @param {Object} props
2538
+ * @param {Object} props.element
2539
+ * @param {String} props.id
2540
+ * @param {String} props.description
2541
+ * @param {Boolean} props.debounce
2542
+ * @param {Boolean} props.disabled
2543
+ * @param {String} props.max
2544
+ * @param {String} props.min
2545
+ * @param {String} props.step
2546
+ * @param {Boolean} props.feel
2547
+ * @param {String} props.label
2548
+ * @param {Function} props.getValue
2549
+ * @param {Function} props.setValue
2550
+ * @param {Function} props.tooltipContainer
2551
+ * @param {Function} props.validate
2552
+ * @param {Function} props.show
2553
+ * @param {Function} props.example
2554
+ * @param {Function} props.variables
2555
+ * @param {Function} props.onFocus
2556
+ * @param {Function} props.onBlur
2454
2557
  */
2455
2558
  function FeelNumberEntry(props) {
2456
2559
  return jsxRuntime.jsx(FeelEntry, {
@@ -2460,24 +2563,24 @@ function FeelNumberEntry(props) {
2460
2563
  });
2461
2564
  }
2462
2565
 
2463
- /**
2464
- * @param {Object} props
2465
- * @param {Object} props.element
2466
- * @param {String} props.id
2467
- * @param {String} props.description
2468
- * @param {Boolean} props.debounce
2469
- * @param {Boolean} props.disabled
2470
- * @param {Boolean} props.feel
2471
- * @param {String} props.label
2472
- * @param {Function} props.getValue
2473
- * @param {Function} props.setValue
2474
- * @param {Function} props.tooltipContainer
2475
- * @param {Function} props.validate
2476
- * @param {Function} props.show
2477
- * @param {Function} props.example
2478
- * @param {Function} props.variables
2479
- * @param {Function} props.onFocus
2480
- * @param {Function} props.onBlur
2566
+ /**
2567
+ * @param {Object} props
2568
+ * @param {Object} props.element
2569
+ * @param {String} props.id
2570
+ * @param {String} props.description
2571
+ * @param {Boolean} props.debounce
2572
+ * @param {Boolean} props.disabled
2573
+ * @param {Boolean} props.feel
2574
+ * @param {String} props.label
2575
+ * @param {Function} props.getValue
2576
+ * @param {Function} props.setValue
2577
+ * @param {Function} props.tooltipContainer
2578
+ * @param {Function} props.validate
2579
+ * @param {Function} props.show
2580
+ * @param {Function} props.example
2581
+ * @param {Function} props.variables
2582
+ * @param {Function} props.onFocus
2583
+ * @param {Function} props.onBlur
2481
2584
  */
2482
2585
  function FeelTextAreaEntry(props) {
2483
2586
  return jsxRuntime.jsx(FeelEntry, {
@@ -2487,24 +2590,24 @@ function FeelTextAreaEntry(props) {
2487
2590
  });
2488
2591
  }
2489
2592
 
2490
- /**
2491
- * @param {Object} props
2492
- * @param {Object} props.element
2493
- * @param {String} props.id
2494
- * @param {String} props.description
2495
- * @param {Boolean} props.debounce
2496
- * @param {Boolean} props.disabled
2497
- * @param {Boolean} props.feel
2498
- * @param {String} props.label
2499
- * @param {Function} props.getValue
2500
- * @param {Function} props.setValue
2501
- * @param {Function} props.tooltipContainer
2502
- * @param {Function} props.validate
2503
- * @param {Function} props.show
2504
- * @param {Function} props.example
2505
- * @param {Function} props.variables
2506
- * @param {Function} props.onFocus
2507
- * @param {Function} props.onBlur
2593
+ /**
2594
+ * @param {Object} props
2595
+ * @param {Object} props.element
2596
+ * @param {String} props.id
2597
+ * @param {String} props.description
2598
+ * @param {Boolean} props.debounce
2599
+ * @param {Boolean} props.disabled
2600
+ * @param {Boolean} props.feel
2601
+ * @param {String} props.label
2602
+ * @param {Function} props.getValue
2603
+ * @param {Function} props.setValue
2604
+ * @param {Function} props.tooltipContainer
2605
+ * @param {Function} props.validate
2606
+ * @param {Function} props.show
2607
+ * @param {Function} props.example
2608
+ * @param {Function} props.variables
2609
+ * @param {Function} props.onFocus
2610
+ * @param {Function} props.onBlur
2508
2611
  */
2509
2612
  function FeelToggleSwitchEntry(props) {
2510
2613
  return jsxRuntime.jsx(FeelEntry, {
@@ -2514,24 +2617,24 @@ function FeelToggleSwitchEntry(props) {
2514
2617
  });
2515
2618
  }
2516
2619
 
2517
- /**
2518
- * @param {Object} props
2519
- * @param {Object} props.element
2520
- * @param {String} props.id
2521
- * @param {String} props.description
2522
- * @param {Boolean} props.debounce
2523
- * @param {Boolean} props.disabled
2524
- * @param {Boolean} props.feel
2525
- * @param {String} props.label
2526
- * @param {Function} props.getValue
2527
- * @param {Function} props.setValue
2528
- * @param {Function} props.tooltipContainer
2529
- * @param {Function} props.validate
2530
- * @param {Function} props.show
2531
- * @param {Function} props.example
2532
- * @param {Function} props.variables
2533
- * @param {Function} props.onFocus
2534
- * @param {Function} props.onBlur
2620
+ /**
2621
+ * @param {Object} props
2622
+ * @param {Object} props.element
2623
+ * @param {String} props.id
2624
+ * @param {String} props.description
2625
+ * @param {Boolean} props.debounce
2626
+ * @param {Boolean} props.disabled
2627
+ * @param {Boolean} props.feel
2628
+ * @param {String} props.label
2629
+ * @param {Function} props.getValue
2630
+ * @param {Function} props.setValue
2631
+ * @param {Function} props.tooltipContainer
2632
+ * @param {Function} props.validate
2633
+ * @param {Function} props.show
2634
+ * @param {Function} props.example
2635
+ * @param {Function} props.variables
2636
+ * @param {Function} props.onFocus
2637
+ * @param {Function} props.onBlur
2535
2638
  */
2536
2639
  function FeelCheckboxEntry(props) {
2537
2640
  return jsxRuntime.jsx(FeelEntry, {
@@ -2541,26 +2644,26 @@ function FeelCheckboxEntry(props) {
2541
2644
  });
2542
2645
  }
2543
2646
 
2544
- /**
2545
- * @param {Object} props
2546
- * @param {Object} props.element
2547
- * @param {String} props.id
2548
- * @param {String} props.description
2549
- * @param {String} props.hostLanguage
2550
- * @param {Boolean} props.singleLine
2551
- * @param {Boolean} props.debounce
2552
- * @param {Boolean} props.disabled
2553
- * @param {Boolean} props.feel
2554
- * @param {String} props.label
2555
- * @param {Function} props.getValue
2556
- * @param {Function} props.setValue
2557
- * @param {Function} props.tooltipContainer
2558
- * @param {Function} props.validate
2559
- * @param {Function} props.show
2560
- * @param {Function} props.example
2561
- * @param {Function} props.variables
2562
- * @param {Function} props.onFocus
2563
- * @param {Function} props.onBlur
2647
+ /**
2648
+ * @param {Object} props
2649
+ * @param {Object} props.element
2650
+ * @param {String} props.id
2651
+ * @param {String} props.description
2652
+ * @param {String} props.hostLanguage
2653
+ * @param {Boolean} props.singleLine
2654
+ * @param {Boolean} props.debounce
2655
+ * @param {Boolean} props.disabled
2656
+ * @param {Boolean} props.feel
2657
+ * @param {String} props.label
2658
+ * @param {Function} props.getValue
2659
+ * @param {Function} props.setValue
2660
+ * @param {Function} props.tooltipContainer
2661
+ * @param {Function} props.validate
2662
+ * @param {Function} props.show
2663
+ * @param {Function} props.example
2664
+ * @param {Function} props.variables
2665
+ * @param {Function} props.onFocus
2666
+ * @param {Function} props.onBlur
2564
2667
  */
2565
2668
  function FeelTemplatingEntry(props) {
2566
2669
  return jsxRuntime.jsx(FeelEntry, {
@@ -2587,19 +2690,19 @@ function prefixId$4(id) {
2587
2690
 
2588
2691
  const noop = () => {};
2589
2692
 
2590
- /**
2591
- * @param {Object} props
2592
- * @param {Object} props.element
2593
- * @param {String} props.id
2594
- * @param {String} props.description
2595
- * @param {Boolean} props.debounce
2596
- * @param {Boolean} props.disabled
2597
- * @param {String} props.label
2598
- * @param {Function} props.getValue
2599
- * @param {Function} props.setValue
2600
- * @param {Function} props.tooltipContainer
2601
- * @param {Function} props.validate
2602
- * @param {Function} props.show
2693
+ /**
2694
+ * @param {Object} props
2695
+ * @param {Object} props.element
2696
+ * @param {String} props.id
2697
+ * @param {String} props.description
2698
+ * @param {Boolean} props.debounce
2699
+ * @param {Boolean} props.disabled
2700
+ * @param {String} props.label
2701
+ * @param {Function} props.getValue
2702
+ * @param {Function} props.setValue
2703
+ * @param {Function} props.tooltipContainer
2704
+ * @param {Function} props.validate
2705
+ * @param {Function} props.show
2603
2706
  */
2604
2707
  function TemplatingEntry(props) {
2605
2708
  const {
@@ -2778,8 +2881,8 @@ function List(props) {
2778
2881
  }
2779
2882
  }, [open, hasItems]);
2780
2883
 
2781
- /**
2782
- * @param {MouseEvent} event
2884
+ /**
2885
+ * @param {MouseEvent} event
2783
2886
  */
2784
2887
  function addItem(event) {
2785
2888
  event.stopPropagation();
@@ -2891,14 +2994,14 @@ function ItemsList(props) {
2891
2994
  });
2892
2995
  }
2893
2996
 
2894
- /**
2895
- * Place new items in the beginning of the list and sort the rest with provided function.
2896
- *
2897
- * @template Item
2898
- * @param {Item[]} currentItems
2899
- * @param {(a: Item, b: Item) => 0 | 1 | -1} [compareFn] function used to sort items
2900
- * @param {boolean} [shouldReset=false] set to `true` to reset state of the hook
2901
- * @returns {Item[]}
2997
+ /**
2998
+ * Place new items in the beginning of the list and sort the rest with provided function.
2999
+ *
3000
+ * @template Item
3001
+ * @param {Item[]} currentItems
3002
+ * @param {(a: Item, b: Item) => 0 | 1 | -1} [compareFn] function used to sort items
3003
+ * @param {boolean} [shouldReset=false] set to `true` to reset state of the hook
3004
+ * @returns {Item[]}
2902
3005
  */
2903
3006
  function useSortedItems(currentItems, compareFn, shouldReset = false) {
2904
3007
  const itemsRef = hooks.useRef(currentItems.slice());
@@ -2969,7 +3072,8 @@ function Select(props) {
2969
3072
  class: "bio-properties-panel-label",
2970
3073
  children: jsxRuntime.jsx(TooltipWrapper, {
2971
3074
  value: tooltip,
2972
- labelId: prefixId$3(id),
3075
+ forId: id,
3076
+ element: props.element,
2973
3077
  children: label
2974
3078
  })
2975
3079
  }), jsxRuntime.jsx("select", {
@@ -3003,20 +3107,20 @@ function Select(props) {
3003
3107
  });
3004
3108
  }
3005
3109
 
3006
- /**
3007
- * @param {object} props
3008
- * @param {object} props.element
3009
- * @param {string} props.id
3010
- * @param {string} [props.description]
3011
- * @param {string} props.label
3012
- * @param {Function} props.getValue
3013
- * @param {Function} props.setValue
3014
- * @param {Function} props.onFocus
3015
- * @param {Function} props.onBlur
3016
- * @param {Function} props.getOptions
3017
- * @param {boolean} [props.disabled]
3018
- * @param {Function} [props.validate]
3019
- * @param {string|import('preact').Component} props.tooltip
3110
+ /**
3111
+ * @param {object} props
3112
+ * @param {object} props.element
3113
+ * @param {string} props.id
3114
+ * @param {string} [props.description]
3115
+ * @param {string} props.label
3116
+ * @param {Function} props.getValue
3117
+ * @param {Function} props.setValue
3118
+ * @param {Function} props.onFocus
3119
+ * @param {Function} props.onBlur
3120
+ * @param {Function} props.getOptions
3121
+ * @param {boolean} [props.disabled]
3122
+ * @param {Function} [props.validate]
3123
+ * @param {string|import('preact').Component} props.tooltip
3020
3124
  */
3021
3125
  function SelectEntry(props) {
3022
3126
  const {
@@ -3064,7 +3168,8 @@ function SelectEntry(props) {
3064
3168
  onBlur: onBlur,
3065
3169
  options: options,
3066
3170
  disabled: disabled,
3067
- tooltip: tooltip
3171
+ tooltip: tooltip,
3172
+ element: element
3068
3173
  }, element), error && jsxRuntime.jsx("div", {
3069
3174
  class: "bio-properties-panel-error",
3070
3175
  children: error
@@ -3191,7 +3296,8 @@ function TextArea(props) {
3191
3296
  class: "bio-properties-panel-label",
3192
3297
  children: jsxRuntime.jsx(TooltipWrapper, {
3193
3298
  value: tooltip,
3194
- labelId: prefixId$1(id),
3299
+ forId: id,
3300
+ element: props.element,
3195
3301
  children: label
3196
3302
  })
3197
3303
  }), jsxRuntime.jsx("textarea", {
@@ -3211,21 +3317,21 @@ function TextArea(props) {
3211
3317
  });
3212
3318
  }
3213
3319
 
3214
- /**
3215
- * @param {object} props
3216
- * @param {object} props.element
3217
- * @param {string} props.id
3218
- * @param {string} props.description
3219
- * @param {boolean} props.debounce
3220
- * @param {string} props.label
3221
- * @param {Function} props.getValue
3222
- * @param {Function} props.setValue
3223
- * @param {Function} props.onFocus
3224
- * @param {Function} props.onBlur
3225
- * @param {number} props.rows
3226
- * @param {boolean} props.monospace
3227
- * @param {Function} [props.validate]
3228
- * @param {boolean} [props.disabled]
3320
+ /**
3321
+ * @param {object} props
3322
+ * @param {object} props.element
3323
+ * @param {string} props.id
3324
+ * @param {string} props.description
3325
+ * @param {boolean} props.debounce
3326
+ * @param {string} props.label
3327
+ * @param {Function} props.getValue
3328
+ * @param {Function} props.setValue
3329
+ * @param {Function} props.onFocus
3330
+ * @param {Function} props.onBlur
3331
+ * @param {number} props.rows
3332
+ * @param {boolean} props.monospace
3333
+ * @param {Function} [props.validate]
3334
+ * @param {boolean} [props.disabled]
3229
3335
  */
3230
3336
  function TextAreaEntry(props) {
3231
3337
  const {
@@ -3278,7 +3384,8 @@ function TextAreaEntry(props) {
3278
3384
  monospace: monospace,
3279
3385
  disabled: disabled,
3280
3386
  autoResize: autoResize,
3281
- tooltip: tooltip
3387
+ tooltip: tooltip,
3388
+ element: element
3282
3389
  }, element), error && jsxRuntime.jsx("div", {
3283
3390
  class: "bio-properties-panel-error",
3284
3391
  children: error
@@ -3313,7 +3420,6 @@ function Textfield(props) {
3313
3420
  } = props;
3314
3421
  const [localValue, setLocalValue] = hooks.useState(value || '');
3315
3422
  const ref = useShowEntryEvent(id);
3316
- const labelRef = hooks.useRef(null);
3317
3423
  const handleInputCallback = hooks.useMemo(() => {
3318
3424
  return debounce(({
3319
3425
  target
@@ -3336,8 +3442,8 @@ function Textfield(props) {
3336
3442
  class: "bio-properties-panel-label",
3337
3443
  children: jsxRuntime.jsx(TooltipWrapper, {
3338
3444
  value: tooltip,
3339
- refElement: labelRef,
3340
- labelId: prefixId(id),
3445
+ forId: id,
3446
+ element: props.element,
3341
3447
  children: label
3342
3448
  })
3343
3449
  }), jsxRuntime.jsx("input", {
@@ -3357,20 +3463,20 @@ function Textfield(props) {
3357
3463
  });
3358
3464
  }
3359
3465
 
3360
- /**
3361
- * @param {Object} props
3362
- * @param {Object} props.element
3363
- * @param {String} props.id
3364
- * @param {String} props.description
3365
- * @param {Boolean} props.debounce
3366
- * @param {Boolean} props.disabled
3367
- * @param {String} props.label
3368
- * @param {Function} props.getValue
3369
- * @param {Function} props.setValue
3370
- * @param {Function} props.onFocus
3371
- * @param {Function} props.onBlur
3372
- * @param {string|import('preact').Component} props.tooltip
3373
- * @param {Function} props.validate
3466
+ /**
3467
+ * @param {Object} props
3468
+ * @param {Object} props.element
3469
+ * @param {String} props.id
3470
+ * @param {String} props.description
3471
+ * @param {Boolean} props.debounce
3472
+ * @param {Boolean} props.disabled
3473
+ * @param {String} props.label
3474
+ * @param {Function} props.getValue
3475
+ * @param {Function} props.setValue
3476
+ * @param {Function} props.onFocus
3477
+ * @param {Function} props.onBlur
3478
+ * @param {string|import('preact').Component} props.tooltip
3479
+ * @param {Function} props.validate
3374
3480
  */
3375
3481
  function TextfieldEntry(props) {
3376
3482
  const {
@@ -3417,7 +3523,8 @@ function TextfieldEntry(props) {
3417
3523
  onFocus: onFocus,
3418
3524
  onBlur: onBlur,
3419
3525
  value: value,
3420
- tooltip: tooltip
3526
+ tooltip: tooltip,
3527
+ element: element
3421
3528
  }, element), error && jsxRuntime.jsx("div", {
3422
3529
  class: "bio-properties-panel-error",
3423
3530
  children: error
@@ -3491,6 +3598,7 @@ exports.TemplatingEntry = TemplatingEntry;
3491
3598
  exports.TextAreaEntry = TextAreaEntry;
3492
3599
  exports.TextFieldEntry = TextfieldEntry;
3493
3600
  exports.ToggleSwitchEntry = ToggleSwitchEntry;
3601
+ exports.TooltipContext = TooltipContext;
3494
3602
  exports.isCheckboxEntryEdited = isEdited$8;
3495
3603
  exports.isFeelEntryEdited = isEdited$5;
3496
3604
  exports.isNumberFieldEntryEdited = isEdited$6;
@@ -3510,4 +3618,5 @@ exports.usePrevious = usePrevious;
3510
3618
  exports.useShowEntryEvent = useShowEntryEvent;
3511
3619
  exports.useStaticCallback = useStaticCallback;
3512
3620
  exports.useStickyIntersectionObserver = useStickyIntersectionObserver;
3621
+ exports.useTooltipContext = useTooltipContext;
3513
3622
  //# sourceMappingURL=index.js.map