@bpmn-io/form-js-viewer 0.7.2 → 0.8.0-alpha.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
@@ -2,10 +2,11 @@ import Ids from 'ids';
2
2
  import { isArray, isFunction, isNumber, bind, assign, isNil, get, isUndefined, set, isString } from 'min-dash';
3
3
  import snarkdown from '@bpmn-io/snarkdown';
4
4
  import { jsx, jsxs } from 'preact/jsx-runtime';
5
- import { useContext, useState, useCallback } from 'preact/hooks';
5
+ import { useContext, useState, useEffect, useRef, useMemo, useCallback } from 'preact/hooks';
6
6
  import { createContext, createElement, Fragment, render } from 'preact';
7
+ import React, { createPortal } from 'preact/compat';
8
+ import classNames from 'classnames';
7
9
  import Markup from 'preact-markup';
8
- import { createPortal } from 'preact/compat';
9
10
  import { Injector } from 'didi';
10
11
 
11
12
  var FN_REF = '__fn';
@@ -807,19 +808,26 @@ class Importer {
807
808
  const {
808
809
  defaultValue,
809
810
  _path,
810
- type
811
- } = formField;
812
-
813
- if (!_path) {
814
- return importedData;
815
- } // (1) try to get value from data
816
- // (2) try to get default value from form field
817
- // (3) get empty value from form field
818
-
811
+ type,
812
+ valuesKey
813
+ } = formField; // get values defined via valuesKey
814
+
815
+ if (valuesKey) {
816
+ importedData = { ...importedData,
817
+ [valuesKey]: get(data, [valuesKey])
818
+ };
819
+ } // try to get value from data
820
+ // if unavailable - try to get default value from form field
821
+ // if unavailable - get empty value from form field
822
+
823
+
824
+ if (_path) {
825
+ importedData = { ...importedData,
826
+ [_path[0]]: get(data, _path, isUndefined(defaultValue) ? this._formFields.get(type).emptyValue : defaultValue)
827
+ };
828
+ }
819
829
 
820
- return { ...importedData,
821
- [_path[0]]: get(data, _path, isUndefined(defaultValue) ? this._formFields.get(type).emptyValue : defaultValue)
822
- };
830
+ return importedData;
823
831
  }, {});
824
832
  }
825
833
 
@@ -980,7 +988,7 @@ function safeMarkdown(markdown) {
980
988
  return sanitizeHTML(html);
981
989
  }
982
990
 
