@bpmn-io/properties-panel 3.28.2 → 3.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/properties-panel.css +8 -1
- package/dist/index.esm.js +83 -109
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +83 -109
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -819,13 +819,20 @@ textarea.bio-properties-panel-input {
|
|
|
819
819
|
}
|
|
820
820
|
|
|
821
821
|
.bio-properties-panel-list-entry-header {
|
|
822
|
-
position:
|
|
822
|
+
position: sticky;
|
|
823
823
|
overflow: hidden;
|
|
824
824
|
display: flex;
|
|
825
825
|
justify-content: space-between;
|
|
826
826
|
height: 32px;
|
|
827
827
|
}
|
|
828
828
|
|
|
829
|
+
.bio-properties-panel-list-entry-header.sticky {
|
|
830
|
+
background-color: var(--color-white);
|
|
831
|
+
border-bottom: 1px solid var(--sticky-group-bottom-border-color);
|
|
832
|
+
top: 32px;
|
|
833
|
+
z-index: 9;
|
|
834
|
+
}
|
|
835
|
+
|
|
829
836
|
/* Nested list dot */
|
|
830
837
|
.bio-properties-panel-list-entry::before {
|
|
831
838
|
content: "";
|
package/dist/index.esm.js
CHANGED
|
@@ -2143,6 +2143,50 @@ function prefixId$6(id) {
|
|
|
2143
2143
|
return `bio-properties-panel-${id}`;
|
|
2144
2144
|
}
|
|
2145
2145
|
|
|
2146
|
+
function TextInput({
|
|
2147
|
+
debounce,
|
|
2148
|
+
element,
|
|
2149
|
+
id,
|
|
2150
|
+
getValue,
|
|
2151
|
+
onBlur,
|
|
2152
|
+
setValue,
|
|
2153
|
+
validate,
|
|
2154
|
+
Component,
|
|
2155
|
+
...props
|
|
2156
|
+
}) {
|
|
2157
|
+
const modelValue = getValue(element);
|
|
2158
|
+
const setModelValue = useCallback((newValue, error) => {
|
|
2159
|
+
if (isFunction(validate)) {
|
|
2160
|
+
error = validate(newValue) || null;
|
|
2161
|
+
}
|
|
2162
|
+
setValue(newValue, error);
|
|
2163
|
+
}, [setValue, validate]);
|
|
2164
|
+
const debouncedSetValue = useDebounce(setModelValue, debounce);
|
|
2165
|
+
const handleInput = useCallback(newValue => {
|
|
2166
|
+
if (newValue !== modelValue) {
|
|
2167
|
+
debouncedSetValue(newValue);
|
|
2168
|
+
}
|
|
2169
|
+
}, [modelValue, debouncedSetValue]);
|
|
2170
|
+
const handleBlur = useCallback(value => {
|
|
2171
|
+
const newValue = value.trim?.() || value;
|
|
2172
|
+
if (newValue !== modelValue) {
|
|
2173
|
+
setModelValue(newValue);
|
|
2174
|
+
}
|
|
2175
|
+
if (isFunction(onBlur)) {
|
|
2176
|
+
onBlur(newValue);
|
|
2177
|
+
}
|
|
2178
|
+
}, [modelValue, setModelValue]);
|
|
2179
|
+
return jsx(Component, {
|
|
2180
|
+
...props,
|
|
2181
|
+
debounce: debounce,
|
|
2182
|
+
element: element,
|
|
2183
|
+
id: id,
|
|
2184
|
+
onInput: handleInput,
|
|
2185
|
+
onBlur: handleBlur,
|
|
2186
|
+
value: modelValue
|
|
2187
|
+
});
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2146
2190
|
const noop$2 = () => {};
|
|
2147
2191
|
|
|
2148
2192
|
/**
|
|
@@ -2171,7 +2215,6 @@ const noop$2 = () => {};
|
|
|
2171
2215
|
*/
|
|
2172
2216
|
function FeelTextfield(props) {
|
|
2173
2217
|
const {
|
|
2174
|
-
debounce,
|
|
2175
2218
|
id,
|
|
2176
2219
|
element,
|
|
2177
2220
|
label,
|
|
@@ -2206,16 +2249,11 @@ function FeelTextfield(props) {
|
|
|
2206
2249
|
const position = hasFocus ? document.activeElement.selectionStart : Infinity;
|
|
2207
2250
|
_setFocus(position + offset);
|
|
2208
2251
|
};
|
|
2209
|
-
|
|
2210
|
-
/**
|
|
2211
|
-
* @type { import('min-dash').DebouncedFunction }
|
|
2212
|
-
*/
|
|
2213
|
-
const handleInputCallback = useDebounce(onInput, debounce);
|
|
2214
2252
|
const handleInput = newValue => {
|
|
2215
2253
|
// we don't commit empty FEEL expressions,
|
|
2216
2254
|
// but instead serialize them as <undefined>
|
|
2217
2255
|
const newModelValue = newValue === '' || newValue === '=' ? undefined : newValue;
|
|
2218
|
-
|
|
2256
|
+
onInput(newModelValue);
|
|
2219
2257
|
};
|
|
2220
2258
|
const handleFeelToggle = useStaticCallback(() => {
|
|
2221
2259
|
if (feel === 'required') {
|
|
@@ -2243,14 +2281,8 @@ function FeelTextfield(props) {
|
|
|
2243
2281
|
setFocus(-1);
|
|
2244
2282
|
}
|
|
2245
2283
|
};
|
|
2246
|
-
const handleOnBlur =
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
// trim and commit on blur
|
|
2250
|
-
onInput(trimmedValue);
|
|
2251
|
-
if (onBlur) {
|
|
2252
|
-
onBlur(e);
|
|
2253
|
-
}
|
|
2284
|
+
const handleOnBlur = () => {
|
|
2285
|
+
onBlur?.(localValue);
|
|
2254
2286
|
};
|
|
2255
2287
|
const handleLint = useStaticCallback((lint = []) => {
|
|
2256
2288
|
const syntaxError = lint.some(report => report.type === 'Syntax Error');
|
|
@@ -2647,46 +2679,28 @@ function FeelEntry(props) {
|
|
|
2647
2679
|
placeholder,
|
|
2648
2680
|
tooltip
|
|
2649
2681
|
} = props;
|
|
2650
|
-
const [validationError, setValidationError] = useState(null);
|
|
2651
2682
|
const [localError, setLocalError] = useState(null);
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
if (isFunction(validate)) {
|
|
2655
|
-
const newValidationError = validate(value) || null;
|
|
2656
|
-
setValidationError(newValidationError);
|
|
2657
|
-
}
|
|
2658
|
-
}, [value, validate]);
|
|
2659
|
-
const onInput = useCallback(newValue => {
|
|
2660
|
-
const value = getValue(element);
|
|
2661
|
-
let newValidationError = null;
|
|
2662
|
-
if (isFunction(validate)) {
|
|
2663
|
-
newValidationError = validate(newValue) || null;
|
|
2664
|
-
}
|
|
2665
|
-
|
|
2666
|
-
// don't create multiple commandStack entries for the same value
|
|
2667
|
-
if (newValue !== value) {
|
|
2668
|
-
setValue(newValue, newValidationError);
|
|
2669
|
-
}
|
|
2670
|
-
setValidationError(newValidationError);
|
|
2671
|
-
}, [element, getValue, setValue, validate]);
|
|
2672
|
-
const onError = useCallback(err => {
|
|
2673
|
-
setLocalError(err);
|
|
2674
|
-
}, []);
|
|
2683
|
+
const value = getValue(element);
|
|
2684
|
+
const validationError = validate?.(value) || null;
|
|
2675
2685
|
const temporaryError = useError(id);
|
|
2676
2686
|
const error = temporaryError || localError || validationError;
|
|
2677
2687
|
return jsxs("div", {
|
|
2678
2688
|
class: classnames(props.class, 'bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
2679
2689
|
"data-entry-id": id,
|
|
2680
|
-
children: [createElement$1(
|
|
2690
|
+
children: [createElement$1(TextInput, {
|
|
2681
2691
|
...props,
|
|
2692
|
+
Component: FeelTextfield,
|
|
2693
|
+
element: element,
|
|
2694
|
+
getValue: getValue,
|
|
2682
2695
|
debounce: debounce,
|
|
2696
|
+
setValue: setValue,
|
|
2697
|
+
validate: validate,
|
|
2683
2698
|
disabled: disabled,
|
|
2684
2699
|
feel: feel,
|
|
2685
2700
|
id: id,
|
|
2686
2701
|
key: element,
|
|
2687
2702
|
label: label,
|
|
2688
|
-
|
|
2689
|
-
onError: onError,
|
|
2703
|
+
onError: setLocalError,
|
|
2690
2704
|
onFocus: onFocus,
|
|
2691
2705
|
onBlur: onBlur,
|
|
2692
2706
|
placeholder: placeholder,
|
|
@@ -3044,7 +3058,9 @@ function List(props) {
|
|
|
3044
3058
|
autoFocusEntry,
|
|
3045
3059
|
...restProps
|
|
3046
3060
|
} = props;
|
|
3061
|
+
const entryRef = useRef(null);
|
|
3047
3062
|
const [open, setOpen] = useState(!!shouldOpen);
|
|
3063
|
+
const [sticky, setSticky] = useState(false);
|
|
3048
3064
|
const hasItems = !!items.length;
|
|
3049
3065
|
const toggleOpen = () => hasItems && setOpen(!open);
|
|
3050
3066
|
const elementChanged = usePrevious(element) !== element;
|
|
@@ -3065,11 +3081,15 @@ function List(props) {
|
|
|
3065
3081
|
setOpen(true);
|
|
3066
3082
|
}
|
|
3067
3083
|
}
|
|
3084
|
+
|
|
3085
|
+
// set css class when entry is sticky to top
|
|
3086
|
+
useStickyIntersectionObserver(entryRef, 'div.bio-properties-panel-scroll-container', setSticky);
|
|
3068
3087
|
return jsxs("div", {
|
|
3069
3088
|
"data-entry-id": id,
|
|
3070
3089
|
class: classnames('bio-properties-panel-entry', 'bio-properties-panel-list-entry', hasItems ? '' : 'empty', open ? 'open' : ''),
|
|
3090
|
+
ref: entryRef,
|
|
3071
3091
|
children: [jsxs("div", {
|
|
3072
|
-
class:
|
|
3092
|
+
class: classnames('bio-properties-panel-list-entry-header', sticky && open ? 'sticky' : ''),
|
|
3073
3093
|
onClick: toggleOpen,
|
|
3074
3094
|
children: [jsx("div", {
|
|
3075
3095
|
title: label,
|
|
@@ -3428,14 +3448,8 @@ function TextArea(props) {
|
|
|
3428
3448
|
setLocalValue(e.target.value);
|
|
3429
3449
|
handleInput(e.target.value);
|
|
3430
3450
|
};
|
|
3431
|
-
const handleOnBlur =
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
// trim and commit on blur
|
|
3435
|
-
onInput(trimmedValue);
|
|
3436
|
-
if (onBlur) {
|
|
3437
|
-
onBlur(e);
|
|
3438
|
-
}
|
|
3451
|
+
const handleOnBlur = () => {
|
|
3452
|
+
onBlur?.(localValue);
|
|
3439
3453
|
};
|
|
3440
3454
|
useLayoutEffect(() => {
|
|
3441
3455
|
autoResize && resizeToContents(ref.current);
|
|
@@ -3513,35 +3527,21 @@ function TextAreaEntry(props) {
|
|
|
3513
3527
|
autoResize,
|
|
3514
3528
|
tooltip
|
|
3515
3529
|
} = props;
|
|
3530
|
+
const value = getValue(element);
|
|
3516
3531
|
const globalError = useError(id);
|
|
3517
|
-
const
|
|
3518
|
-
let value = getValue(element);
|
|
3519
|
-
useEffect(() => {
|
|
3520
|
-
if (isFunction(validate)) {
|
|
3521
|
-
const newValidationError = validate(value) || null;
|
|
3522
|
-
setLocalError(newValidationError);
|
|
3523
|
-
}
|
|
3524
|
-
}, [value, validate]);
|
|
3525
|
-
const onInput = useCallback(newValue => {
|
|
3526
|
-
const value = getValue(element);
|
|
3527
|
-
let newValidationError = null;
|
|
3528
|
-
if (isFunction(validate)) {
|
|
3529
|
-
newValidationError = validate(newValue) || null;
|
|
3530
|
-
}
|
|
3531
|
-
if (newValue !== value) {
|
|
3532
|
-
setValue(newValue, newValidationError);
|
|
3533
|
-
}
|
|
3534
|
-
setLocalError(newValidationError);
|
|
3535
|
-
}, [element, getValue, setValue, validate]);
|
|
3532
|
+
const localError = validate?.(value) || null;
|
|
3536
3533
|
const error = globalError || localError;
|
|
3537
3534
|
return jsxs("div", {
|
|
3538
3535
|
class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
3539
3536
|
"data-entry-id": id,
|
|
3540
|
-
children: [jsx(
|
|
3537
|
+
children: [jsx(TextInput, {
|
|
3538
|
+
Component: TextArea,
|
|
3539
|
+
getValue: getValue,
|
|
3540
|
+
setValue: setValue,
|
|
3541
|
+
validate: validate,
|
|
3541
3542
|
id: id,
|
|
3542
3543
|
label: label,
|
|
3543
3544
|
value: value,
|
|
3544
|
-
onInput: onInput,
|
|
3545
3545
|
onFocus: onFocus,
|
|
3546
3546
|
onBlur: onBlur,
|
|
3547
3547
|
rows: rows,
|
|
@@ -3574,7 +3574,6 @@ function prefixId$2(id) {
|
|
|
3574
3574
|
|
|
3575
3575
|
function Textfield(props) {
|
|
3576
3576
|
const {
|
|
3577
|
-
debounce,
|
|
3578
3577
|
disabled = false,
|
|
3579
3578
|
id,
|
|
3580
3579
|
label,
|
|
@@ -3587,23 +3586,12 @@ function Textfield(props) {
|
|
|
3587
3586
|
} = props;
|
|
3588
3587
|
const [localValue, setLocalValue] = useState(value || '');
|
|
3589
3588
|
const ref = useShowEntryEvent(id);
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
* @type { import('min-dash').DebouncedFunction }
|
|
3593
|
-
*/
|
|
3594
|
-
const handleInputCallback = useDebounce(onInput, debounce);
|
|
3595
|
-
const handleOnBlur = e => {
|
|
3596
|
-
const trimmedValue = e.target.value.trim();
|
|
3597
|
-
|
|
3598
|
-
// trim and commit on blur
|
|
3599
|
-
onInput(trimmedValue);
|
|
3600
|
-
if (onBlur) {
|
|
3601
|
-
onBlur(e);
|
|
3602
|
-
}
|
|
3589
|
+
const handleOnBlur = () => {
|
|
3590
|
+
onBlur?.(localValue);
|
|
3603
3591
|
};
|
|
3604
3592
|
const handleInput = newValue => {
|
|
3605
3593
|
const newModelValue = newValue === '' ? undefined : newValue;
|
|
3606
|
-
|
|
3594
|
+
onInput(newModelValue);
|
|
3607
3595
|
};
|
|
3608
3596
|
const handleLocalInput = e => {
|
|
3609
3597
|
if (e.target.value === localValue) {
|
|
@@ -3678,39 +3666,25 @@ function TextfieldEntry(props) {
|
|
|
3678
3666
|
placeholder,
|
|
3679
3667
|
tooltip
|
|
3680
3668
|
} = props;
|
|
3669
|
+
const value = getValue(element);
|
|
3681
3670
|
const globalError = useError(id);
|
|
3682
|
-
const
|
|
3683
|
-
let value = getValue(element);
|
|
3684
|
-
useEffect(() => {
|
|
3685
|
-
if (isFunction(validate)) {
|
|
3686
|
-
const newValidationError = validate(value) || null;
|
|
3687
|
-
setLocalError(newValidationError);
|
|
3688
|
-
}
|
|
3689
|
-
}, [value, validate]);
|
|
3690
|
-
const onInput = useCallback(newValue => {
|
|
3691
|
-
const value = getValue(element);
|
|
3692
|
-
let newValidationError = null;
|
|
3693
|
-
if (isFunction(validate)) {
|
|
3694
|
-
newValidationError = validate(newValue) || null;
|
|
3695
|
-
}
|
|
3696
|
-
if (newValue !== value) {
|
|
3697
|
-
setValue(newValue, newValidationError);
|
|
3698
|
-
}
|
|
3699
|
-
setLocalError(newValidationError);
|
|
3700
|
-
}, [element, getValue, setValue, validate]);
|
|
3671
|
+
const localError = validate?.(value) || null;
|
|
3701
3672
|
const error = globalError || localError;
|
|
3702
3673
|
return jsxs("div", {
|
|
3703
3674
|
class: classnames('bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
3704
3675
|
"data-entry-id": id,
|
|
3705
|
-
children: [jsx(
|
|
3676
|
+
children: [jsx(TextInput, {
|
|
3677
|
+
Component: Textfield,
|
|
3706
3678
|
debounce: debounce,
|
|
3707
3679
|
disabled: disabled,
|
|
3680
|
+
getValue: getValue,
|
|
3708
3681
|
id: id,
|
|
3709
3682
|
label: label,
|
|
3710
|
-
onInput: onInput,
|
|
3711
3683
|
onFocus: onFocus,
|
|
3712
3684
|
onBlur: onBlur,
|
|
3713
3685
|
placeholder: placeholder,
|
|
3686
|
+
setValue: setValue,
|
|
3687
|
+
validate: validate,
|
|
3714
3688
|
value: value,
|
|
3715
3689
|
tooltip: tooltip,
|
|
3716
3690
|
element: element
|
|
@@ -3734,7 +3708,7 @@ function prefixId$1(id) {
|
|
|
3734
3708
|
return `bio-properties-panel-${id}`;
|
|
3735
3709
|
}
|
|
3736
3710
|
|
|
3737
|
-
const DEFAULT_DEBOUNCE_TIME =
|
|
3711
|
+
const DEFAULT_DEBOUNCE_TIME = 600;
|
|
3738
3712
|
|
|
3739
3713
|
/**
|
|
3740
3714
|
* Creates a debounced version of a function, delaying its execution based on `debounceDelay`.
|