@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
|
@@ -458,13 +458,20 @@
|
|
|
458
458
|
min-height: var(--form-field-height);
|
|
459
459
|
}
|
|
460
460
|
|
|
461
|
-
|
|
462
461
|
.fjs-container .fjs-datepicker,
|
|
463
|
-
.fjs-container .fjs-timepicker
|
|
464
|
-
.fjs-container .fjs-datetime-subsection {
|
|
462
|
+
.fjs-container .fjs-timepicker {
|
|
465
463
|
width: 100%;
|
|
466
464
|
}
|
|
467
465
|
|
|
466
|
+
.fjs-container .fjs-datetime-subsection {
|
|
467
|
+
min-width: 0;
|
|
468
|
+
flex: 1;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
.fjs-container .fjs-datetime-separator {
|
|
472
|
+
width: 10px;
|
|
473
|
+
}
|
|
474
|
+
|
|
468
475
|
.fjs-container .fjs-timepicker-anchor {
|
|
469
476
|
height: 100%;
|
|
470
477
|
display: flex;
|
|
@@ -474,10 +481,6 @@
|
|
|
474
481
|
color: var(--color-icon-base);
|
|
475
482
|
}
|
|
476
483
|
|
|
477
|
-
.fjs-container .fjs-datetime-separator {
|
|
478
|
-
width: 10px;
|
|
479
|
-
}
|
|
480
|
-
|
|
481
484
|
.fjs-container .fjs-input-group {
|
|
482
485
|
display: flex;
|
|
483
486
|
width: 100%;
|
|
@@ -547,11 +550,6 @@
|
|
|
547
550
|
border-radius: 3px;
|
|
548
551
|
}
|
|
549
552
|
|
|
550
|
-
.fjs-container .fjs-vertical-group {
|
|
551
|
-
display: flex;
|
|
552
|
-
width: 100%;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
553
|
.fjs-container .flatpickr-wrapper {
|
|
556
554
|
width: 100%;
|
|
557
555
|
height: 100%;
|
|
@@ -599,6 +597,10 @@
|
|
|
599
597
|
color: var(--cds-text-inverse, var(--color-text));
|
|
600
598
|
}
|
|
601
599
|
|
|
600
|
+
.fjs-container .fjs-form-field-number.fjs-readonly .fjs-number-arrow-container {
|
|
601
|
+
display: none;
|
|
602
|
+
}
|
|
603
|
+
|
|
602
604
|
.fjs-container .fjs-radio {
|
|
603
605
|
display: flex;
|
|
604
606
|
flex-direction: column;
|
package/dist/assets/form-js.css
CHANGED
|
@@ -443,11 +443,19 @@
|
|
|
443
443
|
}
|
|
444
444
|
|
|
445
445
|
.fjs-container .fjs-datepicker,
|
|
446
|
-
.fjs-container .fjs-timepicker
|
|
447
|
-
.fjs-container .fjs-datetime-subsection {
|
|
446
|
+
.fjs-container .fjs-timepicker {
|
|
448
447
|
width: 100%;
|
|
449
448
|
}
|
|
450
449
|
|
|
450
|
+
.fjs-container .fjs-datetime-subsection {
|
|
451
|
+
min-width: 0;
|
|
452
|
+
flex: 1;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.fjs-container .fjs-datetime-separator {
|
|
456
|
+
width: 10px;
|
|
457
|
+
}
|
|
458
|
+
|
|
451
459
|
.fjs-container .fjs-timepicker-anchor {
|
|
452
460
|
height: 100%;
|
|
453
461
|
display: flex;
|
|
@@ -457,10 +465,6 @@
|
|
|
457
465
|
color: var(--color-icon-base);
|
|
458
466
|
}
|
|
459
467
|
|
|
460
|
-
.fjs-container .fjs-datetime-separator {
|
|
461
|
-
width: 10px;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
468
|
.fjs-container .fjs-input-group {
|
|
465
469
|
display: flex;
|
|
466
470
|
width: 100%;
|
|
@@ -529,11 +533,6 @@
|
|
|
529
533
|
border-radius: 3px;
|
|
530
534
|
}
|
|
531
535
|
|
|
532
|
-
.fjs-container .fjs-vertical-group {
|
|
533
|
-
display: flex;
|
|
534
|
-
width: 100%;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
536
|
.fjs-container .flatpickr-wrapper {
|
|
538
537
|
width: 100%;
|
|
539
538
|
height: 100%;
|
|
@@ -581,6 +580,10 @@
|
|
|
581
580
|
color: var(--cds-text-inverse, var(--color-text));
|
|
582
581
|
}
|
|
583
582
|
|
|
583
|
+
.fjs-container .fjs-form-field-number.fjs-readonly .fjs-number-arrow-container {
|
|
584
|
+
display: none;
|
|
585
|
+
}
|
|
586
|
+
|
|
584
587
|
.fjs-container .fjs-radio {
|
|
585
588
|
display: flex;
|
|
586
589
|
flex-direction: column;
|
package/dist/index.cjs
CHANGED
|
@@ -639,9 +639,14 @@ class ConditionChecker {
|
|
|
639
639
|
*
|
|
640
640
|
* @param {Object<string, any>} properties
|
|
641
641
|
* @param {Object<string, any>} data
|
|
642
|
+
* @param {Object} [options]
|
|
643
|
+
* @param {Function} [options.getFilterPath]
|
|
642
644
|
*/
|
|
643
|
-
applyConditions(properties, data = {}) {
|
|
645
|
+
applyConditions(properties, data = {}, options = {}) {
|
|
644
646
|
const newProperties = clone(properties);
|
|
647
|
+
const {
|
|
648
|
+
getFilterPath = field => this._pathRegistry.getValuePath(field)
|
|
649
|
+
} = options;
|
|
645
650
|
const form = this._formFieldRegistry.getAll().find(field => field.type === 'default');
|
|
646
651
|
if (!form) {
|
|
647
652
|
throw new Error('form field registry has no form');
|
|
@@ -658,8 +663,7 @@ class ConditionChecker {
|
|
|
658
663
|
|
|
659
664
|
// only clear the leaf nodes, as groups may both point to the same path
|
|
660
665
|
if (context.isHidden && isClosed) {
|
|
661
|
-
|
|
662
|
-
this._clearObjectValueRecursively(valuePath, newProperties);
|
|
666
|
+
this._clearObjectValueRecursively(getFilterPath(field), newProperties);
|
|
663
667
|
}
|
|
664
668
|
});
|
|
665
669
|
return newProperties;
|
|
@@ -2724,6 +2728,37 @@ function useReadonly(formField, properties = {}) {
|
|
|
2724
2728
|
return readonly || false;
|
|
2725
2729
|
}
|
|
2726
2730
|
|
|
2731
|
+
function usePrevious(value, defaultValue, dependencies) {
|
|
2732
|
+
const ref = hooks.useRef(defaultValue);
|
|
2733
|
+
hooks.useEffect(() => ref.current = value, dependencies);
|
|
2734
|
+
return ref.current;
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
/**
|
|
2738
|
+
* A custom hook to manage state changes with deep comparison.
|
|
2739
|
+
*
|
|
2740
|
+
* @param {any} value - The current value to manage.
|
|
2741
|
+
* @param {any} defaultValue - The initial default value for the state.
|
|
2742
|
+
* @returns {any} - Returns the current state.
|
|
2743
|
+
*/
|
|
2744
|
+
function useDeepCompareState(value, defaultValue) {
|
|
2745
|
+
const [state, setState] = hooks.useState(defaultValue);
|
|
2746
|
+
const previous = usePrevious(value, defaultValue, [value]);
|
|
2747
|
+
const changed = !compare(previous, value);
|
|
2748
|
+
hooks.useEffect(() => {
|
|
2749
|
+
if (changed) {
|
|
2750
|
+
setState(value);
|
|
2751
|
+
}
|
|
2752
|
+
}, [changed, value]);
|
|
2753
|
+
return state;
|
|
2754
|
+
}
|
|
2755
|
+
|
|
2756
|
+
// helpers //////////////////////////
|
|
2757
|
+
|
|
2758
|
+
function compare(a, b) {
|
|
2759
|
+
return JSON.stringify(a) === JSON.stringify(b);
|
|
2760
|
+
}
|
|
2761
|
+
|
|
2727
2762
|
/**
|
|
2728
2763
|
* Template a string reactively based on form data. If the string is not a template, it is returned as is.
|
|
2729
2764
|
* Memoised to minimize re-renders
|
|
@@ -2993,11 +3028,8 @@ function useValuesAsync (field) {
|
|
|
2993
3028
|
state: LOAD_STATES.LOADING
|
|
2994
3029
|
});
|
|
2995
3030
|
const initialData = useService('form')._getState().initialData;
|
|
2996
|
-
const
|
|
2997
|
-
|
|
2998
|
-
return useExpressionEvaluation(valuesExpression);
|
|
2999
|
-
}
|
|
3000
|
-
}, [valuesExpression]);
|
|
3031
|
+
const expressionEvaluation = useExpressionEvaluation(valuesExpression);
|
|
3032
|
+
const evaluatedValues = useDeepCompareState(expressionEvaluation || [], []);
|
|
3001
3033
|
hooks.useEffect(() => {
|
|
3002
3034
|
let values = [];
|
|
3003
3035
|
|
|
@@ -3013,8 +3045,10 @@ function useValuesAsync (field) {
|
|
|
3013
3045
|
values = Array.isArray(staticValues) ? staticValues : [];
|
|
3014
3046
|
|
|
3015
3047
|
// expression
|
|
3016
|
-
} else if (
|
|
3017
|
-
|
|
3048
|
+
} else if (valuesExpression) {
|
|
3049
|
+
if (evaluatedValues && Array.isArray(evaluatedValues)) {
|
|
3050
|
+
values = evaluatedValues;
|
|
3051
|
+
}
|
|
3018
3052
|
} else {
|
|
3019
3053
|
setValuesGetter(buildErrorState('No values source defined in the form definition'));
|
|
3020
3054
|
return;
|
|
@@ -3023,7 +3057,7 @@ function useValuesAsync (field) {
|
|
|
3023
3057
|
// normalize data to support primitives and partially defined objects
|
|
3024
3058
|
values = normalizeValuesData(values);
|
|
3025
3059
|
setValuesGetter(buildLoadedState(values));
|
|
3026
|
-
}, [valuesKey, staticValues, initialData]);
|
|
3060
|
+
}, [valuesKey, staticValues, initialData, valuesExpression, evaluatedValues]);
|
|
3027
3061
|
return valuesGetter;
|
|
3028
3062
|
}
|
|
3029
3063
|
const buildErrorState = error => ({
|
|
@@ -3042,7 +3076,6 @@ const ENTER_KEYDOWN_EVENT = new KeyboardEvent('keydown', {
|
|
|
3042
3076
|
key: 'Enter',
|
|
3043
3077
|
charCode: 13,
|
|
3044
3078
|
keyCode: 13,
|
|
3045
|
-
view: window,
|
|
3046
3079
|
bubbles: true
|
|
3047
3080
|
});
|
|
3048
3081
|
function focusRelevantFlatpickerDay(flatpickrInstance) {
|
|
@@ -3808,7 +3841,8 @@ function DropdownList(props) {
|
|
|
3808
3841
|
hooks.useEffect(() => {
|
|
3809
3842
|
const individualEntries = dropdownContainer.current.children;
|
|
3810
3843
|
if (individualEntries.length && !mouseControl) {
|
|
3811
|
-
individualEntries[focusedValueIndex]
|
|
3844
|
+
const focusedEntry = individualEntries[focusedValueIndex];
|
|
3845
|
+
focusedEntry && focusedEntry.scrollIntoView({
|
|
3812
3846
|
block: 'nearest',
|
|
3813
3847
|
inline: 'nearest'
|
|
3814
3848
|
});
|
|
@@ -6371,10 +6405,9 @@ class Form {
|
|
|
6371
6405
|
}
|
|
6372
6406
|
const data = this._getSubmitData();
|
|
6373
6407
|
const errors = this.validate();
|
|
6374
|
-
const filteredErrors = this._applyConditions(errors, data);
|
|
6375
6408
|
const result = {
|
|
6376
6409
|
data,
|
|
6377
|
-
errors
|
|
6410
|
+
errors
|
|
6378
6411
|
};
|
|
6379
6412
|
this._emit('submit', result);
|
|
6380
6413
|
return result;
|
|
@@ -6397,6 +6430,7 @@ class Form {
|
|
|
6397
6430
|
const {
|
|
6398
6431
|
data
|
|
6399
6432
|
} = this._getState();
|
|
6433
|
+
const getErrorPath = field => [field.id];
|
|
6400
6434
|
const errors = formFieldRegistry.getAll().reduce((errors, field) => {
|
|
6401
6435
|
const {
|
|
6402
6436
|
disabled
|
|
@@ -6406,12 +6440,15 @@ class Form {
|
|
|
6406
6440
|
}
|
|
6407
6441
|
const value = minDash.get(data, pathRegistry.getValuePath(field));
|
|
6408
6442
|
const fieldErrors = validator.validateField(field, value);
|
|
6409
|
-
return minDash.set(errors,
|
|
6443
|
+
return minDash.set(errors, getErrorPath(field), fieldErrors.length ? fieldErrors : undefined);
|
|
6410
6444
|
}, /** @type {Errors} */{});
|
|
6445
|
+
const filteredErrors = this._applyConditions(errors, data, {
|
|
6446
|
+
getFilterPath: getErrorPath
|
|
6447
|
+
});
|
|
6411
6448
|
this._setState({
|
|
6412
|
-
errors
|
|
6449
|
+
errors: filteredErrors
|
|
6413
6450
|
});
|
|
6414
|
-
return
|
|
6451
|
+
return filteredErrors;
|
|
6415
6452
|
}
|
|
6416
6453
|
|
|
6417
6454
|
/**
|
|
@@ -6590,9 +6627,9 @@ class Form {
|
|
|
6590
6627
|
/**
|
|
6591
6628
|
* @internal
|
|
6592
6629
|
*/
|
|
6593
|
-
_applyConditions(toFilter, data) {
|
|
6630
|
+
_applyConditions(toFilter, data, options = {}) {
|
|
6594
6631
|
const conditionChecker = this.get('conditionChecker');
|
|
6595
|
-
return conditionChecker.applyConditions(toFilter, data);
|
|
6632
|
+
return conditionChecker.applyConditions(toFilter, data, options);
|
|
6596
6633
|
}
|
|
6597
6634
|
|
|
6598
6635
|
/**
|
|
@@ -6676,6 +6713,7 @@ exports.FieldFactory = FieldFactory;
|
|
|
6676
6713
|
exports.Form = Form;
|
|
6677
6714
|
exports.FormComponent = FormComponent;
|
|
6678
6715
|
exports.FormContext = FormContext$1;
|
|
6716
|
+
exports.FormField = FormField;
|
|
6679
6717
|
exports.FormFieldRegistry = FormFieldRegistry;
|
|
6680
6718
|
exports.FormFields = FormFields;
|
|
6681
6719
|
exports.FormLayouter = FormLayouter;
|