@bpmn-io/form-js-editor 1.19.0 → 1.20.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/form-js-editor.css +1 -1
- package/dist/assets/properties-panel.css +1 -1
- package/dist/index.cjs +139 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +139 -16
- package/dist/index.es.js.map +1 -1
- package/package.json +5 -5
package/dist/index.es.js
CHANGED
|
@@ -5700,6 +5700,8 @@ function Tooltip(props) {
|
|
|
5700
5700
|
hideDelay = 250
|
|
5701
5701
|
} = props;
|
|
5702
5702
|
const [visible, setVisible] = useState(false);
|
|
5703
|
+
const [tooltipPosition, setTooltipPosition] = useState(null);
|
|
5704
|
+
const [arrowOffset, setArrowOffset] = useState(null);
|
|
5703
5705
|
const showTimeoutRef = useRef(null);
|
|
5704
5706
|
const hideTimeoutRef = useRef(null);
|
|
5705
5707
|
const wrapperRef = useRef(null);
|
|
@@ -5753,6 +5755,20 @@ function Tooltip(props) {
|
|
|
5753
5755
|
document.removeEventListener('mousedown', handleClickOutside);
|
|
5754
5756
|
};
|
|
5755
5757
|
}, [visible, hide]);
|
|
5758
|
+
useLayoutEffect(() => {
|
|
5759
|
+
if (!visible || position) {
|
|
5760
|
+
setTooltipPosition(null);
|
|
5761
|
+
setArrowOffset(null);
|
|
5762
|
+
return;
|
|
5763
|
+
}
|
|
5764
|
+
if (!wrapperRef.current || !tooltipRef.current) return;
|
|
5765
|
+
const {
|
|
5766
|
+
tooltipPosition: newPosition,
|
|
5767
|
+
arrowOffset: newArrowOffset
|
|
5768
|
+
} = getTooltipPosition(wrapperRef.current, tooltipRef.current, direction);
|
|
5769
|
+
setTooltipPosition(newPosition);
|
|
5770
|
+
setArrowOffset(newArrowOffset);
|
|
5771
|
+
}, [visible, position]);
|
|
5756
5772
|
const handleMouseLeave = ({
|
|
5757
5773
|
relatedTarget
|
|
5758
5774
|
}) => {
|
|
@@ -5788,12 +5804,14 @@ function Tooltip(props) {
|
|
|
5788
5804
|
e.code === 'Escape' && hide(false);
|
|
5789
5805
|
};
|
|
5790
5806
|
const renderTooltip = () => {
|
|
5807
|
+
const tooltipStyle = position || (tooltipPosition ? `right: ${tooltipPosition.right}; top: ${tooltipPosition.top}px;` : undefined);
|
|
5808
|
+
const arrowStyle = arrowOffset != null ? `margin-top: ${arrowOffset}px;` : undefined;
|
|
5791
5809
|
return jsxs("div", {
|
|
5792
5810
|
class: `bio-properties-panel-tooltip ${direction}`,
|
|
5793
5811
|
role: "tooltip",
|
|
5794
5812
|
id: "bio-properties-panel-tooltip",
|
|
5795
5813
|
"aria-labelledby": forId,
|
|
5796
|
-
style:
|
|
5814
|
+
style: tooltipStyle,
|
|
5797
5815
|
ref: tooltipRef,
|
|
5798
5816
|
onClick: e => e.stopPropagation(),
|
|
5799
5817
|
onMouseEnter: handleTooltipMouseEnter,
|
|
@@ -5802,7 +5820,8 @@ function Tooltip(props) {
|
|
|
5802
5820
|
class: "bio-properties-panel-tooltip-content",
|
|
5803
5821
|
children: value
|
|
5804
5822
|
}), jsx("div", {
|
|
5805
|
-
class: "bio-properties-panel-tooltip-arrow"
|
|
5823
|
+
class: "bio-properties-panel-tooltip-arrow",
|
|
5824
|
+
style: arrowStyle
|
|
5806
5825
|
})]
|
|
5807
5826
|
});
|
|
5808
5827
|
};
|
|
@@ -5821,11 +5840,47 @@ function Tooltip(props) {
|
|
|
5821
5840
|
|
|
5822
5841
|
// helper
|
|
5823
5842
|
|
|
5824
|
-
function getTooltipPosition(refElement) {
|
|
5843
|
+
function getTooltipPosition(refElement, tooltipElement, direction) {
|
|
5844
|
+
if (!refElement) {
|
|
5845
|
+
return {
|
|
5846
|
+
tooltipPosition: null,
|
|
5847
|
+
arrowOffset: null
|
|
5848
|
+
};
|
|
5849
|
+
}
|
|
5825
5850
|
const refPosition = refElement.getBoundingClientRect();
|
|
5826
5851
|
const right = `calc(100% - ${refPosition.x}px)`;
|
|
5827
|
-
|
|
5828
|
-
|
|
5852
|
+
let top = refPosition.top - 10;
|
|
5853
|
+
let arrowOffset = null;
|
|
5854
|
+
|
|
5855
|
+
// Ensure that the tooltip is within the viewport, adjust the top position if needed.
|
|
5856
|
+
// This is only relevant for the 'right' direction for now
|
|
5857
|
+
if (tooltipElement && direction === 'right') {
|
|
5858
|
+
const tooltipRect = tooltipElement.getBoundingClientRect();
|
|
5859
|
+
const viewportHeight = window.innerHeight;
|
|
5860
|
+
const minTop = 0;
|
|
5861
|
+
const maxTop = viewportHeight - tooltipRect.height;
|
|
5862
|
+
const originalTop = top;
|
|
5863
|
+
if (top > maxTop) {
|
|
5864
|
+
top = maxTop;
|
|
5865
|
+
}
|
|
5866
|
+
if (top < minTop) {
|
|
5867
|
+
top = minTop;
|
|
5868
|
+
}
|
|
5869
|
+
|
|
5870
|
+
// Adjust the arrow position if the tooltip had to be moved to stay within viewport
|
|
5871
|
+
if (top !== originalTop) {
|
|
5872
|
+
const defaultMarginTop = 16;
|
|
5873
|
+
const topDiff = top - originalTop;
|
|
5874
|
+
arrowOffset = defaultMarginTop - topDiff;
|
|
5875
|
+
}
|
|
5876
|
+
}
|
|
5877
|
+
return {
|
|
5878
|
+
tooltipPosition: {
|
|
5879
|
+
right,
|
|
5880
|
+
top
|
|
5881
|
+
},
|
|
5882
|
+
arrowOffset
|
|
5883
|
+
};
|
|
5829
5884
|
}
|
|
5830
5885
|
|
|
5831
5886
|
/**
|
|
@@ -6063,12 +6118,17 @@ function useStickyIntersectionObserver(ref, scrollContainerSelector, setSticky)
|
|
|
6063
6118
|
* The `callback` reference is static and can be safely used in external
|
|
6064
6119
|
* libraries or as a prop that does not cause rerendering of children.
|
|
6065
6120
|
*
|
|
6121
|
+
* The ref update is deferred to useLayoutEffect to prevent stale-closure
|
|
6122
|
+
* bugs when Chrome fires blur on elements removed during re-render.
|
|
6123
|
+
*
|
|
6066
6124
|
* @param {Function} callback function with changing reference
|
|
6067
6125
|
* @returns {Function} static function reference
|
|
6068
6126
|
*/
|
|
6069
6127
|
function useStaticCallback(callback) {
|
|
6070
6128
|
const callbackRef = useRef(callback);
|
|
6071
|
-
|
|
6129
|
+
useLayoutEffect(() => {
|
|
6130
|
+
callbackRef.current = callback;
|
|
6131
|
+
});
|
|
6072
6132
|
return useCallback((...args) => callbackRef.current(...args), []);
|
|
6073
6133
|
}
|
|
6074
6134
|
function useElementVisible(element) {
|
|
@@ -7324,7 +7384,7 @@ function ToggleSwitchEntry(props) {
|
|
|
7324
7384
|
inline: inline,
|
|
7325
7385
|
tooltip: tooltip,
|
|
7326
7386
|
element: element
|
|
7327
|
-
}), jsx(Description$1, {
|
|
7387
|
+
}, element), jsx(Description$1, {
|
|
7328
7388
|
forId: id,
|
|
7329
7389
|
element: element,
|
|
7330
7390
|
value: description
|
|
@@ -7497,7 +7557,7 @@ function prefixId$6(id) {
|
|
|
7497
7557
|
const noop$2 = () => {};
|
|
7498
7558
|
|
|
7499
7559
|
/**
|
|
7500
|
-
* @typedef {'required'|'optional'|'static'} FeelType
|
|
7560
|
+
* @typedef {'required'|'optional'|'optional-default-enabled'|'static'} FeelType
|
|
7501
7561
|
*/
|
|
7502
7562
|
|
|
7503
7563
|
/**
|
|
@@ -7540,7 +7600,7 @@ function FeelTextfield(props) {
|
|
|
7540
7600
|
OptionalComponent = OptionalFeelInput,
|
|
7541
7601
|
tooltip
|
|
7542
7602
|
} = props;
|
|
7543
|
-
const [localValue, setLocalValue] = useState(value);
|
|
7603
|
+
const [localValue, setLocalValue] = useState(getInitialFeelLocalValue(feel, value));
|
|
7544
7604
|
const editorRef = useShowEntryEvent(id);
|
|
7545
7605
|
const containerRef = useRef();
|
|
7546
7606
|
const onInput = useCallback(newValue => {
|
|
@@ -7549,8 +7609,8 @@ function FeelTextfield(props) {
|
|
|
7549
7609
|
const newModelValue = newValue === '' || newValue === '=' ? undefined : newValue;
|
|
7550
7610
|
commitValue(newModelValue);
|
|
7551
7611
|
}, [commitValue]);
|
|
7552
|
-
const feelActive =
|
|
7553
|
-
const feelOnlyValue =
|
|
7612
|
+
const feelActive = isFeelActive(feel, localValue);
|
|
7613
|
+
const feelOnlyValue = getFeelValue(localValue);
|
|
7554
7614
|
const feelLanguageContext = useContext(FeelLanguageContext);
|
|
7555
7615
|
const [focus, _setFocus] = useState(undefined);
|
|
7556
7616
|
const {
|
|
@@ -7613,7 +7673,7 @@ function FeelTextfield(props) {
|
|
|
7613
7673
|
};
|
|
7614
7674
|
const handleOnKeyDown = e => {
|
|
7615
7675
|
if (isCmdWithChar(e)) {
|
|
7616
|
-
handleInput.flush();
|
|
7676
|
+
handleInput.flush?.();
|
|
7617
7677
|
}
|
|
7618
7678
|
};
|
|
7619
7679
|
const handleLint = useStaticCallback((lint = []) => {
|
|
@@ -7737,7 +7797,7 @@ function FeelTextfield(props) {
|
|
|
7737
7797
|
ref: containerRef,
|
|
7738
7798
|
children: [jsx(FeelIndicator, {
|
|
7739
7799
|
active: feelActive,
|
|
7740
|
-
disabled: feel
|
|
7800
|
+
disabled: !isFeelOptional(feel) || disabled,
|
|
7741
7801
|
onClick: handleFeelToggle
|
|
7742
7802
|
}), feelActive ? jsx(FeelEditor, {
|
|
7743
7803
|
name: id,
|
|
@@ -8195,6 +8255,68 @@ function prefixId$5(id) {
|
|
|
8195
8255
|
return `bio-properties-panel-${id}`;
|
|
8196
8256
|
}
|
|
8197
8257
|
|
|
8258
|
+
/**
|
|
8259
|
+
* Determine if FEEL is optional for the configured {@link FeelType}.
|
|
8260
|
+
*
|
|
8261
|
+
* @param {FeelType} feelType
|
|
8262
|
+
*
|
|
8263
|
+
* @return {boolean}
|
|
8264
|
+
*/
|
|
8265
|
+
function isFeelOptional(feelType) {
|
|
8266
|
+
return feelType === 'optional' || feelType === 'optional-default-enabled';
|
|
8267
|
+
}
|
|
8268
|
+
|
|
8269
|
+
/**
|
|
8270
|
+
* Determine if FEEL editing is currently active.
|
|
8271
|
+
*
|
|
8272
|
+
* @param {FeelType} feelType
|
|
8273
|
+
* @param {string} localValue
|
|
8274
|
+
*
|
|
8275
|
+
* @return {boolean}
|
|
8276
|
+
*/
|
|
8277
|
+
function isFeelActive(feelType, localValue) {
|
|
8278
|
+
if (feelType === 'required') {
|
|
8279
|
+
return true;
|
|
8280
|
+
}
|
|
8281
|
+
if (isString(localValue)) {
|
|
8282
|
+
if (localValue.startsWith('=')) {
|
|
8283
|
+
return true;
|
|
8284
|
+
}
|
|
8285
|
+
}
|
|
8286
|
+
return false;
|
|
8287
|
+
}
|
|
8288
|
+
|
|
8289
|
+
/**
|
|
8290
|
+
* @template T
|
|
8291
|
+
* @param {T} value
|
|
8292
|
+
*
|
|
8293
|
+
* @return {string|T}
|
|
8294
|
+
*/
|
|
8295
|
+
function getFeelValue(value) {
|
|
8296
|
+
if (isString(value) && value.startsWith('=')) {
|
|
8297
|
+
return value.substring(1);
|
|
8298
|
+
}
|
|
8299
|
+
return value;
|
|
8300
|
+
}
|
|
8301
|
+
|
|
8302
|
+
/**
|
|
8303
|
+
* Initialize local FEEL value.
|
|
8304
|
+
*
|
|
8305
|
+
* `optional-default-enabled` starts in FEEL mode if no value or empty string is provided.
|
|
8306
|
+
*
|
|
8307
|
+
* @template T
|
|
8308
|
+
* @param {FeelType} feelType
|
|
8309
|
+
* @param {T} value
|
|
8310
|
+
*
|
|
8311
|
+
* @return {string|T}
|
|
8312
|
+
*/
|
|
8313
|
+
function getInitialFeelLocalValue(feelType, value) {
|
|
8314
|
+
if (feelType === 'optional-default-enabled' && (value === undefined || value === '')) {
|
|
8315
|
+
return '=';
|
|
8316
|
+
}
|
|
8317
|
+
return value;
|
|
8318
|
+
}
|
|
8319
|
+
|
|
8198
8320
|
/**
|
|
8199
8321
|
* @typedef { { value: string, label: string, disabled: boolean, children: { value: string, label: string, disabled: boolean } } } Option
|
|
8200
8322
|
*/
|
|
@@ -8445,7 +8567,7 @@ function TextArea(props) {
|
|
|
8445
8567
|
};
|
|
8446
8568
|
const handleOnKeyDown = e => {
|
|
8447
8569
|
if (isCmdWithChar(e)) {
|
|
8448
|
-
handleInput.flush();
|
|
8570
|
+
handleInput.flush?.();
|
|
8449
8571
|
}
|
|
8450
8572
|
};
|
|
8451
8573
|
useLayoutEffect(() => {
|
|
@@ -8660,7 +8782,7 @@ function Textfield(props) {
|
|
|
8660
8782
|
}, [value]);
|
|
8661
8783
|
const handleOnKeyDown = e => {
|
|
8662
8784
|
if (isCmdWithChar(e)) {
|
|
8663
|
-
handleInput.flush();
|
|
8785
|
+
handleInput.flush?.();
|
|
8664
8786
|
}
|
|
8665
8787
|
};
|
|
8666
8788
|
return jsxs("div", {
|
|
@@ -9028,6 +9150,7 @@ function Title(props) {
|
|
|
9028
9150
|
class: "bio-properties-panel-popup__title",
|
|
9029
9151
|
children: title
|
|
9030
9152
|
}), children, showCloseButton && jsx("button", {
|
|
9153
|
+
type: "button",
|
|
9031
9154
|
title: closeButtonTooltip,
|
|
9032
9155
|
class: "bio-properties-panel-popup__close",
|
|
9033
9156
|
onClick: onClose,
|
|
@@ -13800,7 +13923,7 @@ function CustomPropertiesGroup(field, editField) {
|
|
|
13800
13923
|
event.stopPropagation();
|
|
13801
13924
|
return editField(field, ['properties'], removeKey(properties, key));
|
|
13802
13925
|
};
|
|
13803
|
-
const id = `property-${
|
|
13926
|
+
const id = `property-${index}`;
|
|
13804
13927
|
return {
|
|
13805
13928
|
autoFocusEntry: id + '-key',
|
|
13806
13929
|
entries: CustomValueEntry({
|