@bpmn-io/properties-panel 3.39.0 → 3.40.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/assets/properties-panel.css +1 -1
- package/dist/index.esm.js +128 -11
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +127 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1176,7 +1176,7 @@ textarea.bio-properties-panel-input {
|
|
|
1176
1176
|
display: flex;
|
|
1177
1177
|
color: var(--color-white, white);
|
|
1178
1178
|
position: fixed;
|
|
1179
|
-
z-index:
|
|
1179
|
+
z-index: 1001;
|
|
1180
1180
|
max-width: 300px;
|
|
1181
1181
|
font-size: var(--text-size-small);
|
|
1182
1182
|
font-family: var(--font-family);
|
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useContext, useState, useRef, useEffect, useCallback, useMemo
|
|
1
|
+
import { useContext, useState, useRef, useEffect, useLayoutEffect, useCallback, useMemo } from '../preact/hooks';
|
|
2
2
|
import { isFunction, isArray, get, assign, set, isString, isNumber, debounce } from 'min-dash';
|
|
3
3
|
import { createPortal, forwardRef } from '../preact/compat';
|
|
4
4
|
import { jsx, jsxs, Fragment } from '../preact/jsx-runtime';
|
|
@@ -343,6 +343,8 @@ function Tooltip(props) {
|
|
|
343
343
|
hideDelay = 250
|
|
344
344
|
} = props;
|
|
345
345
|
const [visible, setVisible] = useState(false);
|
|
346
|
+
const [tooltipPosition, setTooltipPosition] = useState(null);
|
|
347
|
+
const [arrowOffset, setArrowOffset] = useState(null);
|
|
346
348
|
const showTimeoutRef = useRef(null);
|
|
347
349
|
const hideTimeoutRef = useRef(null);
|
|
348
350
|
const wrapperRef = useRef(null);
|
|
@@ -396,6 +398,20 @@ function Tooltip(props) {
|
|
|
396
398
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
397
399
|
};
|
|
398
400
|
}, [visible, hide]);
|
|
401
|
+
useLayoutEffect(() => {
|
|
402
|
+
if (!visible || position) {
|
|
403
|
+
setTooltipPosition(null);
|
|
404
|
+
setArrowOffset(null);
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
if (!wrapperRef.current || !tooltipRef.current) return;
|
|
408
|
+
const {
|
|
409
|
+
tooltipPosition: newPosition,
|
|
410
|
+
arrowOffset: newArrowOffset
|
|
411
|
+
} = getTooltipPosition(wrapperRef.current, tooltipRef.current, direction);
|
|
412
|
+
setTooltipPosition(newPosition);
|
|
413
|
+
setArrowOffset(newArrowOffset);
|
|
414
|
+
}, [visible, position]);
|
|
399
415
|
const handleMouseLeave = ({
|
|
400
416
|
relatedTarget
|
|
401
417
|
}) => {
|
|
@@ -431,12 +447,14 @@ function Tooltip(props) {
|
|
|
431
447
|
e.code === 'Escape' && hide(false);
|
|
432
448
|
};
|
|
433
449
|
const renderTooltip = () => {
|
|
450
|
+
const tooltipStyle = position || (tooltipPosition ? `right: ${tooltipPosition.right}; top: ${tooltipPosition.top}px;` : undefined);
|
|
451
|
+
const arrowStyle = arrowOffset != null ? `margin-top: ${arrowOffset}px;` : undefined;
|
|
434
452
|
return jsxs("div", {
|
|
435
453
|
class: `bio-properties-panel-tooltip ${direction}`,
|
|
436
454
|
role: "tooltip",
|
|
437
455
|
id: "bio-properties-panel-tooltip",
|
|
438
456
|
"aria-labelledby": forId,
|
|
439
|
-
style:
|
|
457
|
+
style: tooltipStyle,
|
|
440
458
|
ref: tooltipRef,
|
|
441
459
|
onClick: e => e.stopPropagation(),
|
|
442
460
|
onMouseEnter: handleTooltipMouseEnter,
|
|
@@ -445,7 +463,8 @@ function Tooltip(props) {
|
|
|
445
463
|
class: "bio-properties-panel-tooltip-content",
|
|
446
464
|
children: value
|
|
447
465
|
}), jsx("div", {
|
|
448
|
-
class: "bio-properties-panel-tooltip-arrow"
|
|
466
|
+
class: "bio-properties-panel-tooltip-arrow",
|
|
467
|
+
style: arrowStyle
|
|
449
468
|
})]
|
|
450
469
|
});
|
|
451
470
|
};
|
|
@@ -464,11 +483,47 @@ function Tooltip(props) {
|
|
|
464
483
|
|
|
465
484
|
// helper
|
|
466
485
|
|
|
467
|
-
function getTooltipPosition(refElement) {
|
|
486
|
+
function getTooltipPosition(refElement, tooltipElement, direction) {
|
|
487
|
+
if (!refElement) {
|
|
488
|
+
return {
|
|
489
|
+
tooltipPosition: null,
|
|
490
|
+
arrowOffset: null
|
|
491
|
+
};
|
|
492
|
+
}
|
|
468
493
|
const refPosition = refElement.getBoundingClientRect();
|
|
469
494
|
const right = `calc(100% - ${refPosition.x}px)`;
|
|
470
|
-
|
|
471
|
-
|
|
495
|
+
let top = refPosition.top - 10;
|
|
496
|
+
let arrowOffset = null;
|
|
497
|
+
|
|
498
|
+
// Ensure that the tooltip is within the viewport, adjust the top position if needed.
|
|
499
|
+
// This is only relevant for the 'right' direction for now
|
|
500
|
+
if (tooltipElement && direction === 'right') {
|
|
501
|
+
const tooltipRect = tooltipElement.getBoundingClientRect();
|
|
502
|
+
const viewportHeight = window.innerHeight;
|
|
503
|
+
const minTop = 0;
|
|
504
|
+
const maxTop = viewportHeight - tooltipRect.height;
|
|
505
|
+
const originalTop = top;
|
|
506
|
+
if (top > maxTop) {
|
|
507
|
+
top = maxTop;
|
|
508
|
+
}
|
|
509
|
+
if (top < minTop) {
|
|
510
|
+
top = minTop;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// Adjust the arrow position if the tooltip had to be moved to stay within viewport
|
|
514
|
+
if (top !== originalTop) {
|
|
515
|
+
const defaultMarginTop = 16;
|
|
516
|
+
const topDiff = top - originalTop;
|
|
517
|
+
arrowOffset = defaultMarginTop - topDiff;
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return {
|
|
521
|
+
tooltipPosition: {
|
|
522
|
+
right,
|
|
523
|
+
top
|
|
524
|
+
},
|
|
525
|
+
arrowOffset
|
|
526
|
+
};
|
|
472
527
|
}
|
|
473
528
|
|
|
474
529
|
/**
|
|
@@ -2363,7 +2418,7 @@ function prefixId$6(id) {
|
|
|
2363
2418
|
const noop$2 = () => {};
|
|
2364
2419
|
|
|
2365
2420
|
/**
|
|
2366
|
-
* @typedef {'required'|'optional'|'static'} FeelType
|
|
2421
|
+
* @typedef {'required'|'optional'|'optional-default-enabled'|'static'} FeelType
|
|
2367
2422
|
*/
|
|
2368
2423
|
|
|
2369
2424
|
/**
|
|
@@ -2406,7 +2461,7 @@ function FeelTextfield(props) {
|
|
|
2406
2461
|
OptionalComponent = OptionalFeelInput,
|
|
2407
2462
|
tooltip
|
|
2408
2463
|
} = props;
|
|
2409
|
-
const [localValue, setLocalValue] = useState(value);
|
|
2464
|
+
const [localValue, setLocalValue] = useState(getInitialFeelLocalValue(feel, value));
|
|
2410
2465
|
const editorRef = useShowEntryEvent(id);
|
|
2411
2466
|
const containerRef = useRef();
|
|
2412
2467
|
const onInput = useCallback(newValue => {
|
|
@@ -2415,8 +2470,8 @@ function FeelTextfield(props) {
|
|
|
2415
2470
|
const newModelValue = newValue === '' || newValue === '=' ? undefined : newValue;
|
|
2416
2471
|
commitValue(newModelValue);
|
|
2417
2472
|
}, [commitValue]);
|
|
2418
|
-
const feelActive =
|
|
2419
|
-
const feelOnlyValue =
|
|
2473
|
+
const feelActive = isFeelActive(feel, localValue);
|
|
2474
|
+
const feelOnlyValue = getFeelValue(localValue);
|
|
2420
2475
|
const feelLanguageContext = useContext(FeelLanguageContext);
|
|
2421
2476
|
const [focus, _setFocus] = useState(undefined);
|
|
2422
2477
|
const {
|
|
@@ -2603,7 +2658,7 @@ function FeelTextfield(props) {
|
|
|
2603
2658
|
ref: containerRef,
|
|
2604
2659
|
children: [jsx(FeelIndicator, {
|
|
2605
2660
|
active: feelActive,
|
|
2606
|
-
disabled: feel
|
|
2661
|
+
disabled: !isFeelOptional(feel) || disabled,
|
|
2607
2662
|
onClick: handleFeelToggle
|
|
2608
2663
|
}), feelActive ? jsx(FeelEditor, {
|
|
2609
2664
|
name: id,
|
|
@@ -3116,6 +3171,68 @@ function prefixId$5(id) {
|
|
|
3116
3171
|
return `bio-properties-panel-${id}`;
|
|
3117
3172
|
}
|
|
3118
3173
|
|
|
3174
|
+
/**
|
|
3175
|
+
* Determine if FEEL is optional for the configured {@link FeelType}.
|
|
3176
|
+
*
|
|
3177
|
+
* @param {FeelType} feelType
|
|
3178
|
+
*
|
|
3179
|
+
* @return {boolean}
|
|
3180
|
+
*/
|
|
3181
|
+
function isFeelOptional(feelType) {
|
|
3182
|
+
return feelType === 'optional' || feelType === 'optional-default-enabled';
|
|
3183
|
+
}
|
|
3184
|
+
|
|
3185
|
+
/**
|
|
3186
|
+
* Determine if FEEL editing is currently active.
|
|
3187
|
+
*
|
|
3188
|
+
* @param {FeelType} feelType
|
|
3189
|
+
* @param {string} localValue
|
|
3190
|
+
*
|
|
3191
|
+
* @return {boolean}
|
|
3192
|
+
*/
|
|
3193
|
+
function isFeelActive(feelType, localValue) {
|
|
3194
|
+
if (feelType === 'required') {
|
|
3195
|
+
return true;
|
|
3196
|
+
}
|
|
3197
|
+
if (isString(localValue)) {
|
|
3198
|
+
if (localValue.startsWith('=')) {
|
|
3199
|
+
return true;
|
|
3200
|
+
}
|
|
3201
|
+
}
|
|
3202
|
+
return false;
|
|
3203
|
+
}
|
|
3204
|
+
|
|
3205
|
+
/**
|
|
3206
|
+
* @template T
|
|
3207
|
+
* @param {T} value
|
|
3208
|
+
*
|
|
3209
|
+
* @return {string|T}
|
|
3210
|
+
*/
|
|
3211
|
+
function getFeelValue(value) {
|
|
3212
|
+
if (isString(value) && value.startsWith('=')) {
|
|
3213
|
+
return value.substring(1);
|
|
3214
|
+
}
|
|
3215
|
+
return value;
|
|
3216
|
+
}
|
|
3217
|
+
|
|
3218
|
+
/**
|
|
3219
|
+
* Initialize local FEEL value.
|
|
3220
|
+
*
|
|
3221
|
+
* `optional-default-enabled` starts in FEEL mode if no value or empty string is provided.
|
|
3222
|
+
*
|
|
3223
|
+
* @template T
|
|
3224
|
+
* @param {FeelType} feelType
|
|
3225
|
+
* @param {T} value
|
|
3226
|
+
*
|
|
3227
|
+
* @return {string|T}
|
|
3228
|
+
*/
|
|
3229
|
+
function getInitialFeelLocalValue(feelType, value) {
|
|
3230
|
+
if (feelType === 'optional-default-enabled' && (value === undefined || value === '')) {
|
|
3231
|
+
return '=';
|
|
3232
|
+
}
|
|
3233
|
+
return value;
|
|
3234
|
+
}
|
|
3235
|
+
|
|
3119
3236
|
const noop$1 = () => {};
|
|
3120
3237
|
|
|
3121
3238
|
/**
|