@bpmn-io/form-js-editor 1.11.0-alpha.0 → 1.11.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.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",
@@ -1496,6 +1496,8 @@ function Palette(props) {
1496
1496
  const initialPaletteEntries = useRef(collectPaletteEntries(formFields));
1497
1497
  const [paletteEntries, setPaletteEntries] = useState(initialPaletteEntries.current);
1498
1498
  const [searchTerm, setSearchTerm] = useState('');
1499
+
1500
+ /** @type {import("preact").RefObject<HTMLInputElement>} */
1499
1501
  const inputRef = useRef();
1500
1502
  const groups = groupEntries(paletteEntries);
1501
1503
  const simplifyString = useCallback(str => {
@@ -1618,7 +1620,8 @@ function collectPaletteEntries(formFields) {
1618
1620
  config: fieldConfig
1619
1621
  } = formField;
1620
1622
  return {
1621
- label: fieldConfig.label,
1623
+ // fieldConfig.label is used to maintain backwards compatibility with custom form fields
1624
+ label: fieldConfig.name || fieldConfig.label,
1622
1625
  type: type,
1623
1626
  group: fieldConfig.group,
1624
1627
  icon: fieldConfig.icon,
@@ -1921,6 +1924,29 @@ class Dragging {
1921
1924
  }
1922
1925
  return !target.classList.contains(DRAG_NO_DROP_CLS);
1923
1926
  },
1927
+ transformOffset: (offset, event, element) => {
1928
+ if (element.classList.contains(DRAG_ROW_MOVE_CLS)) {
1929
+ const rowOffset = {
1930
+ x: -5,
1931
+ y: -60
1932
+ };
1933
+ return {
1934
+ left: event.clientX + rowOffset.x,
1935
+ top: event.clientY + rowOffset.y
1936
+ };
1937
+ }
1938
+ if (element.classList.contains(DRAG_MOVE_CLS)) {
1939
+ const iconOffset = {
1940
+ x: -5,
1941
+ y: -15
1942
+ };
1943
+ return {
1944
+ left: event.clientX + iconOffset.x,
1945
+ top: event.clientY + iconOffset.y
1946
+ };
1947
+ }
1948
+ return offset;
1949
+ },
1924
1950
  slideFactorX: 10,
1925
1951
  slideFactorY: 5
1926
1952
  };
@@ -2216,6 +2242,8 @@ function Element$1(props) {
2216
2242
  type,
2217
2243
  showOutline
2218
2244
  } = field;
2245
+
2246
+ /** @type {import("preact").RefObject<HTMLDivElement>} */
2219
2247
  const ref = useRef();
2220
2248
  const [hovered, setHovered] = useState(false);
2221
2249
  useEffect(() => {
@@ -4671,7 +4699,7 @@ class MoveFormFieldHandler {
4671
4699
  updateRow(formField, targetRow ? targetRow.id : this._formLayouter.nextRowId());
4672
4700
 
4673
4701
  // (2) Move form field
4674
- mutate(get(schema, sourcePath), sourceIndex, targetIndex);
4702
+ arrayMoveMutable(get(schema, sourcePath), sourceIndex, targetIndex);
4675
4703
 
4676
4704
  // (3) Update internal paths of new form field and its siblings (and their children)
4677
4705
  get(schema, sourcePath).forEach((formField, index) => updatePath(this._formFieldRegistry, formField, index));
@@ -5873,6 +5901,23 @@ function useStaticCallback(callback) {
5873
5901
  callbackRef.current = callback;
5874
5902
  return useCallback((...args) => callbackRef.current(...args), []);
5875
5903
  }
5904
+ function useElementVisible(element) {
5905
+ const [visible, setVisible] = useState(!!element && !!element.clientHeight);
5906
+ useLayoutEffect(() => {
5907
+ if (!element) return;
5908
+ const resizeObserver = new ResizeObserver(([entry]) => {
5909
+ requestAnimationFrame(() => {
5910
+ const newVisible = !!entry.contentRect.height;
5911
+ if (newVisible !== visible) {
5912
+ setVisible(newVisible);
5913
+ }
5914
+ });
5915
+ });
5916
+ resizeObserver.observe(element);
5917
+ return () => resizeObserver.disconnect();
5918
+ }, [element, visible]);
5919
+ return visible;
5920
+ }
5876
5921
  function Group(props) {
5877
5922
  const {
5878
5923
  element,
@@ -7207,12 +7252,13 @@ function FeelTextfieldComponent(props) {
7207
7252
  setFocus(-1);
7208
7253
  }
7209
7254
  };
7210
- const handleLint = useStaticCallback(lint => {
7211
- if (!(lint && lint.length)) {
7255
+ const handleLint = useStaticCallback((lint = []) => {
7256
+ const syntaxError = lint.some(report => report.type === 'Syntax Error');
7257
+ if (syntaxError) {
7258
+ onError('Unparsable FEEL expression.');
7259
+ } else {
7212
7260
  onError(undefined);
7213
- return;
7214
7261
  }
7215
- onError('Unparsable FEEL expression.');
7216
7262
  });
7217
7263
  const handlePopupOpen = (type = 'feel') => {
7218
7264
  const popupOptions = {
@@ -8060,6 +8106,28 @@ function useUpdateLayoutEffect(effect, deps) {
8060
8106
  }
8061
8107
  }, deps);
8062
8108
  }
8109
+
8110
+ /**
8111
+ * @typedef { {
8112
+ * [key: string]: string;
8113
+ * } } TranslateReplacements
8114
+ */
8115
+
8116
+ /**
8117
+ * A simple translation stub to be used for multi-language support.
8118
+ * Can be easily replaced with a more sophisticated solution.
8119
+ *
8120
+ * @param {string} template to interpolate
8121
+ * @param {TranslateReplacements} [replacements] a map with substitutes
8122
+ *
8123
+ * @return {string} the translated string
8124
+ */
8125
+ function translateFallback(template, replacements) {
8126
+ replacements = replacements || {};
8127
+ return template.replace(/{([^}]+)}/g, function (_, key) {
8128
+ return replacements[key] || '{' + key + '}';
8129
+ });
8130
+ }
8063
8131
  function CollapsibleEntry(props) {
8064
8132
  const {
8065
8133
  element,
@@ -8067,7 +8135,8 @@ function CollapsibleEntry(props) {
8067
8135
  id,
8068
8136
  label,
8069
8137
  open: shouldOpen,
8070
- remove
8138
+ remove,
8139
+ translate = translateFallback
8071
8140
  } = props;
8072
8141
  const [open, setOpen] = useState(shouldOpen);
8073
8142
  const toggleOpen = () => setOpen(!open);
@@ -8083,9 +8152,7 @@ function CollapsibleEntry(props) {
8083
8152
  }
8084
8153
  }, [onShow, setOpen])
8085
8154
  };
8086
-
8087
- // todo(pinussilvestrus): translate once we have a translate mechanism for the core
8088
- const placeholderLabel = '<empty>';
8155
+ const placeholderLabel = translate('<empty>');
8089
8156
  return jsxs("div", {
8090
8157
  "data-entry-id": id,
8091
8158
  class: classnames('bio-properties-panel-collapsible-entry', open ? 'open' : ''),
@@ -8098,14 +8165,14 @@ function CollapsibleEntry(props) {
8098
8165
  children: label || placeholderLabel
8099
8166
  }), jsx("button", {
8100
8167
  type: "button",
8101
- title: "Toggle list item",
8168
+ title: translate('Toggle list item'),
8102
8169
  class: "bio-properties-panel-arrow bio-properties-panel-collapsible-entry-arrow",
8103
8170
  children: jsx(ArrowIcon, {
8104
8171
  class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
8105
8172
  })
8106
8173
  }), remove ? jsx("button", {
8107
8174
  type: "button",
8108
- title: "Delete item",
8175
+ title: translate('Delete item'),
8109
8176
  class: "bio-properties-panel-remove-entry",
8110
8177
  onClick: remove,
8111
8178
  children: jsx(DeleteIcon, {})
@@ -8132,7 +8199,8 @@ function CollapsibleEntry(props) {
8132
8199
  function ListItem(props) {
8133
8200
  const {
8134
8201
  autoFocusEntry,
8135
- autoOpen
8202
+ autoOpen,
8203
+ translate = translateFallback
8136
8204
  } = props;
8137
8205
 
8138
8206
  // focus specified entry on auto open
@@ -8154,7 +8222,8 @@ function ListItem(props) {
8154
8222
  class: "bio-properties-panel-list-item",
8155
8223
  children: jsx(CollapsibleEntry, {
8156
8224
  ...props,
8157
- open: autoOpen
8225
+ open: autoOpen,
8226
+ translate: translate
8158
8227
  })
8159
8228
  });
8160
8229
  }
@@ -8170,7 +8239,8 @@ function ListGroup(props) {
8170
8239
  id,
8171
8240
  items,
8172
8241
  label,
8173
- shouldOpen = true
8242
+ shouldOpen = false,
8243
+ translate = translateFallback
8174
8244
  } = props;
8175
8245
  useEffect(() => {
8176
8246
  if (props.shouldSort != undefined) {
@@ -8178,57 +8248,25 @@ function ListGroup(props) {
8178
8248
  }
8179
8249
  }, [props.shouldSort]);
8180
8250
  const groupRef = useRef(null);
8181
- const [open, setOpen] = useLayoutState(['groups', id, 'open'], false);
8251
+ const [open, setOpen] = useLayoutState(['groups', id, 'open'], shouldOpen);
8182
8252
  const [sticky, setSticky] = useState(false);
8183
8253
  const onShow = useCallback(() => setOpen(true), [setOpen]);
8184
8254
  const [localItems, setLocalItems] = useState([]);
8185
- const [newlyAddedItemIds, setNewlyAddedItemIds] = useState([]);
8186
8255
 
8187
8256
  // Flag to mark that add button was clicked in the last render cycle
8188
8257
  const [addTriggered, setAddTriggered] = useState(false);
8189
8258
  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]);
8259
+ const toggleOpen = useCallback(() => setOpen(!open), [open]);
8260
+ const openItemIds = element === prevElement && open && addTriggered ? getNewItemIds(items, localItems) : [];
8202
8261
 
8203
- // (1) handle auto opening when items were added
8262
+ // reset local state after items changed
8204
8263
  useEffect(() => {
8205
- // reset addTriggered flag
8264
+ setLocalItems(items);
8206
8265
  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]);
8266
+ }, [items]);
8228
8267
 
8229
8268
  // set css class when group is sticky to top
8230
8269
  useStickyIntersectionObserver(groupRef, 'div.bio-properties-panel-scroll-container', setSticky);
8231
- const toggleOpen = () => setOpen(!open);
8232
8270
  const hasItems = !!items.length;
8233
8271
  const propertiesPanelContext = {
8234
8272
  ...useContext(LayoutContext),
@@ -8236,6 +8274,7 @@ function ListGroup(props) {
8236
8274
  };
8237
8275
  const handleAddClick = e => {
8238
8276
  setAddTriggered(true);
8277
+ setOpen(true);
8239
8278
  add(e);
8240
8279
  };
8241
8280
  const allErrors = useErrors();
@@ -8272,20 +8311,22 @@ function ListGroup(props) {
8272
8311
  class: "bio-properties-panel-group-header-buttons",
8273
8312
  children: [add ? jsxs("button", {
8274
8313
  type: "button",
8275
- title: "Create new list item",
8314
+ title: translate('Create new list item'),
8276
8315
  class: "bio-properties-panel-group-header-button bio-properties-panel-add-entry",
8277
8316
  onClick: handleAddClick,
8278
8317
  children: [jsx(CreateIcon, {}), !hasItems ? jsx("span", {
8279
8318
  class: "bio-properties-panel-add-entry-label",
8280
- children: "Create"
8319
+ children: translate('Create')
8281
8320
  }) : null]
8282
8321
  }) : null, hasItems ? jsx("div", {
8283
- title: `List contains ${items.length} item${items.length != 1 ? 's' : ''}`,
8322
+ title: translate(`List contains {numOfItems} item${items.length != 1 ? 's' : ''}`, {
8323
+ numOfItems: items.length
8324
+ }),
8284
8325
  class: classnames('bio-properties-panel-list-badge', hasError ? 'bio-properties-panel-list-badge--error' : ''),
8285
8326
  children: items.length
8286
8327
  }) : null, hasItems ? jsx("button", {
8287
8328
  type: "button",
8288
- title: "Toggle section",
8329
+ title: translate('Toggle section'),
8289
8330
  class: "bio-properties-panel-group-header-button bio-properties-panel-arrow",
8290
8331
  children: jsx(ArrowIcon, {
8291
8332
  class: open ? 'bio-properties-panel-arrow-down' : 'bio-properties-panel-arrow-right'
@@ -8296,7 +8337,7 @@ function ListGroup(props) {
8296
8337
  class: classnames('bio-properties-panel-list', open && hasItems ? 'open' : ''),
8297
8338
  children: jsx(LayoutContext.Provider, {
8298
8339
  value: propertiesPanelContext,
8299
- children: localItems.map((item, index) => {
8340
+ children: items.map((item, index) => {
8300
8341
  if (!item) {
8301
8342
  return;
8302
8343
  }
@@ -8305,20 +8346,27 @@ function ListGroup(props) {
8305
8346
  } = item;
8306
8347
 
8307
8348
  // 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);
8349
+ // existing items will not be affected as autoOpen
8350
+ // is only applied on first render
8351
+ const autoOpen = openItemIds.includes(item.id);
8310
8352
  return createElement(ListItem, {
8311
8353
  ...item,
8312
8354
  autoOpen: autoOpen,
8313
8355
  element: element,
8314
8356
  index: index,
8315
- key: id
8357
+ key: id,
8358
+ translate: translate
8316
8359
  });
8317
8360
  })
8318
8361
  })
8319
8362
  })]
8320
8363
  });
8321
8364
  }
8365
+ function getNewItemIds(newItems, oldItems) {
8366
+ const newIds = newItems.map(item => item.id);
8367
+ const oldIds = oldItems.map(item => item.id);
8368
+ return newIds.filter(itemId => !oldIds.includes(itemId));
8369
+ }
8322
8370
  function Checkbox(props) {
8323
8371
  const {
8324
8372
  id,
@@ -8604,13 +8652,14 @@ function TextArea(props) {
8604
8652
  monospace,
8605
8653
  onFocus,
8606
8654
  onBlur,
8607
- autoResize,
8655
+ autoResize = true,
8608
8656
  placeholder,
8609
8657
  rows = autoResize ? 1 : 2,
8610
8658
  tooltip
8611
8659
  } = props;
8612
8660
  const [localValue, setLocalValue] = useState(value);
8613
8661
  const ref = useShowEntryEvent(id);
8662
+ const visible = useElementVisible(ref.current);
8614
8663
  const handleInputCallback = useMemo(() => {
8615
8664
  return debounce(target => onInput(target.value.length ? target.value : undefined));
8616
8665
  }, [onInput, debounce]);
@@ -8622,6 +8671,9 @@ function TextArea(props) {
8622
8671
  useLayoutEffect(() => {
8623
8672
  autoResize && resizeToContents(ref.current);
8624
8673
  }, []);
8674
+ useLayoutEffect(() => {
8675
+ visible && autoResize && resizeToContents(ref.current);
8676
+ }, [visible]);
8625
8677
  useEffect(() => {
8626
8678
  if (value === localValue) {
8627
8679
  return;
@@ -8938,82 +8990,6 @@ const FormPropertiesPanelContext = createContext({
8938
8990
  getService
8939
8991
  });
8940
8992
 
8941
- function arrayAdd(array, index, item) {
8942
- const copy = [...array];
8943
- copy.splice(index, 0, item);
8944
- return copy;
8945
- }
8946
- function countDecimals(number) {
8947
- const num = Big(number);
8948
- if (num.toString() === num.toFixed(0)) return 0;
8949
- return num.toFixed().split('.')[1].length || 0;
8950
- }
8951
-
8952
- /**
8953
- *
8954
- * @param {unknown} value
8955
- * @returns {boolean}
8956
- */
8957
- function isValidNumber(value) {
8958
- return (typeof value === 'number' || typeof value === 'string') && value !== '' && !isNaN(Number(value));
8959
- }
8960
- function textToLabel(text) {
8961
- if (typeof text != 'string') return null;
8962
- for (const line of text.split('\n')) {
8963
- const displayLine = line.trim();
8964
-
8965
- // we use the first non-whitespace line in the text as label
8966
- if (displayLine !== '') {
8967
- return displayLine;
8968
- }
8969
- }
8970
- return null;
8971
- }
8972
-
8973
- /**
8974
- * @param {string} path
8975
- */
8976
- function isValidDotPath(path) {
8977
- return /^\w+(\.\w+)*$/.test(path);
8978
- }
8979
-
8980
- /**
8981
- * @param {string} path
8982
- */
8983
- function isProhibitedPath(path) {
8984
- const prohibitedSegments = ['__proto__', 'prototype', 'constructor'];
8985
- return path.split('.').some(segment => prohibitedSegments.includes(segment));
8986
- }
8987
- const LABELED_NON_INPUTS = ['button', 'group', 'dynamiclist', 'iframe', 'table'];
8988
- const INPUTS = ['checkbox', 'checklist', 'datetime', 'number', 'radio', 'select', 'taglist', 'textfield', 'textarea', 'filepicker'];
8989
- const OPTIONS_INPUTS = ['checklist', 'radio', 'select', 'taglist'];
8990
- function hasEntryConfigured(formFieldDefinition, entryId) {
8991
- const {
8992
- propertiesPanelEntries = []
8993
- } = formFieldDefinition;
8994
- if (!propertiesPanelEntries.length) {
8995
- return false;
8996
- }
8997
- return propertiesPanelEntries.some(id => id === entryId);
8998
- }
8999
- function hasOptionsGroupsConfigured(formFieldDefinition) {
9000
- const {
9001
- propertiesPanelEntries = []
9002
- } = formFieldDefinition;
9003
- if (!propertiesPanelEntries.length) {
9004
- return false;
9005
- }
9006
- return propertiesPanelEntries.some(id => id === 'values');
9007
- }
9008
-
9009
- /**
9010
- * @param {string} path
9011
- */
9012
- function hasIntegerPathSegment(path) {
9013
- return path.split('.').some(segment => /^\d+$/.test(segment));
9014
- }
9015
-
9016
- const headerlessTypes = ['spacer', 'separator', 'expression', 'html'];
9017
8993
  function getPropertiesPanelHeaderProvider(options = {}) {
9018
8994
  const {
9019
8995
  getDocumentationRef,
@@ -9024,19 +9000,8 @@ function getPropertiesPanelHeaderProvider(options = {}) {
9024
9000
  const {
9025
9001
  type
9026
9002
  } = field;
9027
- if (headerlessTypes.includes(type)) {
9028
- return '';
9029
- }
9030
- if (type === 'text') {
9031
- return textToLabel(field.text);
9032
- }
9033
- if (type === 'image') {
9034
- return field.alt;
9035
- }
9036
- if (type === 'default') {
9037
- return field.id;
9038
- }
9039
- return field.label;
9003
+ const fieldDefinition = formFields.get(type).config;
9004
+ return fieldDefinition.getSubheading ? fieldDefinition.getSubheading(field) : field.label;
9040
9005
  },
9041
9006
  getElementIcon: field => {
9042
9007
  const {
@@ -9065,7 +9030,7 @@ function getPropertiesPanelHeaderProvider(options = {}) {
9065
9030
  return 'Form';
9066
9031
  }
9067
9032
  const fieldDefinition = formFields.get(type).config;
9068
- return fieldDefinition.label || type;
9033
+ return fieldDefinition.name || fieldDefinition.label || type;
9069
9034
  },
9070
9035
  getDocumentationRef
9071
9036
  };
@@ -9466,6 +9431,69 @@ function asArray(length) {
9466
9431
  }).map((_, i) => i + 1);
9467
9432
  }
9468
9433
 
9434
+ function arrayAdd(array, index, item) {
9435
+ const copy = [...array];
9436
+ copy.splice(index, 0, item);
9437
+ return copy;
9438
+ }
9439
+ function countDecimals(number) {
9440
+ const num = Big(number);
9441
+ if (num.toString() === num.toFixed(0)) return 0;
9442
+ return num.toFixed().split('.')[1].length || 0;
9443
+ }
9444
+
9445
+ /**
9446
+ *
9447
+ * @param {unknown} value
9448
+ * @returns {boolean}
9449
+ */
9450
+ function isValidNumber(value) {
9451
+ return (typeof value === 'number' || typeof value === 'string') && value !== '' && !isNaN(Number(value));
9452
+ }
9453
+
9454
+ /**
9455
+ * @param {string} path
9456
+ */
9457
+ function isValidDotPath(path) {
9458
+ return /^\w+(\.\w+)*$/.test(path);
9459
+ }
9460
+
9461
+ /**
9462
+ * @param {string} path
9463
+ */
9464
+ function isProhibitedPath(path) {
9465
+ const prohibitedSegments = ['__proto__', 'prototype', 'constructor'];
9466
+ return path.split('.').some(segment => prohibitedSegments.includes(segment));
9467
+ }
9468
+ const LABELED_NON_INPUTS = ['button', 'group', 'dynamiclist', 'iframe', 'table'];
9469
+ const INPUTS = ['checkbox', 'checklist', 'datetime', 'number', 'radio', 'select', 'taglist', 'textfield', 'textarea', 'filepicker'];
9470
+ const OPTIONS_INPUTS = ['checklist', 'radio', 'select', 'taglist'];
9471
+ function hasEntryConfigured(formFieldDefinition, entryId) {
9472
+ const {
9473
+ propertiesPanelEntries = []
9474
+ } = formFieldDefinition;
9475
+ if (!propertiesPanelEntries.length) {
9476
+ return false;
9477
+ }
9478
+ return propertiesPanelEntries.some(id => id === entryId);
9479
+ }
9480
+ function hasOptionsGroupsConfigured(formFieldDefinition) {
9481
+ const {
9482
+ propertiesPanelEntries = []
9483
+ } = formFieldDefinition;
9484
+ if (!propertiesPanelEntries.length) {
9485
+ return false;
9486
+ }
9487
+ return propertiesPanelEntries.some(id => id === 'values');
9488
+ }
9489
+
9490
+ /**
9491
+ * @param {string} path
9492
+ */
9493
+ function hasIntegerPathSegment(path) {
9494
+ return path.split('.').some(segment => /^\d+$/.test(segment));
9495
+ }
9496
+
9469
9497
  function DescriptionEntry(props) {
9470
9498
  const {
9471
9499
  editField,
@@ -9511,7 +9539,7 @@ function Description(props) {
9511
9539
  });
9512
9540
  }
9513
9541
 
9514
- const EMPTY_OPTION = null;
9542
+ const EMPTY_OPTION = '';
9515
9543
  function DefaultValueEntry(props) {
9516
9544
  const {
9517
9545
  editField,
@@ -12623,7 +12651,7 @@ function Multiple(props) {
12623
12651
  feel: 'optional',
12624
12652
  getValue,
12625
12653
  id,
12626
- label: 'Select multiple files',
12654
+ label: 'Upload multiple files',
12627
12655
  inline: true,
12628
12656
  setValue,
12629
12657
  variables
@@ -13444,7 +13472,7 @@ const RenderInjectionModule = {
13444
13472
  };
13445
13473
 
13446
13474
  var _path;
13447
- 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); }
13475
+ 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); }
13448
13476
  var SvgRepeat = function SvgRepeat(props) {
13449
13477
  return /*#__PURE__*/React.createElement("svg", _extends({
13450
13478
  xmlns: "http://www.w3.org/2000/svg",