983
- const type$6 = 'button';
991
+ const type$8 = 'button';
984
992
  function Button(props) {
985
993
  const {
986
994
  disabled,
@@ -990,7 +998,7 @@ function Button(props) {
990
998
  action = 'submit'
991
999
  } = field;
992
1000
  return jsx("div", {
993
- class: formFieldClasses(type$6),
1001
+ class: formFieldClasses(type$8),
994
1002
  children: jsx("button", {
995
1003
  class: "fjs-button",
996
1004
  type: action,
@@ -1007,7 +1015,7 @@ Button.create = function (options = {}) {
1007
1015
  };
1008
1016
  };
1009
1017
 
1010
- Button.type = type$6;
1018
+ Button.type = type$8;
1011
1019
  Button.label = 'Button';
1012
1020
  Button.keyed = true;
1013
1021
 
@@ -1089,7 +1097,7 @@ function Label(props) {
1089
1097
  });
1090
1098
  }
1091
1099
 
1092
- const type$5 = 'checkbox';
1100
+ const type$7 = 'checkbox';
1093
1101
  function Checkbox(props) {
1094
1102
  const {
1095
1103
  disabled,
@@ -1116,7 +1124,7 @@ function Checkbox(props) {
1116
1124
  formId
1117
1125
  } = useContext(FormContext);
1118
1126
  return jsxs("div", {
1119
- class: formFieldClasses(type$5, errors),
1127
+ class: formFieldClasses(type$7, errors),
1120
1128
  children: [jsx(Label, {
1121
1129
  id: prefixId(id, formId),
1122
1130
  label: label,
@@ -1142,7 +1150,7 @@ Checkbox.create = function (options = {}) {
1142
1150
  };
1143
1151
  };
1144
1152
 
1145
- Checkbox.type = type$5;
1153
+ Checkbox.type = type$7;
1146
1154
  Checkbox.label = 'Checkbox';
1147
1155
  Checkbox.keyed = true;
1148
1156
  Checkbox.emptyValue = false;
@@ -1154,6 +1162,152 @@ function useService (type, strict) {
1154
1162
  return getService(type, strict);
1155
1163
  }
1156
1164
 
1165
+ /**
1166
+ * @enum { String }
1167
+ */
1168
+
1169
+ const LOAD_STATES = {
1170
+ LOADING: 'loading',
1171
+ LOADED: 'loaded',
1172
+ ERROR: 'error'
1173
+ };
1174
+ /**
1175
+ * @typedef {Object} ValuesGetter
1176
+ * @property {Object[]} values - The values data
1177
+ * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
1178
+ */
1179
+
1180
+ /**
1181
+ * A hook to load values for single and multiselect components.
1182
+ *
1183
+ * @param {Object} field - The form field to handle values for
1184
+ * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
1185
+ */
1186
+
1187
+ function useValuesAsync (field) {
1188
+ const {
1189
+ valuesKey,
1190
+ values: staticValues
1191
+ } = field;
1192
+ const [valuesGetter, setValuesGetter] = useState({
1193
+ values: [],
1194
+ error: undefined,
1195
+ state: LOAD_STATES.LOADING
1196
+ });
1197
+
1198
+ const initialData = useService('form')._getState().initialData;
1199
+
1200
+ useEffect(() => {
1201
+ let values = [];
1202
+
1203
+ if (valuesKey !== undefined) {
1204
+ const keyedValues = (initialData || {})[valuesKey];
1205
+
1206
+ if (keyedValues && Array.isArray(keyedValues)) {
1207
+ values = keyedValues;
1208
+ }
1209
+ } else if (staticValues !== undefined) {
1210
+ values = Array.isArray(staticValues) ? staticValues : [];
1211
+ } else {
1212
+ setValuesGetter(getErrorState('No values source defined in the form definition'));
1213
+ return;
1214
+ }
1215
+
1216
+ setValuesGetter(buildLoadedState(values));
1217
+ }, [valuesKey, staticValues, initialData]);
1218
+ return valuesGetter;
1219
+ }
1220
+
1221
+ const getErrorState = error => ({
1222
+ values: [],
1223
+ error,
1224
+ state: LOAD_STATES.ERROR
1225
+ });
1226
+
1227
+ const buildLoadedState = values => ({
1228
+ values,
1229
+ error: undefined,
1230
+ state: LOAD_STATES.LOADED
1231
+ });
1232
+
1233
+ const type$6 = 'checklist';
1234
+ function Checklist(props) {
1235
+ const {
1236
+ disabled,
1237
+ errors = [],
1238
+ field,
1239
+ value = []
1240
+ } = props;
1241
+ const {
1242
+ description,
1243
+ id,
1244
+ label
1245
+ } = field;
1246
+
1247
+ const toggleCheckbox = v => {
1248
+ let newValue = [...value];
1249
+
1250
+ if (!newValue.includes(v)) {
1251
+ newValue.push(v);
1252
+ } else {
1253
+ newValue = newValue.filter(x => x != v);
1254
+ }
1255
+
1256
+ props.onChange({
1257
+ field,
1258
+ value: newValue
1259
+ });
1260
+ };
1261
+
1262
+ const {
1263
+ state: loadState,
1264
+ values: options
1265
+ } = useValuesAsync(field);
1266
+ const {
1267
+ formId
1268
+ } = useContext(FormContext);
1269
+ return jsxs("div", {
1270
+ class: formFieldClasses(type$6, errors),
1271
+ children: [jsx(Label, {
1272
+ label: label
1273
+ }), loadState == LOAD_STATES.LOADED && options.map((v, index) => {
1274
+ return jsx(Label, {
1275
+ id: prefixId(`${id}-${index}`, formId),
1276
+ label: v.label,
1277
+ required: false,
1278
+ children: jsx("input", {
1279
+ checked: value.includes(v.value),
1280
+ class: "fjs-input",
1281
+ disabled: disabled,
1282
+ id: prefixId(`${id}-${index}`, formId),
1283
+ type: "checkbox",
1284
+ onClick: () => toggleCheckbox(v.value)
1285
+ })
1286
+ }, `${id}-${index}`);
1287
+ }), jsx(Description, {
1288
+ description: description
1289
+ }), jsx(Errors, {
1290
+ errors: errors
1291
+ })]
1292
+ });
1293
+ }
1294
+
1295
+ Checklist.create = function (options = {}) {
1296
+ if (options.valuesKey) return options;
1297
+ return {
1298
+ values: [{
1299
+ label: 'Value',
1300
+ value: 'value'
1301
+ }],
1302
+ ...options
1303
+ };
1304
+ };
1305
+
1306
+ Checklist.type = type$6;
1307
+ Checklist.label = 'Checklist';
1308
+ Checklist.keyed = true;
1309
+ Checklist.emptyValue = [];
1310
+
1157
1311
  const noop$1 = () => false;
1158
1312
 
1159
1313
  function FormField(props) {
@@ -1362,7 +1516,7 @@ function FormComponent(props) {
1362
1516
  });
1363
1517
  }
1364
1518
 
1365
- const type$4 = 'number';
1519
+ const type$5 = 'number';
1366
1520
  function Number(props) {
1367
1521
  const {
1368
1522
  disabled,
@@ -1394,7 +1548,7 @@ function Number(props) {
1394
1548
  formId
1395
1549
  } = useContext(FormContext);
1396
1550
  return jsxs("div", {
1397
- class: formFieldClasses(type$4, errors),
1551
+ class: formFieldClasses(type$5, errors),
1398
1552
  children: [jsx(Label, {
1399
1553
  id: prefixId(id, formId),
1400
1554
  label: label,
@@ -1419,12 +1573,12 @@ Number.create = function (options = {}) {
1419
1573
  };
1420
1574
  };
1421
1575
 
1422
- Number.type = type$4;
1576
+ Number.type = type$5;
1423
1577
  Number.keyed = true;
1424
1578
  Number.label = 'Number';
1425
1579
  Number.emptyValue = null;
1426
1580
 
1427
- const type$3 = 'radio';
1581
+ const type$4 = 'radio';
1428
1582
  function Radio(props) {
1429
1583
  const {
1430
1584
  disabled,
@@ -1436,8 +1590,7 @@ function Radio(props) {
1436
1590
  description,
1437
1591
  id,
1438
1592
  label,
1439
- validate = {},
1440
- values
1593
+ validate = {}
1441
1594
  } = field;
1442
1595
  const {
1443
1596
  required
@@ -1450,26 +1603,30 @@ function Radio(props) {
1450
1603
  });
1451
1604
  };
1452
1605
 
1606
+ const {
1607
+ state: loadState,
1608
+ values: options
1609
+ } = useValuesAsync(field);
1453
1610
  const {
1454
1611
  formId
1455
1612
  } = useContext(FormContext);
1456
1613
  return jsxs("div", {
1457
- class: formFieldClasses(type$3, errors),
1614
+ class: formFieldClasses(type$4, errors),
1458
1615
  children: [jsx(Label, {
1459
1616
  label: label,
1460
1617
  required: required
1461
- }), values.map((v, index) => {
1618
+ }), loadState == LOAD_STATES.LOADED && options.map((option, index) => {
1462
1619
  return jsx(Label, {
1463
1620
  id: prefixId(`${id}-${index}`, formId),
1464
- label: v.label,
1621
+ label: option.label,
1465
1622
  required: false,
1466
1623
  children: jsx("input", {
1467
- checked: v.value === value,
1624
+ checked: option.value === value,
1468
1625
  class: "fjs-input",
1469
1626
  disabled: disabled,
1470
1627
  id: prefixId(`${id}-${index}`, formId),
1471
1628
  type: "radio",
1472
- onClick: () => onChange(v.value)
1629
+ onClick: () => onChange(option.value)
1473
1630
  })
1474
1631
  }, `${id}-${index}`);
1475
1632
  }), jsx(Description, {
@@ -1481,6 +1638,7 @@ function Radio(props) {
1481
1638
  }
1482
1639
 
1483
1640
  Radio.create = function (options = {}) {
1641
+ if (options.valuesKey) return options;
1484
1642
  return {
1485
1643
  values: [{
1486
1644
  label: 'Value',
@@ -1490,12 +1648,12 @@ Radio.create = function (options = {}) {
1490
1648
  };
1491
1649
  };
1492
1650
 
1493
- Radio.type = type$3;
1651
+ Radio.type = type$4;
1494
1652
  Radio.label = 'Radio';
1495
1653
  Radio.keyed = true;
1496
1654
  Radio.emptyValue = null;
1497
1655
 
1498
- const type$2 = 'select';
1656
+ const type$3 = 'select';
1499
1657
  function Select(props) {
1500
1658
  const {
1501
1659
  disabled,
@@ -1507,8 +1665,7 @@ function Select(props) {
1507
1665
  description,
1508
1666
  id,
1509
1667
  label,
1510
- validate = {},
1511
- values
1668
+ validate = {}
1512
1669
  } = field;
1513
1670
  const {
1514
1671
  required
@@ -1523,11 +1680,15 @@ function Select(props) {
1523
1680
  });
1524
1681
  };
1525
1682
 
1683
+ const {
1684
+ state: loadState,
1685
+ values: options
1686
+ } = useValuesAsync(field);
1526
1687
  const {
1527
1688
  formId
1528
1689
  } = useContext(FormContext);
1529
1690
  return jsxs("div", {
1530
- class: formFieldClasses(type$2, errors),
1691
+ class: formFieldClasses(type$3, errors),
1531
1692
  children: [jsx(Label, {
1532
1693
  id: prefixId(id, formId),
1533
1694
  label: label,
@@ -1540,10 +1701,10 @@ function Select(props) {
1540
1701
  value: value || '',
1541
1702
  children: [jsx("option", {
1542
1703
  value: ""
1543
- }), values.map((v, index) => {
1704
+ }), loadState == LOAD_STATES.LOADED && options.map((option, index) => {
1544
1705
  return jsx("option", {
1545
- value: v.value,
1546
- children: v.label
1706
+ value: option.value,
1707
+ children: option.label
1547
1708
  }, `${id}-${index}`);
1548
1709
  })]
1549
1710
  }), jsx(Description, {
@@ -1555,6 +1716,7 @@ function Select(props) {
1555
1716
  }
1556
1717
 
1557
1718
  Select.create = function (options = {}) {
1719
+ if (options.valuesKey) return options;
1558
1720
  return {
1559
1721
  values: [{
1560
1722
  label: 'Value',
@@ -1564,11 +1726,313 @@ Select.create = function (options = {}) {
1564
1726
  };
1565
1727
  };
1566
1728
 
1567
- Select.type = type$2;
1729
+ Select.type = type$3;
1568
1730
  Select.label = 'Select';
1569
1731
  Select.keyed = true;
1570
1732
  Select.emptyValue = null;
1571
1733
 
1734
+ function _extends() { _extends = Object.assign || 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); }
1735
+ var CloseIcon = (({
1736
+ styles = {},
1737
+ ...props
1738
+ }) => /*#__PURE__*/React.createElement("svg", _extends({
1739
+ width: "16",
1740
+ height: "16",
1741
+ fill: "none",
1742
+ xmlns: "http://www.w3.org/2000/svg"
1743
+ }, props), /*#__PURE__*/React.createElement("path", {
1744
+ fillRule: "evenodd",
1745
+ clipRule: "evenodd",
1746
+ 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",
1747
+ fill: "#000"
1748
+ })));
1749
+
1750
+ function useKeyDownAction(targetKey, action, listenerElement = window) {
1751
+ function downHandler({
1752
+ key
1753
+ }) {
1754
+ if (key === targetKey) {
1755
+ action();
1756
+ }
1757
+ }
1758
+
1759
+ useEffect(() => {
1760
+ listenerElement.addEventListener('keydown', downHandler);
1761
+ return () => {
1762
+ listenerElement.removeEventListener('keydown', downHandler);
1763
+ };
1764
+ });
1765
+ }
1766
+
1767
+ const DEFAULT_LABEL_GETTER = value => value;
1768
+
1769
+ const NOOP = () => {};
1770
+
1771
+ function DropdownList(props) {
1772
+ const {
1773
+ keyEventsListener = window,
1774
+ values = [],
1775
+ getLabel = DEFAULT_LABEL_GETTER,
1776
+ onValueSelected = NOOP,
1777
+ height = 235,
1778
+ emptyListMessage = 'No results'
1779
+ } = props;
1780
+ const [mouseControl, setMouseControl] = useState(true);
1781
+ const [focusedValueIndex, setFocusedValueIndex] = useState(0);
1782
+ const dropdownContainer = useRef();
1783
+ const mouseScreenPos = useRef();
1784
+ const focusedItem = useMemo(() => values.length ? values[focusedValueIndex] : null, [focusedValueIndex, values]);
1785
+ const changeFocusedValueIndex = useCallback(delta => {
1786
+ setFocusedValueIndex(x => Math.min(Math.max(0, x + delta), values.length - 1));
1787
+ }, [values.length]);
1788
+ useEffect(() => {
1789
+ if (focusedValueIndex === 0) return;
1790
+
1791
+ if (!focusedValueIndex || !values.length) {
1792
+ setFocusedValueIndex(0);
1793
+ } else if (focusedValueIndex >= values.length) {
1794
+ setFocusedValueIndex(values.length - 1);
1795
+ }
1796
+ }, [focusedValueIndex, values.length]);
1797
+ useKeyDownAction('ArrowUp', () => {
1798
+ if (values.length) {
1799
+ changeFocusedValueIndex(-1);
1800
+ setMouseControl(false);
1801
+ }
1802
+ }, keyEventsListener);
1803
+ useKeyDownAction('ArrowDown', () => {
1804
+ if (values.length) {
1805
+ changeFocusedValueIndex(1);
1806
+ setMouseControl(false);
1807
+ }
1808
+ }, keyEventsListener);
1809
+ useKeyDownAction('Enter', () => {
1810
+ if (focusedItem) {
1811
+ onValueSelected(focusedItem);
1812
+ }
1813
+ }, keyEventsListener);
1814
+ useEffect(() => {
1815
+ const individualEntries = dropdownContainer.current.children;
1816
+
1817
+ if (individualEntries.length && !mouseControl) {
1818
+ individualEntries[focusedValueIndex].scrollIntoView({
1819
+ block: 'nearest',
1820
+ inline: 'nearest'
1821
+ });
1822
+ }
1823
+ }, [focusedValueIndex, mouseControl]);
1824
+
1825
+ const mouseMove = (e, i) => {
1826
+ const userMoved = !mouseScreenPos.current || mouseScreenPos.current.x !== e.screenX && mouseScreenPos.current.y !== e.screenY;
1827
+
1828
+ if (userMoved) {
1829
+ mouseScreenPos.current = {
1830
+ x: e.screenX,
1831
+ y: e.screenY
1832
+ };
1833
+
1834
+ if (!mouseControl) {
1835
+ setMouseControl(true);
1836
+ setFocusedValueIndex(i);
1837
+ }
1838
+ }
1839
+ };
1840
+
1841
+ return jsxs("div", {
1842
+ ref: dropdownContainer,
1843
+ tabIndex: -1,
1844
+ class: "fjs-dropdownlist",
1845
+ style: {
1846
+ maxHeight: height
1847
+ },
1848
+ children: [!!values.length && values.map((v, i) => {
1849
+ return jsx("div", {
1850
+ class: 'fjs-dropdownlist-item' + (focusedValueIndex === i ? ' focused' : ''),
1851
+ onMouseMove: e => mouseMove(e, i),
1852
+ onMouseEnter: mouseControl ? () => setFocusedValueIndex(i) : undefined,
1853
+ onMouseDown: e => {
1854
+ e.preventDefault();
1855
+ onValueSelected(v);
1856
+ },
1857
+ children: getLabel(v)
1858
+ });
1859
+ }), !values.length && jsx("div", {
1860
+ class: "fjs-dropdownlist-empty",
1861
+ children: emptyListMessage
1862
+ })]
1863
+ });
1864
+ }
1865
+
1866
+ const type$2 = 'taglist';
1867
+ function Taglist(props) {
1868
+ const {
1869
+ disabled,
1870
+ errors = [],
1871
+ field,
1872
+ value: values = []
1873
+ } = props;
1874
+ const {
1875
+ description,
1876
+ id,
1877
+ label
1878
+ } = field;
1879
+ const {
1880
+ formId
1881
+ } = useContext(FormContext);
1882
+ const [filter, setFilter] = useState('');
1883
+ const [selectedValues, setSelectedValues] = useState([]);
1884
+ const [filteredValues, setFilteredValues] = useState([]);
1885
+ const [isDropdownExpanded, setIsDropdownExpanded] = useState(false);
1886
+ const [hasValuesLeft, setHasValuesLeft] = useState(true);
1887
+ const [isEscapeClosed, setIsEscapeClose] = useState(false);
1888
+ const searchbarRef = useRef();
1889
+ const {
1890
+ state: loadState,
1891
+ values: options
1892
+ } = useValuesAsync(field); // Usage of stringify is necessary here because we want this effect to only trigger when there is a value change to the array
1893
+
1894
+ useEffect(() => {
1895
+ if (loadState === LOAD_STATES.LOADED) {
1896
+ const selectedValues = values.map(v => options.find(o => o.value === v)).filter(v => v !== undefined);
1897
+ setSelectedValues(selectedValues);
1898
+ } else {
1899
+ setSelectedValues([]);
1900
+ }
1901
+ }, [JSON.stringify(values), options, loadState]);
1902
+ useEffect(() => {
1903
+ if (loadState === LOAD_STATES.LOADED) {
1904
+ setFilteredValues(options.filter(o => o.label && o.label.toLowerCase().includes(filter.toLowerCase()) && !values.includes(o.value)));
1905
+ } else {
1906
+ setFilteredValues([]);
1907
+ }
1908
+ }, [filter, JSON.stringify(values), options]);
1909
+ useEffect(() => {
1910
+ setHasValuesLeft(selectedValues.length < options.length);
1911
+ }, [selectedValues.length, options.length]);
1912
+
1913
+ const onFilterChange = ({
1914
+ target
1915
+ }) => {
1916
+ setIsEscapeClose(false);
1917
+ setFilter(target.value);
1918
+ };
1919
+
1920
+ const selectValue = option => {
1921
+ setFilter('');
1922
+ props.onChange({
1923
+ value: [...values, option.value],
1924
+ field
1925
+ });
1926
+ };
1927
+
1928
+ const deselectValue = option => {
1929
+ props.onChange({
1930
+ value: values.filter(v => v != option.value),
1931
+ field
1932
+ });
1933
+ };
1934
+
1935
+ const onInputKeyDown = e => {
1936
+ switch (e.key) {
1937
+ case 'ArrowUp':
1938
+ case 'ArrowDown':
1939
+ // We do not want the cursor to seek in the search field when we press up and down
1940
+ e.preventDefault();
1941
+ break;
1942
+
1943
+ case 'Backspace':
1944
+ if (!filter && selectedValues.length) {
1945
+ deselectValue(selectedValues[selectedValues.length - 1]);
1946
+ }
1947
+
1948
+ break;
1949
+
1950
+ case 'Escape':
1951
+ setIsEscapeClose(true);
1952
+ break;
1953
+
1954
+ case 'Enter':
1955
+ if (isEscapeClosed) {
1956
+ setIsEscapeClose(false);
1957
+ }
1958
+
1959
+ break;
1960
+ }
1961
+ };
1962
+
1963
+ return jsxs("div", {
1964
+ class: formFieldClasses(type$2, errors),
1965
+ children: [jsx(Label, {
1966
+ label: label,
1967
+ id: prefixId(id, formId)
1968
+ }), jsxs("div", {
1969
+ class: classNames('fjs-taglist', {
1970
+ 'disabled': disabled
1971
+ }),
1972
+ children: [!disabled && loadState === LOAD_STATES.LOADED && selectedValues.map(sv => {
1973
+ return jsxs("div", {
1974
+ class: "fjs-taglist-tag",
1975
+ onMouseDown: e => e.preventDefault(),
1976
+ children: [jsx("span", {
1977
+ class: "fjs-taglist-tag-label",
1978
+ children: sv.label
1979
+ }), jsx("span", {
1980
+ class: "fjs-taglist-tag-remove",
1981
+ onMouseDown: () => deselectValue(sv),
1982
+ children: jsx(CloseIcon, {})
1983
+ })]
1984
+ });
1985
+ }), jsx("input", {
1986
+ disabled: disabled,
1987
+ class: "fjs-taglist-input",
1988
+ ref: searchbarRef,
1989
+ id: prefixId(`${id}-search`, formId),
1990
+ onChange: onFilterChange,
1991
+ type: "text",
1992
+ value: filter,
1993
+ placeholder: 'Search',
1994
+ autoComplete: "off",
1995
+ onKeyDown: e => onInputKeyDown(e),
1996
+ onMouseDown: () => setIsEscapeClose(false),
1997
+ onFocus: () => setIsDropdownExpanded(true),
1998
+ onBlur: () => {
1999
+ setIsDropdownExpanded(false);
2000
+ setFilter('');
2001
+ }
2002
+ })]
2003
+ }), jsx("div", {
2004
+ class: "fjs-taglist-anchor",
2005
+ children: !disabled && loadState === LOAD_STATES.LOADED && isDropdownExpanded && !isEscapeClosed && jsx(DropdownList, {
2006
+ values: filteredValues,
2007
+ getLabel: v => v.label,
2008
+ onValueSelected: v => selectValue(v),
2009
+ emptyListMessage: hasValuesLeft ? 'No results' : 'All values selected',
2010
+ listenerElement: searchbarRef.current
2011
+ })
2012
+ }), jsx(Description, {
2013
+ description: description
2014
+ }), jsx(Errors, {
2015
+ errors: errors
2016
+ })]
2017
+ });
2018
+ }
2019
+
2020
+ Taglist.create = function (options = {}) {
2021
+ if (options.valuesKey) return options;
2022
+ return {
2023
+ values: [{
2024
+ label: 'Value',
2025
+ value: 'value'
2026
+ }],
2027
+ ...options
2028
+ };
2029
+ };
2030
+
2031
+ Taglist.type = type$2;
2032
+ Taglist.label = 'Taglist';
2033
+ Taglist.keyed = true;
2034
+ Taglist.emptyValue = [];
2035
+
1572
2036
  const type$1 = 'text';
1573
2037
  function Text(props) {
1574
2038
  const {
@@ -1657,7 +2121,7 @@ Textfield.label = 'Text Field';
1657
2121
  Textfield.keyed = true;
1658
2122
  Textfield.emptyValue = '';
1659
2123
 
1660
- const formFields = [Button, Checkbox, Default, Number, Radio, Select, Text, Textfield];
2124
+ const formFields = [Button, Checkbox, Checklist, Default, Number, Radio, Select, Taglist, Text, Textfield];
1661
2125
 
1662
2126
  class FormFields {
1663
2127
  constructor() {
@@ -2144,7 +2608,7 @@ class Form {
2144
2608
 
2145
2609
  }
2146
2610
 
2147
- const schemaVersion = 4;
2611
+ const schemaVersion = 5;
2148
2612
  /**
2149
2613
  * @typedef { import('./types').CreateFormOptions } CreateFormOptions
2150
2614
  */
@@ -2169,5 +2633,5 @@ function createForm(options) {
2169
2633
  });
2170
2634
  }
2171
2635
 
2172
- export { Button, Checkbox, Default, Form, FormComponent, FormContext, FormFieldRegistry, FormFields, FormRenderContext, Number, Radio, Select, Text, Textfield, clone, createForm, createFormContainer, createInjector, findErrors, formFields, generateIdForType, generateIndexForType, isRequired, pathParse, pathStringify, pathsEqual, schemaVersion };
2636
+ export { Button, Checkbox, Checklist, Default, Form, FormComponent, FormContext, FormFieldRegistry, FormFields, FormRenderContext, Number, Radio, Select, Taglist, Text, Textfield, clone, createForm, createFormContainer, createInjector, findErrors, formFields, generateIdForType, generateIndexForType, isRequired, pathParse, pathStringify, pathsEqual, schemaVersion };
2173
2637
  //# sourceMappingURL=index.es.js.map