@bpmn-io/form-js-viewer 0.11.0 → 0.12.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
@@ -1,10 +1,10 @@
1
1
  import Ids from 'ids';
2
- import { isString, isArray, isFunction, isNumber, bind, assign, isNil, get, isUndefined, set, isObject } from 'min-dash';
2
+ import { isString, isArray, isFunction, isNumber, bind, assign, isNil, get, isUndefined, set, findIndex, isObject } from 'min-dash';
3
3
  import { unaryTest, evaluate, parseUnaryTests, parseExpressions } from 'feelin';
4
4
  import Big from 'big.js';
5
5
  import snarkdown from '@bpmn-io/snarkdown';
6
6
  import classNames from 'classnames';
7
- import { jsx, jsxs } from 'preact/jsx-runtime';
7
+ import { jsx, jsxs, Fragment as Fragment$1 } from 'preact/jsx-runtime';
8
8
  import { useContext, useState, useEffect, useRef, useCallback, useMemo } from 'preact/hooks';
9
9
  import { createContext, createElement, Fragment, render } from 'preact';
10
10
  import React, { createPortal } from 'preact/compat';
@@ -740,7 +740,7 @@ function getExpressionVariableNames(expression) {
740
740
  } while (cursor.next());
741
741
  return Array.from(variables);
742
742
  }
