@bpmn-io/form-js-viewer 0.10.1 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -22
- package/README.md +165 -165
- package/dist/assets/form-js.css +715 -611
- package/dist/index.cjs +953 -691
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +877 -606
- package/dist/index.es.js.map +1 -1
- package/dist/types/Form.d.ts +144 -144
- package/dist/types/core/ConditionChecker.d.ts +57 -57
- package/dist/types/core/EventBus.d.ts +1 -1
- package/dist/types/core/FormFieldRegistry.d.ts +17 -17
- package/dist/types/core/Validator.d.ts +7 -7
- package/dist/types/core/index.d.ts +18 -18
- package/dist/types/import/Importer.d.ts +43 -43
- package/dist/types/import/index.d.ts +5 -5
- package/dist/types/index.d.ts +18 -18
- package/dist/types/render/FormFields.d.ts +5 -5
- package/dist/types/render/Renderer.d.ts +23 -23
- package/dist/types/render/components/Description.d.ts +1 -1
- package/dist/types/render/components/Errors.d.ts +1 -1
- package/dist/types/render/components/FormComponent.d.ts +1 -1
- package/dist/types/render/components/FormField.d.ts +1 -1
- package/dist/types/render/components/Label.d.ts +1 -1
- package/dist/types/render/components/PoweredBy.d.ts +1 -1
- package/dist/types/render/components/Sanitizer.d.ts +8 -8
- package/dist/types/render/components/Util.d.ts +17 -17
- package/dist/types/render/components/form-fields/Button.d.ts +12 -11
- package/dist/types/render/components/form-fields/Checkbox.d.ts +14 -13
- package/dist/types/render/components/form-fields/Checklist.d.ts +18 -12
- package/dist/types/render/components/form-fields/Datetime.d.ts +13 -11
- package/dist/types/render/components/form-fields/Default.d.ts +11 -9
- package/dist/types/render/components/form-fields/Image.d.ts +10 -8
- package/dist/types/render/components/form-fields/Number.d.ts +15 -14
- package/dist/types/render/components/form-fields/Radio.d.ts +18 -12
- package/dist/types/render/components/form-fields/Select.d.ts +18 -12
- package/dist/types/render/components/form-fields/Taglist.d.ts +18 -12
- package/dist/types/render/components/form-fields/Text.d.ts +12 -10
- package/dist/types/render/components/form-fields/Textarea.d.ts +14 -13
- package/dist/types/render/components/form-fields/Textfield.d.ts +14 -13
- package/dist/types/render/components/form-fields/parts/Datepicker.d.ts +1 -1
- package/dist/types/render/components/form-fields/parts/DropdownList.d.ts +1 -1
- package/dist/types/render/components/form-fields/parts/InputAdorner.d.ts +1 -1
- package/dist/types/render/components/form-fields/parts/SearchableSelect.d.ts +1 -0
- package/dist/types/render/components/form-fields/parts/SimpleSelect.d.ts +1 -0
- package/dist/types/render/components/form-fields/parts/Timepicker.d.ts +1 -1
- package/dist/types/render/components/icons/index.d.ts +16 -16
- package/dist/types/render/components/index.d.ts +17 -17
- package/dist/types/render/components/util/dateTimeUtil.d.ts +12 -12
- package/dist/types/render/components/util/numberFieldUtil.d.ts +4 -4
- package/dist/types/render/components/util/sanitizerUtil.d.ts +3 -3
- package/dist/types/render/context/FormContext.d.ts +12 -12
- package/dist/types/render/context/FormRenderContext.d.ts +6 -6
- package/dist/types/render/context/index.d.ts +2 -2
- package/dist/types/render/hooks/useCondition.d.ts +9 -9
- package/dist/types/render/hooks/useEvaluation.d.ts +6 -6
- package/dist/types/render/hooks/useExpressionValue.d.ts +5 -5
- package/dist/types/render/hooks/useKeyDownAction.d.ts +1 -1
- package/dist/types/render/hooks/useService.d.ts +1 -1
- package/dist/types/render/hooks/useValuesAsync.d.ts +28 -28
- package/dist/types/render/index.d.ts +11 -11
- package/dist/types/src/types.d.ts +35 -35
- package/dist/types/util/constants/DatetimeConstants.d.ts +24 -24
- package/dist/types/util/constants/ValuesSourceConstants.d.ts +18 -15
- package/dist/types/util/constants/index.d.ts +2 -2
- package/dist/types/util/feel.d.ts +15 -15
- package/dist/types/util/form.d.ts +6 -6
- package/dist/types/util/index.d.ts +26 -25
- package/dist/types/util/injector.d.ts +2 -2
- package/package.json +4 -4
package/dist/index.es.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import Ids from 'ids';
|
|
2
|
-
import { isString, isArray, isFunction, isNumber, bind, assign, isNil, get, isUndefined, set, isObject } from 'min-dash';
|
|
2
|
+
import { isString, isArray, isFunction, isNumber, bind, assign, isNil, get, isUndefined, set, findIndex, isObject } from 'min-dash';
|
|
3
3
|
import { unaryTest, evaluate, parseUnaryTests, parseExpressions } from 'feelin';
|
|
4
4
|
import Big from 'big.js';
|
|
5
5
|
import snarkdown from '@bpmn-io/snarkdown';
|
|
6
6
|
import classNames from 'classnames';
|
|
7
|
-
import { jsx, jsxs } from 'preact/jsx-runtime';
|
|
7
|
+
import { jsx, jsxs, Fragment as Fragment$1 } from 'preact/jsx-runtime';
|
|
8
8
|
import { useContext, useState, useEffect, useRef, useCallback, useMemo } from 'preact/hooks';
|
|
9
9
|
import { createContext, createElement, Fragment, render } from 'preact';
|
|
10
10
|
import React, { createPortal } from 'preact/compat';
|
|
@@ -12,9 +12,9 @@ import flatpickr from 'flatpickr';
|
|
|
12
12
|
import Markup from 'preact-markup';
|
|
13
13
|
import { Injector } from 'didi';
|
|
14
14
|
|
|
15
|
-
/**
|
|
16
|
-
* @typedef {object} Condition
|
|
17
|
-
* @property {string} [hide]
|
|
15
|
+
/**
|
|
16
|
+
* @typedef {object} Condition
|
|
17
|
+
* @property {string} [hide]
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
20
|
class ConditionChecker {
|
|
@@ -23,11 +23,11 @@ class ConditionChecker {
|
|
|
23
23
|
this._eventBus = eventBus;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
/**
|
|
27
|
-
* For given data, remove properties based on condition.
|
|
28
|
-
*
|
|
29
|
-
* @param {Object<string, any>} properties
|
|
30
|
-
* @param {Object<string, any>} data
|
|
26
|
+
/**
|
|
27
|
+
* For given data, remove properties based on condition.
|
|
28
|
+
*
|
|
29
|
+
* @param {Object<string, any>} properties
|
|
30
|
+
* @param {Object<string, any>} data
|
|
31
31
|
*/
|
|
32
32
|
applyConditions(properties, data = {}) {
|
|
33
33
|
const conditions = this._getConditions();
|
|
@@ -46,13 +46,13 @@ class ConditionChecker {
|
|
|
46
46
|
return newProperties;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
/**
|
|
50
|
-
* Check if given condition is met. Returns null for invalid/missing conditions.
|
|
51
|
-
*
|
|
52
|
-
* @param {string} condition
|
|
53
|
-
* @param {import('../types').Data} [data]
|
|
54
|
-
*
|
|
55
|
-
* @returns {boolean|null}
|
|
49
|
+
/**
|
|
50
|
+
* Check if given condition is met. Returns null for invalid/missing conditions.
|
|
51
|
+
*
|
|
52
|
+
* @param {string} condition
|
|
53
|
+
* @param {import('../types').Data} [data]
|
|
54
|
+
*
|
|
55
|
+
* @returns {boolean|null}
|
|
56
56
|
*/
|
|
57
57
|
check(condition, data = {}) {
|
|
58
58
|
if (!condition) {
|
|
@@ -73,12 +73,12 @@ class ConditionChecker {
|
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
/**
|
|
77
|
-
* Check if hide condition is met.
|
|
78
|
-
*
|
|
79
|
-
* @param {Condition} condition
|
|
80
|
-
* @param {Object<string, any>} data
|
|
81
|
-
* @returns {boolean}
|
|
76
|
+
/**
|
|
77
|
+
* Check if hide condition is met.
|
|
78
|
+
*
|
|
79
|
+
* @param {Condition} condition
|
|
80
|
+
* @param {Object<string, any>} data
|
|
81
|
+
* @returns {boolean}
|
|
82
82
|
*/
|
|
83
83
|
_checkHideCondition(condition, data) {
|
|
84
84
|
if (!condition.hide) {
|
|
@@ -88,13 +88,13 @@ class ConditionChecker {
|
|
|
88
88
|
return result === true;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
/**
|
|
92
|
-
* Evaluate an expression.
|
|
93
|
-
*
|
|
94
|
-
* @param {string} expression
|
|
95
|
-
* @param {import('../types').Data} [data]
|
|
96
|
-
*
|
|
97
|
-
* @returns {any}
|
|
91
|
+
/**
|
|
92
|
+
* Evaluate an expression.
|
|
93
|
+
*
|
|
94
|
+
* @param {string} expression
|
|
95
|
+
* @param {import('../types').Data} [data]
|
|
96
|
+
*
|
|
97
|
+
* @returns {any}
|
|
98
98
|
*/
|
|
99
99
|
evaluate(expression, data = {}) {
|
|
100
100
|
if (!expression) {
|
|
@@ -602,7 +602,7 @@ class Validator {
|
|
|
602
602
|
if (type === 'number') {
|
|
603
603
|
const {
|
|
604
604
|
decimalDigits,
|
|
605
|
-
|
|
605
|
+
increment
|
|
606
606
|
} = field;
|
|
607
607
|
if (value === 'NaN') {
|
|
608
608
|
errors = [...errors, 'Value is not a number.'];
|
|
@@ -610,13 +610,13 @@ class Validator {
|
|
|
610
610
|
if (decimalDigits >= 0 && countDecimals(value) > decimalDigits) {
|
|
611
611
|
errors = [...errors, 'Value is expected to ' + (decimalDigits === 0 ? 'be an integer' : `have at most ${decimalDigits} decimal digit${decimalDigits > 1 ? 's' : ''}`) + '.'];
|
|
612
612
|
}
|
|
613
|
-
if (
|
|
613
|
+
if (increment) {
|
|
614
614
|
const bigValue = Big(value);
|
|
615
|
-
const
|
|
616
|
-
const offset = bigValue.mod(
|
|
615
|
+
const bigIncrement = Big(increment);
|
|
616
|
+
const offset = bigValue.mod(bigIncrement);
|
|
617
617
|
if (offset.cmp(0) !== 0) {
|
|
618
618
|
const previousValue = bigValue.minus(offset);
|
|
619
|
-
const nextValue = previousValue.plus(
|
|
619
|
+
const nextValue = previousValue.plus(bigIncrement);
|
|
620
620
|
errors = [...errors, `Please select a valid value, the two nearest valid values are ${previousValue} and ${nextValue}.`];
|
|
621
621
|
}
|
|
622
622
|
}
|
|
@@ -631,10 +631,10 @@ class Validator {
|
|
|
631
631
|
if (validate.required && (isNil(value) || value === '')) {
|
|
632
632
|
errors = [...errors, 'Field is required.'];
|
|
633
633
|
}
|
|
634
|
-
if ('min' in validate && value && value < validate.min) {
|
|
634
|
+
if ('min' in validate && (value || value === 0) && value < validate.min) {
|
|
635
635
|
errors = [...errors, `Field must have minimum value of ${validate.min}.`];
|
|
636
636
|
}
|
|
637
|
-
if ('max' in validate && value && value > validate.max) {
|
|
637
|
+
if ('max' in validate && (value || value === 0) && value > validate.max) {
|
|
638
638
|
errors = [...errors, `Field must have maximum value of ${validate.max}.`];
|
|
639
639
|
}
|
|
640
640
|
if ('minLength' in validate && value && value.trim().length < validate.minLength) {
|
|
@@ -703,11 +703,11 @@ class FormFieldRegistry {
|
|
|
703
703
|
}
|
|
704
704
|
FormFieldRegistry.$inject = ['eventBus'];
|
|
705
705
|
|
|
706
|
-
/**
|
|
707
|
-
* Retrieve variable names from given FEEL unary test.
|
|
708
|
-
*
|
|
709
|
-
* @param {string} unaryTest
|
|
710
|
-
* @returns {string[]}
|
|
706
|
+
/**
|
|
707
|
+
* Retrieve variable names from given FEEL unary test.
|
|
708
|
+
*
|
|
709
|
+
* @param {string} unaryTest
|
|
710
|
+
* @returns {string[]}
|
|
711
711
|
*/
|
|
712
712
|
function getVariableNames(unaryTest) {
|
|
713
713
|
const tree = parseUnaryTests(unaryTest);
|
|
@@ -722,11 +722,11 @@ function getVariableNames(unaryTest) {
|
|
|
722
722
|
return Array.from(variables);
|
|
723
723
|
}
|
|
724
724
|
|
|
725
|
-
/**
|
|
726
|
-
* Retrieve variable names from given FEEL expression.
|
|
727
|
-
*
|
|
728
|
-
* @param {string} expression
|
|
729
|
-
* @returns {string[]}
|
|
725
|
+
/**
|
|
726
|
+
* Retrieve variable names from given FEEL expression.
|
|
727
|
+
*
|
|
728
|
+
* @param {string} expression
|
|
729
|
+
* @returns {string[]}
|
|
730
730
|
*/
|
|
731
731
|
function getExpressionVariableNames(expression) {
|
|
732
732
|
const tree = parseExpressions(expression);
|
|
@@ -740,7 +740,7 @@ function getExpressionVariableNames(expression) {
|
|
|
740
740
|
} while (cursor.next());
|
|
741
741
|
return Array.from(variables);
|
|
742
742
|
}
|
|
743
|
-
function isExpression$
|
|
743
|
+
function isExpression$1(value) {
|
|
744
744
|
return isString(value) && value.startsWith('=');
|
|
745
745
|
}
|
|
746
746
|
|
|
@@ -791,7 +791,10 @@ const VALUES_SOURCES_PATHS = {
|
|
|
791
791
|
[VALUES_SOURCES.INPUT]: ['valuesKey']
|
|
792
792
|
};
|
|
793
793
|
const VALUES_SOURCES_DEFAULTS = {
|
|
794
|
-
[VALUES_SOURCES.STATIC]: [
|
|
794
|
+
[VALUES_SOURCES.STATIC]: [{
|
|
795
|
+
label: 'Value',
|
|
796
|
+
value: 'value'
|
|
797
|
+
}],
|
|
795
798
|
[VALUES_SOURCES.INPUT]: ''
|
|
796
799
|
};
|
|
797
800
|
|
|
@@ -812,10 +815,10 @@ function createInjector(bootstrapModules) {
|
|
|
812
815
|
return injector;
|
|
813
816
|
}
|
|
814
817
|
|
|
815
|
-
/**
|
|
816
|
-
* @param {string?} prefix
|
|
817
|
-
*
|
|
818
|
-
* @returns Element
|
|
818
|
+
/**
|
|
819
|
+
* @param {string?} prefix
|
|
820
|
+
*
|
|
821
|
+
* @returns Element
|
|
819
822
|
*/
|
|
820
823
|
function createFormContainer(prefix = 'fjs') {
|
|
821
824
|
const container = document.createElement('div');
|
|
@@ -860,22 +863,22 @@ function generateIdForType(type) {
|
|
|
860
863
|
return `${type}${generateIndexForType(type)}`;
|
|
861
864
|
}
|
|
862
865
|
|
|
863
|
-
/**
|
|
864
|
-
* @template T
|
|
865
|
-
* @param {T} data
|
|
866
|
-
* @param {(this: any, key: string, value: any) => any} [replacer]
|
|
867
|
-
* @return {T}
|
|
866
|
+
/**
|
|
867
|
+
* @template T
|
|
868
|
+
* @param {T} data
|
|
869
|
+
* @param {(this: any, key: string, value: any) => any} [replacer]
|
|
870
|
+
* @return {T}
|
|
868
871
|
*/
|
|
869
872
|
function clone(data, replacer) {
|
|
870
873
|
return JSON.parse(JSON.stringify(data, replacer));
|
|
871
874
|
}
|
|
872
875
|
|
|
873
|
-
/**
|
|
874
|
-
* Parse the schema for input variables a form might make use of
|
|
875
|
-
*
|
|
876
|
-
* @param {any} schema
|
|
877
|
-
*
|
|
878
|
-
* @return {string[]}
|
|
876
|
+
/**
|
|
877
|
+
* Parse the schema for input variables a form might make use of
|
|
878
|
+
*
|
|
879
|
+
* @param {any} schema
|
|
880
|
+
*
|
|
881
|
+
* @return {string[]}
|
|
879
882
|
*/
|
|
880
883
|
function getSchemaVariables(schema) {
|
|
881
884
|
if (!schema.components) {
|
|
@@ -917,32 +920,26 @@ function getSchemaVariables(schema) {
|
|
|
917
920
|
return Array.from(new Set(variables));
|
|
918
921
|
}
|
|
919
922
|
|
|
920
|
-
// helper ///////////////
|
|
921
|
-
|
|
922
|
-
function isExpression$1(value) {
|
|
923
|
-
return isString(value) && value.startsWith('=');
|
|
924
|
-
}
|
|
925
|
-
|
|
926
923
|
class Importer {
|
|
927
|
-
/**
|
|
928
|
-
* @constructor
|
|
929
|
-
* @param { import('../core').FormFieldRegistry } formFieldRegistry
|
|
930
|
-
* @param { import('../render/FormFields').default } formFields
|
|
924
|
+
/**
|
|
925
|
+
* @constructor
|
|
926
|
+
* @param { import('../core').FormFieldRegistry } formFieldRegistry
|
|
927
|
+
* @param { import('../render/FormFields').default } formFields
|
|
931
928
|
*/
|
|
932
929
|
constructor(formFieldRegistry, formFields) {
|
|
933
930
|
this._formFieldRegistry = formFieldRegistry;
|
|
934
931
|
this._formFields = formFields;
|
|
935
932
|
}
|
|
936
933
|
|
|
937
|
-
/**
|
|
938
|
-
* Import schema adding `id`, `_parent` and `_path`
|
|
939
|
-
* information to each field and adding it to the
|
|
940
|
-
* form field registry.
|
|
941
|
-
*
|
|
942
|
-
* @param {any} schema
|
|
943
|
-
* @param {any} [data]
|
|
944
|
-
*
|
|
945
|
-
* @return { { warnings: Array<any>, schema: any, data: any } }
|
|
934
|
+
/**
|
|
935
|
+
* Import schema adding `id`, `_parent` and `_path`
|
|
936
|
+
* information to each field and adding it to the
|
|
937
|
+
* form field registry.
|
|
938
|
+
*
|
|
939
|
+
* @param {any} schema
|
|
940
|
+
* @param {any} [data]
|
|
941
|
+
*
|
|
942
|
+
* @return { { warnings: Array<any>, schema: any, data: any } }
|
|
946
943
|
*/
|
|
947
944
|
importSchema(schema, data = {}) {
|
|
948
945
|
// TODO: Add warnings - https://github.com/bpmn-io/form-js/issues/289
|
|
@@ -961,11 +958,11 @@ class Importer {
|
|
|
961
958
|
}
|
|
962
959
|
}
|
|
963
960
|
|
|
964
|
-
/**
|
|
965
|
-
* @param {any} formField
|
|
966
|
-
* @param {string} [parentId]
|
|
967
|
-
*
|
|
968
|
-
* @return {any} importedField
|
|
961
|
+
/**
|
|
962
|
+
* @param {any} formField
|
|
963
|
+
* @param {string} [parentId]
|
|
964
|
+
*
|
|
965
|
+
* @return {any} importedField
|
|
969
966
|
*/
|
|
970
967
|
importFormField(formField, parentId) {
|
|
971
968
|
const {
|
|
@@ -1016,10 +1013,10 @@ class Importer {
|
|
|
1016
1013
|
});
|
|
1017
1014
|
}
|
|
1018
1015
|
|
|
1019
|
-
/**
|
|
1020
|
-
* @param {Object} data
|
|
1021
|
-
*
|
|
1022
|
-
* @return {Object} initializedData
|
|
1016
|
+
/**
|
|
1017
|
+
* @param {Object} data
|
|
1018
|
+
*
|
|
1019
|
+
* @return {Object} initializedData
|
|
1023
1020
|
*/
|
|
1024
1021
|
initializeFieldValues(data) {
|
|
1025
1022
|
return this._formFieldRegistry.getAll().reduce((initializedData, formField) => {
|
|
@@ -1069,11 +1066,11 @@ const ATTR_WHITESPACE_PATTERN = /[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u
|
|
|
1069
1066
|
|
|
1070
1067
|
const FORM_ELEMENT = document.createElement('form');
|
|
1071
1068
|
|
|
1072
|
-
/**
|
|
1073
|
-
* Sanitize a HTML string and return the cleaned, safe version.
|
|
1074
|
-
*
|
|
1075
|
-
* @param {string} html
|
|
1076
|
-
* @return {string}
|
|
1069
|
+
/**
|
|
1070
|
+
* Sanitize a HTML string and return the cleaned, safe version.
|
|
1071
|
+
*
|
|
1072
|
+
* @param {string} html
|
|
1073
|
+
* @return {string}
|
|
1077
1074
|
*/
|
|
1078
1075
|
function sanitizeHTML(html) {
|
|
1079
1076
|
const doc = new DOMParser().parseFromString(`<!DOCTYPE html>\n<html><body><div>${html}`, 'text/html');
|
|
@@ -1093,15 +1090,15 @@ function sanitizeImageSource(src) {
|
|
|
1093
1090
|
return valid ? src : '';
|
|
1094
1091
|
}
|
|
1095
1092
|
|
|
1096
|
-
/**
|
|
1097
|
-
* Recursively sanitize a HTML node, potentially
|
|
1098
|
-
* removing it, its children or attributes.
|
|
1099
|
-
*
|
|
1100
|
-
* Inspired by https://github.com/developit/snarkdown/issues/70
|
|
1101
|
-
* and https://github.com/cure53/DOMPurify. Simplified
|
|
1102
|
-
* for our use-case.
|
|
1103
|
-
*
|
|
1104
|
-
* @param {Element} node
|
|
1093
|
+
/**
|
|
1094
|
+
* Recursively sanitize a HTML node, potentially
|
|
1095
|
+
* removing it, its children or attributes.
|
|
1096
|
+
*
|
|
1097
|
+
* Inspired by https://github.com/developit/snarkdown/issues/70
|
|
1098
|
+
* and https://github.com/cure53/DOMPurify. Simplified
|
|
1099
|
+
* for our use-case.
|
|
1100
|
+
*
|
|
1101
|
+
* @param {Element} node
|
|
1105
1102
|
*/
|
|
1106
1103
|
function sanitizeNode(node) {
|
|
1107
1104
|
// allow text nodes
|
|
@@ -1145,13 +1142,13 @@ function sanitizeNode(node) {
|
|
|
1145
1142
|
}
|
|
1146
1143
|
}
|
|
1147
1144
|
|
|
1148
|
-
/**
|
|
1149
|
-
* Validates attributes for validity.
|
|
1150
|
-
*
|
|
1151
|
-
* @param {string} lcTag
|
|
1152
|
-
* @param {string} lcName
|
|
1153
|
-
* @param {string} value
|
|
1154
|
-
* @return {boolean}
|
|
1145
|
+
/**
|
|
1146
|
+
* Validates attributes for validity.
|
|
1147
|
+
*
|
|
1148
|
+
* @param {string} lcTag
|
|
1149
|
+
* @param {string} lcName
|
|
1150
|
+
* @param {string} value
|
|
1151
|
+
* @return {boolean}
|
|
1155
1152
|
*/
|
|
1156
1153
|
function isValidAttribute(lcTag, lcName, value) {
|
|
1157
1154
|
// disallow most attributes based on whitelist
|
|
@@ -1203,14 +1200,14 @@ function safeMarkdown(markdown) {
|
|
|
1203
1200
|
return sanitizeHTML(html);
|
|
1204
1201
|
}
|
|
1205
1202
|
|
|
1206
|
-
/**
|
|
1207
|
-
* Sanitizes an image source to ensure we only allow for data URI and links
|
|
1208
|
-
* that start with http(s).
|
|
1209
|
-
*
|
|
1210
|
-
* Note: Most browsers anyway do not support script execution in <img> elements.
|
|
1211
|
-
*
|
|
1212
|
-
* @param {string} src
|
|
1213
|
-
* @returns {string}
|
|
1203
|
+
/**
|
|
1204
|
+
* Sanitizes an image source to ensure we only allow for data URI and links
|
|
1205
|
+
* that start with http(s).
|
|
1206
|
+
*
|
|
1207
|
+
* Note: Most browsers anyway do not support script execution in <img> elements.
|
|
1208
|
+
*
|
|
1209
|
+
* @param {string} src
|
|
1210
|
+
* @returns {string}
|
|
1214
1211
|
*/
|
|
1215
1212
|
function safeImageSource(src) {
|
|
1216
1213
|
return sanitizeImageSource(src);
|
|
@@ -1235,15 +1232,14 @@ function Button(props) {
|
|
|
1235
1232
|
})
|
|
1236
1233
|
});
|
|
1237
1234
|
}
|
|
1238
|
-
Button.create =
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
};
|
|
1243
|
-
};
|
|
1235
|
+
Button.create = (options = {}) => ({
|
|
1236
|
+
action: 'submit',
|
|
1237
|
+
...options
|
|
1238
|
+
});
|
|
1244
1239
|
Button.type = type$b;
|
|
1245
1240
|
Button.label = 'Button';
|
|
1246
1241
|
Button.keyed = true;
|
|
1242
|
+
Button.group = 'action';
|
|
1247
1243
|
|
|
1248
1244
|
const FormRenderContext = createContext({
|
|
1249
1245
|
Empty: props => {
|
|
@@ -1256,18 +1252,20 @@ const FormRenderContext = createContext({
|
|
|
1256
1252
|
return props.children;
|
|
1257
1253
|
}
|
|
1258
1254
|
});
|
|
1255
|
+
var FormRenderContext$1 = FormRenderContext;
|
|
1259
1256
|
|
|
1260
|
-
/**
|
|
1261
|
-
* @param {string} type
|
|
1262
|
-
* @param {boolean} [strict]
|
|
1263
|
-
*
|
|
1264
|
-
* @returns {any}
|
|
1257
|
+
/**
|
|
1258
|
+
* @param {string} type
|
|
1259
|
+
* @param {boolean} [strict]
|
|
1260
|
+
*
|
|
1261
|
+
* @returns {any}
|
|
1265
1262
|
*/
|
|
1266
1263
|
function getService(type, strict) {}
|
|
1267
1264
|
const FormContext = createContext({
|
|
1268
1265
|
getService,
|
|
1269
1266
|
formId: null
|
|
1270
1267
|
});
|
|
1268
|
+
var FormContext$1 = FormContext;
|
|
1271
1269
|
|
|
1272
1270
|
function Description(props) {
|
|
1273
1271
|
const {
|
|
@@ -1343,7 +1341,7 @@ function Checkbox(props) {
|
|
|
1343
1341
|
};
|
|
1344
1342
|
const {
|
|
1345
1343
|
formId
|
|
1346
|
-
} = useContext(FormContext);
|
|
1344
|
+
} = useContext(FormContext$1);
|
|
1347
1345
|
return jsxs("div", {
|
|
1348
1346
|
class: classNames(formFieldClasses(type$a, {
|
|
1349
1347
|
errors,
|
|
@@ -1370,11 +1368,9 @@ function Checkbox(props) {
|
|
|
1370
1368
|
})]
|
|
1371
1369
|
});
|
|
1372
1370
|
}
|
|
1373
|
-
Checkbox.create =
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
};
|
|
1377
|
-
};
|
|
1371
|
+
Checkbox.create = (options = {}) => ({
|
|
1372
|
+
...options
|
|
1373
|
+
});
|
|
1378
1374
|
Checkbox.type = type$a;
|
|
1379
1375
|
Checkbox.label = 'Checkbox';
|
|
1380
1376
|
Checkbox.keyed = true;
|
|
@@ -1382,16 +1378,17 @@ Checkbox.emptyValue = false;
|
|
|
1382
1378
|
Checkbox.sanitizeValue = ({
|
|
1383
1379
|
value
|
|
1384
1380
|
}) => value === true;
|
|
1381
|
+
Checkbox.group = 'selection';
|
|
1385
1382
|
|
|
1386
1383
|
function useService (type, strict) {
|
|
1387
1384
|
const {
|
|
1388
1385
|
getService
|
|
1389
|
-
} = useContext(FormContext);
|
|
1386
|
+
} = useContext(FormContext$1);
|
|
1390
1387
|
return getService(type, strict);
|
|
1391
1388
|
}
|
|
1392
1389
|
|
|
1393
|
-
/**
|
|
1394
|
-
* @enum { String }
|
|
1390
|
+
/**
|
|
1391
|
+
* @enum { String }
|
|
1395
1392
|
*/
|
|
1396
1393
|
const LOAD_STATES = {
|
|
1397
1394
|
LOADING: 'loading',
|
|
@@ -1399,17 +1396,17 @@ const LOAD_STATES = {
|
|
|
1399
1396
|
ERROR: 'error'
|
|
1400
1397
|
};
|
|
1401
1398
|
|
|
1402
|
-
/**
|
|
1403
|
-
* @typedef {Object} ValuesGetter
|
|
1404
|
-
* @property {Object[]} values - The values data
|
|
1405
|
-
* @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
|
|
1399
|
+
/**
|
|
1400
|
+
* @typedef {Object} ValuesGetter
|
|
1401
|
+
* @property {Object[]} values - The values data
|
|
1402
|
+
* @property {(LOAD_STATES)} state - The values data's loading state, to use for conditional rendering
|
|
1406
1403
|
*/
|
|
1407
1404
|
|
|
1408
|
-
/**
|
|
1409
|
-
* A hook to load values for single and multiselect components.
|
|
1410
|
-
*
|
|
1411
|
-
* @param {Object} field - The form field to handle values for
|
|
1412
|
-
* @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
|
|
1405
|
+
/**
|
|
1406
|
+
* A hook to load values for single and multiselect components.
|
|
1407
|
+
*
|
|
1408
|
+
* @param {Object} field - The form field to handle values for
|
|
1409
|
+
* @return {ValuesGetter} valuesGetter - A values getter object providing loading state and values
|
|
1413
1410
|
*/
|
|
1414
1411
|
function useValuesAsync (field) {
|
|
1415
1412
|
const {
|
|
@@ -1483,8 +1480,8 @@ function parseInputTime(stringTime) {
|
|
|
1483
1480
|
if (is12h) {
|
|
1484
1481
|
const isPM = workingString.includes('pm');
|
|
1485
1482
|
const digits = workingString.match(/\d+/g);
|
|
1486
|
-
const displayHour = parseInt(digits
|
|
1487
|
-
const minute = parseInt(digits
|
|
1483
|
+
const displayHour = parseInt(digits && digits[0]);
|
|
1484
|
+
const minute = parseInt(digits && digits[1]) || 0;
|
|
1488
1485
|
const isValidDisplayHour = isNumber(displayHour) && displayHour >= 1 && displayHour <= 12;
|
|
1489
1486
|
const isValidMinute = minute >= 0 && minute <= 59;
|
|
1490
1487
|
if (!isValidDisplayHour || !isValidMinute) return null;
|
|
@@ -1492,8 +1489,8 @@ function parseInputTime(stringTime) {
|
|
|
1492
1489
|
return hour * 60 + minute;
|
|
1493
1490
|
} else {
|
|
1494
1491
|
const digits = workingString.match(/\d+/g);
|
|
1495
|
-
const hour = parseInt(digits
|
|
1496
|
-
const minute = parseInt(digits
|
|
1492
|
+
const hour = parseInt(digits && digits[0]);
|
|
1493
|
+
const minute = parseInt(digits && digits[1]);
|
|
1497
1494
|
const isValidHour = isNumber(hour) && hour >= 0 && hour <= 23;
|
|
1498
1495
|
const isValidMinute = isNumber(minute) && minute >= 0 && minute <= 59;
|
|
1499
1496
|
if (!isValidHour || !isValidMinute) return null;
|
|
@@ -1696,7 +1693,7 @@ function Checklist(props) {
|
|
|
1696
1693
|
} = useValuesAsync(field);
|
|
1697
1694
|
const {
|
|
1698
1695
|
formId
|
|
1699
|
-
} = useContext(FormContext);
|
|
1696
|
+
} = useContext(FormContext$1);
|
|
1700
1697
|
return jsxs("div", {
|
|
1701
1698
|
class: classNames(formFieldClasses(type$9, {
|
|
1702
1699
|
errors,
|
|
@@ -1728,13 +1725,18 @@ function Checklist(props) {
|
|
|
1728
1725
|
})]
|
|
1729
1726
|
});
|
|
1730
1727
|
}
|
|
1731
|
-
Checklist.create =
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1728
|
+
Checklist.create = (options = {}) => {
|
|
1729
|
+
const defaults = {};
|
|
1730
|
+
|
|
1731
|
+
// provide default values if valuesKey isn't set
|
|
1732
|
+
if (!options.valuesKey) {
|
|
1733
|
+
defaults.values = [{
|
|
1735
1734
|
label: 'Value',
|
|
1736
1735
|
value: 'value'
|
|
1737
|
-
}]
|
|
1736
|
+
}];
|
|
1737
|
+
}
|
|
1738
|
+
return {
|
|
1739
|
+
...defaults,
|
|
1738
1740
|
...options
|
|
1739
1741
|
};
|
|
1740
1742
|
};
|
|
@@ -1743,14 +1745,15 @@ Checklist.label = 'Checklist';
|
|
|
1743
1745
|
Checklist.keyed = true;
|
|
1744
1746
|
Checklist.emptyValue = [];
|
|
1745
1747
|
Checklist.sanitizeValue = sanitizeMultiSelectValue;
|
|
1748
|
+
Checklist.group = 'selection';
|
|
1746
1749
|
|
|
1747
|
-
/**
|
|
1748
|
-
* Check if condition is met with given variables.
|
|
1749
|
-
*
|
|
1750
|
-
* @param {string | undefined} condition
|
|
1751
|
-
* @param {import('../../types').Data} data
|
|
1752
|
-
*
|
|
1753
|
-
* @returns {boolean} true if condition is met or no condition or condition checker exists
|
|
1750
|
+
/**
|
|
1751
|
+
* Check if condition is met with given variables.
|
|
1752
|
+
*
|
|
1753
|
+
* @param {string | undefined} condition
|
|
1754
|
+
* @param {import('../../types').Data} data
|
|
1755
|
+
*
|
|
1756
|
+
* @returns {boolean} true if condition is met or no condition or condition checker exists
|
|
1754
1757
|
*/
|
|
1755
1758
|
function useCondition(condition, data) {
|
|
1756
1759
|
const initialData = useService('form')._getState().initialData;
|
|
@@ -1786,7 +1789,7 @@ function FormField(props) {
|
|
|
1786
1789
|
const {
|
|
1787
1790
|
Element,
|
|
1788
1791
|
Empty
|
|
1789
|
-
} = useContext(FormRenderContext);
|
|
1792
|
+
} = useContext(FormRenderContext$1);
|
|
1790
1793
|
const FormFieldComponent = formFields.get(field.type);
|
|
1791
1794
|
if (!FormFieldComponent) {
|
|
1792
1795
|
throw new Error(`cannot render field <${field.type}>`);
|
|
@@ -1818,7 +1821,7 @@ function Default(props) {
|
|
|
1818
1821
|
const {
|
|
1819
1822
|
Children,
|
|
1820
1823
|
Empty
|
|
1821
|
-
} = useContext(FormRenderContext);
|
|
1824
|
+
} = useContext(FormRenderContext$1);
|
|
1822
1825
|
const {
|
|
1823
1826
|
field
|
|
1824
1827
|
} = props;
|
|
@@ -1837,20 +1840,20 @@ function Default(props) {
|
|
|
1837
1840
|
}), components.length ? null : jsx(Empty, {})]
|
|
1838
1841
|
});
|
|
1839
1842
|
}
|
|
1840
|
-
Default.create =
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
};
|
|
1845
|
-
};
|
|
1843
|
+
Default.create = (options = {}) => ({
|
|
1844
|
+
components: [],
|
|
1845
|
+
...options
|
|
1846
|
+
});
|
|
1846
1847
|
Default.type = 'default';
|
|
1847
1848
|
Default.keyed = false;
|
|
1849
|
+
Default.label = null;
|
|
1850
|
+
Default.group = null;
|
|
1848
1851
|
|
|
1849
|
-
function _extends$
|
|
1852
|
+
function _extends$j() { _extends$j = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$j.apply(this, arguments); }
|
|
1850
1853
|
var CalendarIcon = (({
|
|
1851
1854
|
styles = {},
|
|
1852
1855
|
...props
|
|
1853
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
1856
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$j({
|
|
1854
1857
|
width: "14",
|
|
1855
1858
|
height: "15",
|
|
1856
1859
|
viewBox: "0 0 28 30",
|
|
@@ -1859,8 +1862,8 @@ var CalendarIcon = (({
|
|
|
1859
1862
|
}, props), /*#__PURE__*/React.createElement("path", {
|
|
1860
1863
|
fillRule: "evenodd",
|
|
1861
1864
|
clipRule: "evenodd",
|
|
1862
|
-
|
|
1863
|
-
|
|
1865
|
+
fill: "currentColor",
|
|
1866
|
+
d: "M19 2H9V0H7v2H2a2 2 0 00-2 2v24a2 2 0 002 2h24a2 2 0 002-2V4a2 2 0 00-2-2h-5V0h-2v2zM7 7V4H2v5h24V4h-5v3h-2V4H9v3H7zm-5 4v17h24V11H2z"
|
|
1864
1867
|
})));
|
|
1865
1868
|
|
|
1866
1869
|
function InputAdorner(props) {
|
|
@@ -1873,10 +1876,10 @@ function InputAdorner(props) {
|
|
|
1873
1876
|
disabled,
|
|
1874
1877
|
hasErrors
|
|
1875
1878
|
} = props;
|
|
1876
|
-
const onAdornmentClick = () => inputRef
|
|
1879
|
+
const onAdornmentClick = () => inputRef && inputRef.current && inputRef.current.focus();
|
|
1877
1880
|
return jsxs("div", {
|
|
1878
1881
|
class: classNames('fjs-input-group', {
|
|
1879
|
-
'disabled': disabled
|
|
1882
|
+
'fjs-disabled': disabled
|
|
1880
1883
|
}, {
|
|
1881
1884
|
'hasErrors': hasErrors
|
|
1882
1885
|
}),
|
|
@@ -1925,23 +1928,15 @@ function Datepicker(props) {
|
|
|
1925
1928
|
|
|
1926
1929
|
// setup flatpickr instance
|
|
1927
1930
|
useEffect(() => {
|
|
1928
|
-
if (disabled) {
|
|
1929
|
-
setFlatpickrInstance(null);
|
|
1930
|
-
return;
|
|
1931
|
-
}
|
|
1932
1931
|
let config = {
|
|
1933
1932
|
allowInput: true,
|
|
1934
1933
|
dateFormat: 'm/d/Y',
|
|
1935
1934
|
static: true,
|
|
1936
1935
|
clickOpens: false,
|
|
1936
|
+
// TODO: support dates prior to 1900 (https://github.com/bpmn-io/form-js/issues/533)
|
|
1937
|
+
minDate: disallowPassedDates ? 'today' : '01/01/1900',
|
|
1937
1938
|
errorHandler: () => {/* do nothing, we expect the values to sometimes be erronous and we don't want warnings polluting the console */}
|
|
1938
1939
|
};
|
|
1939
|
-
if (disallowPassedDates) {
|
|
1940
|
-
config = {
|
|
1941
|
-
...config,
|
|
1942
|
-
minDate: 'today'
|
|
1943
|
-
};
|
|
1944
|
-
}
|
|
1945
1940
|
const instance = flatpickr(dateInputRef.current, config);
|
|
1946
1941
|
setFlatpickrInstance(instance);
|
|
1947
1942
|
const onCalendarFocusOut = e => {
|
|
@@ -1961,7 +1956,7 @@ function Datepicker(props) {
|
|
|
1961
1956
|
// flatpicker logic that was lost when setting allowInput to true
|
|
1962
1957
|
instance.config.onOpen = [() => instance.calendarContainer.addEventListener('focusout', onCalendarFocusOut), () => instance.calendarContainer.addEventListener('mousedown', onCalendarMouseDown)];
|
|
1963
1958
|
instance.config.onClose = [() => instance.calendarContainer.removeEventListener('focusout', onCalendarFocusOut), () => instance.calendarContainer.removeEventListener('mousedown', onCalendarMouseDown)];
|
|
1964
|
-
}, [
|
|
1959
|
+
}, [disallowPassedDates]);
|
|
1965
1960
|
|
|
1966
1961
|
// onChange is updated dynamically, so not to re-render the flatpicker every time it changes
|
|
1967
1962
|
useEffect(() => {
|
|
@@ -2025,7 +2020,7 @@ function Datepicker(props) {
|
|
|
2025
2020
|
class: 'fjs-input',
|
|
2026
2021
|
disabled: disabled,
|
|
2027
2022
|
placeholder: "mm/dd/yyyy",
|
|
2028
|
-
autoComplete: "
|
|
2023
|
+
autoComplete: "off",
|
|
2029
2024
|
onFocus: onInputFocus,
|
|
2030
2025
|
onKeyDown: onInputKeyDown,
|
|
2031
2026
|
onMouseDown: e => !flatpickrInstance.isOpen && flatpickrInstance.open(),
|
|
@@ -2038,24 +2033,24 @@ function Datepicker(props) {
|
|
|
2038
2033
|
});
|
|
2039
2034
|
}
|
|
2040
2035
|
|
|
2041
|
-
function _extends$
|
|
2036
|
+
function _extends$i() { _extends$i = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$i.apply(this, arguments); }
|
|
2042
2037
|
var ClockIcon = (({
|
|
2043
2038
|
styles = {},
|
|
2044
2039
|
...props
|
|
2045
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
2040
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$i({
|
|
2046
2041
|
width: "16",
|
|
2047
2042
|
height: "16",
|
|
2048
2043
|
viewBox: "0 0 28 29",
|
|
2049
2044
|
fill: "none",
|
|
2050
2045
|
xmlns: "http://www.w3.org/2000/svg"
|
|
2051
2046
|
}, props), /*#__PURE__*/React.createElement("path", {
|
|
2052
|
-
|
|
2053
|
-
|
|
2047
|
+
fill: "currentColor",
|
|
2048
|
+
d: "M13 14.41L18.59 20 20 18.59l-5-5.01V5h-2v9.41z"
|
|
2054
2049
|
}), /*#__PURE__*/React.createElement("path", {
|
|
2055
2050
|
fillRule: "evenodd",
|
|
2056
2051
|
clipRule: "evenodd",
|
|
2057
|
-
|
|
2058
|
-
|
|
2052
|
+
fill: "currentColor",
|
|
2053
|
+
d: "M6.222 25.64A14 14 0 1021.778 2.36 14 14 0 006.222 25.64zM7.333 4.023a12 12 0 1113.334 19.955A12 12 0 017.333 4.022z"
|
|
2059
2054
|
})));
|
|
2060
2055
|
|
|
2061
2056
|
function useKeyDownAction(targetKey, action, listenerElement = window) {
|
|
@@ -2078,7 +2073,7 @@ const DEFAULT_LABEL_GETTER = value => value;
|
|
|
2078
2073
|
const NOOP = () => {};
|
|
2079
2074
|
function DropdownList(props) {
|
|
2080
2075
|
const {
|
|
2081
|
-
|
|
2076
|
+
listenerElement = window,
|
|
2082
2077
|
values = [],
|
|
2083
2078
|
getLabel = DEFAULT_LABEL_GETTER,
|
|
2084
2079
|
onValueSelected = NOOP,
|
|
@@ -2108,18 +2103,18 @@ function DropdownList(props) {
|
|
|
2108
2103
|
changeFocusedValueIndex(-1);
|
|
2109
2104
|
setMouseControl(false);
|
|
2110
2105
|
}
|
|
2111
|
-
},
|
|
2106
|
+
}, listenerElement);
|
|
2112
2107
|
useKeyDownAction('ArrowDown', () => {
|
|
2113
2108
|
if (values.length) {
|
|
2114
2109
|
changeFocusedValueIndex(1);
|
|
2115
2110
|
setMouseControl(false);
|
|
2116
2111
|
}
|
|
2117
|
-
},
|
|
2112
|
+
}, listenerElement);
|
|
2118
2113
|
useKeyDownAction('Enter', () => {
|
|
2119
2114
|
if (focusedItem) {
|
|
2120
2115
|
onValueSelected(focusedItem);
|
|
2121
2116
|
}
|
|
2122
|
-
},
|
|
2117
|
+
}, listenerElement);
|
|
2123
2118
|
useEffect(() => {
|
|
2124
2119
|
const individualEntries = dropdownContainer.current.children;
|
|
2125
2120
|
if (individualEntries.length && !mouseControl) {
|
|
@@ -2147,6 +2142,7 @@ function DropdownList(props) {
|
|
|
2147
2142
|
ref: dropdownContainer,
|
|
2148
2143
|
tabIndex: -1,
|
|
2149
2144
|
class: "fjs-dropdownlist",
|
|
2145
|
+
onMouseDown: e => e.preventDefault(),
|
|
2150
2146
|
style: {
|
|
2151
2147
|
maxHeight: height,
|
|
2152
2148
|
scrollBehavior: smoothScrolling ? 'smooth' : 'auto'
|
|
@@ -2158,10 +2154,7 @@ function DropdownList(props) {
|
|
|
2158
2154
|
}),
|
|
2159
2155
|
onMouseMove: mouseControl ? undefined : e => onMouseMovedInKeyboardMode(e, i),
|
|
2160
2156
|
onMouseEnter: mouseControl ? () => setFocusedValueIndex(i) : undefined,
|
|
2161
|
-
onMouseDown: e =>
|
|
2162
|
-
e.preventDefault();
|
|
2163
|
-
onValueSelected(v);
|
|
2164
|
-
},
|
|
2157
|
+
onMouseDown: e => onValueSelected(v),
|
|
2165
2158
|
children: getLabel(v)
|
|
2166
2159
|
});
|
|
2167
2160
|
}), !values.length && jsx("div", {
|
|
@@ -2294,7 +2287,7 @@ function Timepicker(props) {
|
|
|
2294
2287
|
value: rawValue,
|
|
2295
2288
|
disabled: disabled,
|
|
2296
2289
|
placeholder: use24h ? 'hh:mm' : 'hh:mm ?m',
|
|
2297
|
-
autoComplete: "
|
|
2290
|
+
autoComplete: "off",
|
|
2298
2291
|
onFocus: () => useDropdown && setDropdownIsOpen(true),
|
|
2299
2292
|
onClick: () => useDropdown && setDropdownIsOpen(true)
|
|
2300
2293
|
|
|
@@ -2345,7 +2338,7 @@ function Datetime(props) {
|
|
|
2345
2338
|
} = validate;
|
|
2346
2339
|
const {
|
|
2347
2340
|
formId
|
|
2348
|
-
} = useContext(FormContext);
|
|
2341
|
+
} = useContext(FormContext$1);
|
|
2349
2342
|
const getNullDateTime = () => ({
|
|
2350
2343
|
date: new Date(Date.parse(null)),
|
|
2351
2344
|
time: null
|
|
@@ -2361,31 +2354,29 @@ function Datetime(props) {
|
|
|
2361
2354
|
date,
|
|
2362
2355
|
time
|
|
2363
2356
|
} = getNullDateTime();
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
}
|
|
2382
|
-
}
|
|
2357
|
+
switch (subtype) {
|
|
2358
|
+
case DATETIME_SUBTYPES.DATE:
|
|
2359
|
+
{
|
|
2360
|
+
date = new Date(Date.parse(value));
|
|
2361
|
+
break;
|
|
2362
|
+
}
|
|
2363
|
+
case DATETIME_SUBTYPES.TIME:
|
|
2364
|
+
{
|
|
2365
|
+
time = parseIsoTime(value);
|
|
2366
|
+
break;
|
|
2367
|
+
}
|
|
2368
|
+
case DATETIME_SUBTYPES.DATETIME:
|
|
2369
|
+
{
|
|
2370
|
+
date = new Date(Date.parse(value));
|
|
2371
|
+
time = isValidDate(date) ? 60 * date.getHours() + date.getMinutes() : null;
|
|
2372
|
+
break;
|
|
2373
|
+
}
|
|
2383
2374
|
}
|
|
2384
2375
|
setDateTime({
|
|
2385
2376
|
date,
|
|
2386
2377
|
time
|
|
2387
2378
|
});
|
|
2388
|
-
}, [subtype, value
|
|
2379
|
+
}, [subtype, value]);
|
|
2389
2380
|
const computeAndSetState = useCallback(({
|
|
2390
2381
|
date,
|
|
2391
2382
|
time
|
|
@@ -2488,12 +2479,12 @@ function Datetime(props) {
|
|
|
2488
2479
|
})]
|
|
2489
2480
|
});
|
|
2490
2481
|
}
|
|
2491
|
-
Datetime.create =
|
|
2492
|
-
const
|
|
2493
|
-
set(
|
|
2494
|
-
set(
|
|
2482
|
+
Datetime.create = (options = {}) => {
|
|
2483
|
+
const defaults = {};
|
|
2484
|
+
set(defaults, DATETIME_SUBTYPE_PATH, DATETIME_SUBTYPES.DATE);
|
|
2485
|
+
set(defaults, DATE_LABEL_PATH, 'Date');
|
|
2495
2486
|
return {
|
|
2496
|
-
...
|
|
2487
|
+
...defaults,
|
|
2497
2488
|
...options
|
|
2498
2489
|
};
|
|
2499
2490
|
};
|
|
@@ -2501,11 +2492,13 @@ Datetime.type = type$8;
|
|
|
2501
2492
|
Datetime.keyed = true;
|
|
2502
2493
|
Datetime.emptyValue = null;
|
|
2503
2494
|
Datetime.sanitizeValue = sanitizeDateTimePickerValue;
|
|
2495
|
+
Datetime.label = 'Date time';
|
|
2496
|
+
Datetime.group = 'basic-input';
|
|
2504
2497
|
|
|
2505
|
-
/**
|
|
2506
|
-
* This file must not be changed or exchanged.
|
|
2507
|
-
*
|
|
2508
|
-
* @see http://bpmn.io/license for more information.
|
|
2498
|
+
/**
|
|
2499
|
+
* This file must not be changed or exchanged.
|
|
2500
|
+
*
|
|
2501
|
+
* @see http://bpmn.io/license for more information.
|
|
2509
2502
|
*/
|
|
2510
2503
|
function Logo() {
|
|
2511
2504
|
return jsxs("svg", {
|
|
@@ -2622,10 +2615,10 @@ function FormComponent(props) {
|
|
|
2622
2615
|
});
|
|
2623
2616
|
}
|
|
2624
2617
|
|
|
2625
|
-
/**
|
|
2626
|
-
*
|
|
2627
|
-
* @param {string | undefined} expression
|
|
2628
|
-
* @param {import('../../types').Data} data
|
|
2618
|
+
/**
|
|
2619
|
+
*
|
|
2620
|
+
* @param {string | undefined} expression
|
|
2621
|
+
* @param {import('../../types').Data} data
|
|
2629
2622
|
*/
|
|
2630
2623
|
function useEvaluation(expression, data) {
|
|
2631
2624
|
const initialData = useService('form')._getState().initialData;
|
|
@@ -2642,9 +2635,9 @@ function useEvaluation(expression, data) {
|
|
|
2642
2635
|
return conditionChecker.evaluate(expression, filteredData);
|
|
2643
2636
|
}
|
|
2644
2637
|
|
|
2645
|
-
/**
|
|
2646
|
-
*
|
|
2647
|
-
* @param {string} value
|
|
2638
|
+
/**
|
|
2639
|
+
*
|
|
2640
|
+
* @param {string} value
|
|
2648
2641
|
*/
|
|
2649
2642
|
function useExpressionValue(value) {
|
|
2650
2643
|
const formData = useService('form')._getState().data;
|
|
@@ -2664,11 +2657,11 @@ function isExpression(value) {
|
|
|
2664
2657
|
return isString(value) && value.startsWith('=');
|
|
2665
2658
|
}
|
|
2666
2659
|
|
|
2667
|
-
function _extends$
|
|
2660
|
+
function _extends$h() { _extends$h = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$h.apply(this, arguments); }
|
|
2668
2661
|
var ImagePlaceholder = (({
|
|
2669
2662
|
styles = {},
|
|
2670
2663
|
...props
|
|
2671
|
-
}) => /*#__PURE__*/React.createElement("svg", _extends$
|
|
2664
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$h({
|
|
2672
2665
|
width: "64",
|
|
2673
2666
|
height: "64",
|
|
2674
2667
|
viewBox: "0 0 1280 1280",
|
|
@@ -2708,7 +2701,7 @@ function Image(props) {
|
|
|
2708
2701
|
const altText = useExpressionValue(alt);
|
|
2709
2702
|
const {
|
|
2710
2703
|
formId
|
|
2711
|
-
} = useContext(FormContext);
|
|
2704
|
+
} = useContext(FormContext$1);
|
|
2712
2705
|
return jsx("div", {
|
|
2713
2706
|
class: formFieldClasses(type$7),
|
|
2714
2707
|
children: jsxs("div", {
|
|
@@ -2727,13 +2720,47 @@ function Image(props) {
|
|
|
2727
2720
|
})
|
|
2728
2721
|
});
|
|
2729
2722
|
}
|
|
2730
|
-
Image.create =
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
};
|
|
2734
|
-
};
|
|
2723
|
+
Image.create = (options = {}) => ({
|
|
2724
|
+
...options
|
|
2725
|
+
});
|
|
2735
2726
|
Image.type = type$7;
|
|
2736
2727
|
Image.keyed = false;
|
|
2728
|
+
Image.label = 'Image view';
|
|
2729
|
+
Image.group = 'presentation';
|
|
2730
|
+
|
|
2731
|
+
function _extends$g() { _extends$g = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$g.apply(this, arguments); }
|
|
2732
|
+
var AngelDownIcon = (({
|
|
2733
|
+
styles = {},
|
|
2734
|
+
...props
|
|
2735
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$g({
|
|
2736
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2737
|
+
width: "8",
|
|
2738
|
+
height: "8"
|
|
2739
|
+
}, props), /*#__PURE__*/React.createElement("path", {
|
|
2740
|
+
fillRule: "evenodd",
|
|
2741
|
+
clipRule: "evenodd",
|
|
2742
|
+
fill: "currentColor",
|
|
2743
|
+
stroke: "currentColor",
|
|
2744
|
+
strokeWidth: ".5",
|
|
2745
|
+
d: "M7.75 1.336L4 6.125.258 1.335 0 1.54l4 5.125L8 1.54zm0 0"
|
|
2746
|
+
})));
|
|
2747
|
+
|
|
2748
|
+
function _extends$f() { _extends$f = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$f.apply(this, arguments); }
|
|
2749
|
+
var AngelUpIcon = (({
|
|
2750
|
+
styles = {},
|
|
2751
|
+
...props
|
|
2752
|
+
}) => /*#__PURE__*/React.createElement("svg", _extends$f({
|
|
2753
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
2754
|
+
width: "8",
|
|
2755
|
+
height: "8"
|
|
2756
|
+
}, props), /*#__PURE__*/React.createElement("path", {
|
|
2757
|
+
fillRule: "evenodd",
|
|
2758
|
+
clipRule: "evenodd",
|
|
2759
|
+
fill: "currentColor",
|
|
2760
|
+
stroke: "currentColor",
|
|
2761
|
+
strokeWidth: ".5",
|
|
2762
|
+
d: "M7.75 6.664L4 1.875.258 6.665 0 6.46l4-5.125L8 6.46zm0 0"
|
|
2763
|
+
})));
|
|
2737
2764
|
|
|
2738
2765
|
const type$6 = 'number';
|
|
2739
2766
|
function Numberfield(props) {
|
|
@@ -2775,6 +2802,7 @@ function Numberfield(props) {
|
|
|
2775
2802
|
}), [stringValueCache, value, field]);
|
|
2776
2803
|
const displayValue = useMemo(() => {
|
|
2777
2804
|
if (value === 'NaN') return 'NaN';
|
|
2805
|
+
if (stringValueCache === '-') return '-';
|
|
2778
2806
|
return cacheValueMatchesState ? stringValueCache : value || value === 0 ? Big(value).toFixed() : '';
|
|
2779
2807
|
}, [stringValueCache, value, cacheValueMatchesState]);
|
|
2780
2808
|
const arrowIncrementValue = useMemo(() => {
|
|
@@ -2794,6 +2822,10 @@ function Numberfield(props) {
|
|
|
2794
2822
|
|
|
2795
2823
|
// treat commas as dots
|
|
2796
2824
|
stringValue = stringValue.replaceAll(',', '.');
|
|
2825
|
+
if (stringValue === '-') {
|
|
2826
|
+
setStringValueCache('-');
|
|
2827
|
+
return;
|
|
2828
|
+
}
|
|
2797
2829
|
if (isNaN(Number(stringValue))) {
|
|
2798
2830
|
setStringValueCache('NaN');
|
|
2799
2831
|
onChange({
|
|
@@ -2857,7 +2889,7 @@ function Numberfield(props) {
|
|
|
2857
2889
|
};
|
|
2858
2890
|
const {
|
|
2859
2891
|
formId
|
|
2860
|
-
} = useContext(FormContext);
|
|
2892
|
+
} = useContext(FormContext$1);
|
|
2861
2893
|
return jsxs("div", {
|
|
2862
2894
|
class: formFieldClasses(type$6, {
|
|
2863
2895
|
errors,
|
|
@@ -2873,7 +2905,7 @@ function Numberfield(props) {
|
|
|
2873
2905
|
post: suffixAdorner,
|
|
2874
2906
|
children: jsxs("div", {
|
|
2875
2907
|
class: classNames('fjs-vertical-group', {
|
|
2876
|
-
'disabled': disabled
|
|
2908
|
+
'fjs-disabled': disabled
|
|
2877
2909
|
}, {
|
|
2878
2910
|
'hasErrors': errors.length
|
|
2879
2911
|
}),
|
|
@@ -2894,22 +2926,24 @@ function Numberfield(props) {
|
|
|
2894
2926
|
value: displayValue
|
|
2895
2927
|
}), jsxs("div", {
|
|
2896
2928
|
class: classNames('fjs-number-arrow-container', {
|
|
2897
|
-
'disabled': disabled
|
|
2929
|
+
'fjs-disabled': disabled
|
|
2898
2930
|
}),
|
|
2899
2931
|
children: [jsx("button", {
|
|
2900
2932
|
class: "fjs-number-arrow-up",
|
|
2901
2933
|
type: "button",
|
|
2934
|
+
"aria-label": "Increment",
|
|
2902
2935
|
onClick: () => increment(),
|
|
2903
2936
|
tabIndex: -1,
|
|
2904
|
-
children:
|
|
2937
|
+
children: jsx(AngelUpIcon, {})
|
|
2905
2938
|
}), jsx("div", {
|
|
2906
2939
|
class: "fjs-number-arrow-separator"
|
|
2907
2940
|
}), jsx("button", {
|
|
2908
2941
|
class: "fjs-number-arrow-down",
|
|
2909
2942
|
type: "button",
|
|
2943
|
+
"aria-label": "Decrement",
|
|
2910
2944
|
onClick: () => decrement(),
|
|
2911
2945
|
tabIndex: -1,
|
|
2912
|
-
children:
|
|
2946
|
+
children: jsx(AngelDownIcon, {})
|
|
2913
2947
|
})]
|
|
2914
2948
|
})]
|
|
2915
2949
|
})
|
|
@@ -2920,7 +2954,9 @@ function Numberfield(props) {
|
|
|
2920
2954
|
})]
|
|
2921
2955
|
});
|
|
2922
2956
|
}
|
|
2923
|
-
Numberfield.create = (options = {}) =>
|
|
2957
|
+
Numberfield.create = (options = {}) => ({
|
|
2958
|
+
...options
|
|
2959
|
+
});
|
|
2924
2960
|
Numberfield.sanitizeValue = ({
|
|
2925
2961
|
value,
|
|
2926
2962
|
formField
|
|
@@ -2938,6 +2974,7 @@ Numberfield.type = type$6;
|
|
|
2938
2974
|
Numberfield.keyed = true;
|
|
2939
2975
|
Numberfield.label = 'Number';
|
|
2940
2976
|
Numberfield.emptyValue = null;
|
|
2977
|
+
Numberfield.group = 'basic-input';
|
|
2941
2978
|
|
|
2942
2979
|
const type$5 = 'radio';
|
|
2943
2980
|
function Radio(props) {
|
|
@@ -2968,7 +3005,7 @@ function Radio(props) {
|
|
|
2968
3005
|
} = useValuesAsync(field);
|
|
2969
3006
|
const {
|
|
2970
3007
|
formId
|
|
2971
|
-
} = useContext(FormContext);
|
|
3008
|
+
} = useContext(FormContext$1);
|
|
2972
3009
|
return jsxs("div", {
|
|
2973
3010
|
class: formFieldClasses(type$5, {
|
|
2974
3011
|
errors,
|
|
@@ -3002,12 +3039,17 @@ function Radio(props) {
|
|
|
3002
3039
|
});
|
|
3003
3040
|
}
|
|
3004
3041
|
Radio.create = function (options = {}) {
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3042
|
+
const defaults = {};
|
|
3043
|
+
|
|
3044
|
+
// provide default values if valuesKey isn't set
|
|
3045
|
+
if (!options.valuesKey) {
|
|
3046
|
+
defaults.values = [{
|
|
3008
3047
|
label: 'Value',
|
|
3009
3048
|
value: 'value'
|
|
3010
|
-
}]
|
|
3049
|
+
}];
|
|
3050
|
+
}
|
|
3051
|
+
return {
|
|
3052
|
+
...defaults,
|
|
3011
3053
|
...options
|
|
3012
3054
|
};
|
|
3013
3055
|
};
|
|
@@ -3016,121 +3058,359 @@ Radio.label = 'Radio';
|
|
|
3016
3058
|
Radio.keyed = true;
|
|
3017
3059
|
Radio.emptyValue = null;
|
|
3018
3060
|
Radio.sanitizeValue = sanitizeSingleSelectValue;
|
|
3019
|
-
|
|
3020
|
-
const type$4 = 'select';
|
|
3021
|
-
function Select(props) {
|
|
3022
|
-
const {
|
|
3023
|
-
disabled,
|
|
3024
|
-
errors = [],
|
|
3025
|
-
field,
|
|
3026
|
-
value
|
|
3027
|
-
} = props;
|
|
3028
|
-
const {
|
|
3029
|
-
description,
|
|
3030
|
-
id,
|
|
3031
|
-
label,
|
|
3032
|
-
validate = {}
|
|
3033
|
-
} = field;
|
|
3034
|
-
const {
|
|
3035
|
-
required
|
|
3036
|
-
} = validate;
|
|
3037
|
-
const onChange = ({
|
|
3038
|
-
target
|
|
3039
|
-
}) => {
|
|
3040
|
-
props.onChange({
|
|
3041
|
-
field,
|
|
3042
|
-
value: target.value === '' ? null : target.value
|
|
3043
|
-
});
|
|
3044
|
-
};
|
|
3045
|
-
const {
|
|
3046
|
-
state: loadState,
|
|
3047
|
-
values: options
|
|
3048
|
-
} = useValuesAsync(field);
|
|
3049
|
-
const {
|
|
3050
|
-
formId
|
|
3051
|
-
} = useContext(FormContext);
|
|
3052
|
-
return jsxs("div", {
|
|
3053
|
-
class: formFieldClasses(type$4, {
|
|
3054
|
-
errors,
|
|
3055
|
-
disabled
|
|
3056
|
-
}),
|
|
3057
|
-
children: [jsx(Label, {
|
|
3058
|
-
id: prefixId(id, formId),
|
|
3059
|
-
label: label,
|
|
3060
|
-
required: required
|
|
3061
|
-
}), jsxs("select", {
|
|
3062
|
-
class: "fjs-select",
|
|
3063
|
-
disabled: disabled,
|
|
3064
|
-
id: prefixId(id, formId),
|
|
3065
|
-
onChange: onChange,
|
|
3066
|
-
value: value || '',
|
|
3067
|
-
children: [jsx("option", {
|
|
3068
|
-
value: ""
|
|
3069
|
-
}), loadState == LOAD_STATES.LOADED && options.map((option, index) => {
|
|
3070
|
-
return jsx("option", {
|
|
3071
|
-
value: option.value,
|
|
3072
|
-
children: option.label
|
|
3073
|
-
}, `${id}-${index}`);
|
|
3074
|
-
})]
|
|
3075
|
-
}), jsx(Description, {
|
|
3076
|
-
description: description
|
|
3077
|
-
}), jsx(Errors, {
|
|
3078
|
-
errors: errors
|
|
3079
|
-
})]
|
|
3080
|
-
});
|
|
3081
|
-
}
|
|
3082
|
-
Select.create = function (options = {}) {
|
|
3083
|
-
if (options.valuesKey) return options;
|
|
3084
|
-
return {
|
|
3085
|
-
values: [{
|
|
3086
|
-
label: 'Value',
|
|
3087
|
-
value: 'value'
|
|
3088
|
-
}],
|
|
3089
|
-
...options
|
|
3090
|
-
};
|
|
3091
|
-
};
|
|
3092
|
-
Select.type = type$4;
|
|
3093
|
-
Select.label = 'Select';
|
|
3094
|
-
Select.keyed = true;
|
|
3095
|
-
Select.emptyValue = null;
|
|
3096
|
-
Select.sanitizeValue = sanitizeSingleSelectValue;
|
|
3061
|
+
Radio.group = 'selection';
|
|
3097
3062
|
|
|
3098
3063
|
function _extends$e() { _extends$e = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$e.apply(this, arguments); }
|
|
3099
|
-
var
|
|
3064
|
+
var XMarkIcon = (({
|
|
3100
3065
|
styles = {},
|
|
3101
3066
|
...props
|
|
3102
3067
|
}) => /*#__PURE__*/React.createElement("svg", _extends$e({
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
xmlns: "http://www.w3.org/2000/svg"
|
|
3068
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3069
|
+
width: "8",
|
|
3070
|
+
height: "8"
|
|
3107
3071
|
}, props), /*#__PURE__*/React.createElement("path", {
|
|
3108
3072
|
fillRule: "evenodd",
|
|
3109
3073
|
clipRule: "evenodd",
|
|
3110
|
-
|
|
3111
|
-
|
|
3074
|
+
fill: "currentColor",
|
|
3075
|
+
stroke: "currentColor",
|
|
3076
|
+
strokeWidth: ".5",
|
|
3077
|
+
d: "M4 3.766L7.43.336l.234.234L4.234 4l3.43 3.43-.234.234L4 4.234.57 7.664.336 7.43 3.766 4 .336.57.57.336zm0 0"
|
|
3112
3078
|
})));
|
|
3113
3079
|
|
|
3114
|
-
|
|
3115
|
-
function Taglist(props) {
|
|
3080
|
+
function SearchableSelect(props) {
|
|
3116
3081
|
const {
|
|
3082
|
+
id,
|
|
3117
3083
|
disabled,
|
|
3118
|
-
errors
|
|
3084
|
+
errors,
|
|
3119
3085
|
field,
|
|
3120
|
-
value
|
|
3086
|
+
value
|
|
3121
3087
|
} = props;
|
|
3122
|
-
const {
|
|
3123
|
-
description,
|
|
3124
|
-
id,
|
|
3125
|
-
label
|
|
3126
|
-
} = field;
|
|
3127
3088
|
const {
|
|
3128
3089
|
formId
|
|
3129
|
-
} = useContext(FormContext);
|
|
3090
|
+
} = useContext(FormContext$1);
|
|
3130
3091
|
const [filter, setFilter] = useState('');
|
|
3131
|
-
const [filteredOptions, setFilteredOptions] = useState([]);
|
|
3132
3092
|
const [isDropdownExpanded, setIsDropdownExpanded] = useState(false);
|
|
3133
|
-
const [
|
|
3093
|
+
const [shouldApplyFilter, setShouldApplyFilter] = useState(true);
|
|
3094
|
+
const [isEscapeClosed, setIsEscapeClose] = useState(false);
|
|
3095
|
+
const searchbarRef = useRef();
|
|
3096
|
+
const {
|
|
3097
|
+
state: loadState,
|
|
3098
|
+
values: options
|
|
3099
|
+
} = useValuesAsync(field);
|
|
3100
|
+
|
|
3101
|
+
// We cache a map of option values to their index so that we don't need to search the whole options array every time to correlate the label
|
|
3102
|
+
const valueToOptionMap = useMemo(() => Object.assign({}, ...options.map((o, x) => ({
|
|
3103
|
+
[o.value]: options[x]
|
|
3104
|
+
}))), [options]);
|
|
3105
|
+
const valueLabel = useMemo(() => value && valueToOptionMap[value] && valueToOptionMap[value].label || '', [value, valueToOptionMap]);
|
|
3106
|
+
|
|
3107
|
+
// whenever we change the underlying value, set the label to it
|
|
3108
|
+
useEffect(() => {
|
|
3109
|
+
setFilter(valueLabel);
|
|
3110
|
+
}, [valueLabel]);
|
|
3111
|
+
const filteredOptions = useMemo(() => {
|
|
3112
|
+
if (loadState === LOAD_STATES.LOADED) {
|
|
3113
|
+
return shouldApplyFilter ? options.filter(o => o.label && o.value && o.label.toLowerCase().includes(filter.toLowerCase())) : options;
|
|
3114
|
+
}
|
|
3115
|
+
return [];
|
|
3116
|
+
}, [filter, loadState, options, shouldApplyFilter]);
|
|
3117
|
+
const onChange = ({
|
|
3118
|
+
target
|
|
3119
|
+
}) => {
|
|
3120
|
+
setIsEscapeClose(false);
|
|
3121
|
+
setIsDropdownExpanded(true);
|
|
3122
|
+
setShouldApplyFilter(true);
|
|
3123
|
+
setFilter(target.value || '');
|
|
3124
|
+
};
|
|
3125
|
+
const setValue = useCallback(option => {
|
|
3126
|
+
setFilter(option && option.label || '');
|
|
3127
|
+
props.onChange({
|
|
3128
|
+
value: option && option.value || null,
|
|
3129
|
+
field
|
|
3130
|
+
});
|
|
3131
|
+
}, [field, props]);
|
|
3132
|
+
const onInputKeyDown = useCallback(keyDownEvent => {
|
|
3133
|
+
switch (keyDownEvent.key) {
|
|
3134
|
+
case 'ArrowUp':
|
|
3135
|
+
keyDownEvent.preventDefault();
|
|
3136
|
+
break;
|
|
3137
|
+
case 'ArrowDown':
|
|
3138
|
+
{
|
|
3139
|
+
if (!isDropdownExpanded) {
|
|
3140
|
+
setIsDropdownExpanded(true);
|
|
3141
|
+
setShouldApplyFilter(false);
|
|
3142
|
+
}
|
|
3143
|
+
keyDownEvent.preventDefault();
|
|
3144
|
+
break;
|
|
3145
|
+
}
|
|
3146
|
+
case 'Escape':
|
|
3147
|
+
setIsEscapeClose(true);
|
|
3148
|
+
break;
|
|
3149
|
+
case 'Enter':
|
|
3150
|
+
if (isEscapeClosed) {
|
|
3151
|
+
setIsEscapeClose(false);
|
|
3152
|
+
}
|
|
3153
|
+
break;
|
|
3154
|
+
}
|
|
3155
|
+
}, [isDropdownExpanded, isEscapeClosed]);
|
|
3156
|
+
const displayState = useMemo(() => {
|
|
3157
|
+
const ds = {};
|
|
3158
|
+
ds.componentReady = !disabled && loadState === LOAD_STATES.LOADED;
|
|
3159
|
+
ds.displayCross = ds.componentReady && value !== null && value !== undefined;
|
|
3160
|
+
ds.displayDropdown = !disabled && isDropdownExpanded && !isEscapeClosed;
|
|
3161
|
+
return ds;
|
|
3162
|
+
}, [disabled, isDropdownExpanded, isEscapeClosed, loadState, value]);
|
|
3163
|
+
const onAngelMouseDown = useCallback(e => {
|
|
3164
|
+
setIsEscapeClose(false);
|
|
3165
|
+
setIsDropdownExpanded(!isDropdownExpanded);
|
|
3166
|
+
const searchbar = searchbarRef.current;
|
|
3167
|
+
isDropdownExpanded ? searchbar.blur() : searchbar.focus();
|
|
3168
|
+
e.preventDefault();
|
|
3169
|
+
}, [isDropdownExpanded]);
|
|
3170
|
+
return jsxs(Fragment$1, {
|
|
3171
|
+
children: [jsxs("div", {
|
|
3172
|
+
id: prefixId(`${id}`, formId),
|
|
3173
|
+
class: classNames('fjs-input-group', {
|
|
3174
|
+
'disabled': disabled
|
|
3175
|
+
}, {
|
|
3176
|
+
'hasErrors': errors.length
|
|
3177
|
+
}),
|
|
3178
|
+
children: [jsx("input", {
|
|
3179
|
+
disabled: disabled,
|
|
3180
|
+
class: "fjs-input",
|
|
3181
|
+
ref: searchbarRef,
|
|
3182
|
+
id: prefixId(`${id}-search`, formId),
|
|
3183
|
+
onChange: onChange,
|
|
3184
|
+
type: "text",
|
|
3185
|
+
value: filter,
|
|
3186
|
+
placeholder: 'Search',
|
|
3187
|
+
autoComplete: "off",
|
|
3188
|
+
onKeyDown: e => onInputKeyDown(e),
|
|
3189
|
+
onMouseDown: () => {
|
|
3190
|
+
setIsEscapeClose(false);
|
|
3191
|
+
setIsDropdownExpanded(true);
|
|
3192
|
+
setShouldApplyFilter(false);
|
|
3193
|
+
},
|
|
3194
|
+
onFocus: () => {
|
|
3195
|
+
setIsDropdownExpanded(true);
|
|
3196
|
+
setShouldApplyFilter(false);
|
|
3197
|
+
},
|
|
3198
|
+
onBlur: () => {
|
|
3199
|
+
setIsDropdownExpanded(false);
|
|
3200
|
+
setFilter(valueLabel);
|
|
3201
|
+
}
|
|
3202
|
+
}), displayState.displayCross && jsxs("span", {
|
|
3203
|
+
class: "fjs-select-cross",
|
|
3204
|
+
onMouseDown: e => {
|
|
3205
|
+
setValue(null);
|
|
3206
|
+
e.preventDefault();
|
|
3207
|
+
},
|
|
3208
|
+
children: [jsx(XMarkIcon, {}), " "]
|
|
3209
|
+
}), jsx("span", {
|
|
3210
|
+
class: "fjs-select-arrow",
|
|
3211
|
+
onMouseDown: e => onAngelMouseDown(e),
|
|
3212
|
+
children: displayState.displayDropdown ? jsx(AngelUpIcon, {}) : jsx(AngelDownIcon, {})
|
|
3213
|
+
})]
|
|
3214
|
+
}), jsx("div", {
|
|
3215
|
+
class: "fjs-select-anchor",
|
|
3216
|
+
children: displayState.displayDropdown && jsx(DropdownList, {
|
|
3217
|
+
values: filteredOptions,
|
|
3218
|
+
getLabel: o => o.label,
|
|
3219
|
+
onValueSelected: o => {
|
|
3220
|
+
setValue(o);
|
|
3221
|
+
setIsDropdownExpanded(false);
|
|
3222
|
+
},
|
|
3223
|
+
listenerElement: searchbarRef.current
|
|
3224
|
+
})
|
|
3225
|
+
})]
|
|
3226
|
+
});
|
|
3227
|
+
}
|
|
3228
|
+
|
|
3229
|
+
function SimpleSelect(props) {
|
|
3230
|
+
const {
|
|
3231
|
+
id,
|
|
3232
|
+
disabled,
|
|
3233
|
+
errors,
|
|
3234
|
+
field,
|
|
3235
|
+
value
|
|
3236
|
+
} = props;
|
|
3237
|
+
const {
|
|
3238
|
+
formId
|
|
3239
|
+
} = useContext(FormContext$1);
|
|
3240
|
+
const [isDropdownExpanded, setIsDropdownExpanded] = useState(false);
|
|
3241
|
+
const selectRef = useRef();
|
|
3242
|
+
const {
|
|
3243
|
+
state: loadState,
|
|
3244
|
+
values: options
|
|
3245
|
+
} = useValuesAsync(field);
|
|
3246
|
+
|
|
3247
|
+
// We cache a map of option values to their index so that we don't need to search the whole options array every time to correlate the label
|
|
3248
|
+
const valueToOptionMap = useMemo(() => Object.assign({}, ...options.map((o, x) => ({
|
|
3249
|
+
[o.value]: options[x]
|
|
3250
|
+
}))), [options]);
|
|
3251
|
+
const valueLabel = useMemo(() => value && valueToOptionMap[value] && valueToOptionMap[value].label || '', [value, valueToOptionMap]);
|
|
3252
|
+
const setValue = useCallback(option => {
|
|
3253
|
+
props.onChange({
|
|
3254
|
+
value: option && option.value || null,
|
|
3255
|
+
field
|
|
3256
|
+
});
|
|
3257
|
+
}, [field, props]);
|
|
3258
|
+
const displayState = useMemo(() => {
|
|
3259
|
+
const ds = {};
|
|
3260
|
+
ds.componentReady = !disabled && loadState === LOAD_STATES.LOADED;
|
|
3261
|
+
ds.displayCross = ds.componentReady && value !== null && value !== undefined;
|
|
3262
|
+
ds.displayDropdown = !disabled && isDropdownExpanded;
|
|
3263
|
+
return ds;
|
|
3264
|
+
}, [disabled, isDropdownExpanded, loadState, value]);
|
|
3265
|
+
const onMouseDown = useCallback(e => {
|
|
3266
|
+
const select = selectRef.current;
|
|
3267
|
+
setIsDropdownExpanded(!isDropdownExpanded);
|
|
3268
|
+
if (isDropdownExpanded) {
|
|
3269
|
+
select.blur();
|
|
3270
|
+
} else {
|
|
3271
|
+
select.focus();
|
|
3272
|
+
}
|
|
3273
|
+
e.preventDefault();
|
|
3274
|
+
}, [isDropdownExpanded]);
|
|
3275
|
+
const initialFocusIndex = useMemo(() => value && findIndex(options, o => o.value === value) || 0, [options, value]);
|
|
3276
|
+
return jsxs(Fragment$1, {
|
|
3277
|
+
children: [jsxs("div", {
|
|
3278
|
+
ref: selectRef,
|
|
3279
|
+
id: prefixId(`${id}`, formId),
|
|
3280
|
+
class: classNames('fjs-input-group', {
|
|
3281
|
+
'disabled': disabled
|
|
3282
|
+
}, {
|
|
3283
|
+
'hasErrors': errors.length
|
|
3284
|
+
}),
|
|
3285
|
+
onFocus: () => setIsDropdownExpanded(true),
|
|
3286
|
+
onBlur: () => setIsDropdownExpanded(false),
|
|
3287
|
+
onMouseDown: e => onMouseDown(e),
|
|
3288
|
+
tabIndex: disabled ? undefined : 0,
|
|
3289
|
+
children: [jsx("div", {
|
|
3290
|
+
class: classNames('fjs-select-display', {
|
|
3291
|
+
'fjs-select-placeholder': !value
|
|
3292
|
+
}),
|
|
3293
|
+
id: prefixId(`${id}-display`, formId),
|
|
3294
|
+
children: valueLabel || 'Select'
|
|
3295
|
+
}), displayState.displayCross && jsx("span", {
|
|
3296
|
+
class: "fjs-select-cross",
|
|
3297
|
+
onMouseDown: e => {
|
|
3298
|
+
setValue(null);
|
|
3299
|
+
e.stopPropagation();
|
|
3300
|
+
},
|
|
3301
|
+
children: jsx(XMarkIcon, {})
|
|
3302
|
+
}), jsx("span", {
|
|
3303
|
+
class: "fjs-select-arrow",
|
|
3304
|
+
children: displayState.displayDropdown ? jsx(AngelUpIcon, {}) : jsx(AngelDownIcon, {})
|
|
3305
|
+
})]
|
|
3306
|
+
}), jsx("div", {
|
|
3307
|
+
class: "fjs-select-anchor",
|
|
3308
|
+
children: displayState.displayDropdown && jsx(DropdownList, {
|
|
3309
|
+
values: options,
|
|
3310
|
+
getLabel: o => o.label,
|
|
3311
|
+
initialFocusIndex: initialFocusIndex,
|
|
3312
|
+
onValueSelected: o => {
|
|
3313
|
+
setValue(o);
|
|
3314
|
+
setIsDropdownExpanded(false);
|
|
3315
|
+
},
|
|
3316
|
+
listenerElement: selectRef.current
|
|
3317
|
+
})
|
|
3318
|
+
})]
|
|
3319
|
+
});
|
|
3320
|
+
}
|
|
3321
|
+
|
|
3322
|
+
const type$4 = 'select';
|
|
3323
|
+
function Select(props) {
|
|
3324
|
+
const {
|
|
3325
|
+
disabled,
|
|
3326
|
+
errors = [],
|
|
3327
|
+
field,
|
|
3328
|
+
onChange,
|
|
3329
|
+
value
|
|
3330
|
+
} = props;
|
|
3331
|
+
const {
|
|
3332
|
+
description,
|
|
3333
|
+
id,
|
|
3334
|
+
label,
|
|
3335
|
+
searchable = false,
|
|
3336
|
+
validate = {}
|
|
3337
|
+
} = field;
|
|
3338
|
+
const {
|
|
3339
|
+
required
|
|
3340
|
+
} = validate;
|
|
3341
|
+
const {
|
|
3342
|
+
formId
|
|
3343
|
+
} = useContext(FormContext$1);
|
|
3344
|
+
const selectProps = useMemo(() => ({
|
|
3345
|
+
id,
|
|
3346
|
+
disabled,
|
|
3347
|
+
errors,
|
|
3348
|
+
field,
|
|
3349
|
+
value,
|
|
3350
|
+
onChange
|
|
3351
|
+
}), [disabled, errors, field, id, value, onChange]);
|
|
3352
|
+
return jsxs("div", {
|
|
3353
|
+
class: formFieldClasses(type$4, {
|
|
3354
|
+
errors,
|
|
3355
|
+
disabled
|
|
3356
|
+
}),
|
|
3357
|
+
children: [jsx(Label, {
|
|
3358
|
+
id: prefixId(id, formId),
|
|
3359
|
+
label: label,
|
|
3360
|
+
required: required
|
|
3361
|
+
}), searchable ? jsx(SearchableSelect, {
|
|
3362
|
+
...selectProps
|
|
3363
|
+
}) : jsx(SimpleSelect, {
|
|
3364
|
+
...selectProps
|
|
3365
|
+
}), jsx(Description, {
|
|
3366
|
+
description: description
|
|
3367
|
+
}), jsx(Errors, {
|
|
3368
|
+
errors: errors
|
|
3369
|
+
})]
|
|
3370
|
+
});
|
|
3371
|
+
}
|
|
3372
|
+
Select.create = (options = {}) => {
|
|
3373
|
+
const defaults = {};
|
|
3374
|
+
|
|
3375
|
+
// provide default values if valuesKey isn't set
|
|
3376
|
+
if (!options.valuesKey) {
|
|
3377
|
+
defaults.values = [{
|
|
3378
|
+
label: 'Value',
|
|
3379
|
+
value: 'value'
|
|
3380
|
+
}];
|
|
3381
|
+
}
|
|
3382
|
+
return {
|
|
3383
|
+
...defaults,
|
|
3384
|
+
...options
|
|
3385
|
+
};
|
|
3386
|
+
};
|
|
3387
|
+
Select.type = type$4;
|
|
3388
|
+
Select.label = 'Select';
|
|
3389
|
+
Select.keyed = true;
|
|
3390
|
+
Select.emptyValue = null;
|
|
3391
|
+
Select.sanitizeValue = sanitizeSingleSelectValue;
|
|
3392
|
+
Select.group = 'selection';
|
|
3393
|
+
|
|
3394
|
+
const type$3 = 'taglist';
|
|
3395
|
+
function Taglist(props) {
|
|
3396
|
+
const {
|
|
3397
|
+
disabled,
|
|
3398
|
+
errors = [],
|
|
3399
|
+
field,
|
|
3400
|
+
value: values = []
|
|
3401
|
+
} = props;
|
|
3402
|
+
const {
|
|
3403
|
+
description,
|
|
3404
|
+
id,
|
|
3405
|
+
label
|
|
3406
|
+
} = field;
|
|
3407
|
+
const {
|
|
3408
|
+
formId
|
|
3409
|
+
} = useContext(FormContext$1);
|
|
3410
|
+
const [filter, setFilter] = useState('');
|
|
3411
|
+
const [filteredOptions, setFilteredOptions] = useState([]);
|
|
3412
|
+
const [isDropdownExpanded, setIsDropdownExpanded] = useState(false);
|
|
3413
|
+
const [hasOptionsLeft, setHasOptionsLeft] = useState(true);
|
|
3134
3414
|
const [isEscapeClosed, setIsEscapeClose] = useState(false);
|
|
3135
3415
|
const searchbarRef = useRef();
|
|
3136
3416
|
const {
|
|
@@ -3214,6 +3494,7 @@ function Taglist(props) {
|
|
|
3214
3494
|
searchbarRef.current.focus();
|
|
3215
3495
|
}
|
|
3216
3496
|
};
|
|
3497
|
+
const shouldDisplayDropdown = useMemo(() => !disabled && loadState === LOAD_STATES.LOADED && isDropdownExpanded && !isEscapeClosed, [disabled, isDropdownExpanded, isEscapeClosed, loadState]);
|
|
3217
3498
|
return jsxs("div", {
|
|
3218
3499
|
class: formFieldClasses(type$3, {
|
|
3219
3500
|
errors,
|
|
@@ -3224,23 +3505,25 @@ function Taglist(props) {
|
|
|
3224
3505
|
id: prefixId(`${id}-search`, formId)
|
|
3225
3506
|
}), jsxs("div", {
|
|
3226
3507
|
class: classNames('fjs-taglist', {
|
|
3227
|
-
'disabled': disabled
|
|
3508
|
+
'fjs-disabled': disabled
|
|
3228
3509
|
}),
|
|
3229
|
-
children: [
|
|
3510
|
+
children: [loadState === LOAD_STATES.LOADED && jsx("div", {
|
|
3230
3511
|
class: "fjs-taglist-tags",
|
|
3231
3512
|
children: values.map(v => {
|
|
3232
3513
|
return jsxs("div", {
|
|
3233
|
-
class:
|
|
3514
|
+
class: classNames('fjs-taglist-tag', {
|
|
3515
|
+
'fjs-disabled': disabled
|
|
3516
|
+
}),
|
|
3234
3517
|
onMouseDown: e => e.preventDefault(),
|
|
3235
3518
|
children: [jsx("span", {
|
|
3236
3519
|
class: "fjs-taglist-tag-label",
|
|
3237
3520
|
children: valueToOptionMap[v] ? valueToOptionMap[v].label : `unexpected value{${v}}`
|
|
3238
|
-
}), jsx("button", {
|
|
3521
|
+
}), !disabled && jsx("button", {
|
|
3239
3522
|
type: "button",
|
|
3240
3523
|
title: "Remove tag",
|
|
3241
3524
|
class: "fjs-taglist-tag-remove",
|
|
3242
3525
|
onClick: event => onTagRemoveClick(event, v),
|
|
3243
|
-
children: jsx(
|
|
3526
|
+
children: jsx(XMarkIcon, {})
|
|
3244
3527
|
})]
|
|
3245
3528
|
});
|
|
3246
3529
|
})
|
|
@@ -3252,7 +3535,7 @@ function Taglist(props) {
|
|
|
3252
3535
|
onChange: onFilterChange,
|
|
3253
3536
|
type: "text",
|
|
3254
3537
|
value: filter,
|
|
3255
|
-
placeholder: 'Search',
|
|
3538
|
+
placeholder: disabled ? '' : 'Search',
|
|
3256
3539
|
autoComplete: "off",
|
|
3257
3540
|
onKeyDown: e => onInputKeyDown(e),
|
|
3258
3541
|
onMouseDown: () => setIsEscapeClose(false),
|
|
@@ -3264,7 +3547,7 @@ function Taglist(props) {
|
|
|
3264
3547
|
})]
|
|
3265
3548
|
}), jsx("div", {
|
|
3266
3549
|
class: "fjs-taglist-anchor",
|
|
3267
|
-
children:
|
|
3550
|
+
children: shouldDisplayDropdown && jsx(DropdownList, {
|
|
3268
3551
|
values: filteredOptions,
|
|
3269
3552
|
getLabel: o => o.label,
|
|
3270
3553
|
onValueSelected: o => selectValue(o.value),
|
|
@@ -3278,21 +3561,222 @@ function Taglist(props) {
|
|
|
3278
3561
|
})]
|
|
3279
3562
|
});
|
|
3280
3563
|
}
|
|
3281
|
-
Taglist.create =
|
|
3282
|
-
|
|
3283
|
-
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
}
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3564
|
+
Taglist.create = (options = {}) => {
|
|
3565
|
+
const defaults = {};
|
|
3566
|
+
|
|
3567
|
+
// provide default values if valuesKey isn't set
|
|
3568
|
+
if (!options.valuesKey) {
|
|
3569
|
+
defaults.values = [{
|
|
3570
|
+
label: 'Value',
|
|
3571
|
+
value: 'value'
|
|
3572
|
+
}];
|
|
3573
|
+
}
|
|
3574
|
+
return {
|
|
3575
|
+
...defaults,
|
|
3576
|
+
...options
|
|
3577
|
+
};
|
|
3578
|
+
};
|
|
3579
|
+
Taglist.type = type$3;
|
|
3580
|
+
Taglist.label = 'Tag list';
|
|
3581
|
+
Taglist.keyed = true;
|
|
3582
|
+
Taglist.emptyValue = [];
|
|
3583
|
+
Taglist.sanitizeValue = sanitizeMultiSelectValue;
|
|
3584
|
+
Taglist.group = 'selection';
|
|
3585
|
+
|
|
3586
|
+
const type$2 = 'text';
|
|
3587
|
+
function Text(props) {
|
|
3588
|
+
const {
|
|
3589
|
+
field,
|
|
3590
|
+
disableLinks
|
|
3591
|
+
} = props;
|
|
3592
|
+
const {
|
|
3593
|
+
text = ''
|
|
3594
|
+
} = field;
|
|
3595
|
+
const textValue = useExpressionValue(text) || '';
|
|
3596
|
+
const componentOverrides = disableLinks ? {
|
|
3597
|
+
'a': DisabledLink
|
|
3598
|
+
} : {};
|
|
3599
|
+
return jsx("div", {
|
|
3600
|
+
class: formFieldClasses(type$2),
|
|
3601
|
+
children: jsx(Markup, {
|
|
3602
|
+
markup: safeMarkdown(textValue),
|
|
3603
|
+
components: componentOverrides,
|
|
3604
|
+
trim: false
|
|
3605
|
+
})
|
|
3606
|
+
});
|
|
3607
|
+
}
|
|
3608
|
+
Text.create = (options = {}) => ({
|
|
3609
|
+
text: '# Text',
|
|
3610
|
+
...options
|
|
3611
|
+
});
|
|
3612
|
+
Text.type = type$2;
|
|
3613
|
+
Text.keyed = false;
|
|
3614
|
+
Text.group = 'presentation';
|
|
3615
|
+
Text.label = 'Text view';
|
|
3616
|
+
function DisabledLink({
|
|
3617
|
+
href,
|
|
3618
|
+
children
|
|
3619
|
+
}) {
|
|
3620
|
+
return jsx("a", {
|
|
3621
|
+
class: "fjs-disabled-link",
|
|
3622
|
+
href: href,
|
|
3623
|
+
tabIndex: -1,
|
|
3624
|
+
children: children
|
|
3625
|
+
});
|
|
3626
|
+
}
|
|
3627
|
+
|
|
3628
|
+
const type$1 = 'textfield';
|
|
3629
|
+
function Textfield(props) {
|
|
3630
|
+
const {
|
|
3631
|
+
disabled,
|
|
3632
|
+
errors = [],
|
|
3633
|
+
field,
|
|
3634
|
+
value = ''
|
|
3635
|
+
} = props;
|
|
3636
|
+
const {
|
|
3637
|
+
description,
|
|
3638
|
+
id,
|
|
3639
|
+
label,
|
|
3640
|
+
appearance = {},
|
|
3641
|
+
validate = {}
|
|
3642
|
+
} = field;
|
|
3643
|
+
const {
|
|
3644
|
+
prefixAdorner,
|
|
3645
|
+
suffixAdorner
|
|
3646
|
+
} = appearance;
|
|
3647
|
+
const {
|
|
3648
|
+
required
|
|
3649
|
+
} = validate;
|
|
3650
|
+
const onChange = ({
|
|
3651
|
+
target
|
|
3652
|
+
}) => {
|
|
3653
|
+
props.onChange({
|
|
3654
|
+
field,
|
|
3655
|
+
value: target.value
|
|
3656
|
+
});
|
|
3657
|
+
};
|
|
3658
|
+
const {
|
|
3659
|
+
formId
|
|
3660
|
+
} = useContext(FormContext$1);
|
|
3661
|
+
return jsxs("div", {
|
|
3662
|
+
class: formFieldClasses(type$1, {
|
|
3663
|
+
errors,
|
|
3664
|
+
disabled
|
|
3665
|
+
}),
|
|
3666
|
+
children: [jsx(Label, {
|
|
3667
|
+
id: prefixId(id, formId),
|
|
3668
|
+
label: label,
|
|
3669
|
+
required: required
|
|
3670
|
+
}), jsx(InputAdorner, {
|
|
3671
|
+
disabled: disabled,
|
|
3672
|
+
pre: prefixAdorner,
|
|
3673
|
+
post: suffixAdorner,
|
|
3674
|
+
children: jsx("input", {
|
|
3675
|
+
class: "fjs-input",
|
|
3676
|
+
disabled: disabled,
|
|
3677
|
+
id: prefixId(id, formId),
|
|
3678
|
+
onInput: onChange,
|
|
3679
|
+
type: "text",
|
|
3680
|
+
value: value
|
|
3681
|
+
})
|
|
3682
|
+
}), jsx(Description, {
|
|
3683
|
+
description: description
|
|
3684
|
+
}), jsx(Errors, {
|
|
3685
|
+
errors: errors
|
|
3686
|
+
})]
|
|
3687
|
+
});
|
|
3688
|
+
}
|
|
3689
|
+
Textfield.create = (options = {}) => ({
|
|
3690
|
+
...options
|
|
3691
|
+
});
|
|
3692
|
+
Textfield.type = type$1;
|
|
3693
|
+
Textfield.label = 'Text field';
|
|
3694
|
+
Textfield.keyed = true;
|
|
3695
|
+
Textfield.emptyValue = '';
|
|
3696
|
+
Textfield.sanitizeValue = ({
|
|
3697
|
+
value
|
|
3698
|
+
}) => isArray(value) || isObject(value) ? '' : String(value);
|
|
3699
|
+
Textfield.group = 'basic-input';
|
|
3700
|
+
|
|
3701
|
+
const type = 'textarea';
|
|
3702
|
+
function Textarea(props) {
|
|
3703
|
+
const {
|
|
3704
|
+
disabled,
|
|
3705
|
+
errors = [],
|
|
3706
|
+
field,
|
|
3707
|
+
value = ''
|
|
3708
|
+
} = props;
|
|
3709
|
+
const {
|
|
3710
|
+
description,
|
|
3711
|
+
id,
|
|
3712
|
+
label,
|
|
3713
|
+
validate = {}
|
|
3714
|
+
} = field;
|
|
3715
|
+
const {
|
|
3716
|
+
required
|
|
3717
|
+
} = validate;
|
|
3718
|
+
const textareaRef = useRef();
|
|
3719
|
+
const onInput = ({
|
|
3720
|
+
target
|
|
3721
|
+
}) => {
|
|
3722
|
+
props.onChange({
|
|
3723
|
+
field,
|
|
3724
|
+
value: target.value
|
|
3725
|
+
});
|
|
3726
|
+
};
|
|
3727
|
+
const autoSizeTextarea = useCallback(textarea => {
|
|
3728
|
+
// Ensures the textarea shrinks back, and improves resizing behavior consistency
|
|
3729
|
+
textarea.style.height = '0px';
|
|
3730
|
+
const computed = window.getComputedStyle(textarea);
|
|
3731
|
+
const calculatedHeight = parseInt(computed.getPropertyValue('border-top-width')) + parseInt(computed.getPropertyValue('padding-top')) + textarea.scrollHeight + parseInt(computed.getPropertyValue('padding-bottom')) + parseInt(computed.getPropertyValue('border-bottom-width'));
|
|
3732
|
+
const minHeight = 75;
|
|
3733
|
+
const maxHeight = 350;
|
|
3734
|
+
const displayHeight = Math.max(Math.min(calculatedHeight, maxHeight), minHeight);
|
|
3735
|
+
textarea.style.height = `${displayHeight}px`;
|
|
3736
|
+
|
|
3737
|
+
// Overflow is hidden by default to hide scrollbar flickering
|
|
3738
|
+
textarea.style.overflow = calculatedHeight > maxHeight ? 'visible' : 'hidden';
|
|
3739
|
+
}, []);
|
|
3740
|
+
useEffect(() => {
|
|
3741
|
+
autoSizeTextarea(textareaRef.current);
|
|
3742
|
+
}, [autoSizeTextarea, value]);
|
|
3743
|
+
const {
|
|
3744
|
+
formId
|
|
3745
|
+
} = useContext(FormContext$1);
|
|
3746
|
+
return jsxs("div", {
|
|
3747
|
+
class: formFieldClasses(type, {
|
|
3748
|
+
errors,
|
|
3749
|
+
disabled
|
|
3750
|
+
}),
|
|
3751
|
+
children: [jsx(Label, {
|
|
3752
|
+
id: prefixId(id, formId),
|
|
3753
|
+
label: label,
|
|
3754
|
+
required: required
|
|
3755
|
+
}), jsx("textarea", {
|
|
3756
|
+
class: "fjs-textarea",
|
|
3757
|
+
disabled: disabled,
|
|
3758
|
+
id: prefixId(id, formId),
|
|
3759
|
+
onInput: onInput,
|
|
3760
|
+
value: value,
|
|
3761
|
+
ref: textareaRef
|
|
3762
|
+
}), jsx(Description, {
|
|
3763
|
+
description: description
|
|
3764
|
+
}), jsx(Errors, {
|
|
3765
|
+
errors: errors
|
|
3766
|
+
})]
|
|
3767
|
+
});
|
|
3768
|
+
}
|
|
3769
|
+
Textarea.create = (options = {}) => ({
|
|
3770
|
+
...options
|
|
3771
|
+
});
|
|
3772
|
+
Textarea.type = type;
|
|
3773
|
+
Textarea.label = 'Text area';
|
|
3774
|
+
Textarea.keyed = true;
|
|
3775
|
+
Textarea.emptyValue = '';
|
|
3776
|
+
Textarea.sanitizeValue = ({
|
|
3777
|
+
value
|
|
3778
|
+
}) => isArray(value) || isObject(value) ? '' : String(value);
|
|
3779
|
+
Textarea.group = 'basic-input';
|
|
3296
3780
|
|
|
3297
3781
|
function _extends$d() { _extends$d = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$d.apply(this, arguments); }
|
|
3298
3782
|
var ButtonIcon = (({
|
|
@@ -3324,18 +3808,18 @@ var ChecklistIcon = (({
|
|
|
3324
3808
|
styles = {},
|
|
3325
3809
|
...props
|
|
3326
3810
|
}) => /*#__PURE__*/React.createElement("svg", _extends$b({
|
|
3811
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
3327
3812
|
width: "54",
|
|
3328
3813
|
height: "54",
|
|
3329
|
-
fill: "none"
|
|
3330
|
-
xmlns: "http://www.w3.org/2000/svg"
|
|
3814
|
+
fill: "none"
|
|
3331
3815
|
}, props), /*#__PURE__*/React.createElement("path", {
|
|
3332
3816
|
fillRule: "evenodd",
|
|
3333
3817
|
clipRule: "evenodd",
|
|
3334
|
-
d: "
|
|
3335
|
-
fill: "#
|
|
3818
|
+
d: "M18 12h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zM18 36h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6zM18 24h-6v6h6v-6zm-6-2a2 2 0 00-2 2v6a2 2 0 002 2h6a2 2 0 002-2v-6a2 2 0 00-2-2h-6z",
|
|
3819
|
+
fill: "#161616"
|
|
3336
3820
|
}), /*#__PURE__*/React.createElement("path", {
|
|
3337
|
-
d: "
|
|
3338
|
-
fill: "#
|
|
3821
|
+
d: "M23 14.5a1 1 0 011-1h19a1 1 0 011 1v1a1 1 0 01-1 1H24a1 1 0 01-1-1v-1zM23 26.5a1 1 0 011-1h19a1 1 0 011 1v1a1 1 0 01-1 1H24a1 1 0 01-1-1v-1zM23 38.5a1 1 0 011-1h19a1 1 0 011 1v1a1 1 0 01-1 1H24a1 1 0 01-1-1v-1z",
|
|
3822
|
+
fill: "#161616"
|
|
3339
3823
|
})));
|
|
3340
3824
|
|
|
3341
3825
|
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); }
|
|
@@ -3536,226 +4020,13 @@ const iconsByType = {
|
|
|
3536
4020
|
default: FormIcon
|
|
3537
4021
|
};
|
|
3538
4022
|
|
|
3539
|
-
const type$2 = 'text';
|
|
3540
|
-
function Text(props) {
|
|
3541
|
-
const {
|
|
3542
|
-
field,
|
|
3543
|
-
disabled
|
|
3544
|
-
} = props;
|
|
3545
|
-
const {
|
|
3546
|
-
text = ''
|
|
3547
|
-
} = field;
|
|
3548
|
-
const textValue = useExpressionValue(text) || '';
|
|
3549
|
-
return jsx("div", {
|
|
3550
|
-
class: formFieldClasses(type$2),
|
|
3551
|
-
children: renderText(field, textValue, disabled)
|
|
3552
|
-
});
|
|
3553
|
-
}
|
|
3554
|
-
Text.create = function (options = {}) {
|
|
3555
|
-
return {
|
|
3556
|
-
text: '# Text',
|
|
3557
|
-
...options
|
|
3558
|
-
};
|
|
3559
|
-
};
|
|
3560
|
-
Text.type = type$2;
|
|
3561
|
-
Text.keyed = false;
|
|
3562
|
-
|
|
3563
|
-
// helper //////////////
|
|
3564
|
-
|
|
3565
|
-
function renderText(field, content, disabled) {
|
|
3566
|
-
const {
|
|
3567
|
-
text
|
|
3568
|
-
} = field;
|
|
3569
|
-
const Icon = iconsByType['text'];
|
|
3570
|
-
if (disabled) {
|
|
3571
|
-
if (!text) {
|
|
3572
|
-
return jsxs("div", {
|
|
3573
|
-
class: "fjs-form-field-placeholder",
|
|
3574
|
-
children: [jsx(Icon, {
|
|
3575
|
-
viewBox: "0 0 54 54"
|
|
3576
|
-
}), "Text view is empty"]
|
|
3577
|
-
});
|
|
3578
|
-
}
|
|
3579
|
-
if (isExpression$2(text)) {
|
|
3580
|
-
return jsxs("div", {
|
|
3581
|
-
class: "fjs-form-field-placeholder",
|
|
3582
|
-
children: [jsx(Icon, {
|
|
3583
|
-
viewBox: "0 0 54 54"
|
|
3584
|
-
}), "Text view is populated by an expression"]
|
|
3585
|
-
});
|
|
3586
|
-
}
|
|
3587
|
-
}
|
|
3588
|
-
return jsx(Markup, {
|
|
3589
|
-
markup: safeMarkdown(content),
|
|
3590
|
-
trim: false
|
|
3591
|
-
});
|
|
3592
|
-
}
|
|
3593
|
-
|
|
3594
|
-
const type$1 = 'textfield';
|
|
3595
|
-
function Textfield(props) {
|
|
3596
|
-
const {
|
|
3597
|
-
disabled,
|
|
3598
|
-
errors = [],
|
|
3599
|
-
field,
|
|
3600
|
-
value = ''
|
|
3601
|
-
} = props;
|
|
3602
|
-
const {
|
|
3603
|
-
description,
|
|
3604
|
-
id,
|
|
3605
|
-
label,
|
|
3606
|
-
appearance = {},
|
|
3607
|
-
validate = {}
|
|
3608
|
-
} = field;
|
|
3609
|
-
const {
|
|
3610
|
-
prefixAdorner,
|
|
3611
|
-
suffixAdorner
|
|
3612
|
-
} = appearance;
|
|
3613
|
-
const {
|
|
3614
|
-
required
|
|
3615
|
-
} = validate;
|
|
3616
|
-
const onChange = ({
|
|
3617
|
-
target
|
|
3618
|
-
}) => {
|
|
3619
|
-
props.onChange({
|
|
3620
|
-
field,
|
|
3621
|
-
value: target.value
|
|
3622
|
-
});
|
|
3623
|
-
};
|
|
3624
|
-
const {
|
|
3625
|
-
formId
|
|
3626
|
-
} = useContext(FormContext);
|
|
3627
|
-
return jsxs("div", {
|
|
3628
|
-
class: formFieldClasses(type$1, {
|
|
3629
|
-
errors,
|
|
3630
|
-
disabled
|
|
3631
|
-
}),
|
|
3632
|
-
children: [jsx(Label, {
|
|
3633
|
-
id: prefixId(id, formId),
|
|
3634
|
-
label: label,
|
|
3635
|
-
required: required
|
|
3636
|
-
}), jsx(InputAdorner, {
|
|
3637
|
-
disabled: disabled,
|
|
3638
|
-
pre: prefixAdorner,
|
|
3639
|
-
post: suffixAdorner,
|
|
3640
|
-
children: jsx("input", {
|
|
3641
|
-
class: "fjs-input",
|
|
3642
|
-
disabled: disabled,
|
|
3643
|
-
id: prefixId(id, formId),
|
|
3644
|
-
onInput: onChange,
|
|
3645
|
-
type: "text",
|
|
3646
|
-
value: value
|
|
3647
|
-
})
|
|
3648
|
-
}), jsx(Description, {
|
|
3649
|
-
description: description
|
|
3650
|
-
}), jsx(Errors, {
|
|
3651
|
-
errors: errors
|
|
3652
|
-
})]
|
|
3653
|
-
});
|
|
3654
|
-
}
|
|
3655
|
-
Textfield.create = function (options = {}) {
|
|
3656
|
-
return {
|
|
3657
|
-
...options
|
|
3658
|
-
};
|
|
3659
|
-
};
|
|
3660
|
-
Textfield.type = type$1;
|
|
3661
|
-
Textfield.label = 'Text field';
|
|
3662
|
-
Textfield.keyed = true;
|
|
3663
|
-
Textfield.emptyValue = '';
|
|
3664
|
-
Textfield.sanitizeValue = ({
|
|
3665
|
-
value
|
|
3666
|
-
}) => isArray(value) || isObject(value) ? '' : String(value);
|
|
3667
|
-
|
|
3668
|
-
const type = 'textarea';
|
|
3669
|
-
function Textarea(props) {
|
|
3670
|
-
const {
|
|
3671
|
-
disabled,
|
|
3672
|
-
errors = [],
|
|
3673
|
-
field,
|
|
3674
|
-
value = ''
|
|
3675
|
-
} = props;
|
|
3676
|
-
const {
|
|
3677
|
-
description,
|
|
3678
|
-
id,
|
|
3679
|
-
label,
|
|
3680
|
-
validate = {}
|
|
3681
|
-
} = field;
|
|
3682
|
-
const {
|
|
3683
|
-
required
|
|
3684
|
-
} = validate;
|
|
3685
|
-
const textareaRef = useRef();
|
|
3686
|
-
const onInput = ({
|
|
3687
|
-
target
|
|
3688
|
-
}) => {
|
|
3689
|
-
props.onChange({
|
|
3690
|
-
field,
|
|
3691
|
-
value: target.value
|
|
3692
|
-
});
|
|
3693
|
-
};
|
|
3694
|
-
const autoSizeTextarea = useCallback(textarea => {
|
|
3695
|
-
// Ensures the textarea shrinks back, and improves resizing behavior consistency
|
|
3696
|
-
textarea.style.height = '0px';
|
|
3697
|
-
const computed = window.getComputedStyle(textarea);
|
|
3698
|
-
const calculatedHeight = parseInt(computed.getPropertyValue('border-top-width')) + parseInt(computed.getPropertyValue('padding-top')) + textarea.scrollHeight + parseInt(computed.getPropertyValue('padding-bottom')) + parseInt(computed.getPropertyValue('border-bottom-width'));
|
|
3699
|
-
const minHeight = 75;
|
|
3700
|
-
const maxHeight = 350;
|
|
3701
|
-
const displayHeight = Math.max(Math.min(calculatedHeight, maxHeight), minHeight);
|
|
3702
|
-
textarea.style.height = `${displayHeight}px`;
|
|
3703
|
-
|
|
3704
|
-
// Overflow is hidden by default to hide scrollbar flickering
|
|
3705
|
-
textarea.style.overflow = calculatedHeight > maxHeight ? 'visible' : 'hidden';
|
|
3706
|
-
}, []);
|
|
3707
|
-
useEffect(() => {
|
|
3708
|
-
autoSizeTextarea(textareaRef.current);
|
|
3709
|
-
}, [autoSizeTextarea, value]);
|
|
3710
|
-
const {
|
|
3711
|
-
formId
|
|
3712
|
-
} = useContext(FormContext);
|
|
3713
|
-
return jsxs("div", {
|
|
3714
|
-
class: formFieldClasses(type, {
|
|
3715
|
-
errors,
|
|
3716
|
-
disabled
|
|
3717
|
-
}),
|
|
3718
|
-
children: [jsx(Label, {
|
|
3719
|
-
id: prefixId(id, formId),
|
|
3720
|
-
label: label,
|
|
3721
|
-
required: required
|
|
3722
|
-
}), jsx("textarea", {
|
|
3723
|
-
class: "fjs-textarea",
|
|
3724
|
-
disabled: disabled,
|
|
3725
|
-
id: prefixId(id, formId),
|
|
3726
|
-
onInput: onInput,
|
|
3727
|
-
value: value,
|
|
3728
|
-
ref: textareaRef
|
|
3729
|
-
}), jsx(Description, {
|
|
3730
|
-
description: description
|
|
3731
|
-
}), jsx(Errors, {
|
|
3732
|
-
errors: errors
|
|
3733
|
-
})]
|
|
3734
|
-
});
|
|
3735
|
-
}
|
|
3736
|
-
Textarea.create = function (options = {}) {
|
|
3737
|
-
return {
|
|
3738
|
-
...options
|
|
3739
|
-
};
|
|
3740
|
-
};
|
|
3741
|
-
Textarea.type = type;
|
|
3742
|
-
Textarea.label = 'Text area';
|
|
3743
|
-
Textarea.keyed = true;
|
|
3744
|
-
Textarea.emptyValue = '';
|
|
3745
|
-
Textarea.sanitizeValue = ({
|
|
3746
|
-
value
|
|
3747
|
-
}) => isArray(value) || isObject(value) ? '' : String(value);
|
|
3748
|
-
|
|
3749
4023
|
const formFields = [Button, Checkbox, Checklist, Default, Image, Numberfield, Datetime, Radio, Select, Taglist, Text, Textfield, Textarea];
|
|
3750
4024
|
|
|
3751
4025
|
class FormFields {
|
|
3752
4026
|
constructor() {
|
|
3753
4027
|
this._formFields = {};
|
|
3754
4028
|
formFields.forEach(formField => {
|
|
3755
|
-
|
|
3756
|
-
type
|
|
3757
|
-
} = formField;
|
|
3758
|
-
this.register(type, formField);
|
|
4029
|
+
this.register(formField.type, formField);
|
|
3759
4030
|
});
|
|
3760
4031
|
}
|
|
3761
4032
|
register(type, formField) {
|
|
@@ -3797,7 +4068,7 @@ function Renderer(config, eventBus, form, injector) {
|
|
|
3797
4068
|
if (!schema) {
|
|
3798
4069
|
return null;
|
|
3799
4070
|
}
|
|
3800
|
-
return jsx(FormContext.Provider, {
|
|
4071
|
+
return jsx(FormContext$1.Provider, {
|
|
3801
4072
|
value: formContext,
|
|
3802
4073
|
children: jsx(FormComponent, {
|
|
3803
4074
|
onChange: onChange,
|
|
@@ -4198,7 +4469,7 @@ class Form {
|
|
|
4198
4469
|
}
|
|
4199
4470
|
}
|
|
4200
4471
|
|
|
4201
|
-
const schemaVersion =
|
|
4472
|
+
const schemaVersion = 7;
|
|
4202
4473
|
|
|
4203
4474
|
/**
|
|
4204
4475
|
* @typedef { import('./types').CreateFormOptions } CreateFormOptions
|
|
@@ -4223,5 +4494,5 @@ function createForm(options) {
|
|
|
4223
4494
|
});
|
|
4224
4495
|
}
|
|
4225
4496
|
|
|
4226
|
-
export { Button, Checkbox, Checklist, DATETIME_SUBTYPES, DATETIME_SUBTYPES_LABELS, DATETIME_SUBTYPE_PATH, DATE_DISALLOW_PAST_PATH, DATE_LABEL_PATH, Datetime, Default, Form, FormComponent, FormContext, FormFieldRegistry, FormFields, FormRenderContext, Image, MINUTES_IN_DAY, Numberfield, Radio, Select, TIME_INTERVAL_PATH, TIME_LABEL_PATH, TIME_SERIALISINGFORMAT_LABELS, TIME_SERIALISING_FORMATS, TIME_SERIALISING_FORMAT_PATH, TIME_USE24H_PATH, Taglist, Text, Textarea, Textfield, VALUES_SOURCES, VALUES_SOURCES_DEFAULTS, VALUES_SOURCES_LABELS, VALUES_SOURCES_PATHS, VALUES_SOURCE_DEFAULT, clone, createForm, createFormContainer, createInjector, findErrors, formFields, generateIdForType, generateIndexForType, getSchemaVariables, getValuesSource, iconsByType, isRequired, pathParse, pathStringify, pathsEqual, schemaVersion };
|
|
4497
|
+
export { Button, Checkbox, Checklist, DATETIME_SUBTYPES, DATETIME_SUBTYPES_LABELS, DATETIME_SUBTYPE_PATH, DATE_DISALLOW_PAST_PATH, DATE_LABEL_PATH, Datetime, Default, Form, FormComponent, FormContext$1 as FormContext, FormFieldRegistry, FormFields, FormRenderContext$1 as FormRenderContext, Image, MINUTES_IN_DAY, Numberfield, Radio, Select, TIME_INTERVAL_PATH, TIME_LABEL_PATH, TIME_SERIALISINGFORMAT_LABELS, TIME_SERIALISING_FORMATS, TIME_SERIALISING_FORMAT_PATH, TIME_USE24H_PATH, Taglist, Text, Textarea, Textfield, VALUES_SOURCES, VALUES_SOURCES_DEFAULTS, VALUES_SOURCES_LABELS, VALUES_SOURCES_PATHS, VALUES_SOURCE_DEFAULT, clone, createForm, createFormContainer, createInjector, findErrors, formFields, generateIdForType, generateIndexForType, getExpressionVariableNames, getSchemaVariables, getValuesSource, getVariableNames, iconsByType, isExpression$1 as isExpression, isRequired, pathParse, pathStringify, pathsEqual, schemaVersion };
|
|
4227
4498
|
//# sourceMappingURL=index.es.js.map
|