@bpmn-io/properties-panel 3.5.0 → 3.6.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 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 handleKeyPress = event => {
1160
- if (event.key === 'Escape') {
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,
@@ -1385,15 +1385,28 @@ function FeelPopupComponent(props) {
1385
1385
  variables
1386
1386
  } = props;
1387
1387
  const editorRef = useRef();
1388
+ const isAutoCompletionOpen = useRef(false);
1388
1389
  const handleSetReturnFocus = () => {
1389
1390
  sourceElement && sourceElement.focus();
1390
1391
  };
1391
- useEffect(() => {
1392
- const editor = editorRef.current;
1393
- if (editor) {
1394
- editor.focus();
1392
+ const onKeyDownCapture = event => {
1393
+ // we use capture here to make sure we handle the event before the editor does
1394
+ if (event.key === 'Escape') {
1395
+ isAutoCompletionOpen.current = autoCompletionOpen(event.target);
1396
+ }
1397
+ };
1398
+ const onKeyDown = event => {
1399
+ if (event.key === 'Escape') {
1400
+ // close popup only if auto completion is not open
1401
+ // we need to do check this because the editor is not
1402
+ // stop propagating the keydown event
1403
+ // cf. https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322/5
1404
+ if (!isAutoCompletionOpen.current) {
1405
+ onClose();
1406
+ isAutoCompletionOpen.current = false;
1407
+ }
1395
1408
  }
1396
- }, [editorRef, id]);
1409
+ };
1397
1410
  return jsxs(Popup, {
1398
1411
  container: container,
1399
1412
  className: "bio-properties-panel-feel-popup",
@@ -1404,6 +1417,8 @@ function FeelPopupComponent(props) {
1404
1417
  // handle focus manually on deactivate
1405
1418
  ,
1406
1419
  returnFocus: false,
1420
+ closeOnEscape: false,
1421
+ delayInitialFocus: false,
1407
1422
  onPostDeactivate: handleSetReturnFocus,
1408
1423
  height: FEEL_POPUP_HEIGHT,
1409
1424
  width: FEEL_POPUP_WIDTH,
@@ -1412,6 +1427,8 @@ function FeelPopupComponent(props) {
1412
1427
  draggable: true
1413
1428
  }), jsx(Popup.Body, {
1414
1429
  children: jsxs("div", {
1430
+ onKeyDownCapture: onKeyDownCapture,
1431
+ onKeyDown: onKeyDown,
1415
1432
  class: "bio-properties-panel-feel-popup__body",
1416
1433
  children: [type === 'feel' && jsx(CodeEditor, {
1417
1434
  enableGutters: true,
@@ -1453,6 +1470,9 @@ function FeelPopupComponent(props) {
1453
1470
  function prefixId$8(id) {
1454
1471
  return `bio-properties-panel-${id}`;
1455
1472
  }
1473
+ function autoCompletionOpen(element) {
1474
+ return element.closest('.cm-editor').querySelector('.cm-tooltip-autocomplete');
1475
+ }
1456
1476
 
1457
1477
  function ToggleSwitch(props) {
1458
1478
  const {
@@ -2202,7 +2222,7 @@ function FeelEntry(props) {
2202
2222
  setLocalError(err);
2203
2223
  }, []);
2204
2224
  const temporaryError = useError(id);
2205
- const error = localError || temporaryError || validationError;
2225
+ const error = temporaryError || localError || validationError;
2206
2226
  return jsxs("div", {
2207
2227
  class: classnames(props.class, 'bio-properties-panel-entry', error ? 'has-error' : ''),
2208
2228
  "data-entry-id": id,