@bpmn-io/form-js-editor 1.10.0 → 1.10.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/index.es.js CHANGED
@@ -10,7 +10,7 @@ import * as React from 'preact/compat';
10
10
  import { createPortal, useRef as useRef$1, useContext as useContext$1, useEffect as useEffect$1, forwardRef } from 'preact/compat';
11
11
  import dragula from '@bpmn-io/draggle';
12
12
  import { classes, query, closest, event, matches, domify } from 'min-dom';
13
- import { mutate } from 'array-move';
13
+ import { arrayMoveMutable } from 'array-move';
14
14
  import { FeelersEditor } from 'feelers';
15
15
  import FeelEditor from '@bpmn-io/feel-editor';
16
16
  import { lineNumbers, EditorView } from '@codemirror/view';
@@ -857,7 +857,7 @@ function useDebounce(fn) {
857
857
  }
858
858
 
859
859
  var _path$5;
860
- function _extends$5() { _extends$5 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$5.apply(this, arguments); }
860
+ function _extends$5() { return _extends$5 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$5.apply(null, arguments); }
861
861
  var SvgClose = function SvgClose(props) {
862
862
  return /*#__PURE__*/React.createElement("svg", _extends$5({
863
863
  xmlns: "http://www.w3.org/2000/svg",
@@ -872,7 +872,7 @@ var SvgClose = function SvgClose(props) {
872
872
  };
873
873
 
874
874
  var _path$4, _path2$1;
875
- function _extends$4() { _extends$4 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$4.apply(this, arguments); }
875
+ function _extends$4() { return _extends$4 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$4.apply(null, arguments); }
876
876
  var SvgDelete = function SvgDelete(props) {
877
877
  return /*#__PURE__*/React.createElement("svg", _extends$4({
878
878
  xmlns: "http://www.w3.org/2000/svg",
@@ -905,7 +905,7 @@ var SvgDelete = function SvgDelete(props) {
905
905
  };
906
906
 
907
907
  var _path$3;
908
- function _extends$3() { _extends$3 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3.apply(this, arguments); }
908
+ function _extends$3() { return _extends$3 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$3.apply(null, arguments); }
909
909
  var SvgDraggable = function SvgDraggable(props) {
910
910
  return /*#__PURE__*/React.createElement("svg", _extends$3({
911
911
  xmlns: "http://www.w3.org/2000/svg",
@@ -925,7 +925,7 @@ var SvgDraggable = function SvgDraggable(props) {
925
925
  };
926
926
 
927
927
  var _path$2;
928
- function _extends$2() { _extends$2 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$2.apply(this, arguments); }
928
+ function _extends$2() { return _extends$2 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$2.apply(null, arguments); }
929
929
  var SvgSearch = function SvgSearch(props) {
930
930
  return /*#__PURE__*/React.createElement("svg", _extends$2({
931
931
  xmlns: "http://www.w3.org/2000/svg",
@@ -939,7 +939,7 @@ var SvgSearch = function SvgSearch(props) {
939
939
  };
940
940
 
941
941
  var _path$1, _rect, _mask, _path2, _path3, _path4, _path5, _path6;
942
- function _extends$1() { _extends$1 = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$1.apply(this, arguments); }
942
+ function _extends$1() { return _extends$1 = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends$1.apply(null, arguments); }
943
943
  var SvgEmptyForm = function SvgEmptyForm(props) {
944
944
  return /*#__PURE__*/React.createElement("svg", _extends$1({
945
945
  xmlns: "http://www.w3.org/2000/svg",
@@ -4671,7 +4671,7 @@ class MoveFormFieldHandler {
4671
4671
  updateRow(formField, targetRow ? targetRow.id : this._formLayouter.nextRowId());
4672
4672
 
4673
4673
  // (2) Move form field
4674
- mutate(get(schema, sourcePath), sourceIndex, targetIndex);
4674
+ arrayMoveMutable(get(schema, sourcePath), sourceIndex, targetIndex);
4675
4675
 
4676
4676
  // (3) Update internal paths of new form field and its siblings (and their children)
4677
4677
  get(schema, sourcePath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
@@ -5873,6 +5873,23 @@ function useStaticCallback(callback) {
5873
5873
  callbackRef.current = callback;
5874
5874
  return useCallback((...args) => callbackRef.current(...args), []);
5875
5875
  }
5876
+ function useElementVisible(element) {
5877
+ const [visible, setVisible] = useState(!!element && !!element.clientHeight);
5878
+ useLayoutEffect(() => {
5879
+ if (!element) return;
5880
+ const resizeObserver = new ResizeObserver(([entry]) => {
5881
+ requestAnimationFrame(() => {
5882
+ const newVisible = !!entry.contentRect.height;
5883
+ if (newVisible !== visible) {
5884
+ setVisible(newVisible);
5885
+ }
5886
+ });
5887
+ });
5888
+ resizeObserver.observe(element);
5889
+ return () => resizeObserver.disconnect();
5890
+ }, [element, visible]);
5891
+ return visible;
5892
+ }
5876
5893
  function Group(props) {
5877
5894
  const {
5878
5895
  element,
@@ -8060,6 +8077,28 @@ function useUpdateLayoutEffect(effect, deps) {
8060
8077
  }
8061
8078
  }, deps);
8062
8079
  }
8080
+
8081
+ /**
8082
+ * @typedef { {
8083
+ * [key: string]: string;
8084
+ * } } TranslateReplacements
8085
+ */
8086
+
8087
+ /**
8088
+ * A simple translation stub to be used for multi-language support.
8089
+ * Can be easily replaced with a more sophisticated solution.
8090
+ *
8091
+ * @param {string} template to interpolate
8092
+ * @param {TranslateReplacements} [replacements] a map with substitutes
8093
+ *
8094
+ * @return {string} the translated string
8095
+ */
8096
+ function translateFallback(template, replacements) {
8097
+ replacements = replacements || {};
8098
+ return template.replace(/{([^}]+)}/g, function (_, key) {
8099
+ return replacements[key] || '{' + key + '}';
8100
+ });
8101
+ }
8063
8102
  function CollapsibleEntry(props) {
8064
8103
  const {
8065
8104
  element,
@@ -8067,7 +8106,8 @@ function CollapsibleEntry(props) {
8067
8106
  id,
8068
8107
  label,
8069
8108
  open: shouldOpen,
8070
- remove
8109
+ remove,
8110
+ translate = translateFallback
8071
8111
  } = props;
8072
8112
  const [open, setOpen] = useState(shouldOpen);
8073
8113
  const toggleOpen = () => setOpen(!open);
@@ -8083,9 +8123,7 @@ function CollapsibleEntry(props) {
8083
8123
  }
8084
8124
  }, [onShow, setOpen])
8085
8125
  };
8086
-
8087
- // todo(pinussilvestrus): translate once we have a translate mechanism for the core
8088
- const placeholderLabel = '<empty>';
8126
+ const placeholderLabel = translate('<empty>');
8089
8127
  return jsxs("div", {
8090
8128
  "data-entry-id": id,
8091
8129
  class: classnames('bio-properties-panel-collapsible-entry', open ? 'open' : ''),
@@ -8098,14 +8136,14 @@ function CollapsibleEntry(props) {
8098
8136
  children: label || placeholderLabel
8099
8137
  }), jsx("button", {
8100
8138
  type: "button",
8101
- title: "Toggle list item",
8139
+ title: translate('Toggle list item'),
8102
8140
  class: "bio-properties-panel-arrow bio-properties-panel-collapsible-entry-arrow",
8103
8141
  children: jsx(ArrowIcon, {
8104
8142
  class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
8105
8143
  })
8106
8144
  }), remove ? jsx("button", {
8107
8145
  type: "button",
8108
- title: "Delete item",
8146
+ title: translate('Delete item'),
8109
8147
  class: "bio-properties-panel-remove-entry",
8110
8148
  onClick: remove,
8111
8149
  children: jsx(DeleteIcon, {})
@@ -8132,7 +8170,8 @@ function CollapsibleEntry(props) {
8132
8170
  function ListItem(props) {
8133
8171
  const {
8134
8172
  autoFocusEntry,
8135
- autoOpen
8173
+ autoOpen,
8174
+ translate = translateFallback
8136
8175
  } = props;
8137
8176
 
8138
8177
  // focus specified entry on auto open
@@ -8154,7 +8193,8 @@ function ListItem(props) {
8154
8193
  class: "bio-properties-panel-list-item",
8155
8194
  children: jsx(CollapsibleEntry, {
8156
8195
  ...props,
8157
- open: autoOpen
8196
+ open: autoOpen,
8197
+ translate: translate
8158
8198
  })
8159
8199
  });
8160
8200
  }
@@ -8170,7 +8210,8 @@ function ListGroup(props) {
8170
8210
  id,
8171
8211
  items,
8172
8212
  label,
8173
- shouldOpen = true
8213
+ shouldOpen = false,
8214
+ translate = translateFallback
8174
8215
  } = props;
8175
8216
  useEffect(() => {
8176
8217
  if (props.shouldSort != undefined) {
@@ -8178,57 +8219,25 @@ function ListGroup(props) {
8178
8219
  }
8179
8220
  }, [props.shouldSort]);
8180
8221
  const groupRef = useRef(null);
8181
- const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
8222
+ const [open, setOpen] = useLayoutState(['groups', id, 'open'], shouldOpen);
8182
8223
  const [sticky, setSticky] = useState(false);
8183
8224
  const onShow = useCallback(() => setOpen(true), [setOpen]);
8184
8225
  const [localItems, setLocalItems] = useState([]);
8185
- const [newlyAddedItemIds, setNewlyAddedItemIds] = useState([]);
8186
8226
 
8187
8227
  // Flag to mark that add button was clicked in the last render cycle
8188
8228
  const [addTriggered, setAddTriggered] = useState(false);
8189
8229
  const prevElement = usePrevious(element);
8190
- const elementChanged = element !== prevElement;
8191
- const shouldHandleEffects = !elementChanged && shouldOpen;
8192
-
8193
- // (0) delay setting items
8194
- //
8195
- // We need to this to align the render cycles of items
8196
- // with the detection of newly added items.
8197
- // This is important, because the autoOpen property can
8198
- // only set per list item on its very first render.
8199
- useEffect(() => {
8200
- setLocalItems(items);
8201
- }, [items]);
8230
+ const toggleOpen = useCallback(() => setOpen(!open), [open]);
8231
+ const openItemIds = element === prevElement && open && addTriggered ? getNewItemIds(items, localItems) : [];
8202
8232
 
8203
- // (1) handle auto opening when items were added
8233
+ // reset local state after items changed
8204
8234
  useEffect(() => {
8205
- // reset addTriggered flag
8235
+ setLocalItems(items);
8206
8236
  setAddTriggered(false);
8207
- if (shouldHandleEffects && localItems) {
8208
- if (addTriggered) {
8209
- const previousItemIds = localItems.map(item => item.id);
8210
- const currentItemsIds = items.map(item => item.id);
8211
- const newItemIds = currentItemsIds.filter(itemId => !previousItemIds.includes(itemId));
8212
-
8213
- // open if not open, configured and triggered by add button
8214
- //
8215
- // TODO(marstamm): remove once we refactor layout handling for listGroups.
8216
- // Ideally, opening should be handled as part of the `add` callback and
8217
- // not be a concern for the ListGroup component.
8218
- if (!open && shouldOpen && newItemIds.length > 0) {
8219
- toggleOpen();
8220
- }
8221
- setNewlyAddedItemIds(newItemIds);
8222
- } else {
8223
- // ignore newly added items that do not result from a triggered add
8224
- setNewlyAddedItemIds([]);
8225
- }
8226
- }
8227
- }, [items, open, shouldHandleEffects, addTriggered, localItems]);
8237
+ }, [items]);
8228
8238
 
8229
8239
  // set css class when group is sticky to top
8230
8240
  useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
8231
- const toggleOpen = () => setOpen(!open);
8232
8241
  const hasItems = !!items.length;
8233
8242
  const propertiesPanelContext = {
8234
8243
  ...useContext(LayoutContext),
@@ -8236,6 +8245,7 @@ function ListGroup(props) {
8236
8245
  };
8237
8246
  const handleAddClick = e => {
8238
8247
  setAddTriggered(true);
8248
+ setOpen(true);
8239
8249
  add(e);
8240
8250
  };
8241
8251
  const allErrors = useErrors();
@@ -8272,20 +8282,22 @@ function ListGroup(props) {
8272
8282
  class: "bio-properties-panel-group-header-buttons",
8273
8283
  children: [add ? jsxs("button", {
8274
8284
  type: "button",
8275
- title: "Create new list item",
8285
+ title: translate('Create new list item'),
8276
8286
  class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
8277
8287
  onClick: handleAddClick,
8278
8288
  children: [jsx(CreateIcon, {}), !hasItems ? jsx("span", {
8279
8289
  class: "bio-properties-panel-add-entry-label",
8280
- children: "Create"
8290
+ children: translate('Create')
8281
8291
  }) : null]
8282
8292
  }) : null, hasItems ? jsx("div", {
8283
- title: `List contains ${items.length} item${items.length != 1 ? 's' : ''}`,
8293
+ title: translate(`List contains {numOfItems} item${items.length != 1 ? 's' : ''}`, {
8294
+ numOfItems: items.length
8295
+ }),
8284
8296
  class: classnames('bio-properties-panel-list-badge', hasError ? 'bio-properties-panel-list-badge--error' : ''),
8285
8297
  children: items.length
8286
8298
  }) : null, hasItems ? jsx("button", {
8287
8299
  type: "button",
8288
- title: "Toggle section",
8300
+ title: translate('Toggle section'),
8289
8301
  class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
8290
8302
  children: jsx(ArrowIcon, {
8291
8303
  class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
@@ -8296,7 +8308,7 @@ function ListGroup(props) {
8296
8308
  class: classnames('bio-properties-panel-list', open && hasItems ? 'open' : ''),
8297
8309
  children: jsx(LayoutContext.Provider, {
8298
8310
  value: propertiesPanelContext,
8299
- children: localItems.map((item, index) => {
8311
+ children: items.map((item, index) => {
8300
8312
  if (!item) {
8301
8313
  return;
8302
8314
  }
@@ -8305,20 +8317,27 @@ function ListGroup(props) {
8305
8317
  } = item;
8306
8318
 
8307
8319
  // if item was added, open it
8308
- // Existing items will not be affected as autoOpen is only applied on first render
8309
- const autoOpen = newlyAddedItemIds.includes(item.id);
8320
+ // existing items will not be affected as autoOpen
8321
+ // is only applied on first render
8322
+ const autoOpen = openItemIds.includes(item.id);
8310
8323
  return createElement(ListItem, {
8311
8324
  ...item,
8312
8325
  autoOpen: autoOpen,
8313
8326
  element: element,
8314
8327
  index: index,
8315
- key: id
8328
+ key: id,
8329
+ translate: translate
8316
8330
  });
8317
8331
  })
8318
8332
  })
8319
8333
  })]
8320
8334
  });
8321
8335
  }
8336
+ function getNewItemIds(newItems, oldItems) {
8337
+ const newIds = newItems.map(item => item.id);
8338
+ const oldIds = oldItems.map(item => item.id);
8339
+ return newIds.filter(itemId => !oldIds.includes(itemId));
8340
+ }
8322
8341
  function Checkbox(props) {
8323
8342
  const {
8324
8343
  id,
@@ -8604,13 +8623,14 @@ function TextArea(props) {
8604
8623
  monospace,
8605
8624
  onFocus,
8606
8625
  onBlur,
8607
- autoResize,
8626
+ autoResize = true,
8608
8627
  placeholder,
8609
8628
  rows = autoResize ? 1 : 2,
8610
8629
  tooltip
8611
8630
  } = props;
8612
8631
  const [localValue, setLocalValue] = useState(value);
8613
8632
  const ref = useShowEntryEvent(id);
8633
+ const visible = useElementVisible(ref.current);
8614
8634
  const handleInputCallback = useMemo(() => {
8615
8635
  return debounce(target => onInput(target.value.length ? target.value : undefined));
8616
8636
  }, [onInput, debounce]);
@@ -8622,6 +8642,9 @@ function TextArea(props) {
8622
8642
  useLayoutEffect(() => {
8623
8643
  autoResize && resizeToContents(ref.current);
8624
8644
  }, []);
8645
+ useLayoutEffect(() => {
8646
+ visible && autoResize && resizeToContents(ref.current);
8647
+ }, [visible]);
8625
8648
  useEffect(() => {
8626
8649
  if (value === localValue) {
8627
8650
  return;
@@ -13336,7 +13359,7 @@ const RenderInjectionModule = {
13336
13359
  };
13337
13360
 
13338
13361
  var _path;
13339
- function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
13362
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
13340
13363
  var SvgRepeat = function SvgRepeat(props) {
13341
13364
  return /*#__PURE__*/React.createElement("svg", _extends({
13342
13365
  xmlns: "http://www.w3.org/2000/svg",