743
- function isExpression$2(value) {
743
+ function isExpression$1(value) {
744
744
  return isString(value) && value.startsWith('=');
745
745
  }
746
746
 
@@ -791,7 +791,10 @@ const VALUES_SOURCES_PATHS = {
791
791
  [VALUES_SOURCES.INPUT]: ['valuesKey']
792
792
  };
793
793
  const VALUES_SOURCES_DEFAULTS = {
794
- [VALUES_SOURCES.STATIC]: [],
794
+ [VALUES_SOURCES.STATIC]: [{
795
+ label: 'Value',
796
+ value: 'value'
797
+ }],
795
798
  [VALUES_SOURCES.INPUT]: ''
796
799
  };
797
800
 
@@ -917,12 +920,6 @@ function getSchemaVariables(schema) {
917
920
  return Array.from(new Set(variables));
918
921
  }
919
922
 
920
- // helper ///////////////
921
-
922
- function isExpression$1(value) {
923
- return isString(value) && value.startsWith('=');
924
- }
925
-
926
923
  class Importer {
927
924
  /**
928
925
  * @constructor
@@ -1235,15 +1232,14 @@ function Button(props) {
1235
1232
  })
1236
1233
  });
1237
1234
  }
1238
- Button.create = function (options = {}) {
1239
- return {
1240
- action: 'submit',
1241
- ...options
1242
- };
1243
- };
1235
+ Button.create = (options = {}) => ({
1236
+ action: 'submit',
1237
+ ...options
1238
+ });
1244
1239
  Button.type = type$b;
1245
1240
  Button.label = 'Button';
1246
1241
  Button.keyed = true;
1242
+ Button.group = 'action';
1247
1243
 
1248
1244
  const FormRenderContext = createContext({
1249
1245
  Empty: props => {
@@ -1256,6 +1252,7 @@ const FormRenderContext = createContext({
1256
1252
  return props.children;
1257
1253
  }
1258
1254
  });
1255
+ var FormRenderContext$1 = FormRenderContext;
1259
1256
 
1260
1257
  /**
1261
1258
  * @param {string} type
@@ -1268,6 +1265,7 @@ const FormContext = createContext({
1268
1265
  getService,
1269
1266
  formId: null
1270
1267
  });
1268
+ var FormContext$1 = FormContext;
1271
1269
 
1272
1270
  function Description(props) {
1273
1271
  const {
@@ -1343,7 +1341,7 @@ function Checkbox(props) {
1343
1341
  };
1344
1342
  const {
1345
1343
  formId
1346
- } = useContext(FormContext);
1344
+ } = useContext(FormContext$1);
1347
1345
  return jsxs("div", {
1348
1346
  class: classNames(formFieldClasses(type$a, {
1349
1347
  errors,
@@ -1370,11 +1368,9 @@ function Checkbox(props) {
1370
1368
  })]
1371
1369
  });
1372
1370
  }
1373
- Checkbox.create = function (options = {}) {
1374
- return {
1375
- ...options
1376
- };
1377
- };
1371
+ Checkbox.create = (options = {}) => ({
1372
+ ...options
1373
+ });
1378
1374
  Checkbox.type = type$a;
1379
1375
  Checkbox.label = 'Checkbox';
1380
1376
  Checkbox.keyed = true;
@@ -1382,11 +1378,12 @@ Checkbox.emptyValue = false;
1382
1378
  Checkbox.sanitizeValue = ({
1383
1379
  value
1384
1380
  }) => value === true;
1381
+ Checkbox.group = 'selection';
1385
1382
 
1386
1383
  function useService (type, strict) {
1387
1384
  const {
1388
1385
  getService
1389
- } = useContext(FormContext);
1386
+ } = useContext(FormContext$1);
1390
1387
  return getService(type, strict);
1391
1388
  }
1392
1389
 
@@ -1483,8 +1480,8 @@ function parseInputTime(stringTime) {
1483
1480
  if (is12h) {
1484
1481
  const isPM = workingString.includes('pm');
1485
1482
  const digits = workingString.match(/\d+/g);
1486
- const displayHour = parseInt(digits?.[0]);
1487
- const minute = parseInt(digits?.[1]) || 0;
1483
+ const displayHour = parseInt(digits && digits[0]);
1484
+ const minute = parseInt(digits && digits[1]) || 0;
1488
1485
  const isValidDisplayHour = isNumber(displayHour) && displayHour >= 1 && displayHour <= 12;
1489
1486
  const isValidMinute = minute >= 0 && minute <= 59;
1490
1487
  if (!isValidDisplayHour || !isValidMinute) return null;
@@ -1492,8 +1489,8 @@ function parseInputTime(stringTime) {
1492
1489
  return hour * 60 + minute;
1493
1490
  } else {
1494
1491
  const digits = workingString.match(/\d+/g);
1495
- const hour = parseInt(digits?.[0]);
1496
- const minute = parseInt(digits?.[1]);
1492
+ const hour = parseInt(digits && digits[0]);
1493
+ const minute = parseInt(digits && digits[1]);
1497
1494
  const isValidHour = isNumber(hour) && hour >= 0 && hour <= 23;
1498
1495
  const isValidMinute = isNumber(minute) && minute >= 0 && minute <= 59;
1499
1496
  if (!isValidHour || !isValidMinute) return null;
@@ -1696,7 +1693,7 @@ function Checklist(props) {
1696
1693
  } = useValuesAsync(field);
1697
1694
  const {
1698
1695
  formId
1699
- } = useContext(FormContext);
1696
+ } = useContext(FormContext$1);
1700
1697
  return jsxs("div", {
1701
1698
  class: classNames(formFieldClasses(type$9, {
1702
1699
  errors,
@@ -1728,13 +1725,18 @@ function Checklist(props) {
1728
1725
  })]
1729
1726
  });
1730
1727
  }
1731
- Checklist.create = function (options = {}) {
1732
- if (options.valuesKey) return options;
1733
- return {
1734
- values: [{
1728
+ Checklist.create = (options = {}) => {
1729
+ const defaults = {};
1730
+
1731
+ // provide default values if valuesKey isn't set
1732
+ if (!options.valuesKey) {
1733
+ defaults.values = [{
1735
1734
  label: 'Value',
1736
1735
  value: 'value'
1737
- }],
1736
+ }];
1737
+ }
1738
+ return {
1739
+ ...defaults,
1738
1740
  ...options
1739
1741
  };
1740
1742
  };
@@ -1743,6 +1745,7 @@ Checklist.label = 'Checklist';
1743
1745
  Checklist.keyed = true;
1744
1746
  Checklist.emptyValue = [];
1745
1747
  Checklist.sanitizeValue = sanitizeMultiSelectValue;
1748
+ Checklist.group = 'selection';
1746
1749
 
1747
1750
  /**
1748
1751
  * Check if condition is met with given variables.
@@ -1786,7 +1789,7 @@ function FormField(props) {
1786
1789
  const {
1787
1790
  Element,
1788
1791
  Empty
1789
- } = useContext(FormRenderContext);
1792
+ } = useContext(FormRenderContext$1);
1790
1793
  const FormFieldComponent = formFields.get(field.type);
1791
1794
  if (!FormFieldComponent) {
1792
1795
  throw new Error(`cannot render field <${field.type}>`);
@@ -1818,7 +1821,7 @@ function Default(props) {
1818
1821
  const {
1819
1822
  Children,
1820
1823
  Empty
1821
- } = useContext(FormRenderContext);
1824
+ } = useContext(FormRenderContext$1);
1822
1825
  const {
1823
1826
  field
1824
1827
  } = props;
@@ -1837,20 +1840,20 @@ function Default(props) {
1837
1840
  }), components.length ? null : jsx(Empty, {})]
1838
1841
  });
1839
1842
  }
1840
- Default.create = function (options = {}) {
1841
- return {
1842
- components: [],
1843
- ...options
1844
- };
1845
- };
1843
+ Default.create = (options = {}) => ({
1844
+ components: [],
1845
+ ...options
1846
+ });
1846
1847
  Default.type = 'default';
1847
1848
  Default.keyed = false;
1849
+ Default.label = null;
1850
+ Default.group = null;
1848
1851
 
1849
- function _extends$h() { _extends$h = 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$h.apply(this, arguments); }
1852
+ function _extends$j() { _extends$j = 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$j.apply(this, arguments); }
1850
1853
  var CalendarIcon = (({
1851
1854
  styles = {},
1852
1855
  ...props
1853
- }) => /*#__PURE__*/React.createElement("svg", _extends$h({
1856
+ }) => /*#__PURE__*/React.createElement("svg", _extends$j({
1854
1857
  width: "14",
1855
1858
  height: "15",
1856
1859
  viewBox: "0 0 28 30",
@@ -1859,8 +1862,8 @@ var CalendarIcon = (({
1859
1862
  }, props), /*#__PURE__*/React.createElement("path", {
1860
1863
  fillRule: "evenodd",
1861
1864
  clipRule: "evenodd",
1862
- d: "M19 2H9V0H7v2H2a2 2 0 00-2 2v24a2 2 0 002 2h24a2 2 0 002-2V4a2 2 0 00-2-2h-5V0h-2v2zM7 7V4H2v5h24V4h-5v3h-2V4H9v3H7zm-5 4v17h24V11H2z",
1863
- fill: "currentColor"
1865
+ fill: "currentColor",
1866
+ d: "M19 2H9V0H7v2H2a2 2 0 00-2 2v24a2 2 0 002 2h24a2 2 0 002-2V4a2 2 0 00-2-2h-5V0h-2v2zM7 7V4H2v5h24V4h-5v3h-2V4H9v3H7zm-5 4v17h24V11H2z"
1864
1867
  })));
1865
1868
 
1866
1869
  function InputAdorner(props) {
@@ -1873,10 +1876,10 @@ function InputAdorner(props) {
1873
1876
  disabled,
1874
1877
  hasErrors
1875
1878
  } = props;
1876
- const onAdornmentClick = () => inputRef?.current?.focus();
1879
+ const onAdornmentClick = () => inputRef && inputRef.current && inputRef.current.focus();
1877
1880
  return jsxs("div", {
1878
1881
  class: classNames('fjs-input-group', {
1879
- 'disabled': disabled
1882
+ 'fjs-disabled': disabled
1880
1883
  }, {
1881
1884
  'hasErrors': hasErrors
1882
1885
  }),
@@ -1930,14 +1933,10 @@ function Datepicker(props) {
1930
1933
  dateFormat: 'm/d/Y',
1931
1934
  static: true,
1932
1935
  clickOpens: false,
1936
+ // TODO: support dates prior to 1900 (https://github.com/bpmn-io/form-js/issues/533)
1937
+ minDate: disallowPassedDates ? 'today' : '01/01/1900',
1933
1938
  errorHandler: () => {/* do nothing, we expect the values to sometimes be erronous and we don't want warnings polluting the console */}
1934
1939
  };
1935
- if (disallowPassedDates) {
1936
- config = {
1937
- ...config,
1938
- minDate: 'today'
1939
- };
1940
- }
1941
1940
  const instance = flatpickr(dateInputRef.current, config);
1942
1941
  setFlatpickrInstance(instance);
1943
1942
  const onCalendarFocusOut = e => {
@@ -2021,7 +2020,7 @@ function Datepicker(props) {
2021
2020
  class: 'fjs-input',
2022
2021
  disabled: disabled,
2023
2022
  placeholder: "mm/dd/yyyy",
2024
- autoComplete: "false",
2023
+ autoComplete: "off",
2025
2024
  onFocus: onInputFocus,
2026
2025
  onKeyDown: onInputKeyDown,
2027
2026
  onMouseDown: e => !flatpickrInstance.isOpen && flatpickrInstance.open(),
@@ -2034,24 +2033,24 @@ function Datepicker(props) {
2034
2033
  });
2035
2034
  }
2036
2035
 
2037
- function _extends$g() { _extends$g = 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$g.apply(this, arguments); }
2036
+ function _extends$i() { _extends$i = 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$i.apply(this, arguments); }
2038
2037
  var ClockIcon = (({
2039
2038
  styles = {},
2040
2039
  ...props
2041
- }) => /*#__PURE__*/React.createElement("svg", _extends$g({
2040
+ }) => /*#__PURE__*/React.createElement("svg", _extends$i({
2042
2041
  width: "16",
2043
2042
  height: "16",
2044
2043
  viewBox: "0 0 28 29",
2045
2044
  fill: "none",
2046
2045
  xmlns: "http://www.w3.org/2000/svg"
2047
2046
  }, props), /*#__PURE__*/React.createElement("path", {
2048
- d: "M13 14.41L18.59 20 20 18.59l-5-5.01V5h-2v9.41z",
2049
- fill: "currentColor"
2047
+ fill: "currentColor",
2048
+ d: "M13 14.41L18.59 20 20 18.59l-5-5.01V5h-2v9.41z"
2050
2049
  }), /*#__PURE__*/React.createElement("path", {
2051
2050
  fillRule: "evenodd",
2052
2051
  clipRule: "evenodd",
2053
- d: "M6.222 25.64A14 14 0 1021.778 2.36 14 14 0 006.222 25.64zM7.333 4.023a12 12 0 1113.334 19.955A12 12 0 017.333 4.022z",
2054
- fill: "currentColor"
2052
+ fill: "currentColor",
2053
+ d: "M6.222 25.64A14 14 0 1021.778 2.36 14 14 0 006.222 25.64zM7.333 4.023a12 12 0 1113.334 19.955A12 12 0 017.333 4.022z"
2055
2054
  })));
2056
2055
 
2057
2056
  function useKeyDownAction(targetKey, action, listenerElement = window) {
@@ -2074,7 +2073,7 @@ const DEFAULT_LABEL_GETTER = value => value;
2074
2073
  const NOOP = () => {};
2075
2074
  function DropdownList(props) {
2076
2075
  const {
2077
- keyEventsListener = window,
2076
+ listenerElement = window,
2078
2077
  values = [],
2079
2078
  getLabel = DEFAULT_LABEL_GETTER,
2080
2079
  onValueSelected = NOOP,
@@ -2104,18 +2103,18 @@ function DropdownList(props) {
2104
2103
  changeFocusedValueIndex(-1);
2105
2104
  setMouseControl(false);
2106
2105
  }
2107
- }, keyEventsListener);
2106
+ }, listenerElement);
2108
2107
  useKeyDownAction('ArrowDown', () => {
2109
2108
  if (values.length) {
2110
2109
  changeFocusedValueIndex(1);
2111
2110
  setMouseControl(false);
2112
2111
  }
2113
- }, keyEventsListener);
2112
+ }, listenerElement);
2114
2113
  useKeyDownAction('Enter', () => {
2115
2114
  if (focusedItem) {
2116
2115
  onValueSelected(focusedItem);
2117
2116
  }
2118
- }, keyEventsListener);
2117
+ }, listenerElement);
2119
2118
  useEffect(() => {
2120
2119
  const individualEntries = dropdownContainer.current.children;
2121
2120
  if (individualEntries.length && !mouseControl) {
@@ -2288,7 +2287,7 @@ function Timepicker(props) {
2288
2287
  value: rawValue,
2289
2288
  disabled: disabled,
2290
2289
  placeholder: use24h ? 'hh:mm' : 'hh:mm ?m',
2291
- autoComplete: "false",
2290
+ autoComplete: "off",
2292
2291
  onFocus: () => useDropdown && setDropdownIsOpen(true),
2293
2292
  onClick: () => useDropdown && setDropdownIsOpen(true)
2294
2293
 
@@ -2339,7 +2338,7 @@ function Datetime(props) {
2339
2338
  } = validate;
2340
2339
  const {
2341
2340
  formId
2342
- } = useContext(FormContext);
2341
+ } = useContext(FormContext$1);
2343
2342
  const getNullDateTime = () => ({
2344
2343
  date: new Date(Date.parse(null)),
2345
2344
  time: null
@@ -2480,12 +2479,12 @@ function Datetime(props) {
2480
2479
  })]
2481
2480
  });
2482
2481
  }
2483
- Datetime.create = function (options = {}) {
2484
- const newOptions = {};
2485
- set(newOptions, DATETIME_SUBTYPE_PATH, DATETIME_SUBTYPES.DATE);
2486
- set(newOptions, DATE_LABEL_PATH, 'Date');
2482
+ Datetime.create = (options = {}) => {
2483
+ const defaults = {};
2484
+ set(defaults, DATETIME_SUBTYPE_PATH, DATETIME_SUBTYPES.DATE);
2485
+ set(defaults, DATE_LABEL_PATH, 'Date');
2487
2486
  return {
2488
- ...newOptions,
2487
+ ...defaults,
2489
2488
  ...options
2490
2489
  };
2491
2490
  };
@@ -2493,6 +2492,8 @@ Datetime.type = type$8;
2493
2492
  Datetime.keyed = true;
2494
2493
  Datetime.emptyValue = null;
2495
2494
  Datetime.sanitizeValue = sanitizeDateTimePickerValue;
2495
+ Datetime.label = 'Date time';
2496
+ Datetime.group = 'basic-input';
2496
2497
 
2497
2498
  /**
2498
2499
  * This file must not be changed or exchanged.
@@ -2656,11 +2657,11 @@ function isExpression(value) {
2656
2657
  return isString(value) && value.startsWith('=');
2657
2658
  }
2658
2659
 
2659
- function _extends$f() { _extends$f = 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$f.apply(this, arguments); }
2660
+ function _extends$h() { _extends$h = 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$h.apply(this, arguments); }
2660
2661
  var ImagePlaceholder = (({
2661
2662
  styles = {},
2662
2663
  ...props
2663
- }) => /*#__PURE__*/React.createElement("svg", _extends$f({
2664
+ }) => /*#__PURE__*/React.createElement("svg", _extends$h({
2664
2665
  width: "64",
2665
2666
  height: "64",
2666
2667
  viewBox: "0 0 1280 1280",
@@ -2700,7 +2701,7 @@ function Image(props) {
2700
2701
  const altText = useExpressionValue(alt);
2701
2702
  const {
2702
2703
  formId
2703
- } = useContext(FormContext);
2704
+ } = useContext(FormContext$1);
2704
2705
  return jsx("div", {
2705
2706
  class: formFieldClasses(type$7),
2706
2707
  children: jsxs("div", {
@@ -2719,13 +2720,47 @@ function Image(props) {
2719
2720
  })
2720
2721
  });
2721
2722
  }
2722
- Image.create = function (options = {}) {
2723
- return {
2724
- ...options
2725
- };
2726
- };
2723
+ Image.create = (options = {}) => ({
2724
+ ...options
2725
+ });
2727
2726
  Image.type = type$7;
2728
2727
  Image.keyed = false;
2728
+ Image.label = 'Image view';
2729
+ Image.group = 'presentation';
2730
+
2731
+ function _extends$g() { _extends$g = 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$g.apply(this, arguments); }
2732
+ var AngelDownIcon = (({
2733
+ styles = {},
2734
+ ...props
2735
+ }) => /*#__PURE__*/React.createElement("svg", _extends$g({
2736
+ xmlns: "http://www.w3.org/2000/svg",
2737
+ width: "8",
2738
+ height: "8"
2739
+ }, props), /*#__PURE__*/React.createElement("path", {
2740
+ fillRule: "evenodd",
2741
+ clipRule: "evenodd",
2742
+ fill: "currentColor",
2743
+ stroke: "currentColor",
2744
+ strokeWidth: ".5",
2745
+ d: "M7.75 1.336L4 6.125.258 1.335 0 1.54l4 5.125L8 1.54zm0 0"
2746
+ })));
2747
+
2748
+ function _extends$f() { _extends$f = 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$f.apply(this, arguments); }
2749
+ var AngelUpIcon = (({
2750
+ styles = {},
2751
+ ...props
2752
+ }) => /*#__PURE__*/React.createElement("svg", _extends$f({
2753
+ xmlns: "http://www.w3.org/2000/svg",
2754
+ width: "8",
2755
+ height: "8"
2756
+ }, props), /*#__PURE__*/React.createElement("path", {
2757
+ fillRule: "evenodd",
2758
+ clipRule: "evenodd",
2759
+ fill: "currentColor",
2760
+ stroke: "currentColor",
2761
+ strokeWidth: ".5",
2762
+ d: "M7.75 6.664L4 1.875.258 6.665 0 6.46l4-5.125L8 6.46zm0 0"
2763
+ })));
2729
2764
 
2730
2765
  const type$6 = 'number';
2731
2766
  function Numberfield(props) {
@@ -2854,7 +2889,7 @@ function Numberfield(props) {
2854
2889
  };
2855
2890
  const {
2856
2891
  formId
2857
- } = useContext(FormContext);
2892
+ } = useContext(FormContext$1);
2858
2893
  return jsxs("div", {
2859
2894
  class: formFieldClasses(type$6, {
2860
2895
  errors,
@@ -2870,7 +2905,7 @@ function Numberfield(props) {
2870
2905
  post: suffixAdorner,
2871
2906
  children: jsxs("div", {
2872
2907
  class: classNames('fjs-vertical-group', {
2873
- 'disabled': disabled
2908
+ 'fjs-disabled': disabled
2874
2909
  }, {
2875
2910
  'hasErrors': errors.length
2876
2911
  }),
@@ -2891,22 +2926,24 @@ function Numberfield(props) {
2891
2926
  value: displayValue
2892
2927
  }), jsxs("div", {
2893
2928
  class: classNames('fjs-number-arrow-container', {
2894
- 'disabled': disabled
2929
+ 'fjs-disabled': disabled
2895
2930
  }),
2896
2931
  children: [jsx("button", {
2897
2932
  class: "fjs-number-arrow-up",
2898
2933
  type: "button",
2934
+ "aria-label": "Increment",
2899
2935
  onClick: () => increment(),
2900
2936
  tabIndex: -1,
2901
- children: "\u02C4"
2937
+ children: jsx(AngelUpIcon, {})
2902
2938
  }), jsx("div", {
2903
2939
  class: "fjs-number-arrow-separator"
2904
2940
  }), jsx("button", {
2905
2941
  class: "fjs-number-arrow-down",
2906
2942
  type: "button",
2943
+ "aria-label": "Decrement",
2907
2944
  onClick: () => decrement(),
2908
2945
  tabIndex: -1,
2909
- children: "\u02C5"
2946
+ children: jsx(AngelDownIcon, {})
2910
2947
  })]
2911
2948
  })]
2912
2949
  })
@@ -2917,7 +2954,9 @@ function Numberfield(props) {
2917
2954
  })]
2918
2955
  });
2919
2956
  }
2920
- Numberfield.create = (options = {}) => options;
2957
+ Numberfield.create = (options = {}) => ({
2958
+ ...options
2959
+ });
2921
2960
  Numberfield.sanitizeValue = ({
2922
2961
  value,
2923
2962
  formField
@@ -2935,6 +2974,7 @@ Numberfield.type = type$6;
2935
2974
  Numberfield.keyed = true;
2936
2975
  Numberfield.label = 'Number';
2937
2976
  Numberfield.emptyValue = null;
2977
+ Numberfield.group = 'basic-input';
2938
2978
 
2939
2979
  const type$5 = 'radio';
2940
2980
  function Radio(props) {
@@ -2965,7 +3005,7 @@ function Radio(props) {
2965
3005
  } = useValuesAsync(field);
2966
3006
  const {
2967
3007
  formId
2968
- } = useContext(FormContext);
3008
+ } = useContext(FormContext$1);
2969
3009
  return jsxs("div", {
2970
3010
  class: formFieldClasses(type$5, {
2971
3011
  errors,
@@ -2999,12 +3039,17 @@ function Radio(props) {
2999
3039
  });
3000
3040
  }
3001
3041
  Radio.create = function (options = {}) {
3002
- if (options.valuesKey) return options;
3003
- return {
3004
- values: [{
3042
+ const defaults = {};
3043
+
3044
+ // provide default values if valuesKey isn't set
3045
+ if (!options.valuesKey) {
3046
+ defaults.values = [{
3005
3047
  label: 'Value',
3006
3048
  value: 'value'
3007
- }],
3049
+ }];
3050
+ }
3051
+ return {
3052
+ ...defaults,
3008
3053
  ...options
3009
3054
  };
3010
3055
  };
@@ -3013,6 +3058,266 @@ Radio.label = 'Radio';
3013
3058
  Radio.keyed = true;
3014
3059
  Radio.emptyValue = null;
3015
3060
  Radio.sanitizeValue = sanitizeSingleSelectValue;
3061
+ Radio.group = 'selection';
3062
+
3063
+ function _extends$e() { _extends$e = 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$e.apply(this, arguments); }
3064
+ var XMarkIcon = (({
3065
+ styles = {},
3066
+ ...props
3067
+ }) => /*#__PURE__*/React.createElement("svg", _extends$e({
3068
+ xmlns: "http://www.w3.org/2000/svg",
3069
+ width: "8",
3070
+ height: "8"
3071
+ }, props), /*#__PURE__*/React.createElement("path", {
3072
+ fillRule: "evenodd",
3073
+ clipRule: "evenodd",
3074
+ fill: "currentColor",
3075
+ stroke: "currentColor",
3076
+ strokeWidth: ".5",
3077
+ d: "M4 3.766L7.43.336l.234.234L4.234 4l3.43 3.43-.234.234L4 4.234.57 7.664.336 7.43 3.766 4 .336.57.57.336zm0 0"
3078
+ })));
3079
+
3080
+ function SearchableSelect(props) {
3081
+ const {
3082
+ id,
3083
+ disabled,
3084
+ errors,
3085
+ field,
3086
+ value
3087
+ } = props;
3088
+ const {
3089
+ formId
3090
+ } = useContext(FormContext$1);
3091
+ const [filter, setFilter] = useState('');
3092
+ const [isDropdownExpanded, setIsDropdownExpanded] = useState(false);
3093
+ const [shouldApplyFilter, setShouldApplyFilter] = useState(true);
3094
+ const [isEscapeClosed, setIsEscapeClose] = useState(false);
3095
+ const searchbarRef = useRef();
3096
+ const {
3097
+ state: loadState,
3098
+ values: options
3099
+ } = useValuesAsync(field);
3100
+
3101
+ // We cache a map of option values to their index so that we don't need to search the whole options array every time to correlate the label
3102
+ const valueToOptionMap = useMemo(() => Object.assign({}, ...options.map((o, x) => ({
3103
+ [o.value]: options[x]
3104
+ }))), [options]);
3105
+ const valueLabel = useMemo(() => value && valueToOptionMap[value] && valueToOptionMap[value].label || '', [value, valueToOptionMap]);
3106
+
3107
+ // whenever we change the underlying value, set the label to it
3108
+ useEffect(() => {
3109
+ setFilter(valueLabel);
3110
+ }, [valueLabel]);
3111
+ const filteredOptions = useMemo(() => {
3112
+ if (loadState === LOAD_STATES.LOADED) {
3113
+ return shouldApplyFilter ? options.filter(o => o.label && o.value && o.label.toLowerCase().includes(filter.toLowerCase())) : options;
3114
+ }
3115
+ return [];
3116
+ }, [filter, loadState, options, shouldApplyFilter]);
3117
+ const onChange = ({
3118
+ target
3119
+ }) => {
3120
+ setIsEscapeClose(false);
3121
+ setIsDropdownExpanded(true);
3122
+ setShouldApplyFilter(true);
3123
+ setFilter(target.value || '');
3124
+ };
3125
+ const setValue = useCallback(option => {
3126
+ setFilter(option && option.label || '');
3127
+ props.onChange({
3128
+ value: option && option.value || null,
3129
+ field
3130
+ });
3131
+ }, [field, props]);
3132
+ const onInputKeyDown = useCallback(keyDownEvent => {
3133
+ switch (keyDownEvent.key) {
3134
+ case 'ArrowUp':
3135
+ keyDownEvent.preventDefault();
3136
+ break;
3137
+ case 'ArrowDown':
3138
+ {
3139
+ if (!isDropdownExpanded) {
3140
+ setIsDropdownExpanded(true);
3141
+ setShouldApplyFilter(false);
3142
+ }
3143
+ keyDownEvent.preventDefault();
3144
+ break;
3145
+ }
3146
+ case 'Escape':
3147
+ setIsEscapeClose(true);
3148
+ break;
3149
+ case 'Enter':
3150
+ if (isEscapeClosed) {
3151
+ setIsEscapeClose(false);
3152
+ }
3153
+ break;
3154
+ }
3155
+ }, [isDropdownExpanded, isEscapeClosed]);
3156
+ const displayState = useMemo(() => {
3157
+ const ds = {};
3158
+ ds.componentReady = !disabled && loadState === LOAD_STATES.LOADED;
3159
+ ds.displayCross = ds.componentReady && value !== null && value !== undefined;
3160
+ ds.displayDropdown = !disabled && isDropdownExpanded && !isEscapeClosed;
3161
+ return ds;
3162
+ }, [disabled, isDropdownExpanded, isEscapeClosed, loadState, value]);
3163
+ const onAngelMouseDown = useCallback(e => {
3164
+ setIsEscapeClose(false);
3165
+ setIsDropdownExpanded(!isDropdownExpanded);
3166
+ const searchbar = searchbarRef.current;
3167
+ isDropdownExpanded ? searchbar.blur() : searchbar.focus();
3168
+ e.preventDefault();
3169
+ }, [isDropdownExpanded]);
3170
+ return jsxs(Fragment$1, {
3171
+ children: [jsxs("div", {
3172
+ id: prefixId(`${id}`, formId),
3173
+ class: classNames('fjs-input-group', {
3174
+ 'disabled': disabled
3175
+ }, {
3176
+ 'hasErrors': errors.length
3177
+ }),
3178
+ children: [jsx("input", {
3179
+ disabled: disabled,
3180
+ class: "fjs-input",
3181
+ ref: searchbarRef,
3182
+ id: prefixId(`${id}-search`, formId),
3183
+ onChange: onChange,
3184
+ type: "text",
3185
+ value: filter,
3186
+ placeholder: 'Search',
3187
+ autoComplete: "off",
3188
+ onKeyDown: e => onInputKeyDown(e),
3189
+ onMouseDown: () => {
3190
+ setIsEscapeClose(false);
3191
+ setIsDropdownExpanded(true);
3192
+ setShouldApplyFilter(false);
3193
+ },
3194
+ onFocus: () => {
3195
+ setIsDropdownExpanded(true);
3196
+ setShouldApplyFilter(false);
3197
+ },
3198
+ onBlur: () => {
3199
+ setIsDropdownExpanded(false);
3200
+ setFilter(valueLabel);
3201
+ }
3202
+ }), displayState.displayCross && jsxs("span", {
3203
+ class: "fjs-select-cross",
3204
+ onMouseDown: e => {
3205
+ setValue(null);
3206
+ e.preventDefault();
3207
+ },
3208
+ children: [jsx(XMarkIcon, {}), " "]
3209
+ }), jsx("span", {
3210
+ class: "fjs-select-arrow",
3211
+ onMouseDown: e => onAngelMouseDown(e),
3212
+ children: displayState.displayDropdown ? jsx(AngelUpIcon, {}) : jsx(AngelDownIcon, {})
3213
+ })]
3214
+ }), jsx("div", {
3215
+ class: "fjs-select-anchor",
3216
+ children: displayState.displayDropdown && jsx(DropdownList, {
3217
+ values: filteredOptions,
3218
+ getLabel: o => o.label,
3219
+ onValueSelected: o => {
3220
+ setValue(o);
3221
+ setIsDropdownExpanded(false);
3222
+ },
3223
+ listenerElement: searchbarRef.current
3224
+ })
3225
+ })]
3226
+ });
3227
+ }
3228
+
3229
+ function SimpleSelect(props) {
3230
+ const {
3231
+ id,
3232
+ disabled,
3233
+ errors,
3234
+ field,
3235
+ value
3236
+ } = props;
3237
+ const {
3238
+ formId
3239
+ } = useContext(FormContext$1);
3240
+ const [isDropdownExpanded, setIsDropdownExpanded] = useState(false);
3241
+ const selectRef = useRef();
3242
+ const {
3243
+ state: loadState,
3244
+ values: options
3245
+ } = useValuesAsync(field);
3246
+
3247
+ // We cache a map of option values to their index so that we don't need to search the whole options array every time to correlate the label
3248
+ const valueToOptionMap = useMemo(() => Object.assign({}, ...options.map((o, x) => ({
3249
+ [o.value]: options[x]
3250
+ }))), [options]);
3251
+ const valueLabel = useMemo(() => value && valueToOptionMap[value] && valueToOptionMap[value].label || '', [value, valueToOptionMap]);
3252
+ const setValue = useCallback(option => {
3253
+ props.onChange({
3254
+ value: option && option.value || null,
3255
+ field
3256
+ });
3257
+ }, [field, props]);
3258
+ const displayState = useMemo(() => {
3259
+ const ds = {};
3260
+ ds.componentReady = !disabled && loadState === LOAD_STATES.LOADED;
3261
+ ds.displayCross = ds.componentReady && value !== null && value !== undefined;
3262
+ ds.displayDropdown = !disabled && isDropdownExpanded;
3263
+ return ds;
3264
+ }, [disabled, isDropdownExpanded, loadState, value]);
3265
+ const onMouseDown = useCallback(e => {
3266
+ const select = selectRef.current;
3267
+ setIsDropdownExpanded(!isDropdownExpanded);
3268
+ if (isDropdownExpanded) {
3269
+ select.blur();
3270
+ } else {
3271
+ select.focus();
3272
+ }
3273
+ e.preventDefault();
3274
+ }, [isDropdownExpanded]);
3275
+ const initialFocusIndex = useMemo(() => value && findIndex(options, o => o.value === value) || 0, [options, value]);
3276
+ return jsxs(Fragment$1, {
3277
+ children: [jsxs("div", {
3278
+ ref: selectRef,
3279
+ id: prefixId(`${id}`, formId),
3280
+ class: classNames('fjs-input-group', {
3281
+ 'disabled': disabled
3282
+ }, {
3283
+ 'hasErrors': errors.length
3284
+ }),
3285
+ onFocus: () => setIsDropdownExpanded(true),
3286
+ onBlur: () => setIsDropdownExpanded(false),
3287
+ onMouseDown: e => onMouseDown(e),
3288
+ tabIndex: disabled ? undefined : 0,
3289
+ children: [jsx("div", {
3290
+ class: classNames('fjs-select-display', {
3291
+ 'fjs-select-placeholder': !value
3292
+ }),
3293
+ id: prefixId(`${id}-display`, formId),
3294
+ children: valueLabel || 'Select'
3295
+ }), displayState.displayCross && jsx("span", {
3296
+ class: "fjs-select-cross",
3297
+ onMouseDown: e => {
3298
+ setValue(null);
3299
+ e.stopPropagation();
3300
+ },
3301
+ children: jsx(XMarkIcon, {})
3302
+ }), jsx("span", {
3303
+ class: "fjs-select-arrow",
3304
+ children: displayState.displayDropdown ? jsx(AngelUpIcon, {}) : jsx(AngelDownIcon, {})
3305
+ })]
3306
+ }), jsx("div", {
3307
+ class: "fjs-select-anchor",
3308
+ children: displayState.displayDropdown && jsx(DropdownList, {
3309
+ values: options,
3310
+ getLabel: o => o.label,
3311
+ initialFocusIndex: initialFocusIndex,
3312
+ onValueSelected: o => {
3313
+ setValue(o);
3314
+ setIsDropdownExpanded(false);
3315
+ },
3316
+ listenerElement: selectRef.current
3317
+ })
3318
+ })]
3319
+ });
3320
+ }
3016
3321
 
3017
3322
  const type$4 = 'select';
3018
3323
  function Select(props) {
@@ -3020,32 +3325,30 @@ function Select(props) {
3020
3325
  disabled,
3021
3326
  errors = [],
3022
3327
  field,
3328
+ onChange,
3023
3329
  value
3024
3330
  } = props;
3025
3331
  const {
3026
3332
  description,
3027
3333
  id,
3028
3334
  label,
3335
+ searchable = false,
3029
3336
  validate = {}
3030
3337
  } = field;
3031
3338
  const {
3032
3339
  required
3033
3340
  } = validate;
3034
- const onChange = ({
3035
- target
3036
- }) => {
3037
- props.onChange({
3038
- field,
3039
- value: target.value === '' ? null : target.value
3040
- });
3041
- };
3042
- const {
3043
- state: loadState,
3044
- values: options
3045
- } = useValuesAsync(field);
3046
3341
  const {
3047
3342
  formId
3048
- } = useContext(FormContext);
3343
+ } = useContext(FormContext$1);
3344
+ const selectProps = useMemo(() => ({
3345
+ id,
3346
+ disabled,
3347
+ errors,
3348
+ field,
3349
+ value,
3350
+ onChange
3351
+ }), [disabled, errors, field, id, value, onChange]);
3049
3352
  return jsxs("div", {
3050
3353
  class: formFieldClasses(type$4, {
3051
3354
  errors,
@@ -3055,20 +3358,10 @@ function Select(props) {
3055
3358
  id: prefixId(id, formId),
3056
3359
  label: label,
3057
3360
  required: required
3058
- }), jsxs("select", {
3059
- class: "fjs-select",
3060
- disabled: disabled,
3061
- id: prefixId(id, formId),
3062
- onChange: onChange,
3063
- value: value || '',
3064
- children: [jsx("option", {
3065
- value: ""
3066
- }), loadState == LOAD_STATES.LOADED && options.map((option, index) => {
3067
- return jsx("option", {
3068
- value: option.value,
3069
- children: option.label
3070
- }, `${id}-${index}`);
3071
- })]
3361
+ }), searchable ? jsx(SearchableSelect, {
3362
+ ...selectProps
3363
+ }) : jsx(SimpleSelect, {
3364
+ ...selectProps
3072
3365
  }), jsx(Description, {
3073
3366
  description: description
3074
3367
  }), jsx(Errors, {
@@ -3076,13 +3369,18 @@ function Select(props) {
3076
3369
  })]
3077
3370
  });
3078
3371
  }
3079
- Select.create = function (options = {}) {
3080
- if (options.valuesKey) return options;
3081
- return {
3082
- values: [{
3372
+ Select.create = (options = {}) => {
3373
+ const defaults = {};
3374
+
3375
+ // provide default values if valuesKey isn't set
3376
+ if (!options.valuesKey) {
3377
+ defaults.values = [{
3083
3378
  label: 'Value',
3084
3379
  value: 'value'
3085
- }],
3380
+ }];
3381
+ }
3382
+ return {
3383
+ ...defaults,
3086
3384
  ...options
3087
3385
  };
3088
3386
  };
@@ -3091,22 +3389,7 @@ Select.label = 'Select';
3091
3389
  Select.keyed = true;
3092
3390
  Select.emptyValue = null;
3093
3391
  Select.sanitizeValue = sanitizeSingleSelectValue;
3094
-
3095
- function _extends$e() { _extends$e = 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$e.apply(this, arguments); }
3096
- var CloseIcon = (({
3097
- styles = {},
3098
- ...props
3099
- }) => /*#__PURE__*/React.createElement("svg", _extends$e({
3100
- width: "16",
3101
- height: "16",
3102
- fill: "none",
3103
- xmlns: "http://www.w3.org/2000/svg"
3104
- }, props), /*#__PURE__*/React.createElement("path", {
3105
- fillRule: "evenodd",
3106
- clipRule: "evenodd",
3107
- d: "M12 4.7l-.7-.7L8 7.3 4.7 4l-.7.7L7.3 8 4 11.3l.7.7L8 8.7l3.3 3.3.7-.7L8.7 8 12 4.7z",
3108
- fill: "currentColor"
3109
- })));
3392
+ Select.group = 'selection';
3110
3393
 
3111
3394
  const type$3 = 'taglist';
3112
3395
  function Taglist(props) {
@@ -3123,7 +3406,7 @@ function Taglist(props) {
3123
3406
  } = field;
3124
3407
  const {
3125
3408
  formId
3126
- } = useContext(FormContext);
3409
+ } = useContext(FormContext$1);
3127
3410
  const [filter, setFilter] = useState('');
3128
3411
  const [filteredOptions, setFilteredOptions] = useState([]);
3129
3412
  const [isDropdownExpanded, setIsDropdownExpanded] = useState(false);
@@ -3211,6 +3494,7 @@ function Taglist(props) {
3211
3494
  searchbarRef.current.focus();
3212
3495
  }
3213
3496
  };
3497
+ const shouldDisplayDropdown = useMemo(() => !disabled && loadState === LOAD_STATES.LOADED && isDropdownExpanded && !isEscapeClosed, [disabled, isDropdownExpanded, isEscapeClosed, loadState]);
3214
3498
  return jsxs("div", {
3215
3499
  class: formFieldClasses(type$3, {
3216
3500
  errors,
@@ -3221,23 +3505,25 @@ function Taglist(props) {
3221
3505
  id: prefixId(`${id}-search`, formId)
3222
3506
  }), jsxs("div", {
3223
3507
  class: classNames('fjs-taglist', {
3224
- 'disabled': disabled
3508
+ 'fjs-disabled': disabled
3225
3509
  }),
3226
- children: [!disabled && loadState === LOAD_STATES.LOADED && jsx("div", {
3510
+ children: [loadState === LOAD_STATES.LOADED && jsx("div", {
3227
3511
  class: "fjs-taglist-tags",
3228
3512
  children: values.map(v => {
3229
3513
  return jsxs("div", {
3230
- class: "fjs-taglist-tag",
3514
+ class: classNames('fjs-taglist-tag', {
3515
+ 'fjs-disabled': disabled
3516
+ }),
3231
3517
  onMouseDown: e => e.preventDefault(),
3232
3518
  children: [jsx("span", {
3233
3519
  class: "fjs-taglist-tag-label",
3234
3520
  children: valueToOptionMap[v] ? valueToOptionMap[v].label : `unexpected value{${v}}`
3235
- }), jsx("button", {
3521
+ }), !disabled && jsx("button", {
3236
3522
  type: "button",
3237
3523
  title: "Remove tag",
3238
3524
  class: "fjs-taglist-tag-remove",
3239
3525
  onClick: event => onTagRemoveClick(event, v),
3240
- children: jsx(CloseIcon, {})
3526
+ children: jsx(XMarkIcon, {})
3241
3527
  })]
3242
3528
  });
3243
3529
  })
@@ -3249,7 +3535,7 @@ function Taglist(props) {
3249
3535
  onChange: onFilterChange,
3250
3536
  type: "text",
3251
3537
  value: filter,
3252
- placeholder: 'Search',
3538
+ placeholder: disabled ? '' : 'Search',
3253
3539
  autoComplete: "off",
3254
3540
  onKeyDown: e => onInputKeyDown(e),
3255
3541
  onMouseDown: () => setIsEscapeClose(false),
@@ -3261,7 +3547,7 @@ function Taglist(props) {
3261
3547
  })]
3262
3548
  }), jsx("div", {
3263
3549
  class: "fjs-taglist-anchor",
3264
- children: !disabled && loadState === LOAD_STATES.LOADED && isDropdownExpanded && !isEscapeClosed && jsx(DropdownList, {
3550
+ children: shouldDisplayDropdown && jsx(DropdownList, {
3265
3551
  values: filteredOptions,
3266
3552
  getLabel: o => o.label,
3267
3553
  onValueSelected: o => selectValue(o.value),
@@ -3275,33 +3561,234 @@ function Taglist(props) {
3275
3561
  })]
3276
3562
  });
3277
3563
  }
3278
- Taglist.create = function (options = {}) {
3279
- if (options.valuesKey) return options;
3280
- return {
3281
- values: [{
3564
+ Taglist.create = (options = {}) => {
3565
+ const defaults = {};
3566
+
3567
+ // provide default values if valuesKey isn't set
3568
+ if (!options.valuesKey) {
3569
+ defaults.values = [{
3282
3570
  label: 'Value',
3283
3571
  value: 'value'
3284
- }],
3572
+ }];
3573
+ }
3574
+ return {
3575
+ ...defaults,
3285
3576
  ...options
3286
3577
  };
3287
3578
  };
3288
3579
  Taglist.type = type$3;
3289
- Taglist.label = 'Taglist';
3580
+ Taglist.label = 'Tag list';
3290
3581
  Taglist.keyed = true;
3291
3582
  Taglist.emptyValue = [];
3292
3583
  Taglist.sanitizeValue = sanitizeMultiSelectValue;
3584
+ Taglist.group = 'selection';
3293
3585
 
3294
- function _extends$d() { _extends$d = 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$d.apply(this, arguments); }
3295
- var ButtonIcon = (({
3296
- styles = {},
3297
- ...props
3298
- }) => /*#__PURE__*/React.createElement("svg", _extends$d({
3299
- xmlns: "http://www.w3.org/2000/svg",
3300
- width: "54",
3301
- height: "54"
3302
- }, props), /*#__PURE__*/React.createElement("path", {
3303
- fillRule: "evenodd",
3304
- d: "M45 17a3 3 0 013 3v14a3 3 0 01-3 3H9a3 3 0 01-3-3V20a3 3 0 013-3h36zm-9 8.889H18v2.222h18V25.89z"
3586
+ const type$2 = 'text';
3587
+ function Text(props) {
3588
+ const {
3589
+ field,
3590
+ disableLinks
3591
+ } = props;
3592
+ const {
3593
+ text = ''
3594
+ } = field;
3595
+ const textValue = useExpressionValue(text) || '';
3596
+ const componentOverrides = disableLinks ? {
3597
+ 'a': DisabledLink
3598
+ } : {};
3599
+ return jsx("div", {
3600
+ class: formFieldClasses(type$2),
3601
+ children: jsx(Markup, {
3602
+ markup: safeMarkdown(textValue),
3603
+ components: componentOverrides,
3604
+ trim: false
3605
+ })
3606
+ });
3607
+ }
3608
+ Text.create = (options = {}) => ({
3609
+ text: '# Text',
3610
+ ...options
3611
+ });
3612
+ Text.type = type$2;
3613
+ Text.keyed = false;
3614
+ Text.group = 'presentation';
3615
+ Text.label = 'Text view';
3616
+ function DisabledLink({
3617
+ href,
3618
+ children
3619
+ }) {
3620
+ return jsx("a", {
3621
+ class: "fjs-disabled-link",
3622
+ href: href,
3623
+ tabIndex: -1,
3624
+ children: children
3625
+ });
3626
+ }
3627
+
3628
+ const type$1 = 'textfield';
3629
+ function Textfield(props) {
3630
+ const {
3631
+ disabled,
3632
+ errors = [],
3633
+ field,
3634
+ value = ''
3635
+ } = props;
3636
+ const {
3637
+ description,
3638
+ id,
3639
+ label,
3640
+ appearance = {},
3641
+ validate = {}
3642
+ } = field;
3643
+ const {
3644
+ prefixAdorner,
3645
+ suffixAdorner
3646
+ } = appearance;
3647
+ const {
3648
+ required
3649
+ } = validate;
3650
+ const onChange = ({
3651
+ target
3652
+ }) => {
3653
+ props.onChange({
3654
+ field,
3655
+ value: target.value
3656
+ });
3657
+ };
3658
+ const {
3659
+ formId
3660
+ } = useContext(FormContext$1);
3661
+ return jsxs("div", {
3662
+ class: formFieldClasses(type$1, {
3663
+ errors,
3664
+ disabled
3665
+ }),
3666
+ children: [jsx(Label, {
3667
+ id: prefixId(id, formId),
3668
+ label: label,
3669
+ required: required
3670
+ }), jsx(InputAdorner, {
3671
+ disabled: disabled,
3672
+ pre: prefixAdorner,
3673
+ post: suffixAdorner,
3674
+ children: jsx("input", {
3675
+ class: "fjs-input",
3676
+ disabled: disabled,
3677
+ id: prefixId(id, formId),
3678
+ onInput: onChange,
3679
+ type: "text",
3680
+ value: value
3681
+ })
3682
+ }), jsx(Description, {
3683
+ description: description
3684
+ }), jsx(Errors, {
3685
+ errors: errors
3686
+ })]
3687
+ });
3688
+ }
3689
+ Textfield.create = (options = {}) => ({
3690
+ ...options
3691
+ });
3692
+ Textfield.type = type$1;
3693
+ Textfield.label = 'Text field';
3694
+ Textfield.keyed = true;
3695
+ Textfield.emptyValue = '';
3696
+ Textfield.sanitizeValue = ({
3697
+ value
3698
+ }) => isArray(value) || isObject(value) ? '' : String(value);
3699
+ Textfield.group = 'basic-input';
3700
+
3701
+ const type = 'textarea';
3702
+ function Textarea(props) {
3703
+ const {
3704
+ disabled,
3705
+ errors = [],
3706
+ field,
3707
+ value = ''
3708
+ } = props;
3709
+ const {
3710
+ description,
3711
+ id,
3712
+ label,
3713
+ validate = {}
3714
+ } = field;
3715
+ const {
3716
+ required
3717
+ } = validate;
3718
+ const textareaRef = useRef();
3719
+ const onInput = ({
3720
+ target
3721
+ }) => {
3722
+ props.onChange({
3723
+ field,
3724
+ value: target.value
3725
+ });
3726
+ };
3727
+ const autoSizeTextarea = useCallback(textarea => {
3728
+ // Ensures the textarea shrinks back, and improves resizing behavior consistency
3729
+ textarea.style.height = '0px';
3730
+ const computed = window.getComputedStyle(textarea);
3731
+ const calculatedHeight = parseInt(computed.getPropertyValue('border-top-width')) + parseInt(computed.getPropertyValue('padding-top')) + textarea.scrollHeight + parseInt(computed.getPropertyValue('padding-bottom')) + parseInt(computed.getPropertyValue('border-bottom-width'));
3732
+ const minHeight = 75;
3733
+ const maxHeight = 350;
3734
+ const displayHeight = Math.max(Math.min(calculatedHeight, maxHeight), minHeight);
3735
+ textarea.style.height = `${displayHeight}px`;
3736
+
3737
+ // Overflow is hidden by default to hide scrollbar flickering
3738
+ textarea.style.overflow = calculatedHeight > maxHeight ? 'visible' : 'hidden';
3739
+ }, []);
3740
+ useEffect(() => {
3741
+ autoSizeTextarea(textareaRef.current);
3742
+ }, [autoSizeTextarea, value]);
3743
+ const {
3744
+ formId
3745
+ } = useContext(FormContext$1);
3746
+ return jsxs("div", {
3747
+ class: formFieldClasses(type, {
3748
+ errors,
3749
+ disabled
3750
+ }),
3751
+ children: [jsx(Label, {
3752
+ id: prefixId(id, formId),
3753
+ label: label,
3754
+ required: required
3755
+ }), jsx("textarea", {
3756
+ class: "fjs-textarea",
3757
+ disabled: disabled,
3758
+ id: prefixId(id, formId),
3759
+ onInput: onInput,
3760
+ value: value,
3761
+ ref: textareaRef
3762
+ }), jsx(Description, {
3763
+ description: description
3764
+ }), jsx(Errors, {
3765
+ errors: errors
3766
+ })]
3767
+ });
3768
+ }
3769
+ Textarea.create = (options = {}) => ({
3770
+ ...options
3771
+ });
3772
+ Textarea.type = type;
3773
+ Textarea.label = 'Text area';
3774
+ Textarea.keyed = true;
3775
+ Textarea.emptyValue = '';
3776
+ Textarea.sanitizeValue = ({
3777
+ value
3778
+ }) => isArray(value) || isObject(value) ? '' : String(value);
3779
+ Textarea.group = 'basic-input';
3780
+
3781
+ function _extends$d() { _extends$d = 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$d.apply(this, arguments); }
3782
+ var ButtonIcon = (({
3783
+ styles = {},
3784
+ ...props
3785
+ }) => /*#__PURE__*/React.createElement("svg", _extends$d({
3786
+ xmlns: "http://www.w3.org/2000/svg",
3787
+ width: "54",
3788
+ height: "54"
3789
+ }, props), /*#__PURE__*/React.createElement("path", {
3790
+ fillRule: "evenodd",
3791
+ d: "M45 17a3 3 0 013 3v14a3 3 0 01-3 3H9a3 3 0 01-3-3V20a3 3 0 013-3h36zm-9 8.889H18v2.222h18V25.89z"
3305
3792
  })));
3306
3793
 
3307
3794
  function _extends$c() { _extends$c = 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$c.apply(this, arguments); }
@@ -3533,226 +4020,13 @@ const iconsByType = {
3533
4020
  default: FormIcon
3534
4021
  };
3535
4022
 
3536
- const type$2 = 'text';
3537
- function Text(props) {
3538
- const {
3539
- field,
3540
- disabled
3541
- } = props;
3542
- const {
3543
- text = ''
3544
- } = field;
3545
- const textValue = useExpressionValue(text) || '';
3546
- return jsx("div", {
3547
- class: formFieldClasses(type$2),
3548
- children: renderText(field, textValue, disabled)
3549
- });
3550
- }
3551
- Text.create = function (options = {}) {
3552
- return {
3553
- text: '# Text',
3554
- ...options
3555
- };
3556
- };
3557
- Text.type = type$2;
3558
- Text.keyed = false;
3559
-
3560
- // helper //////////////
3561
-
3562
- function renderText(field, content, disabled) {
3563
- const {
3564
- text
3565
- } = field;
3566
- const Icon = iconsByType['text'];
3567
- if (disabled) {
3568
- if (!text) {
3569
- return jsxs("div", {
3570
- class: "fjs-form-field-placeholder",
3571
- children: [jsx(Icon, {
3572
- viewBox: "0 0 54 54"
3573
- }), "Text view is empty"]
3574
- });
3575
- }
3576
- if (isExpression$2(text)) {
3577
- return jsxs("div", {
3578
- class: "fjs-form-field-placeholder",
3579
- children: [jsx(Icon, {
3580
- viewBox: "0 0 54 54"
3581
- }), "Text view is populated by an expression"]
3582
- });
3583
- }
3584
- }
3585
- return jsx(Markup, {
3586
- markup: safeMarkdown(content),
3587
- trim: false
3588
- });
3589
- }
3590
-
3591
- const type$1 = 'textfield';
3592
- function Textfield(props) {
3593
- const {
3594
- disabled,
3595
- errors = [],
3596
- field,
3597
- value = ''
3598
- } = props;
3599
- const {
3600
- description,
3601
- id,
3602
- label,
3603
- appearance = {},
3604
- validate = {}
3605
- } = field;
3606
- const {
3607
- prefixAdorner,
3608
- suffixAdorner
3609
- } = appearance;
3610
- const {
3611
- required
3612
- } = validate;
3613
- const onChange = ({
3614
- target
3615
- }) => {
3616
- props.onChange({
3617
- field,
3618
- value: target.value
3619
- });
3620
- };
3621
- const {
3622
- formId
3623
- } = useContext(FormContext);
3624
- return jsxs("div", {
3625
- class: formFieldClasses(type$1, {
3626
- errors,
3627
- disabled
3628
- }),
3629
- children: [jsx(Label, {
3630
- id: prefixId(id, formId),
3631
- label: label,
3632
- required: required
3633
- }), jsx(InputAdorner, {
3634
- disabled: disabled,
3635
- pre: prefixAdorner,
3636
- post: suffixAdorner,
3637
- children: jsx("input", {
3638
- class: "fjs-input",
3639
- disabled: disabled,
3640
- id: prefixId(id, formId),
3641
- onInput: onChange,
3642
- type: "text",
3643
- value: value
3644
- })
3645
- }), jsx(Description, {
3646
- description: description
3647
- }), jsx(Errors, {
3648
- errors: errors
3649
- })]
3650
- });
3651
- }
3652
- Textfield.create = function (options = {}) {
3653
- return {
3654
- ...options
3655
- };
3656
- };
3657
- Textfield.type = type$1;
3658
- Textfield.label = 'Text field';
3659
- Textfield.keyed = true;
3660
- Textfield.emptyValue = '';
3661
- Textfield.sanitizeValue = ({
3662
- value
3663
- }) => isArray(value) || isObject(value) ? '' : String(value);
3664
-
3665
- const type = 'textarea';
3666
- function Textarea(props) {
3667
- const {
3668
- disabled,
3669
- errors = [],
3670
- field,
3671
- value = ''
3672
- } = props;
3673
- const {
3674
- description,
3675
- id,
3676
- label,
3677
- validate = {}
3678
- } = field;
3679
- const {
3680
- required
3681
- } = validate;
3682
- const textareaRef = useRef();
3683
- const onInput = ({
3684
- target
3685
- }) => {
3686
- props.onChange({
3687
- field,
3688
- value: target.value
3689
- });
3690
- };
3691
- const autoSizeTextarea = useCallback(textarea => {
3692
- // Ensures the textarea shrinks back, and improves resizing behavior consistency
3693
- textarea.style.height = '0px';
3694
- const computed = window.getComputedStyle(textarea);
3695
- const calculatedHeight = parseInt(computed.getPropertyValue('border-top-width')) + parseInt(computed.getPropertyValue('padding-top')) + textarea.scrollHeight + parseInt(computed.getPropertyValue('padding-bottom')) + parseInt(computed.getPropertyValue('border-bottom-width'));
3696
- const minHeight = 75;
3697
- const maxHeight = 350;
3698
- const displayHeight = Math.max(Math.min(calculatedHeight, maxHeight), minHeight);
3699
- textarea.style.height = `${displayHeight}px`;
3700
-
3701
- // Overflow is hidden by default to hide scrollbar flickering
3702
- textarea.style.overflow = calculatedHeight > maxHeight ? 'visible' : 'hidden';
3703
- }, []);
3704
- useEffect(() => {
3705
- autoSizeTextarea(textareaRef.current);
3706
- }, [autoSizeTextarea, value]);
3707
- const {
3708
- formId
3709
- } = useContext(FormContext);
3710
- return jsxs("div", {
3711
- class: formFieldClasses(type, {
3712
- errors,
3713
- disabled
3714
- }),
3715
- children: [jsx(Label, {
3716
- id: prefixId(id, formId),
3717
- label: label,
3718
- required: required
3719
- }), jsx("textarea", {
3720
- class: "fjs-textarea",
3721
- disabled: disabled,
3722
- id: prefixId(id, formId),
3723
- onInput: onInput,
3724
- value: value,
3725
- ref: textareaRef
3726
- }), jsx(Description, {
3727
- description: description
3728
- }), jsx(Errors, {
3729
- errors: errors
3730
- })]
3731
- });
3732
- }
3733
- Textarea.create = function (options = {}) {
3734
- return {
3735
- ...options
3736
- };
3737
- };
3738
- Textarea.type = type;
3739
- Textarea.label = 'Text area';
3740
- Textarea.keyed = true;
3741
- Textarea.emptyValue = '';
3742
- Textarea.sanitizeValue = ({
3743
- value
3744
- }) => isArray(value) || isObject(value) ? '' : String(value);
3745
-
3746
4023
  const formFields = [Button, Checkbox, Checklist, Default, Image, Numberfield, Datetime, Radio, Select, Taglist, Text, Textfield, Textarea];
3747
4024
 
3748
4025
  class FormFields {
3749
4026
  constructor() {
3750
4027
  this._formFields = {};
3751
4028
  formFields.forEach(formField => {
3752
- const {
3753
- type
3754
- } = formField;
3755
- this.register(type, formField);
4029
+ this.register(formField.type, formField);
3756
4030
  });
3757
4031
  }
3758
4032
  register(type, formField) {
@@ -3794,7 +4068,7 @@ function Renderer(config, eventBus, form, injector) {
3794
4068
  if (!schema) {
3795
4069
  return null;
3796
4070
  }
3797
- return jsx(FormContext.Provider, {
4071
+ return jsx(FormContext$1.Provider, {
3798
4072
  value: formContext,
3799
4073
  children: jsx(FormComponent, {
3800
4074
  onChange: onChange,
@@ -4195,7 +4469,7 @@ class Form {
4195
4469
  }
4196
4470
  }
4197
4471
 
4198
- const schemaVersion = 6;
4472
+ const schemaVersion = 7;
4199
4473
 
4200
4474
  /**
4201
4475
  * @typedef { import('./types').CreateFormOptions } CreateFormOptions
@@ -4220,5 +4494,5 @@ function createForm(options) {
4220
4494
  });
4221
4495
  }
4222
4496
 
4223
- export { Button, Checkbox, Checklist, DATETIME_SUBTYPES, DATETIME_SUBTYPES_LABELS, DATETIME_SUBTYPE_PATH, DATE_DISALLOW_PAST_PATH, DATE_LABEL_PATH, Datetime, Default, Form, FormComponent, FormContext, FormFieldRegistry, FormFields, FormRenderContext, Image, MINUTES_IN_DAY, Numberfield, Radio, Select, TIME_INTERVAL_PATH, TIME_LABEL_PATH, TIME_SERIALISINGFORMAT_LABELS, TIME_SERIALISING_FORMATS, TIME_SERIALISING_FORMAT_PATH, TIME_USE24H_PATH, Taglist, Text, Textarea, Textfield, VALUES_SOURCES, VALUES_SOURCES_DEFAULTS, VALUES_SOURCES_LABELS, VALUES_SOURCES_PATHS, VALUES_SOURCE_DEFAULT, clone, createForm, createFormContainer, createInjector, findErrors, formFields, generateIdForType, generateIndexForType, getSchemaVariables, getValuesSource, iconsByType, isRequired, pathParse, pathStringify, pathsEqual, schemaVersion };
4497
+ export { Button, Checkbox, Checklist, DATETIME_SUBTYPES, DATETIME_SUBTYPES_LABELS, DATETIME_SUBTYPE_PATH, DATE_DISALLOW_PAST_PATH, DATE_LABEL_PATH, Datetime, Default, Form, FormComponent, FormContext$1 as FormContext, FormFieldRegistry, FormFields, FormRenderContext$1 as FormRenderContext, Image, MINUTES_IN_DAY, Numberfield, Radio, Select, TIME_INTERVAL_PATH, TIME_LABEL_PATH, TIME_SERIALISINGFORMAT_LABELS, TIME_SERIALISING_FORMATS, TIME_SERIALISING_FORMAT_PATH, TIME_USE24H_PATH, Taglist, Text, Textarea, Textfield, VALUES_SOURCES, VALUES_SOURCES_DEFAULTS, VALUES_SOURCES_LABELS, VALUES_SOURCES_PATHS, VALUES_SOURCE_DEFAULT, clone, createForm, createFormContainer, createInjector, findErrors, formFields, generateIdForType, generateIndexForType, getExpressionVariableNames, getSchemaVariables, getValuesSource, getVariableNames, iconsByType, isExpression$1 as isExpression, isRequired, pathParse, pathStringify, pathsEqual, schemaVersion };
4224
4498
  //# sourceMappingURL=index.es.js.map