x-ui-design 0.6.49 → 0.6.51
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/esm/types/hooks/useWatchError.d.ts +2 -0
- package/dist/esm/types/types/form.d.ts +1 -0
- package/dist/index.esm.js +47 -32
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +46 -31
- package/dist/index.js.map +1 -1
- package/lib/components/Form/Form.tsx +2 -6
- package/lib/components/Form/Item/Item.tsx +6 -6
- package/lib/hooks/useForm.ts +38 -7
- package/lib/hooks/useWatchError.ts +20 -0
- package/lib/types/form.ts +1 -0
- package/package.json +1 -1
- package/src/app/page.tsx +5 -16
|
@@ -102,6 +102,7 @@ export interface FormInstance {
|
|
|
102
102
|
subscribeToField: (name: string, callback: (value: RuleTypes) => void) => () => void;
|
|
103
103
|
subscribeToForm: (callback: (values: Record<string, RuleTypes>) => void) => () => void;
|
|
104
104
|
subscribeToFields: (names: string[], callback: (values: Record<string, RuleTypes>) => void) => () => void;
|
|
105
|
+
subscribeToError?: (name: string, callback: (errors?: string[]) => void) => void;
|
|
105
106
|
isFieldValidating: (name: string) => boolean;
|
|
106
107
|
onFieldsChange?: (changedFields: FieldData[]) => void;
|
|
107
108
|
onValuesChange?: (changedValues: Record<string, RuleTypes>, allValues: Record<string, RuleTypes>) => void;
|
package/dist/index.esm.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import require$$1 from 'react/jsx-runtime';
|
|
2
|
-
import React, { useRef, useState, Children, isValidElement, Fragment, Suspense, useContext, useMemo,
|
|
2
|
+
import React, { useRef, useState, Children, isValidElement, Fragment, Suspense, useEffect, useContext, useMemo, createContext, useImperativeHandle, memo, useCallback, useLayoutEffect } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
4
|
import ReactDOMServer from 'react-dom/server';
|
|
5
5
|
|
|
@@ -620,7 +620,8 @@ const useForm = (initialValues = {}, onFieldsChange, onValuesChange, scrollToFir
|
|
|
620
620
|
});
|
|
621
621
|
const fieldInstancesRef = useRef({});
|
|
622
622
|
const [isReseting, setIsReseting] = useState(false);
|
|
623
|
-
const
|
|
623
|
+
const errorsRef = useRef({});
|
|
624
|
+
const errorSubscribers = useRef({});
|
|
624
625
|
const fieldSubscribers = useRef({});
|
|
625
626
|
const formSubscribers = useRef([]);
|
|
626
627
|
function getFormFields() {
|
|
@@ -644,13 +645,13 @@ const useForm = (initialValues = {}, onFieldsChange, onValuesChange, scrollToFir
|
|
|
644
645
|
}, {});
|
|
645
646
|
}
|
|
646
647
|
function getFieldError(name) {
|
|
647
|
-
return
|
|
648
|
+
return errorsRef.current[name] || [];
|
|
648
649
|
}
|
|
649
650
|
function getFieldWarning(name) {
|
|
650
651
|
return warningsRef.current[name] || [];
|
|
651
652
|
}
|
|
652
653
|
function getFieldsError() {
|
|
653
|
-
return Object.entries(
|
|
654
|
+
return Object.entries(errorsRef.current).map(([name, err]) => ({
|
|
654
655
|
name,
|
|
655
656
|
errors: err
|
|
656
657
|
}));
|
|
@@ -664,9 +665,8 @@ const useForm = (initialValues = {}, onFieldsChange, onValuesChange, scrollToFir
|
|
|
664
665
|
touchedFieldsRef.current.add(name);
|
|
665
666
|
}
|
|
666
667
|
if (reset === null) {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
});
|
|
668
|
+
errorsRef.current[name] = [];
|
|
669
|
+
notifyErrorSubscribers(name);
|
|
670
670
|
return;
|
|
671
671
|
}
|
|
672
672
|
if (!errors?.length) {
|
|
@@ -687,9 +687,7 @@ const useForm = (initialValues = {}, onFieldsChange, onValuesChange, scrollToFir
|
|
|
687
687
|
}
|
|
688
688
|
});
|
|
689
689
|
} else {
|
|
690
|
-
|
|
691
|
-
[name]: errors
|
|
692
|
-
});
|
|
690
|
+
errorsRef.current[name] = errors;
|
|
693
691
|
}
|
|
694
692
|
}
|
|
695
693
|
function setFieldsValue(values, reset) {
|
|
@@ -765,11 +763,9 @@ const useForm = (initialValues = {}, onFieldsChange, onValuesChange, scrollToFir
|
|
|
765
763
|
}
|
|
766
764
|
}
|
|
767
765
|
}));
|
|
768
|
-
|
|
769
|
-
...prev,
|
|
770
|
-
[name]: fieldErrors
|
|
771
|
-
}));
|
|
766
|
+
errorsRef.current[name] = fieldErrors;
|
|
772
767
|
warningsRef.current[name] = fieldWarnings;
|
|
768
|
+
notifyErrorSubscribers(name);
|
|
773
769
|
return fieldErrors.length === 0;
|
|
774
770
|
}
|
|
775
771
|
async function validateFields(nameList) {
|
|
@@ -790,6 +786,7 @@ const useForm = (initialValues = {}, onFieldsChange, onValuesChange, scrollToFir
|
|
|
790
786
|
});
|
|
791
787
|
}
|
|
792
788
|
}
|
|
789
|
+
fieldsToValidate.forEach(name => notifyErrorSubscribers(name));
|
|
793
790
|
return results.every(valid => valid);
|
|
794
791
|
}
|
|
795
792
|
function resetFields(nameList, showError = true) {
|
|
@@ -799,10 +796,8 @@ const useForm = (initialValues = {}, onFieldsChange, onValuesChange, scrollToFir
|
|
|
799
796
|
formData[name] = initialValues[name];
|
|
800
797
|
touchedFieldsRef.current.delete(name);
|
|
801
798
|
delete warningsRef.current[name];
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
[name]: []
|
|
805
|
-
}));
|
|
799
|
+
errorsRef.current[name] = [];
|
|
800
|
+
notifyErrorSubscribers(name);
|
|
806
801
|
setFieldValue(name, initialValues[name], undefined, showError);
|
|
807
802
|
});
|
|
808
803
|
} else {
|
|
@@ -848,6 +843,19 @@ const useForm = (initialValues = {}, onFieldsChange, onValuesChange, scrollToFir
|
|
|
848
843
|
fieldCallbacks.forEach(unsubscribe => unsubscribe());
|
|
849
844
|
};
|
|
850
845
|
}
|
|
846
|
+
function subscribeToError(name, callback) {
|
|
847
|
+
if (!errorSubscribers.current[name]) {
|
|
848
|
+
errorSubscribers.current[name] = [];
|
|
849
|
+
}
|
|
850
|
+
errorSubscribers.current[name].push(callback);
|
|
851
|
+
return () => {
|
|
852
|
+
errorSubscribers.current[name] = errorSubscribers.current[name].filter(cb => cb !== callback);
|
|
853
|
+
};
|
|
854
|
+
}
|
|
855
|
+
function notifyErrorSubscribers(name) {
|
|
856
|
+
const errors = getFieldError(name);
|
|
857
|
+
errorSubscribers.current[name]?.forEach(cb => cb(errors));
|
|
858
|
+
}
|
|
851
859
|
function setScrollToFirstError(value) {
|
|
852
860
|
_scrollToFirstError.current = value;
|
|
853
861
|
}
|
|
@@ -894,6 +902,7 @@ const useForm = (initialValues = {}, onFieldsChange, onValuesChange, scrollToFir
|
|
|
894
902
|
setFieldInstance,
|
|
895
903
|
subscribeToFields,
|
|
896
904
|
setScrollToFirstError,
|
|
905
|
+
subscribeToError,
|
|
897
906
|
scrollToFirstError,
|
|
898
907
|
isReseting,
|
|
899
908
|
setOnFinish,
|
|
@@ -983,6 +992,20 @@ function flattenChildren(children) {
|
|
|
983
992
|
return result;
|
|
984
993
|
}
|
|
985
994
|
|
|
995
|
+
function useWatchError(form, name) {
|
|
996
|
+
const [errors, setErrors] = useState(form.getFieldError(name));
|
|
997
|
+
useEffect(() => {
|
|
998
|
+
// Subscribe directly to error changes
|
|
999
|
+
const unsubscribe = form.subscribeToError?.(name, newErrors => {
|
|
1000
|
+
setErrors(newErrors);
|
|
1001
|
+
});
|
|
1002
|
+
// Initialize on mount
|
|
1003
|
+
setErrors(form.getFieldError(name));
|
|
1004
|
+
return unsubscribe;
|
|
1005
|
+
}, [form, name]);
|
|
1006
|
+
return errors;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
986
1009
|
var css_248z$l = ".xUi-form-item{display:flex;position:relative}.xUi-form-item.noStyle{display:inline-flex;margin-bottom:0}.xUi-form-item-label{align-items:center;color:var(--xui-text-color);display:flex;font-size:var(--xui-font-size-md);font-weight:500;line-height:20px;margin-bottom:4px}.xUi-form-item-error{color:var(--xui-error-color);display:block;font-size:var(--xui-font-size-xs);line-height:16px;margin-bottom:8px;margin-top:4px;min-height:16px;position:relative;right:0;text-align:end;user-select:none}.xUi-form-item-required{color:var(--xui-error-color);display:inline-block;font-size:var(--xui-font-size-md);line-height:1;margin-left:4px;margin-right:4px}.xUi-form-item.horizontal{align-items:center;flex-direction:row;gap:4px}.xUi-form-item.vertical{align-self:flex-start;flex-direction:column}.xUi-form-item .xUi-input-container{width:-webkit-fill-available}";
|
|
987
1010
|
styleInject(css_248z$l);
|
|
988
1011
|
|
|
@@ -1009,10 +1032,10 @@ const FormItem$1 = ({
|
|
|
1009
1032
|
if (!formContext) {
|
|
1010
1033
|
throw new Error('FormItem must be used within a Form');
|
|
1011
1034
|
}
|
|
1035
|
+
const errors = useWatchError(formContext, name)?.[0];
|
|
1012
1036
|
const {
|
|
1013
1037
|
isReseting,
|
|
1014
1038
|
registerField,
|
|
1015
|
-
getFieldError,
|
|
1016
1039
|
getFieldValue,
|
|
1017
1040
|
setFieldValue,
|
|
1018
1041
|
getFieldInstance,
|
|
@@ -1046,7 +1069,6 @@ const FormItem$1 = ({
|
|
|
1046
1069
|
}
|
|
1047
1070
|
}, [dependencies, name]);
|
|
1048
1071
|
const isRequired = useMemo(() => rules.some(rule => rule.required), [rules]);
|
|
1049
|
-
const errorMessage = getFieldError(name)?.[0];
|
|
1050
1072
|
return /*#__PURE__*/React.createElement("div", {
|
|
1051
1073
|
style: style,
|
|
1052
1074
|
"data-instance": name,
|
|
@@ -1079,7 +1101,7 @@ const FormItem$1 = ({
|
|
|
1079
1101
|
name: name,
|
|
1080
1102
|
child: child,
|
|
1081
1103
|
value: value,
|
|
1082
|
-
error: !!
|
|
1104
|
+
error: !!errors,
|
|
1083
1105
|
fieldValue: fieldValue,
|
|
1084
1106
|
setFieldValue: setFieldValue,
|
|
1085
1107
|
feedbackIcons: feedbackIcons,
|
|
@@ -1095,7 +1117,7 @@ const FormItem$1 = ({
|
|
|
1095
1117
|
}, extra || '') : null, !props.noStyle && /*#__PURE__*/React.createElement("span", {
|
|
1096
1118
|
ref: errorRef,
|
|
1097
1119
|
className: clsx([`${prefixCls}-error`, {
|
|
1098
|
-
[`${prefixCls}-has-error`]:
|
|
1120
|
+
[`${prefixCls}-has-error`]: errors?.length
|
|
1099
1121
|
}]),
|
|
1100
1122
|
style: {
|
|
1101
1123
|
...(removeErrorMessageHeight ? {
|
|
@@ -1105,7 +1127,7 @@ const FormItem$1 = ({
|
|
|
1105
1127
|
marginBottom: 0
|
|
1106
1128
|
} : {})
|
|
1107
1129
|
}
|
|
1108
|
-
},
|
|
1130
|
+
}, errors || ''));
|
|
1109
1131
|
}
|
|
1110
1132
|
return child;
|
|
1111
1133
|
}));
|
|
@@ -1213,15 +1235,8 @@ const Form$1 = ({
|
|
|
1213
1235
|
const formInstance = useMemo(() => form || internalForm, [form, internalForm]);
|
|
1214
1236
|
const handleSubmit = async e => {
|
|
1215
1237
|
e.preventDefault();
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
} else if (onFinishFailed) {
|
|
1219
|
-
const errorFields = formInstance.getFieldsError().filter(e => e.errors.length);
|
|
1220
|
-
onFinishFailed({
|
|
1221
|
-
values: formInstance.getFieldsValue(),
|
|
1222
|
-
errorFields
|
|
1223
|
-
});
|
|
1224
|
-
}
|
|
1238
|
+
e.stopPropagation();
|
|
1239
|
+
await formInstance.submit();
|
|
1225
1240
|
};
|
|
1226
1241
|
const childrenList = useMemo(() => flattenChildren(children), [children]);
|
|
1227
1242
|
useEffect(() => {
|