@bpmn-io/properties-panel 3.18.1 → 3.19.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/index.esm.js +48 -134
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +47 -133
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useContext, useState, useRef, useEffect, useMemo, useCallback, useLayoutEffect } from '../preact/hooks';
|
|
2
|
-
import { isFunction, isString, isArray, get, assign, set,
|
|
2
|
+
import { isFunction, isString, isArray, get, assign, set, isNumber, debounce } from 'min-dash';
|
|
3
3
|
import { createPortal, forwardRef } from '../preact/compat';
|
|
4
4
|
import { jsx, jsxs, Fragment } from '../preact/jsx-runtime';
|
|
5
5
|
import { createContext, createElement } from '../preact';
|
|
@@ -967,6 +967,7 @@ const useBufferedFocus = function (editor, ref) {
|
|
|
967
967
|
};
|
|
968
968
|
const CodeEditor = forwardRef((props, ref) => {
|
|
969
969
|
const {
|
|
970
|
+
contentAttributes,
|
|
970
971
|
enableGutters,
|
|
971
972
|
value,
|
|
972
973
|
onInput,
|
|
@@ -1012,7 +1013,8 @@ const CodeEditor = forwardRef((props, ref) => {
|
|
|
1012
1013
|
tooltipContainer: tooltipContainer,
|
|
1013
1014
|
value: localValue,
|
|
1014
1015
|
variables: variables,
|
|
1015
|
-
extensions: [...(enableGutters ? [lineNumbers()] : []), EditorView.lineWrapping]
|
|
1016
|
+
extensions: [...(enableGutters ? [lineNumbers()] : []), EditorView.lineWrapping],
|
|
1017
|
+
contentAttributes
|
|
1016
1018
|
});
|
|
1017
1019
|
setEditor(editor);
|
|
1018
1020
|
return () => {
|
|
@@ -2102,9 +2104,12 @@ function FeelTextfieldComponent(props) {
|
|
|
2102
2104
|
disabled: feel !== 'optional' || disabled,
|
|
2103
2105
|
onClick: handleFeelToggle
|
|
2104
2106
|
}), feelActive ? jsx(CodeEditor, {
|
|
2105
|
-
id: prefixId$5(id),
|
|
2106
2107
|
name: id,
|
|
2107
2108
|
onInput: handleLocalInput,
|
|
2109
|
+
contentAttributes: {
|
|
2110
|
+
'id': prefixId$5(id),
|
|
2111
|
+
'aria-label': label
|
|
2112
|
+
},
|
|
2108
2113
|
disabled: disabled,
|
|
2109
2114
|
popupOpen: popuOpen,
|
|
2110
2115
|
onFeelToggle: () => {
|
|
@@ -2661,7 +2666,6 @@ const DEFAULT_TOOLTIP = {};
|
|
|
2661
2666
|
* id: String,
|
|
2662
2667
|
* items: Array<ListItemDefinition>,
|
|
2663
2668
|
* label: String,
|
|
2664
|
-
* shouldSort?: Boolean,
|
|
2665
2669
|
* shouldOpen?: Boolean
|
|
2666
2670
|
* } } ListGroupDefinition
|
|
2667
2671
|
*
|
|
@@ -3094,6 +3098,7 @@ function ListItem(props) {
|
|
|
3094
3098
|
} else if (isFunction(focusableInput.focus)) {
|
|
3095
3099
|
focusableInput.focus();
|
|
3096
3100
|
}
|
|
3101
|
+
focusableInput.scrollIntoView();
|
|
3097
3102
|
}
|
|
3098
3103
|
}
|
|
3099
3104
|
}, [autoOpen, autoFocusEntry]);
|
|
@@ -3118,97 +3123,61 @@ function ListGroup(props) {
|
|
|
3118
3123
|
id,
|
|
3119
3124
|
items,
|
|
3120
3125
|
label,
|
|
3121
|
-
shouldOpen = true
|
|
3122
|
-
shouldSort = true
|
|
3126
|
+
shouldOpen = true
|
|
3123
3127
|
} = props;
|
|
3128
|
+
useEffect(() => {
|
|
3129
|
+
if (props.shouldSort != undefined) {
|
|
3130
|
+
console.warn('the property \'shouldSort\' is no longer supported');
|
|
3131
|
+
}
|
|
3132
|
+
}, [props.shouldSort]);
|
|
3124
3133
|
const groupRef = useRef(null);
|
|
3125
3134
|
const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
|
|
3126
3135
|
const [sticky, setSticky] = useState(false);
|
|
3127
3136
|
const onShow = useCallback(() => setOpen(true), [setOpen]);
|
|
3128
|
-
const [
|
|
3129
|
-
const [
|
|
3137
|
+
const [localItems, setLocalItems] = useState([]);
|
|
3138
|
+
const [newlyAddedItemIds, setNewlyAddedItemIds] = useState([]);
|
|
3130
3139
|
|
|
3131
3140
|
// Flag to mark that add button was clicked in the last render cycle
|
|
3132
3141
|
const [addTriggered, setAddTriggered] = useState(false);
|
|
3133
|
-
const prevItems = usePrevious(items);
|
|
3134
3142
|
const prevElement = usePrevious(element);
|
|
3135
3143
|
const elementChanged = element !== prevElement;
|
|
3136
|
-
const shouldHandleEffects = !elementChanged &&
|
|
3137
|
-
|
|
3138
|
-
//
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
//
|
|
3144
|
-
|
|
3145
|
-
// (0) set initial ordering from given items
|
|
3144
|
+
const shouldHandleEffects = !elementChanged && shouldOpen;
|
|
3145
|
+
|
|
3146
|
+
// (0) delay setting items
|
|
3147
|
+
//
|
|
3148
|
+
// We need to this to align the render cycles of items
|
|
3149
|
+
// with the detection of newly added items.
|
|
3150
|
+
// This is important, because the autoOpen property can
|
|
3151
|
+
// only set per list item on its very first render.
|
|
3146
3152
|
useEffect(() => {
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
}
|
|
3150
|
-
}, [items, element]);
|
|
3153
|
+
setLocalItems(items);
|
|
3154
|
+
}, [items]);
|
|
3151
3155
|
|
|
3152
|
-
// (1) items were added
|
|
3156
|
+
// (1) handle auto opening when items were added
|
|
3153
3157
|
useEffect(() => {
|
|
3154
3158
|
// reset addTriggered flag
|
|
3155
3159
|
setAddTriggered(false);
|
|
3156
|
-
if (shouldHandleEffects &&
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3160
|
+
if (shouldHandleEffects && localItems) {
|
|
3161
|
+
if (addTriggered) {
|
|
3162
|
+
const previousItemIds = localItems.map(item => item.id);
|
|
3163
|
+
const currentItemsIds = items.map(item => item.id);
|
|
3164
|
+
const newItemIds = currentItemsIds.filter(itemId => !previousItemIds.includes(itemId));
|
|
3165
|
+
|
|
3166
|
+
// open if not open, configured and triggered by add button
|
|
3167
|
+
//
|
|
3168
|
+
// TODO(marstamm): remove once we refactor layout handling for listGroups.
|
|
3169
|
+
// Ideally, opening should be handled as part of the `add` callback and
|
|
3170
|
+
// not be a concern for the ListGroup component.
|
|
3171
|
+
if (!open && shouldOpen && newItemIds.length > 0) {
|
|
3172
|
+
toggleOpen();
|
|
3161
3173
|
}
|
|
3162
|
-
|
|
3163
|
-
let newOrdering = ordering;
|
|
3164
|
-
|
|
3165
|
-
// open if not open, configured and triggered by add button
|
|
3166
|
-
//
|
|
3167
|
-
// TODO(marstamm): remove once we refactor layout handling for listGroups.
|
|
3168
|
-
// Ideally, opening should be handled as part of the `add` callback and
|
|
3169
|
-
// not be a concern for the ListGroup component.
|
|
3170
|
-
if (addTriggered && !open && shouldOpen) {
|
|
3171
|
-
toggleOpen();
|
|
3172
|
-
}
|
|
3173
|
-
|
|
3174
|
-
// filter when not open and configured
|
|
3175
|
-
if (!open && shouldSort) {
|
|
3176
|
-
newOrdering = createOrdering(sortItems(items));
|
|
3177
|
-
}
|
|
3178
|
-
|
|
3179
|
-
// add new items on top or bottom depending on sorting behavior
|
|
3180
|
-
newOrdering = newOrdering.filter(item => !add.includes(item));
|
|
3181
|
-
if (shouldSort) {
|
|
3182
|
-
newOrdering.unshift(...add);
|
|
3174
|
+
setNewlyAddedItemIds(newItemIds);
|
|
3183
3175
|
} else {
|
|
3184
|
-
|
|
3176
|
+
// ignore newly added items that do not result from a triggered add
|
|
3177
|
+
setNewlyAddedItemIds([]);
|
|
3185
3178
|
}
|
|
3186
|
-
setOrdering(newOrdering);
|
|
3187
|
-
setNewItemAdded(addTriggered);
|
|
3188
|
-
} else {
|
|
3189
|
-
setNewItemAdded(false);
|
|
3190
|
-
}
|
|
3191
|
-
}, [items, open, shouldHandleEffects, addTriggered]);
|
|
3192
|
-
|
|
3193
|
-
// (2) sort items on open if shouldSort is set
|
|
3194
|
-
useEffect(() => {
|
|
3195
|
-
if (shouldSort && open && !newItemAdded) {
|
|
3196
|
-
setOrdering(createOrdering(sortItems(items)));
|
|
3197
|
-
}
|
|
3198
|
-
}, [open, shouldSort]);
|
|
3199
|
-
|
|
3200
|
-
// (3) items were deleted
|
|
3201
|
-
useEffect(() => {
|
|
3202
|
-
if (shouldHandleEffects && prevItems && items.length < prevItems.length) {
|
|
3203
|
-
let keep = [];
|
|
3204
|
-
ordering.forEach(o => {
|
|
3205
|
-
if (getItem(items, o)) {
|
|
3206
|
-
keep.push(o);
|
|
3207
|
-
}
|
|
3208
|
-
});
|
|
3209
|
-
setOrdering(keep);
|
|
3210
3179
|
}
|
|
3211
|
-
}, [items, shouldHandleEffects]);
|
|
3180
|
+
}, [items, open, shouldHandleEffects, addTriggered, localItems]);
|
|
3212
3181
|
|
|
3213
3182
|
// set css class when group is sticky to top
|
|
3214
3183
|
useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
|
|
@@ -3280,8 +3249,7 @@ function ListGroup(props) {
|
|
|
3280
3249
|
class: classnames('bio-properties-panel-list', open && hasItems ? 'open' : ''),
|
|
3281
3250
|
children: jsx(LayoutContext.Provider, {
|
|
3282
3251
|
value: propertiesPanelContext,
|
|
3283
|
-
children:
|
|
3284
|
-
const item = getItem(items, o);
|
|
3252
|
+
children: localItems.map((item, index) => {
|
|
3285
3253
|
if (!item) {
|
|
3286
3254
|
return;
|
|
3287
3255
|
}
|
|
@@ -3291,7 +3259,7 @@ function ListGroup(props) {
|
|
|
3291
3259
|
|
|
3292
3260
|
// if item was added, open it
|
|
3293
3261
|
// Existing items will not be affected as autoOpen is only applied on first render
|
|
3294
|
-
const autoOpen =
|
|
3262
|
+
const autoOpen = newlyAddedItemIds.includes(item.id);
|
|
3295
3263
|
return createElement(ListItem, {
|
|
3296
3264
|
...item,
|
|
3297
3265
|
autoOpen: autoOpen,
|
|
@@ -3305,21 +3273,6 @@ function ListGroup(props) {
|
|
|
3305
3273
|
});
|
|
3306
3274
|
}
|
|
3307
3275
|
|
|
3308
|
-
// helpers ////////////////////
|
|
3309
|
-
|
|
3310
|
-
/**
|
|
3311
|
-
* Sorts given items alphanumeric by label
|
|
3312
|
-
*/
|
|
3313
|
-
function sortItems(items) {
|
|
3314
|
-
return sortBy(items, i => i.label.toLowerCase());
|
|
3315
|
-
}
|
|
3316
|
-
function getItem(items, id) {
|
|
3317
|
-
return find(items, i => i.id === id);
|
|
3318
|
-
}
|
|
3319
|
-
function createOrdering(items) {
|
|
3320
|
-
return items.map(i => i.id);
|
|
3321
|
-
}
|
|
3322
|
-
|
|
3323
3276
|
function Checkbox(props) {
|
|
3324
3277
|
const {
|
|
3325
3278
|
id,
|
|
@@ -3611,16 +3564,12 @@ function List(props) {
|
|
|
3611
3564
|
onAdd,
|
|
3612
3565
|
onRemove,
|
|
3613
3566
|
autoFocusEntry,
|
|
3614
|
-
compareFn,
|
|
3615
3567
|
...restProps
|
|
3616
3568
|
} = props;
|
|
3617
3569
|
const [open, setOpen] = useState(!!shouldOpen);
|
|
3618
3570
|
const hasItems = !!items.length;
|
|
3619
3571
|
const toggleOpen = () => hasItems && setOpen(!open);
|
|
3620
|
-
const opening = !usePrevious(open) && open;
|
|
3621
3572
|
const elementChanged = usePrevious(element) !== element;
|
|
3622
|
-
const shouldReset = opening || elementChanged;
|
|
3623
|
-
const sortedItems = useSortedItems(items, compareFn, shouldReset);
|
|
3624
3573
|
const newItems = useNewItems(items, elementChanged);
|
|
3625
3574
|
useEffect(() => {
|
|
3626
3575
|
if (open && !hasItems) {
|
|
@@ -3678,7 +3627,7 @@ function List(props) {
|
|
|
3678
3627
|
component: component,
|
|
3679
3628
|
element: element,
|
|
3680
3629
|
id: id,
|
|
3681
|
-
items:
|
|
3630
|
+
items: items,
|
|
3682
3631
|
newItems: newItems,
|
|
3683
3632
|
onRemove: onRemove,
|
|
3684
3633
|
open: open
|
|
@@ -3742,41 +3691,6 @@ function ItemsList(props) {
|
|
|
3742
3691
|
})
|
|
3743
3692
|
});
|
|
3744
3693
|
}
|
|
3745
|
-
|
|
3746
|
-
/**
|
|
3747
|
-
* Place new items in the beginning of the list and sort the rest with provided function.
|
|
3748
|
-
*
|
|
3749
|
-
* @template Item
|
|
3750
|
-
* @param {Item[]} currentItems
|
|
3751
|
-
* @param {(a: Item, b: Item) => 0 | 1 | -1} [compareFn] function used to sort items
|
|
3752
|
-
* @param {boolean} [shouldReset=false] set to `true` to reset state of the hook
|
|
3753
|
-
* @returns {Item[]}
|
|
3754
|
-
*/
|
|
3755
|
-
function useSortedItems(currentItems, compareFn, shouldReset = false) {
|
|
3756
|
-
const itemsRef = useRef(currentItems.slice());
|
|
3757
|
-
|
|
3758
|
-
// (1) Reset and optionally sort.
|
|
3759
|
-
if (shouldReset) {
|
|
3760
|
-
itemsRef.current = currentItems.slice();
|
|
3761
|
-
if (compareFn) {
|
|
3762
|
-
itemsRef.current.sort(compareFn);
|
|
3763
|
-
}
|
|
3764
|
-
} else {
|
|
3765
|
-
const items = itemsRef.current;
|
|
3766
|
-
|
|
3767
|
-
// (2) Add new item to the list.
|
|
3768
|
-
for (const item of currentItems) {
|
|
3769
|
-
if (!items.includes(item)) {
|
|
3770
|
-
// Unshift or push depending on whether we have a compareFn
|
|
3771
|
-
compareFn ? items.unshift(item) : items.push(item);
|
|
3772
|
-
}
|
|
3773
|
-
}
|
|
3774
|
-
|
|
3775
|
-
// (3) Filter out removed items.
|
|
3776
|
-
itemsRef.current = items.filter(item => currentItems.includes(item));
|
|
3777
|
-
}
|
|
3778
|
-
return itemsRef.current;
|
|
3779
|
-
}
|
|
3780
3694
|
function useNewItems(items = [], shouldReset) {
|
|
3781
3695
|
const previousItems = usePrevious(items.slice()) || [];
|
|
3782
3696
|
if (shouldReset) {
|