@bpmn-io/form-js-viewer 0.10.0-alpha.3 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +165 -164
  3. package/dist/assets/flatpickr/light.css +809 -0
  4. package/dist/assets/form-js.css +611 -498
  5. package/dist/index.cjs +1493 -369
  6. package/dist/index.cjs.map +1 -1
  7. package/dist/index.es.js +1475 -372
  8. package/dist/index.es.js.map +1 -1
  9. package/dist/types/Form.d.ts +144 -144
  10. package/dist/types/core/ConditionChecker.d.ts +57 -57
  11. package/dist/types/core/EventBus.d.ts +1 -1
  12. package/dist/types/core/FormFieldRegistry.d.ts +17 -17
  13. package/dist/types/core/Validator.d.ts +7 -7
  14. package/dist/types/core/index.d.ts +18 -18
  15. package/dist/types/import/Importer.d.ts +43 -43
  16. package/dist/types/import/index.d.ts +5 -5
  17. package/dist/types/index.d.ts +18 -18
  18. package/dist/types/render/FormFields.d.ts +5 -5
  19. package/dist/types/render/Renderer.d.ts +23 -23
  20. package/dist/types/render/components/Description.d.ts +1 -1
  21. package/dist/types/render/components/Errors.d.ts +1 -1
  22. package/dist/types/render/components/FormComponent.d.ts +1 -1
  23. package/dist/types/render/components/FormField.d.ts +1 -1
  24. package/dist/types/render/components/Label.d.ts +1 -1
  25. package/dist/types/render/components/PoweredBy.d.ts +1 -1
  26. package/dist/types/render/components/Sanitizer.d.ts +8 -8
  27. package/dist/types/render/components/Util.d.ts +17 -19
  28. package/dist/types/render/components/form-fields/Button.d.ts +11 -11
  29. package/dist/types/render/components/form-fields/Checkbox.d.ts +13 -13
  30. package/dist/types/render/components/form-fields/Checklist.d.ts +12 -12
  31. package/dist/types/render/components/form-fields/Datetime.d.ts +11 -0
  32. package/dist/types/render/components/form-fields/Default.d.ts +9 -9
  33. package/dist/types/render/components/form-fields/Image.d.ts +8 -8
  34. package/dist/types/render/components/form-fields/Number.d.ts +14 -14
  35. package/dist/types/render/components/form-fields/Radio.d.ts +12 -12
  36. package/dist/types/render/components/form-fields/Select.d.ts +12 -12
  37. package/dist/types/render/components/form-fields/Taglist.d.ts +12 -12
  38. package/dist/types/render/components/form-fields/Text.d.ts +10 -10
  39. package/dist/types/render/components/form-fields/Textarea.d.ts +13 -13
  40. package/dist/types/render/components/form-fields/Textfield.d.ts +13 -13
  41. package/dist/types/render/components/form-fields/parts/Datepicker.d.ts +1 -0
  42. package/dist/types/render/components/form-fields/parts/DropdownList.d.ts +1 -1
  43. package/dist/types/render/components/form-fields/parts/InputAdorner.d.ts +1 -0
  44. package/dist/types/render/components/form-fields/parts/Timepicker.d.ts +1 -0
  45. package/dist/types/render/components/icons/index.d.ts +16 -0
  46. package/dist/types/render/components/index.d.ts +17 -15
  47. package/dist/types/render/components/util/dateTimeUtil.d.ts +12 -0
  48. package/dist/types/render/components/util/numberFieldUtil.d.ts +4 -4
  49. package/dist/types/render/components/util/sanitizerUtil.d.ts +3 -0
  50. package/dist/types/render/context/FormContext.d.ts +12 -12
  51. package/dist/types/render/context/FormRenderContext.d.ts +6 -6
  52. package/dist/types/render/context/index.d.ts +2 -2
  53. package/dist/types/render/hooks/useCondition.d.ts +9 -9
  54. package/dist/types/render/hooks/useEvaluation.d.ts +6 -6
  55. package/dist/types/render/hooks/useExpressionValue.d.ts +5 -5
  56. package/dist/types/render/hooks/useKeyDownAction.d.ts +1 -1
  57. package/dist/types/render/hooks/useService.d.ts +1 -1
  58. package/dist/types/render/hooks/useValuesAsync.d.ts +28 -28
  59. package/dist/types/render/index.d.ts +11 -11
  60. package/dist/types/src/types.d.ts +35 -35
  61. package/dist/types/util/constants/DatetimeConstants.d.ts +24 -0
  62. package/dist/types/util/constants/ValuesSourceConstants.d.ts +15 -0
  63. package/dist/types/util/constants/index.d.ts +2 -0
  64. package/dist/types/util/feel.d.ts +15 -14
  65. package/dist/types/util/form.d.ts +6 -6
  66. package/dist/types/util/index.d.ts +25 -24
  67. package/dist/types/util/injector.d.ts +2 -2
  68. package/package.json +4 -2
package/dist/index.cjs CHANGED
@@ -12,6 +12,7 @@ var jsxRuntime = require('preact/jsx-runtime');
12
12
  var hooks = require('preact/hooks');
13
13
  var preact = require('preact');
14
14
  var React = require('preact/compat');
15
+ var flatpickr = require('flatpickr');
15
16
  var Markup = require('preact-markup');
16
17
  var didi = require('didi');
17
18
 
@@ -22,11 +23,12 @@ var Big__default = /*#__PURE__*/_interopDefaultLegacy(Big);
22
23
  var snarkdown__default = /*#__PURE__*/_interopDefaultLegacy(snarkdown);
23
24
  var classNames__default = /*#__PURE__*/_interopDefaultLegacy(classNames);
24
25
  var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
26
+ var flatpickr__default = /*#__PURE__*/_interopDefaultLegacy(flatpickr);
25
27
  var Markup__default = /*#__PURE__*/_interopDefaultLegacy(Markup);
26
28
 
27
- /**
28
- * @typedef {object} Condition
29
- * @property {string} [hide]
29
+ /**
30
+ * @typedef {object} Condition
31
+ * @property {string} [hide]
30
32
  */
31
33
 
