@bpmn-io/properties-panel 3.5.0 → 3.7.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 +119 -21
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +120 -21
- package/dist/index.js.map +1 -1
- package/package.json +4 -1
package/dist/index.esm.js
CHANGED
|
@@ -1132,6 +1132,7 @@ const noop$3 = () => {};
|
|
|
1132
1132
|
* @param {Object} props
|
|
1133
1133
|
* @param {HTMLElement} [props.container]
|
|
1134
1134
|
* @param {string} [props.className]
|
|
1135
|
+
* @param {boolean} [props.delayInitialFocus]
|
|
1135
1136
|
* @param {{x: number, y: number}} [props.position]
|
|
1136
1137
|
* @param {number} [props.width]
|
|
1137
1138
|
* @param {number} [props.height]
|
|
@@ -1139,12 +1140,14 @@ const noop$3 = () => {};
|
|
|
1139
1140
|
* @param {Function} [props.onPostActivate]
|
|
1140
1141
|
* @param {Function} [props.onPostDeactivate]
|
|
1141
1142
|
* @param {boolean} [props.returnFocus]
|
|
1143
|
+
* @param {boolean} [props.closeOnEscape]
|
|
1142
1144
|
* @param {string} props.title
|
|
1143
1145
|
*/
|
|
1144
1146
|
function Popup(props) {
|
|
1145
1147
|
const {
|
|
1146
1148
|
container,
|
|
1147
1149
|
className,
|
|
1150
|
+
delayInitialFocus,
|
|
1148
1151
|
position,
|
|
1149
1152
|
width,
|
|
1150
1153
|
height,
|
|
@@ -1152,12 +1155,15 @@ function Popup(props) {
|
|
|
1152
1155
|
onPostActivate = noop$3,
|
|
1153
1156
|
onPostDeactivate = noop$3,
|
|
1154
1157
|
returnFocus = true,
|
|
1158
|
+
closeOnEscape = true,
|
|
1155
1159
|
title
|
|
1156
1160
|
} = props;
|
|
1157
1161
|
const focusTrapRef = useRef(null);
|
|
1158
1162
|
const popupRef = useRef(null);
|
|
1159
|
-
const
|
|
1160
|
-
|
|
1163
|
+
const handleKeydown = event => {
|
|
1164
|
+
// do not allow keyboard events to bubble
|
|
1165
|
+
event.stopPropagation();
|
|
1166
|
+
if (closeOnEscape && event.key === 'Escape') {
|
|
1161
1167
|
onClose();
|
|
1162
1168
|
}
|
|
1163
1169
|
};
|
|
@@ -1182,14 +1188,6 @@ function Popup(props) {
|
|
|
1182
1188
|
if (height) {
|
|
1183
1189
|
style.height = height + 'px';
|
|
1184
1190
|
}
|
|
1185
|
-
useEffect(() => {
|
|
1186
|
-
if (popupRef.current) {
|
|
1187
|
-
popupRef.current.addEventListener('keydown', handleKeyPress);
|
|
1188
|
-
}
|
|
1189
|
-
return () => {
|
|
1190
|
-
popupRef.current.removeEventListener('keydown', handleKeyPress);
|
|
1191
|
-
};
|
|
1192
|
-
}, [popupRef]);
|
|
1193
1191
|
useEffect(() => {
|
|
1194
1192
|
if (popupRef.current) {
|
|
1195
1193
|
popupRef.current.addEventListener('focusin', handleFocus);
|
|
@@ -1202,6 +1200,7 @@ function Popup(props) {
|
|
|
1202
1200
|
if (popupRef.current) {
|
|
1203
1201
|
focusTrapRef.current = focusTrap.createFocusTrap(popupRef.current, {
|
|
1204
1202
|
clickOutsideDeactivates: true,
|
|
1203
|
+
delayInitialFocus,
|
|
1205
1204
|
fallbackFocus: popupRef.current,
|
|
1206
1205
|
onPostActivate,
|
|
1207
1206
|
onPostDeactivate,
|
|
@@ -1215,6 +1214,7 @@ function Popup(props) {
|
|
|
1215
1214
|
"aria-label": title,
|
|
1216
1215
|
tabIndex: -1,
|
|
1217
1216
|
ref: popupRef,
|
|
1217
|
+
onKeyDown: handleKeydown,
|
|
1218
1218
|
role: "dialog",
|
|
1219
1219
|
class: classnames('bio-properties-panel-popup', className),
|
|
1220
1220
|
style: style,
|
|
@@ -1329,6 +1329,11 @@ const FEEL_POPUP_HEIGHT = 250;
|
|
|
1329
1329
|
function FEELPopupRoot(props) {
|
|
1330
1330
|
const {
|
|
1331
1331
|
element,
|
|
1332
|
+
eventBus = {
|
|
1333
|
+
fire() {},
|
|
1334
|
+
on() {},
|
|
1335
|
+
off() {}
|
|
1336
|
+
},
|
|
1332
1337
|
popupContainer
|
|
1333
1338
|
} = props;
|
|
1334
1339
|
const prevElement = usePrevious(element);
|
|
@@ -1336,15 +1341,23 @@ function FEELPopupRoot(props) {
|
|
|
1336
1341
|
const [open, setOpen] = useState(false);
|
|
1337
1342
|
const [source, setSource] = useState(null);
|
|
1338
1343
|
const [sourceElement, setSourceElement] = useState(null);
|
|
1339
|
-
const
|
|
1340
|
-
|
|
1344
|
+
const emit = (type, context) => {
|
|
1345
|
+
eventBus.fire('feelPopup.' + type, context);
|
|
1346
|
+
};
|
|
1347
|
+
const isOpen = useCallback(() => {
|
|
1348
|
+
return !!open;
|
|
1349
|
+
}, [open]);
|
|
1350
|
+
const handleOpen = (entryId, config, _sourceElement) => {
|
|
1351
|
+
setSource(entryId);
|
|
1341
1352
|
setPopupConfig(config);
|
|
1342
1353
|
setOpen(true);
|
|
1343
1354
|
setSourceElement(_sourceElement);
|
|
1355
|
+
emit('opened');
|
|
1344
1356
|
};
|
|
1345
1357
|
const handleClose = () => {
|
|
1346
1358
|
setOpen(false);
|
|
1347
1359
|
setSource(null);
|
|
1360
|
+
emit('closed');
|
|
1348
1361
|
};
|
|
1349
1362
|
const feelPopupContext = {
|
|
1350
1363
|
open: handleOpen,
|
|
@@ -1354,10 +1367,33 @@ function FEELPopupRoot(props) {
|
|
|
1354
1367
|
|
|
1355
1368
|
// close popup on element change, cf. https://github.com/bpmn-io/properties-panel/issues/270
|
|
1356
1369
|
useEffect(() => {
|
|
1357
|
-
if (element && element !== prevElement) {
|
|
1370
|
+
if (element && prevElement && element !== prevElement) {
|
|
1358
1371
|
handleClose();
|
|
1359
1372
|
}
|
|
1360
1373
|
}, [element]);
|
|
1374
|
+
|
|
1375
|
+
// allow close and open via events
|
|
1376
|
+
useEffect(() => {
|
|
1377
|
+
const handlePopupOpen = context => {
|
|
1378
|
+
const {
|
|
1379
|
+
entryId,
|
|
1380
|
+
popupConfig,
|
|
1381
|
+
sourceElement
|
|
1382
|
+
} = context;
|
|
1383
|
+
handleOpen(entryId, popupConfig, sourceElement);
|
|
1384
|
+
};
|
|
1385
|
+
const handleIsOpen = () => {
|
|
1386
|
+
return isOpen();
|
|
1387
|
+
};
|
|
1388
|
+
eventBus.on('feelPopup._close', handleClose);
|
|
1389
|
+
eventBus.on('feelPopup._open', handlePopupOpen);
|
|
1390
|
+
eventBus.on('feelPopup._isOpen', handleIsOpen);
|
|
1391
|
+
return () => {
|
|
1392
|
+
eventBus.off('feelPopup._close', handleClose);
|
|
1393
|
+
eventBus.off('feelPopup._open', handleOpen);
|
|
1394
|
+
eventBus.off('feelPopup._isOpen', handleIsOpen);
|
|
1395
|
+
};
|
|
1396
|
+
}, [eventBus, isOpen]);
|
|
1361
1397
|
return jsxs(FeelPopupContext.Provider, {
|
|
1362
1398
|
value: feelPopupContext,
|
|
1363
1399
|
children: [open && jsx(FeelPopupComponent, {
|
|
@@ -1385,15 +1421,28 @@ function FeelPopupComponent(props) {
|
|
|
1385
1421
|
variables
|
|
1386
1422
|
} = props;
|
|
1387
1423
|
const editorRef = useRef();
|
|
1424
|
+
const isAutoCompletionOpen = useRef(false);
|
|
1388
1425
|
const handleSetReturnFocus = () => {
|
|
1389
1426
|
sourceElement && sourceElement.focus();
|
|
1390
1427
|
};
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
if (
|
|
1394
|
-
|
|
1428
|
+
const onKeyDownCapture = event => {
|
|
1429
|
+
// we use capture here to make sure we handle the event before the editor does
|
|
1430
|
+
if (event.key === 'Escape') {
|
|
1431
|
+
isAutoCompletionOpen.current = autoCompletionOpen(event.target);
|
|
1432
|
+
}
|
|
1433
|
+
};
|
|
1434
|
+
const onKeyDown = event => {
|
|
1435
|
+
if (event.key === 'Escape') {
|
|
1436
|
+
// close popup only if auto completion is not open
|
|
1437
|
+
// we need to do check this because the editor is not
|
|
1438
|
+
// stop propagating the keydown event
|
|
1439
|
+
// cf. https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322/5
|
|
1440
|
+
if (!isAutoCompletionOpen.current) {
|
|
1441
|
+
onClose();
|
|
1442
|
+
isAutoCompletionOpen.current = false;
|
|
1443
|
+
}
|
|
1395
1444
|
}
|
|
1396
|
-
}
|
|
1445
|
+
};
|
|
1397
1446
|
return jsxs(Popup, {
|
|
1398
1447
|
container: container,
|
|
1399
1448
|
className: "bio-properties-panel-feel-popup",
|
|
@@ -1404,6 +1453,8 @@ function FeelPopupComponent(props) {
|
|
|
1404
1453
|
// handle focus manually on deactivate
|
|
1405
1454
|
,
|
|
1406
1455
|
returnFocus: false,
|
|
1456
|
+
closeOnEscape: false,
|
|
1457
|
+
delayInitialFocus: false,
|
|
1407
1458
|
onPostDeactivate: handleSetReturnFocus,
|
|
1408
1459
|
height: FEEL_POPUP_HEIGHT,
|
|
1409
1460
|
width: FEEL_POPUP_WIDTH,
|
|
@@ -1412,6 +1463,8 @@ function FeelPopupComponent(props) {
|
|
|
1412
1463
|
draggable: true
|
|
1413
1464
|
}), jsx(Popup.Body, {
|
|
1414
1465
|
children: jsxs("div", {
|
|
1466
|
+
onKeyDownCapture: onKeyDownCapture,
|
|
1467
|
+
onKeyDown: onKeyDown,
|
|
1415
1468
|
class: "bio-properties-panel-feel-popup__body",
|
|
1416
1469
|
children: [type === 'feel' && jsx(CodeEditor, {
|
|
1417
1470
|
enableGutters: true,
|
|
@@ -1453,6 +1506,9 @@ function FeelPopupComponent(props) {
|
|
|
1453
1506
|
function prefixId$8(id) {
|
|
1454
1507
|
return `bio-properties-panel-${id}`;
|
|
1455
1508
|
}
|
|
1509
|
+
function autoCompletionOpen(element) {
|
|
1510
|
+
return element.closest('.cm-editor').querySelector('.cm-tooltip-autocomplete');
|
|
1511
|
+
}
|
|
1456
1512
|
|
|
1457
1513
|
function ToggleSwitch(props) {
|
|
1458
1514
|
const {
|
|
@@ -2202,7 +2258,7 @@ function FeelEntry(props) {
|
|
|
2202
2258
|
setLocalError(err);
|
|
2203
2259
|
}, []);
|
|
2204
2260
|
const temporaryError = useError(id);
|
|
2205
|
-
const error =
|
|
2261
|
+
const error = temporaryError || localError || validationError;
|
|
2206
2262
|
return jsxs("div", {
|
|
2207
2263
|
class: classnames(props.class, 'bio-properties-panel-entry', error ? 'has-error' : ''),
|
|
2208
2264
|
"data-entry-id": id,
|
|
@@ -2611,6 +2667,7 @@ function PropertiesPanel(props) {
|
|
|
2611
2667
|
value: eventContext,
|
|
2612
2668
|
children: jsx(FEELPopupRoot, {
|
|
2613
2669
|
element: element,
|
|
2670
|
+
eventBus: eventBus,
|
|
2614
2671
|
popupContainer: feelPopupContainer,
|
|
2615
2672
|
children: jsxs("div", {
|
|
2616
2673
|
class: "bio-properties-panel",
|
|
@@ -4076,9 +4133,50 @@ function debounceInput(debounceDelay) {
|
|
|
4076
4133
|
}
|
|
4077
4134
|
debounceInput.$inject = ['config.debounceInput'];
|
|
4078
4135
|
|
|
4079
|
-
var index = {
|
|
4136
|
+
var index$1 = {
|
|
4080
4137
|
debounceInput: ['factory', debounceInput]
|
|
4081
4138
|
};
|
|
4082
4139
|
|
|
4083
|
-
|
|
4140
|
+
class FeelPopupModule {
|
|
4141
|
+
constructor(eventBus) {
|
|
4142
|
+
this._eventBus = eventBus;
|
|
4143
|
+
}
|
|
4144
|
+
|
|
4145
|
+
/**
|
|
4146
|
+
* Check if the FEEL popup is open.
|
|
4147
|
+
* @return {Boolean}
|
|
4148
|
+
*/
|
|
4149
|
+
isOpen() {
|
|
4150
|
+
return this._eventBus.fire('feelPopup._isOpen');
|
|
4151
|
+
}
|
|
4152
|
+
|
|
4153
|
+
/**
|
|
4154
|
+
* Open the FEEL popup.
|
|
4155
|
+
*
|
|
4156
|
+
* @param {String} entryId
|
|
4157
|
+
* @param {Object} popupConfig
|
|
4158
|
+
* @param {HTMLElement} sourceElement
|
|
4159
|
+
*/
|
|
4160
|
+
open(entryId, popupConfig, sourceElement) {
|
|
4161
|
+
return this._eventBus.fire('feelPopup._open', {
|
|
4162
|
+
entryId,
|
|
4163
|
+
popupConfig,
|
|
4164
|
+
sourceElement
|
|
4165
|
+
});
|
|
4166
|
+
}
|
|
4167
|
+
|
|
4168
|
+
/**
|
|
4169
|
+
* Close the FEEL popup.
|
|
4170
|
+
*/
|
|
4171
|
+
close() {
|
|
4172
|
+
return this._eventBus.fire('feelPopup._close');
|
|
4173
|
+
}
|
|
4174
|
+
}
|
|
4175
|
+
FeelPopupModule.$inject = ['eventBus'];
|
|
4176
|
+
|
|
4177
|
+
var index = {
|
|
4178
|
+
feelPopup: ['type', FeelPopupModule]
|
|
4179
|
+
};
|
|
4180
|
+
|
|
4181
|
+
export { ArrowIcon, CheckboxEntry, CollapsibleEntry, CreateIcon, index$1 as DebounceInputModule, DeleteIcon, DescriptionContext, Description as DescriptionEntry, DragIcon, DropdownButton, ErrorsContext, EventContext, ExternalLinkIcon, FeelCheckboxEntry, FeelEntry, FeelIcon$1 as FeelIcon, FeelNumberEntry, index as FeelPopupModule, FeelTemplatingEntry, FeelTextAreaEntry, FeelToggleSwitchEntry, Group, Header, HeaderButton, LayoutContext, List as ListEntry, ListGroup, ListItem, NumberFieldEntry, Placeholder, Popup, PropertiesPanel, LayoutContext as PropertiesPanelContext, SelectEntry, Simple as SimpleEntry, TemplatingEntry, TextAreaEntry, TextfieldEntry as TextFieldEntry, ToggleSwitchEntry, TooltipContext, isEdited$5 as isCheckboxEntryEdited, isEdited$6 as isFeelEntryEdited, isEdited$7 as isNumberFieldEntryEdited, isEdited$3 as isSelectEntryEdited, isEdited$2 as isSimpleEntryEdited, isEdited$4 as isTemplatingEntryEdited, isEdited$1 as isTextAreaEntryEdited, isEdited as isTextFieldEntryEdited, isEdited$8 as isToggleSwitchEntryEdited, useDescriptionContext, useError, useErrors, useEvent, useKeyFactory, useLayoutState, usePrevious, useShowEntryEvent, useStaticCallback, useStickyIntersectionObserver, useTooltipContext };
|
|
4084
4182
|
//# sourceMappingURL=index.esm.js.map
|