@bpmn-io/form-js-viewer 1.3.0-alpha.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/form-js-base.css +14 -12
- package/dist/assets/form-js.css +14 -11
- package/dist/index.cjs +58 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.es.js +59 -22
- package/dist/index.es.js.map +1 -1
- package/dist/types/Form.d.ts +1 -1
- package/dist/types/features/expression-language/ConditionChecker.d.ts +4 -0
- package/dist/types/render/components/index.d.ts +2 -1
- package/dist/types/render/hooks/index.d.ts +2 -0
- package/dist/types/render/hooks/useDeepCompareState.d.ts +8 -0
- package/dist/types/render/hooks/usePrevious.d.ts +1 -0
- package/package.json +4 -4
package/dist/index.es.js
CHANGED
|
@@ -5,7 +5,7 @@ import { parseExpression, parseUnaryTests, evaluate, unaryTest } from 'feelin';
|
|
|
5
5
|
import { evaluate as evaluate$1, parser, buildSimpleTree } from 'feelers';
|
|
6
6
|
import classNames from 'classnames';
|
|
7
7
|
import { jsx, jsxs, Fragment as Fragment$1 } from 'preact/jsx-runtime';
|
|
8
|
-
import { useContext, useMemo, useEffect,
|
|
8
|
+
import { useContext, useMemo, useEffect, useRef, useState, useCallback, useLayoutEffect } from 'preact/hooks';
|
|
9
9
|
import { createContext, createElement, Fragment, render } from 'preact';
|
|
10
10
|
import * as React from 'preact/compat';
|
|
11
11
|
import { createPortal } from 'preact/compat';
|
|
@@ -619,9 +619,14 @@ class ConditionChecker {
|
|
|
619
619
|
*
|
|
620
620
|
* @param {Object<string, any>} properties
|
|
621
621
|
* @param {Object<string, any>} data
|
|
622
|
+
* @param {Object} [options]
|
|
623
|
+
* @param {Function} [options.getFilterPath]
|
|
622
624
|
*/
|
|
623
|
-
applyConditions(properties, data = {}) {
|
|
625
|
+
applyConditions(properties, data = {}, options = {}) {
|
|
624
626
|
const newProperties = clone(properties);
|
|
627
|
+
const {
|
|
628
|
+
getFilterPath = field => this._pathRegistry.getValuePath(field)
|
|
629
|
+
} = options;
|
|
625
630
|
const form = this._formFieldRegistry.getAll().find(field => field.type === 'default');
|
|
626
631
|
if (!form) {
|
|
627
632
|
throw new Error('form field registry has no form');
|
|
@@ -638,8 +643,7 @@ class ConditionChecker {
|
|
|
638
643
|
|
|
639
644
|
// only clear the leaf nodes, as groups may both point to the same path
|
|
640
645
|
if (context.isHidden && isClosed) {
|
|
641
|
-
|
|
642
|
-
this._clearObjectValueRecursively(valuePath, newProperties);
|
|
646
|
+
this._clearObjectValueRecursively(getFilterPath(field), newProperties);
|
|
643
647
|
}
|
|
644
648
|
});
|
|
645
649
|
return newProperties;
|
|
@@ -2704,6 +2708,37 @@ function useReadonly(formField, properties = {}) {
|
|
|
2704
2708
|
return readonly || false;
|
|
2705
2709
|
}
|
|
2706
2710
|
|
|
2711
|
+
function usePrevious(value, defaultValue, dependencies) {
|
|
2712
|
+
const ref = useRef(defaultValue);
|
|
2713
|
+
useEffect(() => ref.current = value, dependencies);
|
|
2714
|
+
return ref.current;
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
/**
|
|
2718
|
+
* A custom hook to manage state changes with deep comparison.
|
|
2719
|
+
*
|
|
2720
|
+
* @param {any} value - The current value to manage.
|
|
2721
|
+
* @param {any} defaultValue - The initial default value for the state.
|
|
2722
|
+
* @returns {any} - Returns the current state.
|
|
2723
|
+
*/
|
|
2724
|
+
function useDeepCompareState(value, defaultValue) {
|
|
2725
|
+
const [state, setState] = useState(defaultValue);
|
|
2726
|
+
const previous = usePrevious(value, defaultValue, [value]);
|
|
2727
|
+
const changed = !compare(previous, value);
|
|
2728
|
+
useEffect(() => {
|
|
2729
|
+
if (changed) {
|
|
2730
|
+
setState(value);
|
|
2731
|
+
}
|
|
2732
|
+
}, [changed, value]);
|
|
2733
|
+
return state;
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2736
|
+
// helpers //////////////////////////
|
|
2737
|
+
|
|
2738
|
+
function compare(a, b) {
|
|
2739
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
2740
|
+
}
|
|
2741
|
+
|
|
2707
2742
|
/**
|
|
2708
2743
|
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
2709
2744
|
* Memoised to minimize re-renders
|
|
@@ -2973,11 +3008,8 @@ function useValuesAsync (field) {
|
|
|
2973
3008
|
state: LOAD_STATES.LOADING
|
|
2974
3009
|
});
|
|
2975
3010
|
const initialData = useService('form')._getState().initialData;
|
|
2976
|
-
const
|
|
2977
|
-
|
|
2978
|
-
return useExpressionEvaluation(valuesExpression);
|
|
2979
|
-
}
|
|
2980
|
-
}, [valuesExpression]);
|
|
3011
|
+
const expressionEvaluation = useExpressionEvaluation(valuesExpression);
|
|
3012
|
+
const evaluatedValues = useDeepCompareState(expressionEvaluation || [], []);
|
|
2981
3013
|
useEffect(() => {
|
|
2982
3014
|
let values = [];
|
|
2983
3015
|
|
|
@@ -2993,8 +3025,10 @@ function useValuesAsync (field) {
|
|
|
2993
3025
|
values = Array.isArray(staticValues) ? staticValues : [];
|
|
2994
3026
|
|
|
2995
3027
|
// expression
|
|
2996
|
-
} else if (
|
|
2997
|
-
|
|
3028
|
+
} else if (valuesExpression) {
|
|
3029
|
+
if (evaluatedValues && Array.isArray(evaluatedValues)) {
|
|
3030
|
+
values = evaluatedValues;
|
|
3031
|
+
}
|
|
2998
3032
|
} else {
|
|
2999
3033
|
setValuesGetter(buildErrorState('No values source defined in the form definition'));
|
|
3000
3034
|
return;
|
|
@@ -3003,7 +3037,7 @@ function useValuesAsync (field) {
|
|
|
3003
3037
|
// normalize data to support primitives and partially defined objects
|
|
3004
3038
|
values = normalizeValuesData(values);
|
|
3005
3039
|
setValuesGetter(buildLoadedState(values));
|
|
3006
|
-
}, [valuesKey, staticValues, initialData]);
|
|
3040
|
+
}, [valuesKey, staticValues, initialData, valuesExpression, evaluatedValues]);
|
|
3007
3041
|
return valuesGetter;
|
|
3008
3042
|
}
|
|
3009
3043
|
const buildErrorState = error => ({
|
|
@@ -3022,7 +3056,6 @@ const ENTER_KEYDOWN_EVENT = new KeyboardEvent('keydown', {
|
|
|
3022
3056
|
key: 'Enter',
|
|
3023
3057
|
charCode: 13,
|
|
3024
3058
|
keyCode: 13,
|
|
3025
|
-
view: window,
|
|
3026
3059
|
bubbles: true
|
|
3027
3060
|
});
|
|
3028
3061
|
function focusRelevantFlatpickerDay(flatpickrInstance) {
|
|
@@ -3788,7 +3821,8 @@ function DropdownList(props) {
|
|
|
3788
3821
|
useEffect(() => {
|
|
3789
3822
|
const individualEntries = dropdownContainer.current.children;
|
|
3790
3823
|
if (individualEntries.length && !mouseControl) {
|
|
3791
|
-
individualEntries[focusedValueIndex]
|
|
3824
|
+
const focusedEntry = individualEntries[focusedValueIndex];
|
|
3825
|
+
focusedEntry && focusedEntry.scrollIntoView({
|
|
3792
3826
|
block: 'nearest',
|
|
3793
3827
|
inline: 'nearest'
|
|
3794
3828
|
});
|
|
@@ -6351,10 +6385,9 @@ class Form {
|
|
|
6351
6385
|
}
|
|
6352
6386
|
const data = this._getSubmitData();
|
|
6353
6387
|
const errors = this.validate();
|
|
6354
|
-
const filteredErrors = this._applyConditions(errors, data);
|
|
6355
6388
|
const result = {
|
|
6356
6389
|
data,
|
|
6357
|
-
errors
|
|
6390
|
+
errors
|
|
6358
6391
|
};
|
|
6359
6392
|
this._emit('submit', result);
|
|
6360
6393
|
return result;
|
|
@@ -6377,6 +6410,7 @@ class Form {
|
|
|
6377
6410
|
const {
|
|
6378
6411
|
data
|
|
6379
6412
|
} = this._getState();
|
|
6413
|
+
const getErrorPath = field => [field.id];
|
|
6380
6414
|
const errors = formFieldRegistry.getAll().reduce((errors, field) => {
|
|
6381
6415
|
const {
|
|
6382
6416
|
disabled
|
|
@@ -6386,12 +6420,15 @@ class Form {
|
|
|
6386
6420
|
}
|
|
6387
6421
|
const value = get(data, pathRegistry.getValuePath(field));
|
|
6388
6422
|
const fieldErrors = validator.validateField(field, value);
|
|
6389
|
-
return set(errors,
|
|
6423
|
+
return set(errors, getErrorPath(field), fieldErrors.length ? fieldErrors : undefined);
|
|
6390
6424
|
}, /** @type {Errors} */{});
|
|
6425
|
+
const filteredErrors = this._applyConditions(errors, data, {
|
|
6426
|
+
getFilterPath: getErrorPath
|
|
6427
|
+
});
|
|
6391
6428
|
this._setState({
|
|
6392
|
-
errors
|
|
6429
|
+
errors: filteredErrors
|
|
6393
6430
|
});
|
|
6394
|
-
return
|
|
6431
|
+
return filteredErrors;
|
|
6395
6432
|
}
|
|
6396
6433
|
|
|
6397
6434
|
/**
|
|
@@ -6570,9 +6607,9 @@ class Form {
|
|
|
6570
6607
|
/**
|
|
6571
6608
|
* @internal
|
|
6572
6609
|
*/
|
|
6573
|
-
_applyConditions(toFilter, data) {
|
|
6610
|
+
_applyConditions(toFilter, data, options = {}) {
|
|
6574
6611
|
const conditionChecker = this.get('conditionChecker');
|
|
6575
|
-
return conditionChecker.applyConditions(toFilter, data);
|
|
6612
|
+
return conditionChecker.applyConditions(toFilter, data, options);
|
|
6576
6613
|
}
|
|
6577
6614
|
|
|
6578
6615
|
/**
|
|
@@ -6638,5 +6675,5 @@ function createForm(options) {
|
|
|
6638
6675
|
});
|
|
6639
6676
|
}
|
|
6640
6677
|
|
|
6641
|
-
export { Button, Checkbox, Checklist, ConditionChecker, DATETIME_SUBTYPES, DATETIME_SUBTYPES_LABELS, DATETIME_SUBTYPE_PATH, DATE_DISALLOW_PAST_PATH, DATE_LABEL_PATH, Datetime, FormComponent$1 as Default, ExpressionLanguageModule, FeelExpressionLanguage, FeelersTemplating, FieldFactory, Form, FormComponent, FormContext$1 as FormContext, FormFieldRegistry, FormFields, FormLayouter, FormRenderContext$1 as FormRenderContext, Group, Image, Importer, MINUTES_IN_DAY, MarkdownModule, MarkdownRenderer, Numberfield, PathRegistry, Radio, Select, Spacer, 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, ViewerCommands, ViewerCommandsModule, clone, createForm, createFormContainer, createInjector, formFields, generateIdForType, generateIndexForType, getSchemaVariables, getValuesSource, iconsByType, isRequired, pathParse, pathsEqual, runRecursively, schemaVersion };
|
|
6678
|
+
export { Button, Checkbox, Checklist, ConditionChecker, DATETIME_SUBTYPES, DATETIME_SUBTYPES_LABELS, DATETIME_SUBTYPE_PATH, DATE_DISALLOW_PAST_PATH, DATE_LABEL_PATH, Datetime, FormComponent$1 as Default, ExpressionLanguageModule, FeelExpressionLanguage, FeelersTemplating, FieldFactory, Form, FormComponent, FormContext$1 as FormContext, FormField, FormFieldRegistry, FormFields, FormLayouter, FormRenderContext$1 as FormRenderContext, Group, Image, Importer, MINUTES_IN_DAY, MarkdownModule, MarkdownRenderer, Numberfield, PathRegistry, Radio, Select, Spacer, 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, ViewerCommands, ViewerCommandsModule, clone, createForm, createFormContainer, createInjector, formFields, generateIdForType, generateIndexForType, getSchemaVariables, getValuesSource, iconsByType, isRequired, pathParse, pathsEqual, runRecursively, schemaVersion };
|
|
6642
6679
|
//# sourceMappingURL=index.es.js.map
|