32
34
  class ConditionChecker {
@@ -35,11 +37,11 @@ class ConditionChecker {
35
37
  this._eventBus = eventBus;
36
38
  }
37
39
 
38
- /**
39
- * For given data, remove properties based on condition.
40
- *
41
- * @param {Object<string, any>} properties
42
- * @param {Object<string, any>} data
40
+ /**
41
+ * For given data, remove properties based on condition.
42
+ *
43
+ * @param {Object<string, any>} properties
44
+ * @param {Object<string, any>} data
43
45
  */
44
46
  applyConditions(properties, data = {}) {
45
47
  const conditions = this._getConditions();
@@ -58,13 +60,13 @@ class ConditionChecker {
58
60
  return newProperties;
59
61
  }
60
62
 
61
- /**
62
- * Check if given condition is met. Returns null for invalid/missing conditions.
63
- *
64
- * @param {string} condition
65
- * @param {import('../types').Data} [data]
66
- *
67
- * @returns {boolean|null}
63
+ /**
64
+ * Check if given condition is met. Returns null for invalid/missing conditions.
65
+ *
66
+ * @param {string} condition
67
+ * @param {import('../types').Data} [data]
68
+ *
69
+ * @returns {boolean|null}
68
70
  */
69
71
  check(condition, data = {}) {
70
72
  if (!condition) {
@@ -85,12 +87,12 @@ class ConditionChecker {
85
87
  }
86
88
  }
87
89
 
88
- /**
89
- * Check if hide condition is met.
90
- *
91
- * @param {Condition} condition
92
- * @param {Object<string, any>} data
93
- * @returns {boolean}
90
+ /**
91
+ * Check if hide condition is met.
92
+ *
93
+ * @param {Condition} condition
94
+ * @param {Object<string, any>} data
95
+ * @returns {boolean}
94
96
  */
95
97
  _checkHideCondition(condition, data) {
96
98
  if (!condition.hide) {
@@ -100,13 +102,13 @@ class ConditionChecker {
100
102
  return result === true;
101
103
  }
102
104
 
103
- /**
104
- * Evaluate an expression.
105
- *
106
- * @param {string} expression
107
- * @param {import('../types').Data} [data]
108
- *
109
- * @returns {any}
105
+ /**
106
+ * Evaluate an expression.
107
+ *
108
+ * @param {string} expression
109
+ * @param {import('../types').Data} [data]
110
+ *
111
+ * @returns {any}
110
112
  */
111
113
  evaluate(expression, data = {}) {
112
114
  if (!expression) {
@@ -715,11 +717,11 @@ class FormFieldRegistry {
715
717
  }
716
718
  FormFieldRegistry.$inject = ['eventBus'];
717
719
 
718
- /**
719
- * Retrieve variable names from given FEEL unary test.
720
- *
721
- * @param {string} unaryTest
722
- * @returns {string[]}
720
+ /**
721
+ * Retrieve variable names from given FEEL unary test.
722
+ *
723
+ * @param {string} unaryTest
724
+ * @returns {string[]}
723
725
  */
724
726
  function getVariableNames(unaryTest) {
725
727
  const tree = feelin.parseUnaryTests(unaryTest);
@@ -734,11 +736,11 @@ function getVariableNames(unaryTest) {
734
736
  return Array.from(variables);
735
737
  }
736
738
 
737
- /**
738
- * Retrieve variable names from given FEEL expression.
739
- *
740
- * @param {string} expression
741
- * @returns {string[]}
739
+ /**
740
+ * Retrieve variable names from given FEEL expression.
741
+ *
742
+ * @param {string} expression
743
+ * @returns {string[]}
742
744
  */
743
745
  function getExpressionVariableNames(expression) {
744
746
  const tree = feelin.parseExpressions(expression);
@@ -752,6 +754,71 @@ function getExpressionVariableNames(expression) {
752
754
  } while (cursor.next());
753
755
  return Array.from(variables);
754
756
  }
757
+ function isExpression$2(value) {
758
+ return minDash.isString(value) && value.startsWith('=');
759
+ }
760
+
761
+ // config ///////////////////
762
+
763
+ const MINUTES_IN_DAY = 60 * 24;
764
+ const DATETIME_SUBTYPES = {
765
+ DATE: 'date',
766
+ TIME: 'time',
767
+ DATETIME: 'datetime'
768
+ };
769
+ const TIME_SERIALISING_FORMATS = {
770
+ UTC_OFFSET: 'utc_offset',
771
+ UTC_NORMALIZED: 'utc_normalized',
772
+ NO_TIMEZONE: 'no_timezone'
773
+ };
774
+ const DATETIME_SUBTYPES_LABELS = {
775
+ [DATETIME_SUBTYPES.DATE]: 'Date',
776
+ [DATETIME_SUBTYPES.TIME]: 'Time',
777
+ [DATETIME_SUBTYPES.DATETIME]: 'Date & Time'
778
+ };
779
+ const TIME_SERIALISINGFORMAT_LABELS = {
780
+ [TIME_SERIALISING_FORMATS.UTC_OFFSET]: 'UTC offset',
781
+ [TIME_SERIALISING_FORMATS.UTC_NORMALIZED]: 'UTC normalized',
782
+ [TIME_SERIALISING_FORMATS.NO_TIMEZONE]: 'No timezone'
783
+ };
784
+ const DATETIME_SUBTYPE_PATH = ['subtype'];
785
+ const DATE_LABEL_PATH = ['dateLabel'];
786
+ const DATE_DISALLOW_PAST_PATH = ['disallowPassedDates'];
787
+ const TIME_LABEL_PATH = ['timeLabel'];
788
+ const TIME_USE24H_PATH = ['use24h'];
789
+ const TIME_INTERVAL_PATH = ['timeInterval'];
790
+ const TIME_SERIALISING_FORMAT_PATH = ['timeSerializingFormat'];
791
+
792
+ // config ///////////////////
793
+
794
+ const VALUES_SOURCES = {
795
+ STATIC: 'static',
796
+ INPUT: 'input'
797
+ };
798
+ const VALUES_SOURCE_DEFAULT = VALUES_SOURCES.STATIC;
799
+ const VALUES_SOURCES_LABELS = {
800
+ [VALUES_SOURCES.STATIC]: 'Static',
801
+ [VALUES_SOURCES.INPUT]: 'Input data'
802
+ };
803
+ const VALUES_SOURCES_PATHS = {
804
+ [VALUES_SOURCES.STATIC]: ['values'],
805
+ [VALUES_SOURCES.INPUT]: ['valuesKey']
806
+ };
807
+ const VALUES_SOURCES_DEFAULTS = {
808
+ [VALUES_SOURCES.STATIC]: [],
809
+ [VALUES_SOURCES.INPUT]: ''
810
+ };
811
+
812
+ // helpers ///////////////////
813
+
814
+ function getValuesSource(field) {
815
+ for (const source of Object.values(VALUES_SOURCES)) {
816
+ if (minDash.get(field, VALUES_SOURCES_PATHS[source]) !== undefined) {
817
+ return source;
818
+ }
819
+ }
820
+ return VALUES_SOURCE_DEFAULT;
821
+ }
755
822
 
756
823
  function createInjector(bootstrapModules) {
757
824
  const injector = new didi.Injector(bootstrapModules);
@@ -759,10 +826,10 @@ function createInjector(bootstrapModules) {
759
826
  return injector;
760
827
  }
761
828
 
762
- /**
763
- * @param {string?} prefix
764
- *
765
- * @returns Element
829
+ /**
830
+ * @param {string?} prefix
831
+ *
832
+ * @returns Element
766
833
  */
767
834
  function createFormContainer(prefix = 'fjs') {
768
835
  const container = document.createElement('div');
@@ -770,7 +837,7 @@ function createFormContainer(prefix = 'fjs') {
770
837
  return container;
771
838
  }
772
839
 
773
- const EXPRESSION_PROPERTIES = ['alt', 'source'];
840
+ const EXPRESSION_PROPERTIES = ['alt', 'source', 'text'];
774
841
  function findErrors(errors, path) {
775
842
  return errors[pathStringify(path)];
776
843
  }
@@ -807,22 +874,22 @@ function generateIdForType(type) {
807
874
  return `${type}${generateIndexForType(type)}`;
808
875
  }
809
876
 
810
- /**
811
- * @template T
812
- * @param {T} data
813
- * @param {(this: any, key: string, value: any) => any} [replacer]
814
- * @return {T}
877
+ /**
878
+ * @template T
879
+ * @param {T} data
880
+ * @param {(this: any, key: string, value: any) => any} [replacer]
881
+ * @return {T}
815
882
  */
816
883
  function clone(data, replacer) {
817
884
  return JSON.parse(JSON.stringify(data, replacer));
818
885
  }
819
886
 
820
- /**
821
- * Parse the schema for input variables a form might make use of
822
- *
823
- * @param {any} schema
824
- *
825
- * @return {string[]}
887
+ /**
888
+ * Parse the schema for input variables a form might make use of
889
+ *
890
+ * @param {any} schema
891
+ *
892
+ * @return {string[]}
826
893
  */
827
894
  function getSchemaVariables(schema) {
828
895
  if (!schema.components) {
@@ -835,7 +902,7 @@ function getSchemaVariables(schema) {
835
902
  type,
836
903
  conditional
837
904
  } = component;
838
- if (['text', 'button'].includes(type)) {
905
+ if (['button'].includes(type)) {
839
906
  return variables;
840
907
  }
841
908
  if (key) {
@@ -871,25 +938,25 @@ function isExpression$1(value) {
871
938
  }
872
939
 
873
940
  class Importer {
874
- /**
875
- * @constructor
876
- * @param { import('../core').FormFieldRegistry } formFieldRegistry
877
- * @param { import('../render/FormFields').default } formFields
941
+ /**
942
+ * @constructor
943
+ * @param { import('../core').FormFieldRegistry } formFieldRegistry
944
+ * @param { import('../render/FormFields').default } formFields
878
945
  */
879
946
  constructor(formFieldRegistry, formFields) {
880
947
  this._formFieldRegistry = formFieldRegistry;
881
948
  this._formFields = formFields;
882
949
  }
883
950
 
884
- /**
885
- * Import schema adding `id`, `_parent` and `_path`
886
- * information to each field and adding it to the
887
- * form field registry.
888
- *
889
- * @param {any} schema
890
- * @param {any} [data]
891
- *
892
- * @return { { warnings: Array<any>, schema: any, data: any } }
951
+ /**
952
+ * Import schema adding `id`, `_parent` and `_path`
953
+ * information to each field and adding it to the
954
+ * form field registry.
955
+ *
956
+ * @param {any} schema
957
+ * @param {any} [data]
958
+ *
959
+ * @return { { warnings: Array<any>, schema: any, data: any } }
893
960
  */
894
961
  importSchema(schema, data = {}) {
895
962
  // TODO: Add warnings - https://github.com/bpmn-io/form-js/issues/289
@@ -908,11 +975,11 @@ class Importer {
908
975
  }
909
976
  }
910
977
 
911
- /**
912
- * @param {any} formField
913
- * @param {string} [parentId]
914
- *
915
- * @return {any} importedField
978
+ /**
979
+ * @param {any} formField
980
+ * @param {string} [parentId]
981
+ *
982
+ * @return {any} importedField
916
983
  */
917
984
  importFormField(formField, parentId) {
918
985
  const {
@@ -963,10 +1030,10 @@ class Importer {
963
1030
  });
964
1031
  }
965
1032
 
966
- /**
967
- * @param {Object} data
968
- *
969
- * @return {Object} initializedData
1033
+ /**
1034
+ * @param {Object} data
1035
+ *
1036
+ * @return {Object} initializedData
970
1037
  */
971
1038
  initializeFieldValues(data) {
972
1039
  return this._formFieldRegistry.getAll().reduce((initializedData, formField) => {
@@ -1008,7 +1075,7 @@ var importModule = {
1008
1075
 
1009
1076
  const NODE_TYPE_TEXT = 3,
1010
1077
  NODE_TYPE_ELEMENT = 1;
1011
- const ALLOWED_NODES = ['h1', 'h2', 'h3', 'h4', 'h5', 'span', 'em', 'a', 'p', 'div', 'ul', 'ol', 'li', 'hr', 'blockquote', 'img', 'pre', 'code', 'br', 'strong'];
1078
+ const ALLOWED_NODES = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'span', 'em', 'a', 'p', 'div', 'ul', 'ol', 'li', 'hr', 'blockquote', 'img', 'pre', 'code', 'br', 'strong'];
1012
1079
  const ALLOWED_ATTRIBUTES = ['align', 'alt', 'class', 'href', 'id', 'name', 'rel', 'target', 'src'];
1013
1080
  const ALLOWED_URI_PATTERN = /^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i; // eslint-disable-line no-useless-escape
1014
1081
  const ALLOWED_IMAGE_SRC_PATTERN = /^(https?|data):.*/i; // eslint-disable-line no-useless-escape
@@ -1016,11 +1083,11 @@ const ATTR_WHITESPACE_PATTERN = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u
1016
1083
 
1017
1084
  const FORM_ELEMENT = document.createElement('form');
1018
1085
 
1019
- /**
1020
- * Sanitize a HTML string and return the cleaned, safe version.
1021
- *
1022
- * @param {string} html
1023
- * @return {string}
1086
+ /**
1087
+ * Sanitize a HTML string and return the cleaned, safe version.
1088
+ *
1089
+ * @param {string} html
1090
+ * @return {string}
1024
1091
  */
1025
1092
  function sanitizeHTML(html) {
1026
1093
  const doc = new DOMParser().parseFromString(`<!DOCTYPE html>\n<html><body><div>${html}`, 'text/html');
@@ -1040,15 +1107,15 @@ function sanitizeImageSource(src) {
1040
1107
  return valid ? src : '';
1041
1108
  }
1042
1109
 
1043
- /**
1044
- * Recursively sanitize a HTML node, potentially
1045
- * removing it, its children or attributes.
1046
- *
1047
- * Inspired by https://github.com/developit/snarkdown/issues/70
1048
- * and https://github.com/cure53/DOMPurify. Simplified
1049
- * for our use-case.
1050
- *
1051
- * @param {Element} node
1110
+ /**
1111
+ * Recursively sanitize a HTML node, potentially
1112
+ * removing it, its children or attributes.
1113
+ *
1114
+ * Inspired by https://github.com/developit/snarkdown/issues/70
1115
+ * and https://github.com/cure53/DOMPurify. Simplified
1116
+ * for our use-case.
1117
+ *
1118
+ * @param {Element} node
1052
1119
  */
1053
1120
  function sanitizeNode(node) {
1054
1121
  // allow text nodes
@@ -1092,13 +1159,13 @@ function sanitizeNode(node) {
1092
1159
  }
1093
1160
  }
1094
1161
 
1095
- /**
1096
- * Validates attributes for validity.
1097
- *
1098
- * @param {string} lcTag
1099
- * @param {string} lcName
1100
- * @param {string} value
1101
- * @return {boolean}
1162
+ /**
1163
+ * Validates attributes for validity.
1164
+ *
1165
+ * @param {string} lcTag
1166
+ * @param {string} lcName
1167
+ * @param {string} value
1168
+ * @return {boolean}
1102
1169
  */
1103
1170
  function isValidAttribute(lcTag, lcName, value) {
1104
1171
  // disallow most attributes based on whitelist
@@ -1140,7 +1207,7 @@ function prefixId(id, formId) {
1140
1207
  return `fjs-form-${id}`;
1141
1208
  }
1142
1209
  function markdownToHTML(markdown) {
1143
- const htmls = markdown.split(/(?:\r?\n){2,}/).map(line => /^((\d+.)|[><\s#-*])/.test(line) ? snarkdown__default['default'](line) : `<p>${snarkdown__default['default'](line)}</p>`);
1210
+ const htmls = markdown.toString().split(/(?:\r?\n){2,}/).map(line => /^((\d+.)|[><\s#-*])/.test(line) ? snarkdown__default['default'](line) : `<p>${snarkdown__default['default'](line)}</p>`);
1144
1211
  return htmls.join('\n\n');
1145
1212
  }
1146
1213
 
@@ -1150,58 +1217,20 @@ function safeMarkdown(markdown) {
1150
1217
  return sanitizeHTML(html);
1151
1218
  }
1152
1219
 
1153
- /**
1154
- * Sanitizes an image source to ensure we only allow for data URI and links
1155
- * that start with http(s).
1156
- *
1157
- * Note: Most browsers anyway do not support script execution in <img> elements.
1158
- *
1159
- * @param {string} src
1160
- * @returns {string}
1220
+ /**
1221
+ * Sanitizes an image source to ensure we only allow for data URI and links
1222
+ * that start with http(s).
1223
+ *
1224
+ * Note: Most browsers anyway do not support script execution in <img> elements.
1225
+ *
1226
+ * @param {string} src
1227
+ * @returns {string}
1161
1228
  */
1162
1229
  function safeImageSource(src) {
1163
1230
  return sanitizeImageSource(src);
1164
1231
  }
1165
- function sanitizeSingleSelectValue(options) {
1166
- const {
1167
- formField,
1168
- data,
1169
- value
1170
- } = options;
1171
- const {
1172
- valuesKey,
1173
- values
1174
- } = formField;
1175
- try {
1176
- const validValues = (valuesKey ? minDash.get(data, [valuesKey]) : values).map(v => v.value) || [];
1177
- return validValues.includes(value) ? value : null;
1178
- } catch (error) {
1179
- // use default value in case of formatting error
1180
- // TODO(@Skaiir): log a warning when this happens - https://github.com/bpmn-io/form-js/issues/289
1181
- return null;
1182
- }
1183
- }
1184
- function sanitizeMultiSelectValue(options) {
1185
- const {
1186
- formField,
1187
- data,
1188
- value
1189
- } = options;
1190
- const {
1191
- valuesKey,
1192
- values
1193
- } = formField;
1194
- try {
1195
- const validValues = (valuesKey ? minDash.get(data, [valuesKey]) : values).map(v => v.value) || [];
1196
- return value.filter(v => validValues.includes(v));
1197
- } catch (error) {
1198
- // use default value in case of formatting error
1199
- // TODO(@Skaiir): log a warning when this happens - https://github.com/bpmn-io/form-js/issues/289
1200
- return [];
1201
- }
1202
- }
1203
1232
 
1204
- const type$a = 'button';
1233
+ const type$b = 'button';
1205
1234
  function Button(props) {
1206
1235
  const {
1207
1236
  disabled,
@@ -1211,7 +1240,7 @@ function Button(props) {
1211
1240
  action = 'submit'
1212
1241
  } = field;
1213
1242
  return jsxRuntime.jsx("div", {
1214
- class: formFieldClasses(type$a),
1243
+ class: formFieldClasses(type$b),
1215
1244
  children: jsxRuntime.jsx("button", {
1216
1245
  class: "fjs-button",
1217
1246
  type: action,
@@ -1226,7 +1255,7 @@ Button.create = function (options = {}) {
1226
1255
  ...options
1227
1256
  };
1228
1257
  };
1229
- Button.type = type$a;
1258
+ Button.type = type$b;
1230
1259
  Button.label = 'Button';
1231
1260
  Button.keyed = true;
1232
1261
 
@@ -1242,11 +1271,11 @@ const FormRenderContext = preact.createContext({
1242
1271
  }
1243
1272
  });
1244
1273
 
1245
- /**
1246
- * @param {string} type
1247
- * @param {boolean} [strict]
1248
- *
1249
- * @returns {any}
1274
+ /**
1275
+ * @param {string} type
1276
+ * @param {boolean} [strict]
1277
+ *
1278
+ * @returns {any}
1250
1279
  */
1251
1280
  function getService(type, strict) {}
1252
1281
  const FormContext = preact.createContext({
@@ -1290,11 +1319,14 @@ function Label(props) {
1290
1319
  const {
1291
1320
  id,
1292
1321
  label,
1322
+ collapseOnEmpty = true,
1293
1323
  required = false
1294
1324
  } = props;
1295
1325
  return jsxRuntime.jsxs("label", {
1296
1326
  for: id,
1297
- class: classNames__default['default']('fjs-form-field-label', props['class']),
1327
+ class: classNames__default['default']('fjs-form-field-label', {
1328
+ 'fjs-incollapsible-label': !collapseOnEmpty
1329
+ }, props['class']),
1298
1330
  children: [props.children, label || '', required && jsxRuntime.jsx("span", {
1299
1331
  class: "fjs-asterix",
1300
1332
  children: "*"
@@ -1302,7 +1334,7 @@ function Label(props) {
1302
1334
  });
1303
1335
  }
1304
1336
 
1305
- const type$9 = 'checkbox';
1337
+ const type$a = 'checkbox';
1306
1338
  function Checkbox(props) {
1307
1339
  const {
1308
1340
  disabled,
@@ -1327,7 +1359,7 @@ function Checkbox(props) {
1327
1359
  formId
1328
1360
  } = hooks.useContext(FormContext);
1329
1361
  return jsxRuntime.jsxs("div", {
1330
- class: classNames__default['default'](formFieldClasses(type$9, {
1362
+ class: classNames__default['default'](formFieldClasses(type$a, {
1331
1363
  errors,
1332
1364
  disabled
1333
1365
  }), {
@@ -1357,7 +1389,7 @@ Checkbox.create = function (options = {}) {
1357
1389
  ...options
1358
1390
  };
1359
1391
  };
1360
- Checkbox.type = type$9;
1392
+ Checkbox.type = type$a;
1361
1393
  Checkbox.label = 'Checkbox';
1362
1394
  Checkbox.keyed = true;
1363
1395
  Checkbox.emptyValue = false;
@@ -1372,8 +1404,8 @@ function useService (type, strict) {
1372
1404
  return getService(type, strict);
1373
1405
  }
1374
1406
 
1375
- /**
1376
- * @enum { String }
1407
+ /**
1408
+ * @enum { String }
1377
1409
  */
1378
1410
  const LOAD_STATES = {
1379
1411
  LOADING: 'loading',
@@ -1381,17 +1413,17 @@ const LOAD_STATES = {
1381
1413
  ERROR: 'error'
1382
1414
  };
1383
1415
 
1384
- /**
1385
- * @typedef {Object} ValuesGetter
1386
- * @property {Object[]} values - The values data
1387
- * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
1416
+ /**
1417
+ * @typedef {Object} ValuesGetter
1418
+ * @property {Object[]} values - The values data
1419
+ * @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
1388
1420
  */
1389
1421
 
1390
- /**
1391
- * A hook to load values for single and multiselect components.
1392
- *
1393
- * @param {Object} field - The form field to handle values for
1394
- * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
1422
+ /**
1423
+ * A hook to load values for single and multiselect components.
1424
+ *
1425
+ * @param {Object} field - The form field to handle values for
1426
+ * @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
1395
1427
  */
1396
1428
  function useValuesAsync (field) {
1397
1429
  const {
@@ -1432,7 +1464,222 @@ const buildLoadedState = values => ({
1432
1464
  state: LOAD_STATES.LOADED
1433
1465
  });
1434
1466
 
1435
- const type$8 = 'checklist';
1467
+ const ENTER_KEYDOWN_EVENT = new KeyboardEvent('keydown', {
1468
+ code: 'Enter',
1469
+ key: 'Enter',
1470
+ charCode: 13,
1471
+ keyCode: 13,
1472
+ view: window,
1473
+ bubbles: true
1474
+ });
1475
+ function focusRelevantFlatpickerDay(flatpickrInstance) {
1476
+ if (!flatpickrInstance) return;
1477
+ !flatpickrInstance.isOpen && flatpickrInstance.open();
1478
+ const container = flatpickrInstance.calendarContainer;
1479
+ const dayToFocus = container.querySelector('.flatpickr-day.selected') || container.querySelector('.flatpickr-day.today') || container.querySelector('.flatpickr-day');
1480
+ dayToFocus && dayToFocus.focus();
1481
+ }
1482
+ function formatTime(use24h, minutes) {
1483
+ if (minutes === null) return null;
1484
+ const wrappedMinutes = minutes % (24 * 60);
1485
+ const minute = minutes % 60;
1486
+ let hour = Math.floor(wrappedMinutes / 60);
1487
+ if (use24h) {
1488
+ return _getZeroPaddedString(hour) + ':' + _getZeroPaddedString(minute);
1489
+ }
1490
+ hour = hour % 12 || 12;
1491
+ const isPM = wrappedMinutes >= 12 * 60;
1492
+ return _getZeroPaddedString(hour) + ':' + _getZeroPaddedString(minute) + ' ' + (isPM ? 'PM' : 'AM');
1493
+ }
1494
+ function parseInputTime(stringTime) {
1495
+ let workingString = stringTime.toLowerCase();
1496
+ const is12h = workingString.includes('am') || workingString.includes('pm');
1497
+ if (is12h) {
1498
+ const isPM = workingString.includes('pm');
1499
+ const digits = workingString.match(/\d+/g);
1500
+ const displayHour = parseInt(digits?.[0]);
1501
+ const minute = parseInt(digits?.[1]) || 0;
1502
+ const isValidDisplayHour = minDash.isNumber(displayHour) && displayHour >= 1 && displayHour <= 12;
1503
+ const isValidMinute = minute >= 0 && minute <= 59;
1504
+ if (!isValidDisplayHour || !isValidMinute) return null;
1505
+ const hour = displayHour % 12 + (isPM ? 12 : 0);
1506
+ return hour * 60 + minute;
1507
+ } else {
1508
+ const digits = workingString.match(/\d+/g);
1509
+ const hour = parseInt(digits?.[0]);
1510
+ const minute = parseInt(digits?.[1]);
1511
+ const isValidHour = minDash.isNumber(hour) && hour >= 0 && hour <= 23;
1512
+ const isValidMinute = minDash.isNumber(minute) && minute >= 0 && minute <= 59;
1513
+ if (!isValidHour || !isValidMinute) return null;
1514
+ return hour * 60 + minute;
1515
+ }
1516
+ }
1517
+ function serializeTime(minutes, offset, timeSerializingFormat) {
1518
+ if (timeSerializingFormat === TIME_SERIALISING_FORMATS.UTC_NORMALIZED) {
1519
+ const normalizedMinutes = (minutes + offset + MINUTES_IN_DAY) % MINUTES_IN_DAY;
1520
+ return _getZeroPaddedString(Math.floor(normalizedMinutes / 60)) + ':' + _getZeroPaddedString(normalizedMinutes % 60) + 'Z';
1521
+ }
1522
+ const baseTime = _getZeroPaddedString(Math.floor(minutes / 60)) + ':' + _getZeroPaddedString(minutes % 60);
1523
+ const addUTCOffset = timeSerializingFormat === TIME_SERIALISING_FORMATS.UTC_OFFSET;
1524
+ return baseTime + (addUTCOffset ? formatTimezoneOffset(offset) : '');
1525
+ }
1526
+ function parseIsoTime(isoTimeString) {
1527
+ if (!isoTimeString) return null;
1528
+ const parseBasicMinutes = timeString => {
1529
+ const timeSegments = timeString.split(':');
1530
+ const hour = parseInt(timeSegments[0]);
1531
+ const minute = timeSegments.length > 1 ? parseInt(timeSegments[1]) : 0;
1532
+ if (isNaN(hour) || hour < 0 || hour > 24 || isNaN(minute) || minute < 0 || minute > 60) return null;
1533
+ return hour * 60 + minute;
1534
+ };
1535
+ const localOffset = new Date().getTimezoneOffset();
1536
+
1537
+ // Parse normalized time
1538
+ if (isoTimeString.includes('Z')) {
1539
+ isoTimeString = isoTimeString.replace('Z', '');
1540
+ const minutes = parseBasicMinutes(isoTimeString);
1541
+ if (minutes === null) return null;
1542
+ return (minutes - localOffset + MINUTES_IN_DAY) % MINUTES_IN_DAY;
1543
+ }
1544
+
1545
+ // Parse offset positive time
1546
+ else if (isoTimeString.includes('+')) {
1547
+ const [timeString, offsetString] = isoTimeString.split('+');
1548
+ const minutes = parseBasicMinutes(timeString);
1549
+ let inboundOffset = parseBasicMinutes(offsetString);
1550
+ if (minutes === null || inboundOffset === null) return null;
1551
+
1552
+ // The offset is flipped for consistency with javascript
1553
+ inboundOffset = -inboundOffset;
1554
+ return (minutes + inboundOffset - localOffset + MINUTES_IN_DAY) % MINUTES_IN_DAY;
1555
+ }
1556
+
1557
+ // Parse offset negative time
1558
+ else if (isoTimeString.includes('-')) {
1559
+ const [timeString, offsetString] = isoTimeString.split('-');
1560
+ const minutes = parseBasicMinutes(timeString);
1561
+ let inboundOffset = parseBasicMinutes(offsetString);
1562
+ if (minutes === null || inboundOffset === null) return null;
1563
+ return (minutes + inboundOffset - localOffset + MINUTES_IN_DAY) % MINUTES_IN_DAY;
1564
+ }
1565
+
1566
+ // Default to local parsing
1567
+ else {
1568
+ return parseBasicMinutes(isoTimeString);
1569
+ }
1570
+ }
1571
+ function serializeDate(date) {
1572
+ var d = new Date(date),
1573
+ month = '' + (d.getMonth() + 1),
1574
+ day = '' + d.getDate(),
1575
+ year = d.getFullYear();
1576
+ if (month.length < 2) month = '0' + month;
1577
+ if (day.length < 2) day = '0' + day;
1578
+ return [year, month, day].join('-');
1579
+ }
1580
+
1581
+ // this method is used to make the `new Date(value)` parsing behavior stricter
1582
+ function isDateTimeInputInformationSufficient(value) {
1583
+ if (!value || typeof value !== 'string') return false;
1584
+ const segments = value.split('T');
1585
+ if (segments.length != 2) return false;
1586
+ const dateNumbers = segments[0].split('-');
1587
+ if (dateNumbers.length != 3) return false;
1588
+ return true;
1589
+ }
1590
+
1591
+ // this method checks if the date isn't a datetime, or a partial date
1592
+ function isDateInputInformationMatching(value) {
1593
+ if (!value || typeof value !== 'string') return false;
1594
+ if (value.includes('T')) return false;
1595
+ const dateNumbers = value.split('-');
1596
+ if (dateNumbers.length != 3) return false;
1597
+ return true;
1598
+ }
1599
+ function serializeDateTime(date, time, timeSerializingFormat) {
1600
+ const workingDate = new Date();
1601
+ workingDate.setFullYear(date.getFullYear(), date.getMonth(), date.getDate());
1602
+ workingDate.setHours(Math.floor(time / 60), time % 60, 0, 0);
1603
+ if (timeSerializingFormat === TIME_SERIALISING_FORMATS.UTC_NORMALIZED) {
1604
+ const timezoneOffsetMinutes = workingDate.getTimezoneOffset();
1605
+ const dayOffset = time + timezoneOffsetMinutes < 0 ? -1 : time + timezoneOffsetMinutes > MINUTES_IN_DAY ? 1 : 0;
1606
+
1607
+ // Apply the date rollover pre-emptively
1608
+ workingDate.setHours(workingDate.getHours() + dayOffset * 24);
1609
+ }
1610
+ return serializeDate(workingDate) + 'T' + serializeTime(time, workingDate.getTimezoneOffset(), timeSerializingFormat);
1611
+ }
1612
+ function formatTimezoneOffset(minutes) {
1613
+ return _getSignedPaddedHours(minutes) + ':' + _getZeroPaddedString(Math.abs(minutes % 60));
1614
+ }
1615
+ function isInvalidDateString(value) {
1616
+ return isNaN(new Date(Date.parse(value)).getTime());
1617
+ }
1618
+ function _getSignedPaddedHours(minutes) {
1619
+ if (minutes > 0) {
1620
+ return '-' + _getZeroPaddedString(Math.floor(minutes / 60));
1621
+ } else {
1622
+ return '+' + _getZeroPaddedString(Math.floor((0 - minutes) / 60));
1623
+ }
1624
+ }
1625
+ function _getZeroPaddedString(time) {
1626
+ return time.toString().padStart(2, '0');
1627
+ }
1628
+
1629
+ function sanitizeDateTimePickerValue(options) {
1630
+ const {
1631
+ formField,
1632
+ value
1633
+ } = options;
1634
+ const {
1635
+ subtype
1636
+ } = formField;
1637
+ if (typeof value !== 'string') return null;
1638
+ if (subtype === DATETIME_SUBTYPES.DATE && (isInvalidDateString(value) || !isDateInputInformationMatching(value))) return null;
1639
+ if (subtype === DATETIME_SUBTYPES.TIME && parseIsoTime(value) === null) return null;
1640
+ if (subtype === DATETIME_SUBTYPES.DATETIME && (isInvalidDateString(value) || !isDateTimeInputInformationSufficient(value))) return null;
1641
+ return value;
1642
+ }
1643
+ function sanitizeSingleSelectValue(options) {
1644
+ const {
1645
+ formField,
1646
+ data,
1647
+ value
1648
+ } = options;
1649
+ const {
1650
+ valuesKey,
1651
+ values
1652
+ } = formField;
1653
+ try {
1654
+ const validValues = (valuesKey ? minDash.get(data, [valuesKey]) : values).map(v => v.value) || [];
1655
+ return validValues.includes(value) ? value : null;
1656
+ } catch (error) {
1657
+ // use default value in case of formatting error
1658
+ // TODO(@Skaiir): log a warning when this happens - https://github.com/bpmn-io/form-js/issues/289
1659
+ return null;
1660
+ }
1661
+ }
1662
+ function sanitizeMultiSelectValue(options) {
1663
+ const {
1664
+ formField,
1665
+ data,
1666
+ value
1667
+ } = options;
1668
+ const {
1669
+ valuesKey,
1670
+ values
1671
+ } = formField;
1672
+ try {
1673
+ const validValues = (valuesKey ? minDash.get(data, [valuesKey]) : values).map(v => v.value) || [];
1674
+ return value.filter(v => validValues.includes(v));
1675
+ } catch (error) {
1676
+ // use default value in case of formatting error
1677
+ // TODO(@Skaiir): log a warning when this happens - https://github.com/bpmn-io/form-js/issues/289
1678
+ return [];
1679
+ }
1680
+ }
1681
+
1682
+ const type$9 = 'checklist';
1436
1683
  function Checklist(props) {
1437
1684
  const {
1438
1685
  disabled,
@@ -1465,7 +1712,7 @@ function Checklist(props) {
1465
1712
  formId
1466
1713
  } = hooks.useContext(FormContext);
1467
1714
  return jsxRuntime.jsxs("div", {
1468
- class: classNames__default['default'](formFieldClasses(type$8, {
1715
+ class: classNames__default['default'](formFieldClasses(type$9, {
1469
1716
  errors,
1470
1717
  disabled
1471
1718
  })),
@@ -1505,26 +1752,33 @@ Checklist.create = function (options = {}) {
1505
1752
  ...options
1506
1753
  };
1507
1754
  };
1508
- Checklist.type = type$8;
1755
+ Checklist.type = type$9;
1509
1756
  Checklist.label = 'Checklist';
1510
1757
  Checklist.keyed = true;
1511
1758
  Checklist.emptyValue = [];
1512
1759
  Checklist.sanitizeValue = sanitizeMultiSelectValue;
1513
1760
 
1514
- /**
1515
- * Check if condition is met with given variables.
1516
- *
1517
- * @param {string | undefined} condition
1518
- * @param {import('../../types').Data} data
1519
- *
1520
- * @returns {boolean} true if condition is met or no condition or condition checker exists
1761
+ /**
1762
+ * Check if condition is met with given variables.
1763
+ *
1764
+ * @param {string | undefined} condition
1765
+ * @param {import('../../types').Data} data
1766
+ *
1767
+ * @returns {boolean} true if condition is met or no condition or condition checker exists
1521
1768
  */
1522
1769
  function useCondition(condition, data) {
1770
+ const initialData = useService('form')._getState().initialData;
1523
1771
  const conditionChecker = useService('conditionChecker', false);
1524
1772
  if (!conditionChecker) {
1525
1773
  return null;
1526
1774
  }
1527
- return conditionChecker.check(condition, data);
1775
+
1776
+ // make sure we do not use data from hidden fields
1777
+ const filteredData = {
1778
+ ...initialData,
1779
+ ...conditionChecker.applyConditions(data, data)
1780
+ };
1781
+ return conditionChecker.check(condition, filteredData);
1528
1782
  }
1529
1783
 
1530
1784
  const noop$1 = () => false;
@@ -1606,32 +1860,688 @@ Default.create = function (options = {}) {
1606
1860
  Default.type = 'default';
1607
1861
  Default.keyed = false;
1608
1862
 
1609
- /**
1610
- * This file must not be changed or exchanged.
1611
- *
1612
- * @see http://bpmn.io/license for more information.
1613
- */
1614
- function Logo() {
1615
- return jsxRuntime.jsxs("svg", {
1616
- xmlns: "http://www.w3.org/2000/svg",
1617
- viewBox: "0 0 14.02 5.57",
1618
- width: "53",
1619
- height: "21",
1620
- style: "vertical-align:middle",
1621
- children: [jsxRuntime.jsx("path", {
1622
- fill: "currentColor",
1623
- d: "M1.88.92v.14c0 .41-.13.68-.4.8.33.14.46.44.46.86v.33c0 .61-.33.95-.95.95H0V0h.95c.65 0 .93.3.93.92zM.63.57v1.06h.24c.24 0 .38-.1.38-.43V.98c0-.28-.1-.4-.32-.4zm0 1.63v1.22h.36c.2 0 .32-.1.32-.39v-.35c0-.37-.12-.48-.4-.48H.63zM4.18.99v.52c0 .64-.31.98-.94.98h-.3V4h-.62V0h.92c.63 0 .94.35.94.99zM2.94.57v1.35h.3c.2 0 .3-.09.3-.37v-.6c0-.29-.1-.38-.3-.38h-.3zm2.89 2.27L6.25 0h.88v4h-.6V1.12L6.1 3.99h-.6l-.46-2.82v2.82h-.55V0h.87zM8.14 1.1V4h-.56V0h.79L9 2.4V0h.56v4h-.64zm2.49 2.29v.6h-.6v-.6zM12.12 1c0-.63.33-1 .95-1 .61 0 .95.37.95 1v2.04c0 .64-.34 1-.95 1-.62 0-.95-.37-.95-1zm.62 2.08c0 .28.13.39.33.39s.32-.1.32-.4V.98c0-.29-.12-.4-.32-.4s-.33.11-.33.4z"
1624
- }), jsxRuntime.jsx("path", {
1625
- fill: "currentColor",
1626
- d: "M0 4.53h14.02v1.04H0zM11.08 0h.63v.62h-.63zm.63 4V1h-.63v2.98z"
1863
+ 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); }
1864
+ var CalendarIcon = (({
1865
+ styles = {},
1866
+ ...props
1867
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$h({
1868
+ width: "14",
1869
+ height: "15",
1870
+ viewBox: "0 0 28 30",
1871
+ fill: "none",
1872
+ xmlns: "http://www.w3.org/2000/svg"
1873
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
1874
+ fillRule: "evenodd",
1875
+ clipRule: "evenodd",
1876
+ 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",
1877
+ fill: "#000"
1878
+ })));
1879
+
1880
+ function InputAdorner(props) {
1881
+ const {
1882
+ pre = null,
1883
+ post = null,
1884
+ rootRef,
1885
+ inputRef,
1886
+ children,
1887
+ disabled,
1888
+ hasErrors
1889
+ } = props;
1890
+ const onAdornmentClick = () => inputRef?.current?.focus();
1891
+ return jsxRuntime.jsxs("div", {
1892
+ class: classNames__default['default']('fjs-input-group', {
1893
+ 'disabled': disabled
1894
+ }, {
1895
+ 'hasErrors': hasErrors
1896
+ }),
1897
+ ref: rootRef,
1898
+ children: [pre !== null && jsxRuntime.jsxs("span", {
1899
+ class: "fjs-input-adornment border-right border-radius-left",
1900
+ onClick: onAdornmentClick,
1901
+ children: [" ", pre, " "]
1902
+ }), children, post !== null && jsxRuntime.jsxs("span", {
1903
+ class: "fjs-input-adornment border-left border-radius-right",
1904
+ onClick: onAdornmentClick,
1905
+ children: [" ", post, " "]
1627
1906
  })]
1628
1907
  });
1629
1908
  }
1630
- function Lightbox(props) {
1909
+
1910
+ function Datepicker(props) {
1631
1911
  const {
1632
- open
1633
- } = props;
1634
- if (!open) {
1912
+ id,
1913
+ label,
1914
+ collapseLabelOnEmpty,
1915
+ formId,
1916
+ required,
1917
+ disabled,
1918
+ disallowPassedDates,
1919
+ date,
1920
+ setDate
1921
+ } = props;
1922
+ const dateInputRef = hooks.useRef();
1923
+ const focusScopeRef = hooks.useRef();
1924
+ const [flatpickrInstance, setFlatpickrInstance] = hooks.useState(null);
1925
+ const [isInputDirty, setIsInputDirty] = hooks.useState(false);
1926
+ const [forceFocusCalendar, setForceFocusCalendar] = hooks.useState(false);
1927
+
1928
+ // shorts the date value back to the source
1929
+ hooks.useEffect(() => {
1930
+ if (!flatpickrInstance || !flatpickrInstance.config) return;
1931
+ flatpickrInstance.setDate(date, true);
1932
+ setIsInputDirty(false);
1933
+ }, [flatpickrInstance, date.toString()]);
1934
+ hooks.useEffect(() => {
1935
+ if (!forceFocusCalendar) return;
1936
+ focusRelevantFlatpickerDay(flatpickrInstance);
1937
+ setForceFocusCalendar(false);
1938
+ }, [flatpickrInstance, forceFocusCalendar]);
1939
+
1940
+ // setup flatpickr instance
1941
+ hooks.useEffect(() => {
1942
+ if (disabled) {
1943
+ setFlatpickrInstance(null);
1944
+ return;
1945
+ }
1946
+ let config = {
1947
+ allowInput: true,
1948
+ dateFormat: 'm/d/Y',
1949
+ static: true,
1950
+ clickOpens: false,
1951
+ errorHandler: () => {/* do nothing, we expect the values to sometimes be erronous and we don't want warnings polluting the console */}
1952
+ };
1953
+ if (disallowPassedDates) {
1954
+ config = {
1955
+ ...config,
1956
+ minDate: 'today'
1957
+ };
1958
+ }
1959
+ const instance = flatpickr__default['default'](dateInputRef.current, config);
1960
+ setFlatpickrInstance(instance);
1961
+ const onCalendarFocusOut = e => {
1962
+ if (!instance.calendarContainer.contains(e.relatedTarget) && e.relatedTarget != dateInputRef.current) {
1963
+ instance.close();
1964
+ }
1965
+ };
1966
+
1967
+ // remove dirty tag to have mouse day selection prioritize input blur
1968
+ const onCalendarMouseDown = e => {
1969
+ if (e.target.classList.contains('flatpickr-day')) {
1970
+ setIsInputDirty(false);
1971
+ }
1972
+ };
1973
+
1974
+ // when the dropdown of the datepickr opens, we register a few event handlers to re-implement some of the
1975
+ // flatpicker logic that was lost when setting allowInput to true
1976
+ instance.config.onOpen = [() => instance.calendarContainer.addEventListener('focusout', onCalendarFocusOut), () => instance.calendarContainer.addEventListener('mousedown', onCalendarMouseDown)];
1977
+ instance.config.onClose = [() => instance.calendarContainer.removeEventListener('focusout', onCalendarFocusOut), () => instance.calendarContainer.removeEventListener('mousedown', onCalendarMouseDown)];
1978
+ }, [disabled, disallowPassedDates]);
1979
+
1980
+ // onChange is updated dynamically, so not to re-render the flatpicker every time it changes
1981
+ hooks.useEffect(() => {
1982
+ if (!flatpickrInstance || !flatpickrInstance.config) return;
1983
+ flatpickrInstance.config.onChange = [date => setDate(new Date(date)), () => setIsInputDirty(false)];
1984
+ }, [flatpickrInstance, setDate]);
1985
+ const onInputKeyDown = hooks.useCallback(e => {
1986
+ if (!flatpickrInstance) return;
1987
+ if (e.code === 'Escape') {
1988
+ flatpickrInstance.close();
1989
+ }
1990
+ if (e.code === 'ArrowDown') {
1991
+ if (isInputDirty) {
1992
+ // trigger an enter keypress to submit the new input, then focus calendar day on the next render cycle
1993
+ dateInputRef.current.dispatchEvent(ENTER_KEYDOWN_EVENT);
1994
+ setIsInputDirty(false);
1995
+ setForceFocusCalendar(true);
1996
+ } else {
1997
+ // focus calendar day immediately
1998
+ focusRelevantFlatpickerDay(flatpickrInstance);
1999
+ }
2000
+ e.preventDefault();
2001
+ }
2002
+ if (e.code === 'Enter') {
2003
+ setIsInputDirty(false);
2004
+ }
2005
+ }, [flatpickrInstance, isInputDirty]);
2006
+ const onInputFocus = hooks.useCallback(e => {
2007
+ if (!flatpickrInstance || focusScopeRef.current.contains(e.relatedTarget)) return;
2008
+ flatpickrInstance.open();
2009
+ }, [flatpickrInstance]);
2010
+
2011
+ // simulate an enter press on blur to make sure the date value is submitted in all scenarios
2012
+ const onInputBlur = hooks.useCallback(e => {
2013
+ if (!isInputDirty || e.relatedTarget && e.relatedTarget.classList.contains('flatpickr-day')) return;
2014
+ dateInputRef.current.dispatchEvent(ENTER_KEYDOWN_EVENT);
2015
+ setIsInputDirty(false);
2016
+ }, [isInputDirty]);
2017
+ const fullId = `${prefixId(id, formId)}--date`;
2018
+ return jsxRuntime.jsxs("div", {
2019
+ class: "fjs-datetime-subsection",
2020
+ children: [jsxRuntime.jsx(Label, {
2021
+ id: fullId,
2022
+ label: label,
2023
+ collapseOnEmpty: collapseLabelOnEmpty,
2024
+ required: required
2025
+ }), jsxRuntime.jsx(InputAdorner, {
2026
+ pre: jsxRuntime.jsx(CalendarIcon, {}),
2027
+ disabled: disabled,
2028
+ rootRef: focusScopeRef,
2029
+ inputRef: dateInputRef,
2030
+ children: jsxRuntime.jsx("div", {
2031
+ class: "fjs-datepicker",
2032
+ style: {
2033
+ width: '100%'
2034
+ },
2035
+ children: jsxRuntime.jsx("input", {
2036
+ ref: dateInputRef,
2037
+ type: "text",
2038
+ id: fullId,
2039
+ class: 'fjs-input',
2040
+ disabled: disabled,
2041
+ placeholder: "mm/dd/yyyy",
2042
+ autoComplete: "false",
2043
+ onFocus: onInputFocus,
2044
+ onKeyDown: onInputKeyDown,
2045
+ onMouseDown: e => !flatpickrInstance.isOpen && flatpickrInstance.open(),
2046
+ onBlur: onInputBlur,
2047
+ onInput: e => setIsInputDirty(true),
2048
+ "data-input": true
2049
+ })
2050
+ })
2051
+ })]
2052
+ });
2053
+ }
2054
+
2055
+ 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); }
2056
+ var ClockIcon = (({
2057
+ styles = {},
2058
+ ...props
2059
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$g({
2060
+ width: "16",
2061
+ height: "16",
2062
+ viewBox: "0 0 28 29",
2063
+ fill: "none",
2064
+ xmlns: "http://www.w3.org/2000/svg"
2065
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
2066
+ d: "M13 14.41L18.59 20 20 18.59l-5-5.01V5h-2v9.41z",
2067
+ fill: "#000"
2068
+ }), /*#__PURE__*/React__default['default'].createElement("path", {
2069
+ fillRule: "evenodd",
2070
+ clipRule: "evenodd",
2071
+ 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",
2072
+ fill: "#000"
2073
+ })));
2074
+
2075
+ function useKeyDownAction(targetKey, action, listenerElement = window) {
2076
+ function downHandler({
2077
+ key
2078
+ }) {
2079
+ if (key === targetKey) {
2080
+ action();
2081
+ }
2082
+ }
2083
+ hooks.useEffect(() => {
2084
+ listenerElement.addEventListener('keydown', downHandler);
2085
+ return () => {
2086
+ listenerElement.removeEventListener('keydown', downHandler);
2087
+ };
2088
+ });
2089
+ }
2090
+
2091
+ const DEFAULT_LABEL_GETTER = value => value;
2092
+ const NOOP = () => {};
2093
+ function DropdownList(props) {
2094
+ const {
2095
+ keyEventsListener = window,
2096
+ values = [],
2097
+ getLabel = DEFAULT_LABEL_GETTER,
2098
+ onValueSelected = NOOP,
2099
+ height = 235,
2100
+ emptyListMessage = 'No results',
2101
+ initialFocusIndex = 0
2102
+ } = props;
2103
+ const [mouseControl, setMouseControl] = hooks.useState(false);
2104
+ const [focusedValueIndex, setFocusedValueIndex] = hooks.useState(initialFocusIndex);
2105
+ const [smoothScrolling, setSmoothScrolling] = hooks.useState(false);
2106
+ const dropdownContainer = hooks.useRef();
2107
+ const mouseScreenPos = hooks.useRef();
2108
+ const focusedItem = hooks.useMemo(() => values.length ? values[focusedValueIndex] : null, [focusedValueIndex, values]);
2109
+ const changeFocusedValueIndex = hooks.useCallback(delta => {
2110
+ setFocusedValueIndex(x => Math.min(Math.max(0, x + delta), values.length - 1));
2111
+ }, [values.length]);
2112
+ hooks.useEffect(() => {
2113
+ if (focusedValueIndex === 0) return;
2114
+ if (!focusedValueIndex || !values.length) {
2115
+ setFocusedValueIndex(0);
2116
+ } else if (focusedValueIndex >= values.length) {
2117
+ setFocusedValueIndex(values.length - 1);
2118
+ }
2119
+ }, [focusedValueIndex, values.length]);
2120
+ useKeyDownAction('ArrowUp', () => {
2121
+ if (values.length) {
2122
+ changeFocusedValueIndex(-1);
2123
+ setMouseControl(false);
2124
+ }
2125
+ }, keyEventsListener);
2126
+ useKeyDownAction('ArrowDown', () => {
2127
+ if (values.length) {
2128
+ changeFocusedValueIndex(1);
2129
+ setMouseControl(false);
2130
+ }
2131
+ }, keyEventsListener);
2132
+ useKeyDownAction('Enter', () => {
2133
+ if (focusedItem) {
2134
+ onValueSelected(focusedItem);
2135
+ }
2136
+ }, keyEventsListener);
2137
+ hooks.useEffect(() => {
2138
+ const individualEntries = dropdownContainer.current.children;
2139
+ if (individualEntries.length && !mouseControl) {
2140
+ individualEntries[focusedValueIndex].scrollIntoView({
2141
+ block: 'nearest',
2142
+ inline: 'nearest'
2143
+ });
2144
+ }
2145
+ }, [focusedValueIndex, mouseControl]);
2146
+ hooks.useEffect(() => {
2147
+ setSmoothScrolling(true);
2148
+ }, []);
2149
+ const onMouseMovedInKeyboardMode = (event, valueIndex) => {
2150
+ const userMovedCursor = !mouseScreenPos.current || mouseScreenPos.current.x !== event.screenX && mouseScreenPos.current.y !== event.screenY;
2151
+ if (userMovedCursor) {
2152
+ mouseScreenPos.current = {
2153
+ x: event.screenX,
2154
+ y: event.screenY
2155
+ };
2156
+ setMouseControl(true);
2157
+ setFocusedValueIndex(valueIndex);
2158
+ }
2159
+ };
2160
+ return jsxRuntime.jsxs("div", {
2161
+ ref: dropdownContainer,
2162
+ tabIndex: -1,
2163
+ class: "fjs-dropdownlist",
2164
+ style: {
2165
+ maxHeight: height,
2166
+ scrollBehavior: smoothScrolling ? 'smooth' : 'auto'
2167
+ },
2168
+ children: [values.length > 0 && values.map((v, i) => {
2169
+ return jsxRuntime.jsx("div", {
2170
+ class: classNames__default['default']('fjs-dropdownlist-item', {
2171
+ 'focused': focusedValueIndex === i
2172
+ }),
2173
+ onMouseMove: mouseControl ? undefined : e => onMouseMovedInKeyboardMode(e, i),
2174
+ onMouseEnter: mouseControl ? () => setFocusedValueIndex(i) : undefined,
2175
+ onMouseDown: e => {
2176
+ e.preventDefault();
2177
+ onValueSelected(v);
2178
+ },
2179
+ children: getLabel(v)
2180
+ });
2181
+ }), !values.length && jsxRuntime.jsx("div", {
2182
+ class: "fjs-dropdownlist-empty",
2183
+ children: emptyListMessage
2184
+ })]
2185
+ });
2186
+ }
2187
+
2188
+ function Timepicker(props) {
2189
+ const {
2190
+ id,
2191
+ label,
2192
+ collapseLabelOnEmpty,
2193
+ formId,
2194
+ required,
2195
+ disabled,
2196
+ use24h = false,
2197
+ timeInterval,
2198
+ time,
2199
+ setTime
2200
+ } = props;
2201
+ const timeInputRef = hooks.useRef();
2202
+ const [dropdownIsOpen, setDropdownIsOpen] = hooks.useState(false);
2203
+ const useDropdown = hooks.useMemo(() => timeInterval !== 1, [timeInterval]);
2204
+ const [rawValue, setRawValue] = hooks.useState('');
2205
+
2206
+ // populates values from source
2207
+ hooks.useEffect(() => {
2208
+ if (time === null) {
2209
+ setRawValue('');
2210
+ return;
2211
+ }
2212
+ const intervalAdjustedTime = time - time % timeInterval;
2213
+ setRawValue(formatTime(use24h, intervalAdjustedTime));
2214
+ if (intervalAdjustedTime != time) {
2215
+ setTime(intervalAdjustedTime);
2216
+ }
2217
+ }, [time, setTime, use24h, timeInterval]);
2218
+ const propagateRawToMinute = hooks.useCallback(newRawValue => {
2219
+ const localRawValue = newRawValue || rawValue;
2220
+
2221
+ // If no raw value exists, set the minute to null
2222
+ if (!localRawValue) {
2223
+ setTime(null);
2224
+ return;
2225
+ }
2226
+ const minutes = parseInputTime(localRawValue);
2227
+
2228
+ // If raw string couldn't be parsed, clean everything up
2229
+ if (!minDash.isNumber(minutes)) {
2230
+ setRawValue('');
2231
+ setTime(null);
2232
+ return;
2233
+ }
2234
+
2235
+ // Enforce the minutes to match the timeInterval
2236
+ const correctedMinutes = minutes - minutes % timeInterval;
2237
+
2238
+ // Enforce the raw text to be formatted properly
2239
+ setRawValue(formatTime(use24h, correctedMinutes));
2240
+ setTime(correctedMinutes);
2241
+ }, [rawValue, timeInterval, use24h, setTime]);
2242
+ const timeOptions = hooks.useMemo(() => {
2243
+ const minutesInDay = 24 * 60;
2244
+ const intervalCount = Math.floor(minutesInDay / timeInterval);
2245
+ return [...Array(intervalCount).keys()].map(intervalIndex => formatTime(use24h, intervalIndex * timeInterval));
2246
+ }, [timeInterval, use24h]);
2247
+ const initialFocusIndex = hooks.useMemo(() => {
2248
+ // if there are no options, there will not be any focusing
2249
+ if (!timeOptions || !timeInterval) return null;
2250
+
2251
+ // if there is a set minute value, we focus it in the dropdown
2252
+ if (time) return time / timeInterval;
2253
+ const cacheTime = parseInputTime(rawValue);
2254
+
2255
+ // if there is a valid value in the input cache, we try and focus close to it
2256
+ if (cacheTime) {
2257
+ const flooredCacheTime = cacheTime - cacheTime % timeInterval;
2258
+ return flooredCacheTime / timeInterval;
2259
+ }
2260
+
2261
+ // If there is no set value, simply focus the middle of the dropdown (12:00)
2262
+ return Math.floor(timeOptions.length / 2);
2263
+ }, [rawValue, time, timeInterval, timeOptions]);
2264
+ const onInputKeyDown = e => {
2265
+ switch (e.key) {
2266
+ case 'ArrowUp':
2267
+ e.preventDefault();
2268
+ break;
2269
+ case 'ArrowDown':
2270
+ useDropdown && setDropdownIsOpen(true);
2271
+ e.preventDefault();
2272
+ break;
2273
+ case 'Escape':
2274
+ useDropdown && setDropdownIsOpen(false);
2275
+ break;
2276
+ case 'Enter':
2277
+ !dropdownIsOpen && propagateRawToMinute();
2278
+ break;
2279
+ }
2280
+ };
2281
+ const onInputBlur = e => {
2282
+ setDropdownIsOpen(false);
2283
+ propagateRawToMinute();
2284
+ };
2285
+ const onDropdownValueSelected = value => {
2286
+ setDropdownIsOpen(false);
2287
+ propagateRawToMinute(value);
2288
+ };
2289
+ const fullId = `${prefixId(id, formId)}--time`;
2290
+ return jsxRuntime.jsxs("div", {
2291
+ class: "fjs-datetime-subsection",
2292
+ children: [jsxRuntime.jsx(Label, {
2293
+ id: fullId,
2294
+ label: label,
2295
+ collapseOnEmpty: collapseLabelOnEmpty,
2296
+ required: required
2297
+ }), jsxRuntime.jsx(InputAdorner, {
2298
+ pre: jsxRuntime.jsx(ClockIcon, {}),
2299
+ inputRef: timeInputRef,
2300
+ disabled: disabled,
2301
+ children: jsxRuntime.jsxs("div", {
2302
+ class: "fjs-timepicker fjs-timepicker-anchor",
2303
+ children: [jsxRuntime.jsx("input", {
2304
+ ref: timeInputRef,
2305
+ type: "text",
2306
+ id: fullId,
2307
+ class: "fjs-input",
2308
+ value: rawValue,
2309
+ disabled: disabled,
2310
+ placeholder: use24h ? 'hh:mm' : 'hh:mm ?m',
2311
+ autoComplete: "false",
2312
+ onFocus: () => useDropdown && setDropdownIsOpen(true),
2313
+ onClick: () => useDropdown && setDropdownIsOpen(true)
2314
+
2315
+ // @ts-ignore
2316
+ ,
2317
+ onInput: e => {
2318
+ setRawValue(e.target.value);
2319
+ useDropdown && setDropdownIsOpen(false);
2320
+ },
2321
+ onBlur: onInputBlur,
2322
+ onKeyDown: onInputKeyDown,
2323
+ "data-input": true
2324
+ }), dropdownIsOpen && jsxRuntime.jsx(DropdownList, {
2325
+ values: timeOptions,
2326
+ height: 150,
2327
+ onValueSelected: onDropdownValueSelected,
2328
+ listenerElement: timeInputRef.current,
2329
+ initialFocusIndex: initialFocusIndex
2330
+ })]
2331
+ })
2332
+ })]
2333
+ });
2334
+ }
2335
+
2336
+ const type$8 = 'datetime';
2337
+ function Datetime(props) {
2338
+ const {
2339
+ disabled,
2340
+ errors = [],
2341
+ field,
2342
+ onChange,
2343
+ value = ''
2344
+ } = props;
2345
+ const {
2346
+ description,
2347
+ id,
2348
+ dateLabel,
2349
+ timeLabel,
2350
+ validate = {},
2351
+ subtype,
2352
+ use24h,
2353
+ disallowPassedDates,
2354
+ timeInterval,
2355
+ timeSerializingFormat
2356
+ } = field;
2357
+ const {
2358
+ required
2359
+ } = validate;
2360
+ const {
2361
+ formId
2362
+ } = hooks.useContext(FormContext);
2363
+ const getNullDateTime = () => ({
2364
+ date: new Date(Date.parse(null)),
2365
+ time: null
2366
+ });
2367
+ const [dateTime, setDateTime] = hooks.useState(getNullDateTime());
2368
+ const [dateTimeUpdateRequest, setDateTimeUpdateRequest] = hooks.useState(null);
2369
+ const isValidDate = date => date && !isNaN(date.getTime());
2370
+ const isValidTime = time => !isNaN(parseInt(time));
2371
+ const useDatePicker = hooks.useMemo(() => subtype === DATETIME_SUBTYPES.DATE || subtype === DATETIME_SUBTYPES.DATETIME, [subtype]);
2372
+ const useTimePicker = hooks.useMemo(() => subtype === DATETIME_SUBTYPES.TIME || subtype === DATETIME_SUBTYPES.DATETIME, [subtype]);
2373
+ hooks.useEffect(() => {
2374
+ let {
2375
+ date,
2376
+ time
2377
+ } = getNullDateTime();
2378
+ if (!disabled) {
2379
+ switch (subtype) {
2380
+ case DATETIME_SUBTYPES.DATE:
2381
+ {
2382
+ date = new Date(Date.parse(value));
2383
+ break;
2384
+ }
2385
+ case DATETIME_SUBTYPES.TIME:
2386
+ {
2387
+ time = parseIsoTime(value);
2388
+ break;
2389
+ }
2390
+ case DATETIME_SUBTYPES.DATETIME:
2391
+ {
2392
+ date = new Date(Date.parse(value));
2393
+ time = isValidDate(date) ? 60 * date.getHours() + date.getMinutes() : null;
2394
+ break;
2395
+ }
2396
+ }
2397
+ }
2398
+ setDateTime({
2399
+ date,
2400
+ time
2401
+ });
2402
+ }, [subtype, value, disabled]);
2403
+ const computeAndSetState = hooks.useCallback(({
2404
+ date,
2405
+ time
2406
+ }) => {
2407
+ let newDateTimeValue = null;
2408
+ if (subtype === DATETIME_SUBTYPES.DATE && isValidDate(date)) {
2409
+ newDateTimeValue = serializeDate(date);
2410
+ } else if (subtype === DATETIME_SUBTYPES.TIME && isValidTime(time)) {
2411
+ newDateTimeValue = serializeTime(time, new Date().getTimezoneOffset(), timeSerializingFormat);
2412
+ } else if (subtype === DATETIME_SUBTYPES.DATETIME && isValidDate(date) && isValidTime(time)) {
2413
+ newDateTimeValue = serializeDateTime(date, time, timeSerializingFormat);
2414
+ }
2415
+ onChange({
2416
+ value: newDateTimeValue,
2417
+ field
2418
+ });
2419
+ }, [field, onChange, subtype, timeSerializingFormat]);
2420
+ hooks.useEffect(() => {
2421
+ if (dateTimeUpdateRequest) {
2422
+ if (dateTimeUpdateRequest.refreshOnly) {
2423
+ computeAndSetState(dateTime);
2424
+ } else {
2425
+ const newDateTime = {
2426
+ ...dateTime,
2427
+ ...dateTimeUpdateRequest
2428
+ };
2429
+ setDateTime(newDateTime);
2430
+ computeAndSetState(newDateTime);
2431
+ }
2432
+ setDateTimeUpdateRequest(null);
2433
+ }
2434
+ }, [computeAndSetState, dateTime, dateTimeUpdateRequest]);
2435
+ hooks.useEffect(() => {
2436
+ setDateTimeUpdateRequest({
2437
+ refreshOnly: true
2438
+ });
2439
+ }, [timeSerializingFormat]);
2440
+ const allErrors = hooks.useMemo(() => {
2441
+ if (required || subtype !== DATETIME_SUBTYPES.DATETIME) return errors;
2442
+ const isOnlyOneFieldSet = isValidDate(dateTime.date) && !isValidTime(dateTime.time) || !isValidDate(dateTime.date) && isValidTime(dateTime.time);
2443
+ return isOnlyOneFieldSet ? ['Date and time must both be entered.', ...errors] : errors;
2444
+ }, [required, subtype, dateTime, errors]);
2445
+ const setDate = hooks.useCallback(date => {
2446
+ setDateTimeUpdateRequest(prev => prev ? {
2447
+ ...prev,
2448
+ date
2449
+ } : {
2450
+ date
2451
+ });
2452
+ }, []);
2453
+ const setTime = hooks.useCallback(time => {
2454
+ setDateTimeUpdateRequest(prev => prev ? {
2455
+ ...prev,
2456
+ time
2457
+ } : {
2458
+ time
2459
+ });
2460
+ }, []);
2461
+ const datePickerProps = {
2462
+ id,
2463
+ label: dateLabel,
2464
+ collapseLabelOnEmpty: !timeLabel,
2465
+ formId,
2466
+ required,
2467
+ disabled,
2468
+ disallowPassedDates,
2469
+ date: dateTime.date,
2470
+ setDate
2471
+ };
2472
+ const timePickerProps = {
2473
+ id,
2474
+ label: timeLabel,
2475
+ collapseLabelOnEmpty: !dateLabel,
2476
+ formId,
2477
+ required,
2478
+ disabled,
2479
+ use24h,
2480
+ timeInterval,
2481
+ time: dateTime.time,
2482
+ setTime
2483
+ };
2484
+ return jsxRuntime.jsxs("div", {
2485
+ class: formFieldClasses(type$8, {
2486
+ errors: allErrors,
2487
+ disabled
2488
+ }),
2489
+ children: [jsxRuntime.jsxs("div", {
2490
+ class: classNames__default['default']('fjs-vertical-group'),
2491
+ children: [useDatePicker && jsxRuntime.jsx(Datepicker, {
2492
+ ...datePickerProps
2493
+ }), useTimePicker && useDatePicker && jsxRuntime.jsx("div", {
2494
+ class: "fjs-datetime-separator"
2495
+ }), useTimePicker && jsxRuntime.jsx(Timepicker, {
2496
+ ...timePickerProps
2497
+ })]
2498
+ }), jsxRuntime.jsx(Description, {
2499
+ description: description
2500
+ }), jsxRuntime.jsx(Errors, {
2501
+ errors: allErrors
2502
+ })]
2503
+ });
2504
+ }
2505
+ Datetime.create = function (options = {}) {
2506
+ const newOptions = {};
2507
+ minDash.set(newOptions, DATETIME_SUBTYPE_PATH, DATETIME_SUBTYPES.DATE);
2508
+ minDash.set(newOptions, DATE_LABEL_PATH, 'Date');
2509
+ return {
2510
+ ...newOptions,
2511
+ ...options
2512
+ };
2513
+ };
2514
+ Datetime.type = type$8;
2515
+ Datetime.keyed = true;
2516
+ Datetime.emptyValue = null;
2517
+ Datetime.sanitizeValue = sanitizeDateTimePickerValue;
2518
+
2519
+ /**
2520
+ * This file must not be changed or exchanged.
2521
+ *
2522
+ * @see http://bpmn.io/license for more information.
2523
+ */
2524
+ function Logo() {
2525
+ return jsxRuntime.jsxs("svg", {
2526
+ xmlns: "http://www.w3.org/2000/svg",
2527
+ viewBox: "0 0 14.02 5.57",
2528
+ width: "53",
2529
+ height: "21",
2530
+ style: "vertical-align:middle",
2531
+ children: [jsxRuntime.jsx("path", {
2532
+ fill: "currentColor",
2533
+ d: "M1.88.92v.14c0 .41-.13.68-.4.8.33.14.46.44.46.86v.33c0 .61-.33.95-.95.95H0V0h.95c.65 0 .93.3.93.92zM.63.57v1.06h.24c.24 0 .38-.1.38-.43V.98c0-.28-.1-.4-.32-.4zm0 1.63v1.22h.36c.2 0 .32-.1.32-.39v-.35c0-.37-.12-.48-.4-.48H.63zM4.18.99v.52c0 .64-.31.98-.94.98h-.3V4h-.62V0h.92c.63 0 .94.35.94.99zM2.94.57v1.35h.3c.2 0 .3-.09.3-.37v-.6c0-.29-.1-.38-.3-.38h-.3zm2.89 2.27L6.25 0h.88v4h-.6V1.12L6.1 3.99h-.6l-.46-2.82v2.82h-.55V0h.87zM8.14 1.1V4h-.56V0h.79L9 2.4V0h.56v4h-.64zm2.49 2.29v.6h-.6v-.6zM12.12 1c0-.63.33-1 .95-1 .61 0 .95.37.95 1v2.04c0 .64-.34 1-.95 1-.62 0-.95-.37-.95-1zm.62 2.08c0 .28.13.39.33.39s.32-.1.32-.4V.98c0-.29-.12-.4-.32-.4s-.33.11-.33.4z"
2534
+ }), jsxRuntime.jsx("path", {
2535
+ fill: "currentColor",
2536
+ d: "M0 4.53h14.02v1.04H0zM11.08 0h.63v.62h-.63zm.63 4V1h-.63v2.98z"
2537
+ })]
2538
+ });
2539
+ }
2540
+ function Lightbox(props) {
2541
+ const {
2542
+ open
2543
+ } = props;
2544
+ if (!open) {
1635
2545
  return null;
1636
2546
  }
1637
2547
  return jsxRuntime.jsxs("div", {
@@ -1726,22 +2636,29 @@ function FormComponent(props) {
1726
2636
  });
1727
2637
  }
1728
2638
 
1729
- /**
1730
- *
1731
- * @param {string | undefined} expression
1732
- * @param {import('../../types').Data} data
2639
+ /**
2640
+ *
2641
+ * @param {string | undefined} expression
2642
+ * @param {import('../../types').Data} data
1733
2643
  */
1734
2644
  function useEvaluation(expression, data) {
2645
+ const initialData = useService('form')._getState().initialData;
1735
2646
  const conditionChecker = useService('conditionChecker', false);
1736
2647
  if (!conditionChecker) {
1737
2648
  return null;
1738
2649
  }
1739
- return conditionChecker.evaluate(expression, data);
2650
+
2651
+ // make sure we do not use data from hidden fields
2652
+ const filteredData = {
2653
+ ...initialData,
2654
+ ...conditionChecker.applyConditions(data, data)
2655
+ };
2656
+ return conditionChecker.evaluate(expression, filteredData);
1740
2657
  }
1741
2658
 
1742
- /**
1743
- *
1744
- * @param {string} value
2659
+ /**
2660
+ *
2661
+ * @param {string} value
1745
2662
  */
1746
2663
  function useExpressionValue(value) {
1747
2664
  const formData = useService('form')._getState().data;
@@ -1761,11 +2678,11 @@ function isExpression(value) {
1761
2678
  return minDash.isString(value) && value.startsWith('=');
1762
2679
  }
1763
2680
 
1764
- 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); }
2681
+ 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); }
1765
2682
  var ImagePlaceholder = (({
1766
2683
  styles = {},
1767
2684
  ...props
1768
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$1({
2685
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$f({
1769
2686
  width: "64",
1770
2687
  height: "64",
1771
2688
  viewBox: "0 0 1280 1280",
@@ -1845,11 +2762,16 @@ function Numberfield(props) {
1845
2762
  description,
1846
2763
  id,
1847
2764
  label,
2765
+ appearance = {},
1848
2766
  validate = {},
1849
2767
  decimalDigits,
1850
2768
  serializeToString = false,
1851
2769
  increment: incrementValue
1852
2770
  } = field;
2771
+ const {
2772
+ prefixAdorner,
2773
+ suffixAdorner
2774
+ } = appearance;
1853
2775
  const {
1854
2776
  required
1855
2777
  } = validate;
@@ -1959,45 +2881,52 @@ function Numberfield(props) {
1959
2881
  id: prefixId(id, formId),
1960
2882
  label: label,
1961
2883
  required: required
1962
- }), jsxRuntime.jsxs("div", {
1963
- class: classNames__default['default']('fjs-input-group', {
1964
- 'disabled': disabled
1965
- }, {
1966
- 'hasErrors': errors.length
1967
- }),
1968
- children: [jsxRuntime.jsx("input", {
1969
- ref: inputRef,
1970
- class: "fjs-input",
1971
- disabled: disabled,
1972
- id: prefixId(id, formId),
1973
- onKeyDown: onKeyDown,
1974
- onKeyPress: onKeyPress
1975
-
1976
- // @ts-ignore
1977
- ,
1978
- onInput: e => setValue(e.target.value),
1979
- type: "text",
1980
- autoComplete: "off",
1981
- step: arrowIncrementValue,
1982
- value: displayValue
1983
- }), jsxRuntime.jsxs("div", {
1984
- class: classNames__default['default']('fjs-number-arrow-container', {
2884
+ }), jsxRuntime.jsx(InputAdorner, {
2885
+ disabled: disabled,
2886
+ pre: prefixAdorner,
2887
+ post: suffixAdorner,
2888
+ children: jsxRuntime.jsxs("div", {
2889
+ class: classNames__default['default']('fjs-vertical-group', {
1985
2890
  'disabled': disabled
2891
+ }, {
2892
+ 'hasErrors': errors.length
1986
2893
  }),
1987
- children: [jsxRuntime.jsx("button", {
1988
- class: "fjs-number-arrow-up",
1989
- onClick: () => increment(),
1990
- tabIndex: -1,
1991
- children: "\u02C4"
1992
- }), jsxRuntime.jsx("div", {
1993
- class: "fjs-number-arrow-separator"
1994
- }), jsxRuntime.jsx("button", {
1995
- class: "fjs-number-arrow-down",
1996
- onClick: () => decrement(),
1997
- tabIndex: -1,
1998
- children: "\u02C5"
2894
+ children: [jsxRuntime.jsx("input", {
2895
+ ref: inputRef,
2896
+ class: "fjs-input",
2897
+ disabled: disabled,
2898
+ id: prefixId(id, formId),
2899
+ onKeyDown: onKeyDown,
2900
+ onKeyPress: onKeyPress
2901
+
2902
+ // @ts-ignore
2903
+ ,
2904
+ onInput: e => setValue(e.target.value),
2905
+ type: "text",
2906
+ autoComplete: "off",
2907
+ step: arrowIncrementValue,
2908
+ value: displayValue
2909
+ }), jsxRuntime.jsxs("div", {
2910
+ class: classNames__default['default']('fjs-number-arrow-container', {
2911
+ 'disabled': disabled
2912
+ }),
2913
+ children: [jsxRuntime.jsx("button", {
2914
+ class: "fjs-number-arrow-up",
2915
+ type: "button",
2916
+ onClick: () => increment(),
2917
+ tabIndex: -1,
2918
+ children: "\u02C4"
2919
+ }), jsxRuntime.jsx("div", {
2920
+ class: "fjs-number-arrow-separator"
2921
+ }), jsxRuntime.jsx("button", {
2922
+ class: "fjs-number-arrow-down",
2923
+ type: "button",
2924
+ onClick: () => decrement(),
2925
+ tabIndex: -1,
2926
+ children: "\u02C5"
2927
+ })]
1999
2928
  })]
2000
- })]
2929
+ })
2001
2930
  }), jsxRuntime.jsx(Description, {
2002
2931
  description: description
2003
2932
  }), jsxRuntime.jsx(Errors, {
@@ -2180,11 +3109,11 @@ Select.keyed = true;
2180
3109
  Select.emptyValue = null;
2181
3110
  Select.sanitizeValue = sanitizeSingleSelectValue;
2182
3111
 
2183
- 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); }
3112
+ 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); }
2184
3113
  var CloseIcon = (({
2185
3114
  styles = {},
2186
3115
  ...props
2187
- }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends({
3116
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$e({
2188
3117
  width: "16",
2189
3118
  height: "16",
2190
3119
  fill: "none",
@@ -2196,113 +3125,6 @@ var CloseIcon = (({
2196
3125
  fill: "currentColor"
2197
3126
  })));
2198
3127
 
2199
- function useKeyDownAction(targetKey, action, listenerElement = window) {
2200
- function downHandler({
2201
- key
2202
- }) {
2203
- if (key === targetKey) {
2204
- action();
2205
- }
2206
- }
2207
- hooks.useEffect(() => {
2208
- listenerElement.addEventListener('keydown', downHandler);
2209
- return () => {
2210
- listenerElement.removeEventListener('keydown', downHandler);
2211
- };
2212
- });
2213
- }
2214
-
2215
- const DEFAULT_LABEL_GETTER = value => value;
2216
- const NOOP = () => {};
2217
- function DropdownList(props) {
2218
- const {
2219
- keyEventsListener = window,
2220
- values = [],
2221
- getLabel = DEFAULT_LABEL_GETTER,
2222
- onValueSelected = NOOP,
2223
- height = 235,
2224
- emptyListMessage = 'No results'
2225
- } = props;
2226
- const [mouseControl, setMouseControl] = hooks.useState(true);
2227
- const [focusedValueIndex, setFocusedValueIndex] = hooks.useState(0);
2228
- const dropdownContainer = hooks.useRef();
2229
- const mouseScreenPos = hooks.useRef();
2230
- const focusedItem = hooks.useMemo(() => values.length ? values[focusedValueIndex] : null, [focusedValueIndex, values]);
2231
- const changeFocusedValueIndex = hooks.useCallback(delta => {
2232
- setFocusedValueIndex(x => Math.min(Math.max(0, x + delta), values.length - 1));
2233
- }, [values.length]);
2234
- hooks.useEffect(() => {
2235
- if (focusedValueIndex === 0) return;
2236
- if (!focusedValueIndex || !values.length) {
2237
- setFocusedValueIndex(0);
2238
- } else if (focusedValueIndex >= values.length) {
2239
- setFocusedValueIndex(values.length - 1);
2240
- }
2241
- }, [focusedValueIndex, values.length]);
2242
- useKeyDownAction('ArrowUp', () => {
2243
- if (values.length) {
2244
- changeFocusedValueIndex(-1);
2245
- setMouseControl(false);
2246
- }
2247
- }, keyEventsListener);
2248
- useKeyDownAction('ArrowDown', () => {
2249
- if (values.length) {
2250
- changeFocusedValueIndex(1);
2251
- setMouseControl(false);
2252
- }
2253
- }, keyEventsListener);
2254
- useKeyDownAction('Enter', () => {
2255
- if (focusedItem) {
2256
- onValueSelected(focusedItem);
2257
- }
2258
- }, keyEventsListener);
2259
- hooks.useEffect(() => {
2260
- const individualEntries = dropdownContainer.current.children;
2261
- if (individualEntries.length && !mouseControl) {
2262
- individualEntries[focusedValueIndex].scrollIntoView({
2263
- block: 'nearest',
2264
- inline: 'nearest'
2265
- });
2266
- }
2267
- }, [focusedValueIndex, mouseControl]);
2268
- const mouseMove = (e, i) => {
2269
- const userMoved = !mouseScreenPos.current || mouseScreenPos.current.x !== e.screenX && mouseScreenPos.current.y !== e.screenY;
2270
- if (userMoved) {
2271
- mouseScreenPos.current = {
2272
- x: e.screenX,
2273
- y: e.screenY
2274
- };
2275
- if (!mouseControl) {
2276
- setMouseControl(true);
2277
- setFocusedValueIndex(i);
2278
- }
2279
- }
2280
- };
2281
- return jsxRuntime.jsxs("div", {
2282
- ref: dropdownContainer,
2283
- tabIndex: -1,
2284
- class: "fjs-dropdownlist",
2285
- style: {
2286
- maxHeight: height
2287
- },
2288
- children: [!!values.length && values.map((v, i) => {
2289
- return jsxRuntime.jsx("div", {
2290
- class: 'fjs-dropdownlist-item' + (focusedValueIndex === i ? ' focused' : ''),
2291
- onMouseMove: e => mouseMove(e, i),
2292
- onMouseEnter: mouseControl ? () => setFocusedValueIndex(i) : undefined,
2293
- onMouseDown: e => {
2294
- e.preventDefault();
2295
- onValueSelected(v);
2296
- },
2297
- children: getLabel(v)
2298
- });
2299
- }), !values.length && jsxRuntime.jsx("div", {
2300
- class: "fjs-dropdownlist-empty",
2301
- children: emptyListMessage
2302
- })]
2303
- });
2304
- }
2305
-
2306
3128
  const type$3 = 'taglist';
2307
3129
  function Taglist(props) {
2308
3130
  const {
@@ -2486,20 +3308,261 @@ Taglist.keyed = true;
2486
3308
  Taglist.emptyValue = [];
2487
3309
  Taglist.sanitizeValue = sanitizeMultiSelectValue;
2488
3310
 
3311
+ 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); }
3312
+ var ButtonIcon = (({
3313
+ styles = {},
3314
+ ...props
3315
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$d({
3316
+ xmlns: "http://www.w3.org/2000/svg",
3317
+ width: "54",
3318
+ height: "54"
3319
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3320
+ fillRule: "evenodd",
3321
+ 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"
3322
+ })));
3323
+
3324
+ 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); }
3325
+ var CheckboxIcon = (({
3326
+ styles = {},
3327
+ ...props
3328
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$c({
3329
+ xmlns: "http://www.w3.org/2000/svg",
3330
+ width: "54",
3331
+ height: "54"
3332
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3333
+ d: "M34 18H20a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V20a2 2 0 00-2-2zm-9 14l-5-5 1.41-1.41L25 29.17l7.59-7.59L34 23l-9 9z"
3334
+ })));
3335
+
3336
+ function _extends$b() { _extends$b = 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$b.apply(this, arguments); }
3337
+ var ChecklistIcon = (({
3338
+ styles = {},
3339
+ ...props
3340
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$b({
3341
+ width: "54",
3342
+ height: "54",
3343
+ fill: "none",
3344
+ xmlns: "http://www.w3.org/2000/svg"
3345
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3346
+ fillRule: "evenodd",
3347
+ clipRule: "evenodd",
3348
+ d: "M19 24h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zm6 18h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zm6-30h-6v6h6V8zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2V8a2 2 0 00-2-2h-6z",
3349
+ fill: "#22242A"
3350
+ }), /*#__PURE__*/React__default['default'].createElement("path", {
3351
+ d: "M26 26a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2zm0 16a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2zm0-32a1 1 0 011-1h15a1 1 0 011 1v2a1 1 0 01-1 1H27a1 1 0 01-1-1v-2z",
3352
+ fill: "#22242A"
3353
+ })));
3354
+
3355
+ function _extends$a() { _extends$a = 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$a.apply(this, arguments); }
3356
+ var DatetimeIcon = (({
3357
+ styles = {},
3358
+ ...props
3359
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$a({
3360
+ xmlns: "http://www.w3.org/2000/svg",
3361
+ width: "54",
3362
+ height: "54",
3363
+ fill: "none"
3364
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3365
+ fill: "#000",
3366
+ fillRule: "evenodd",
3367
+ d: "M37.908 13.418h-5.004v-2.354h-1.766v2.354H21.13v-2.354h-1.766v2.354H14.36c-1.132 0-2.06.928-2.06 2.06v23.549c0 1.132.928 2.06 2.06 2.06h6.77v-1.766h-6.358a.707.707 0 01-.706-.706V15.89c0-.39.316-.707.706-.707h4.592v2.355h1.766v-2.355h10.008v2.355h1.766v-2.355h4.592c.39 0 .707.317.707.707v6.358h1.765v-6.77c0-1.133-.927-2.06-2.06-2.06z",
3368
+ clipRule: "evenodd"
3369
+ }), /*#__PURE__*/React__default['default'].createElement("path", {
3370
+ fill: "#000",
3371
+ d: "M35.13 37.603l1.237-1.237-3.468-3.475v-5.926h-1.754v6.654l3.984 3.984z"
3372
+ }), /*#__PURE__*/React__default['default'].createElement("path", {
3373
+ fill: "#000",
3374
+ fillRule: "evenodd",
3375
+ d: "M23.08 36.962a9.678 9.678 0 1017.883-7.408 9.678 9.678 0 00-17.882 7.408zm4.54-10.292a7.924 7.924 0 118.805 13.177A7.924 7.924 0 0127.62 26.67z",
3376
+ clipRule: "evenodd"
3377
+ })));
3378
+
3379
+ function _extends$9() { _extends$9 = 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$9.apply(this, arguments); }
3380
+ var TaglistIcon = (({
3381
+ styles = {},
3382
+ ...props
3383
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$9({
3384
+ width: "54",
3385
+ height: "54",
3386
+ fill: "none",
3387
+ xmlns: "http://www.w3.org/2000/svg"
3388
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3389
+ fillRule: "evenodd",
3390
+ clipRule: "evenodd",
3391
+ d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1z",
3392
+ fill: "#000"
3393
+ }), /*#__PURE__*/React__default['default'].createElement("path", {
3394
+ d: "M11 22a1 1 0 011-1h19a1 1 0 011 1v10a1 1 0 01-1 1H12a1 1 0 01-1-1V22z",
3395
+ fill: "#505562"
3396
+ })));
3397
+
3398
+ function _extends$8() { _extends$8 = 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$8.apply(this, arguments); }
3399
+ var FormIcon = (({
3400
+ styles = {},
3401
+ ...props
3402
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$8({
3403
+ xmlns: "http://www.w3.org/2000/svg",
3404
+ width: "54",
3405
+ height: "54"
3406
+ }, props), /*#__PURE__*/React__default['default'].createElement("rect", {
3407
+ x: "15",
3408
+ y: "17",
3409
+ width: "24",
3410
+ height: "4",
3411
+ rx: "1"
3412
+ }), /*#__PURE__*/React__default['default'].createElement("rect", {
3413
+ x: "15",
3414
+ y: "25",
3415
+ width: "24",
3416
+ height: "4",
3417
+ rx: "1"
3418
+ }), /*#__PURE__*/React__default['default'].createElement("rect", {
3419
+ x: "15",
3420
+ y: "33",
3421
+ width: "13",
3422
+ height: "4",
3423
+ rx: "1"
3424
+ })));
3425
+
3426
+ function _extends$7() { _extends$7 = 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$7.apply(this, arguments); }
3427
+ var ColumnsIcon = (({
3428
+ styles = {},
3429
+ ...props
3430
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$7({
3431
+ xmlns: "http://www.w3.org/2000/svg",
3432
+ width: "54",
3433
+ height: "54"
3434
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3435
+ fillRule: "evenodd",
3436
+ d: "M8 33v5a1 1 0 001 1h4v2H9a3 3 0 01-3-3v-5h2zm18 6v2H15v-2h11zm13 0v2H28v-2h11zm9-6v5a3 3 0 01-3 3h-4v-2h4a1 1 0 00.993-.883L46 38v-5h2zM8 22v9H6v-9h2zm40 0v9h-2v-9h2zm-35-9v2H9a1 1 0 00-.993.883L8 16v4H6v-4a3 3 0 013-3h4zm32 0a3 3 0 013 3v4h-2v-4a1 1 0 00-.883-.993L45 15h-4v-2h4zm-6 0v2H28v-2h11zm-13 0v2H15v-2h11z"
3437
+ })));
3438
+
3439
+ function _extends$6() { _extends$6 = 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$6.apply(this, arguments); }
3440
+ var NumberIcon = (({
3441
+ styles = {},
3442
+ ...props
3443
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$6({
3444
+ xmlns: "http://www.w3.org/2000/svg",
3445
+ width: "54",
3446
+ height: "54"
3447
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3448
+ fillRule: "evenodd",
3449
+ d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1zM35 28.444h7l-3.5 4-3.5-4zM35 26h7l-3.5-4-3.5 4z"
3450
+ })));
3451
+
3452
+ 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); }
3453
+ var RadioIcon = (({
3454
+ styles = {},
3455
+ ...props
3456
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$5({
3457
+ xmlns: "http://www.w3.org/2000/svg",
3458
+ width: "54",
3459
+ height: "54"
3460
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3461
+ d: "M27 22c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5zm0-5c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8z"
3462
+ })));
3463
+
3464
+ 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); }
3465
+ var SelectIcon = (({
3466
+ styles = {},
3467
+ ...props
3468
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$4({
3469
+ xmlns: "http://www.w3.org/2000/svg",
3470
+ width: "54",
3471
+ height: "54"
3472
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3473
+ fillRule: "evenodd",
3474
+ d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1zm-12 7h9l-4.5 6-4.5-6z"
3475
+ })));
3476
+
3477
+ 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); }
3478
+ var TextIcon = (({
3479
+ styles = {},
3480
+ ...props
3481
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$3({
3482
+ xmlns: "http://www.w3.org/2000/svg",
3483
+ width: "54",
3484
+ height: "54"
3485
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3486
+ d: "M20.58 33.77h-3l-1.18-3.08H11l-1.1 3.08H7l5.27-13.54h2.89zm-5-5.36l-1.86-5-1.83 5zM22 20.23h5.41a15.47 15.47 0 012.4.14 3.42 3.42 0 011.41.55 3.47 3.47 0 011 1.14 3 3 0 01.42 1.58 3.26 3.26 0 01-1.91 2.94 3.63 3.63 0 011.91 1.22 3.28 3.28 0 01.66 2 4 4 0 01-.43 1.8 3.63 3.63 0 01-1.09 1.4 3.89 3.89 0 01-1.83.65q-.69.07-3.3.09H22zm2.73 2.25v3.13h3.8a1.79 1.79 0 001.1-.49 1.41 1.41 0 00.41-1 1.49 1.49 0 00-.35-1 1.54 1.54 0 00-1-.48c-.27 0-1.05-.05-2.34-.05zm0 5.39v3.62h2.57a11.52 11.52 0 001.88-.09 1.65 1.65 0 001-.54 1.6 1.6 0 00.38-1.14 1.75 1.75 0 00-.29-1 1.69 1.69 0 00-.86-.62 9.28 9.28 0 00-2.41-.23zM44.35 28.79l2.65.84a5.94 5.94 0 01-2 3.29A5.74 5.74 0 0141.38 34a5.87 5.87 0 01-4.44-1.84 7.09 7.09 0 01-1.73-5A7.43 7.43 0 0137 21.87 6 6 0 0141.54 20a5.64 5.64 0 014 1.47A5.33 5.33 0 0147 24l-2.7.65a2.8 2.8 0 00-2.86-2.27A3.09 3.09 0 0039 23.42a5.31 5.31 0 00-.93 3.5 5.62 5.62 0 00.93 3.65 3 3 0 002.4 1.09 2.72 2.72 0 001.82-.66 4 4 0 001.13-2.21z"
3487
+ })));
3488
+
3489
+ 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); }
3490
+ var TextfieldIcon = (({
3491
+ styles = {},
3492
+ ...props
3493
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$2({
3494
+ xmlns: "http://www.w3.org/2000/svg",
3495
+ width: "54",
3496
+ height: "54"
3497
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3498
+ fillRule: "evenodd",
3499
+ d: "M45 16a3 3 0 013 3v16a3 3 0 01-3 3H9a3 3 0 01-3-3V19a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v16a1 1 0 001 1h36a1 1 0 001-1V19a1 1 0 00-1-1zm-32 4v10h-2V22h2z"
3500
+ })));
3501
+
3502
+ 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); }
3503
+ var TextareaIcon = (({
3504
+ styles = {},
3505
+ ...props
3506
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends$1({
3507
+ xmlns: "http://www.w3.org/2000/svg",
3508
+ width: "54",
3509
+ height: "54"
3510
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3511
+ fillRule: "evenodd",
3512
+ d: "M45 13a3 3 0 013 3v22a3 3 0 01-3 3H9a3 3 0 01-3-3V16a3 3 0 013-3h36zm0 2H9a1 1 0 00-1 1v22a1 1 0 001 1h36a1 1 0 001-1V16a1 1 0 00-1-1zm-1.136 15.5l.848.849-6.363 6.363-.849-.848 6.364-6.364zm.264 3.5l.849.849-2.828 2.828-.849-.849L44.128 34zM13 19v10h-2V19h2z"
3513
+ })));
3514
+
3515
+ 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); }
3516
+ var ImageIcon = (({
3517
+ styles = {},
3518
+ ...props
3519
+ }) => /*#__PURE__*/React__default['default'].createElement("svg", _extends({
3520
+ width: "54",
3521
+ height: "54",
3522
+ fill: "none",
3523
+ xmlns: "http://www.w3.org/2000/svg"
3524
+ }, props), /*#__PURE__*/React__default['default'].createElement("path", {
3525
+ fillRule: "evenodd",
3526
+ clipRule: "evenodd",
3527
+ d: "M34.636 21.91A3.818 3.818 0 1127 21.908a3.818 3.818 0 017.636 0zm-2 0A1.818 1.818 0 1129 21.908a1.818 1.818 0 013.636 0z",
3528
+ fill: "#000"
3529
+ }), /*#__PURE__*/React__default['default'].createElement("path", {
3530
+ fillRule: "evenodd",
3531
+ clipRule: "evenodd",
3532
+ d: "M15 13a2 2 0 00-2 2v24a2 2 0 002 2h24a2 2 0 002-2V15a2 2 0 00-2-2H15zm24 2H15v12.45l4.71-4.709a1.91 1.91 0 012.702 0l6.695 6.695 2.656-1.77a1.91 1.91 0 012.411.239L39 32.73V15zM15 39v-8.754c.06-.038.116-.083.168-.135l5.893-5.893 6.684 6.685a1.911 1.911 0 002.41.238l2.657-1.77 6.02 6.02c.052.051.108.097.168.135V39H15z",
3533
+ fill: "#000"
3534
+ })));
3535
+
3536
+ const iconsByType = {
3537
+ button: ButtonIcon,
3538
+ checkbox: CheckboxIcon,
3539
+ checklist: ChecklistIcon,
3540
+ columns: ColumnsIcon,
3541
+ datetime: DatetimeIcon,
3542
+ image: ImageIcon,
3543
+ number: NumberIcon,
3544
+ radio: RadioIcon,
3545
+ select: SelectIcon,
3546
+ taglist: TaglistIcon,
3547
+ text: TextIcon,
3548
+ textfield: TextfieldIcon,
3549
+ textarea: TextareaIcon,
3550
+ default: FormIcon
3551
+ };
3552
+
2489
3553
  const type$2 = 'text';
2490
3554
  function Text(props) {
2491
3555
  const {
2492
- field
3556
+ field,
3557
+ disabled
2493
3558
  } = props;
2494
3559
  const {
2495
3560
  text = ''
2496
3561
  } = field;
3562
+ const textValue = useExpressionValue(text) || '';
2497
3563
  return jsxRuntime.jsx("div", {
2498
3564
  class: formFieldClasses(type$2),
2499
- children: jsxRuntime.jsx(Markup__default['default'], {
2500
- markup: safeMarkdown(text),
2501
- trim: false
2502
- })
3565
+ children: renderText(field, textValue, disabled)
2503
3566
  });
2504
3567
  }
2505
3568
  Text.create = function (options = {}) {
@@ -2511,6 +3574,37 @@ Text.create = function (options = {}) {
2511
3574
  Text.type = type$2;
2512
3575
  Text.keyed = false;
2513
3576
 
3577
+ // helper //////////////
3578
+
3579
+ function renderText(field, content, disabled) {
3580
+ const {
3581
+ text
3582
+ } = field;
3583
+ const Icon = iconsByType['text'];
3584
+ if (disabled) {
3585
+ if (!text) {
3586
+ return jsxRuntime.jsxs("div", {
3587
+ class: "fjs-form-field-placeholder",
3588
+ children: [jsxRuntime.jsx(Icon, {
3589
+ viewBox: "0 0 54 54"
3590
+ }), "Text view is empty"]
3591
+ });
3592
+ }
3593
+ if (isExpression$2(text)) {
3594
+ return jsxRuntime.jsxs("div", {
3595
+ class: "fjs-form-field-placeholder",
3596
+ children: [jsxRuntime.jsx(Icon, {
3597
+ viewBox: "0 0 54 54"
3598
+ }), "Text view is populated by an expression"]
3599
+ });
3600
+ }
3601
+ }
3602
+ return jsxRuntime.jsx(Markup__default['default'], {
3603
+ markup: safeMarkdown(content),
3604
+ trim: false
3605
+ });
3606
+ }
3607
+
2514
3608
  const type$1 = 'textfield';
2515
3609
  function Textfield(props) {
2516
3610
  const {
@@ -2523,8 +3617,13 @@ function Textfield(props) {
2523
3617
  description,
2524
3618
  id,
2525
3619
  label,
3620
+ appearance = {},
2526
3621
  validate = {}
2527
3622
  } = field;
3623
+ const {
3624
+ prefixAdorner,
3625
+ suffixAdorner
3626
+ } = appearance;
2528
3627
  const {
2529
3628
  required
2530
3629
  } = validate;
@@ -2548,13 +3647,18 @@ function Textfield(props) {
2548
3647
  id: prefixId(id, formId),
2549
3648
  label: label,
2550
3649
  required: required
2551
- }), jsxRuntime.jsx("input", {
2552
- class: "fjs-input",
3650
+ }), jsxRuntime.jsx(InputAdorner, {
2553
3651
  disabled: disabled,
2554
- id: prefixId(id, formId),
2555
- onInput: onChange,
2556
- type: "text",
2557
- value: value
3652
+ pre: prefixAdorner,
3653
+ post: suffixAdorner,
3654
+ children: jsxRuntime.jsx("input", {
3655
+ class: "fjs-input",
3656
+ disabled: disabled,
3657
+ id: prefixId(id, formId),
3658
+ onInput: onChange,
3659
+ type: "text",
3660
+ value: value
3661
+ })
2558
3662
  }), jsxRuntime.jsx(Description, {
2559
3663
  description: description
2560
3664
  }), jsxRuntime.jsx(Errors, {
@@ -2656,7 +3760,7 @@ Textarea.sanitizeValue = ({
2656
3760
  value
2657
3761
  }) => minDash.isArray(value) || minDash.isObject(value) ? '' : String(value);
2658
3762
 
2659
- const formFields = [Button, Checkbox, Checklist, Default, Image, Numberfield, Radio, Select, Taglist, Text, Textfield, Textarea];
3763
+ const formFields = [Button, Checkbox, Checklist, Default, Image, Numberfield, Datetime, Radio, Select, Taglist, Text, Textfield, Textarea];
2660
3764
 
2661
3765
  class FormFields {
2662
3766
  constructor() {
@@ -3136,6 +4240,12 @@ function createForm(options) {
3136
4240
  exports.Button = Button;
3137
4241
  exports.Checkbox = Checkbox;
3138
4242
  exports.Checklist = Checklist;
4243
+ exports.DATETIME_SUBTYPES = DATETIME_SUBTYPES;
4244
+ exports.DATETIME_SUBTYPES_LABELS = DATETIME_SUBTYPES_LABELS;
4245
+ exports.DATETIME_SUBTYPE_PATH = DATETIME_SUBTYPE_PATH;
4246
+ exports.DATE_DISALLOW_PAST_PATH = DATE_DISALLOW_PAST_PATH;
4247
+ exports.DATE_LABEL_PATH = DATE_LABEL_PATH;
4248
+ exports.Datetime = Datetime;
3139
4249
  exports.Default = Default;
3140
4250
  exports.Form = Form;
3141
4251
  exports.FormComponent = FormComponent;
@@ -3144,13 +4254,25 @@ exports.FormFieldRegistry = FormFieldRegistry;
3144
4254
  exports.FormFields = FormFields;
3145
4255
  exports.FormRenderContext = FormRenderContext;
3146
4256
  exports.Image = Image;
4257
+ exports.MINUTES_IN_DAY = MINUTES_IN_DAY;
3147
4258
  exports.Numberfield = Numberfield;
3148
4259
  exports.Radio = Radio;
3149
4260
  exports.Select = Select;
4261
+ exports.TIME_INTERVAL_PATH = TIME_INTERVAL_PATH;
4262
+ exports.TIME_LABEL_PATH = TIME_LABEL_PATH;
4263
+ exports.TIME_SERIALISINGFORMAT_LABELS = TIME_SERIALISINGFORMAT_LABELS;
4264
+ exports.TIME_SERIALISING_FORMATS = TIME_SERIALISING_FORMATS;
4265
+ exports.TIME_SERIALISING_FORMAT_PATH = TIME_SERIALISING_FORMAT_PATH;
4266
+ exports.TIME_USE24H_PATH = TIME_USE24H_PATH;
3150
4267
  exports.Taglist = Taglist;
3151
4268
  exports.Text = Text;
3152
4269
  exports.Textarea = Textarea;
3153
4270
  exports.Textfield = Textfield;
4271
+ exports.VALUES_SOURCES = VALUES_SOURCES;
4272
+ exports.VALUES_SOURCES_DEFAULTS = VALUES_SOURCES_DEFAULTS;
4273
+ exports.VALUES_SOURCES_LABELS = VALUES_SOURCES_LABELS;
4274
+ exports.VALUES_SOURCES_PATHS = VALUES_SOURCES_PATHS;
4275
+ exports.VALUES_SOURCE_DEFAULT = VALUES_SOURCE_DEFAULT;
3154
4276
  exports.clone = clone;
3155
4277
  exports.createForm = createForm;
3156
4278
  exports.createFormContainer = createFormContainer;
@@ -3160,6 +4282,8 @@ exports.formFields = formFields;
3160
4282
  exports.generateIdForType = generateIdForType;
3161
4283
  exports.generateIndexForType = generateIndexForType;
3162
4284
  exports.getSchemaVariables = getSchemaVariables;
4285
+ exports.getValuesSource = getValuesSource;
4286
+ exports.iconsByType = iconsByType;
3163
4287
  exports.isRequired = isRequired;
3164
4288
  exports.pathParse = pathParse;
3165
4289
  exports.pathStringify = pathStringify;