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.
@@ -0,0 +1,2 @@
1
+ import type { FormInstance } from '../types/form';
2
+ export declare function useWatchError(form: FormInstance, name: string): string[] | undefined;
@@ -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, useEffect, createContext, useImperativeHandle, memo, useCallback, useLayoutEffect } from 'react';
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 [errors, setErrors] = useState({});
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 errors[name] || [];
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(errors).map(([name, err]) => ({
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
- setErrors({
668
- [name]: []
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
- setErrors({
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
- setErrors(prev => ({
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
- setErrors(prev => ({
803
- ...prev,
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: !!errorMessage,
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`]: errorMessage?.length
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
- }, errorMessage || ''));
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
- if (await formInstance.validateFields()) {
1217
- onFinish?.(formInstance.getFieldsValue());
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(() => {