@hi-ui/form 4.3.3 → 4.3.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @hi-ui/form
2
2
 
3
+ ## 4.3.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#3476](https://github.com/XiaoMi/hiui/pull/3476) [`b12cd78`](https://github.com/XiaoMi/hiui/commit/b12cd78a3e701a0efaacc6f14705a0afcb0fae08) Thanks [@zyprepare](https://github.com/zyprepare)! - fix(form): 修复当 initialValues 为 {} 时无法正常重置表单问题 (#3475)
8
+
3
9
  ## 4.3.3
4
10
 
5
11
  ### Patch Changes
@@ -365,7 +365,7 @@ var useForm = function useForm(_a) {
365
365
  var onResetLatestRef = useLatest.useLatestRef(onReset);
366
366
  var resetForm = React.useCallback(function (nextState) {
367
367
  return tslib.__awaiter(void 0, void 0, void 0, /*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee2() {
368
- var values, errors, touched, submitting, validating, dispatchFn;
368
+ var values, errors, touched, registeredKeys, formValues, submitting, validating, dispatchFn;
369
369
  return _regeneratorRuntime__default["default"].wrap(function _callee2$(_context2) {
370
370
  while (1) {
371
371
  switch (_context2.prev = _context2.next) {
@@ -373,6 +373,32 @@ var useForm = function useForm(_a) {
373
373
  values = nextState && nextState.values ? nextState.values : initialValuesRef.current;
374
374
  errors = nextState && nextState.errors ? nextState.errors : initialErrorsRef.current;
375
375
  touched = nextState && nextState.touched ? nextState.touched : initialTouchedRef.current;
376
+ registeredKeys = getRegisteredKeys();
377
+ formValues = formState.values; // 处理缺失的字段:如果 registeredKeys 中的字段在 values 中不存在,
378
+ // 则根据 formValues 中对应字段的类型设置对应的空值
379
+ if (registeredKeys.length > 0) {
380
+ // 确保 values 是一个对象
381
+ if (!values || _typeof(values) !== 'object' || typeAssertion.isArray(values)) {
382
+ values = {};
383
+ } else {
384
+ // 浅拷贝 values 避免修改原始对象
385
+ values = Object.assign({}, values);
386
+ }
387
+ registeredKeys.forEach(function (field) {
388
+ // 检查字段是否存在于 values 中
389
+ var valueInReset = objectUtils.getNested(values, field);
390
+ // 如果字段不存在(undefined),则根据 formValues 中的类型设置空值
391
+ if (valueInReset === undefined) {
392
+ var currentValue = objectUtils.getNested(formValues, field);
393
+ // 如果当前值存在(包括 null),根据其类型设置对应的空值
394
+ if (currentValue !== undefined) {
395
+ var emptyValue = index.getEmptyValueByType(currentValue);
396
+ // setNested 返回新对象,需要重新赋值
397
+ values = objectUtils.setNested(values, field, emptyValue);
398
+ }
399
+ }
400
+ });
401
+ }
376
402
  initialValuesRef.current = values;
377
403
  // @ts-ignore
378
404
  initialErrorsRef.current = errors;
@@ -392,25 +418,25 @@ var useForm = function useForm(_a) {
392
418
  });
393
419
  };
394
420
  if (!onResetLatestRef.current) {
395
- _context2.next = 15;
421
+ _context2.next = 18;
396
422
  break;
397
423
  }
398
- _context2.next = 12;
424
+ _context2.next = 15;
399
425
  return onResetLatestRef.current(formState.values);
400
- case 12:
426
+ case 15:
401
427
  dispatchFn();
402
- _context2.next = 16;
428
+ _context2.next = 19;
403
429
  break;
404
- case 15:
430
+ case 18:
405
431
  dispatchFn();
406
- case 16:
432
+ case 19:
407
433
  case "end":
408
434
  return _context2.stop();
409
435
  }
410
436
  }
411
437
  }, _callee2);
412
438
  }));
413
- }, [onResetLatestRef, formState.values]);
439
+ }, [formState.values, getRegisteredKeys, onResetLatestRef]);
414
440
  /**
415
441
  * 表单提交
416
442
  */
@@ -9,6 +9,7 @@
9
9
  */
10
10
  'use strict';
11
11
 
12
+ var _typeof = require("@babel/runtime/helpers/typeof");
12
13
  Object.defineProperty(exports, '__esModule', {
13
14
  value: true
14
15
  });
@@ -40,6 +41,65 @@ var mergeValues = function mergeValues(source, override) {
40
41
  }
41
42
  return target;
42
43
  };
44
+ /**
45
+ * 根据值的类型返回对应的空值
46
+ */
47
+ var getEmptyValueByType = function getEmptyValueByType(value) {
48
+ // 优先处理特殊对象类型(instanceof 检查)
49
+ if (typeAssertion.isArray(value)) {
50
+ return [];
51
+ }
52
+ if (value instanceof Date) {
53
+ return null;
54
+ }
55
+ if (value instanceof RegExp) {
56
+ return /(?:)/;
57
+ }
58
+ if (value instanceof Map) {
59
+ return new Map();
60
+ }
61
+ if (value instanceof Set) {
62
+ return new Set();
63
+ }
64
+ // 注意:WeakMap 和 WeakSet 无法创建空实例,返回 null
65
+ if (value instanceof WeakMap) {
66
+ return null;
67
+ }
68
+ if (value instanceof WeakSet) {
69
+ return null;
70
+ }
71
+ // 处理基本类型(typeof 检查)
72
+ if (_typeof(value) === 'symbol') {
73
+ return Symbol('');
74
+ }
75
+ if (typeof value === 'bigint') {
76
+ return BigInt(0);
77
+ }
78
+ if (typeof value === 'string') {
79
+ return '';
80
+ }
81
+ if (typeof value === 'number') {
82
+ return null;
83
+ }
84
+ if (typeof value === 'boolean') {
85
+ return false;
86
+ }
87
+ if (typeof value === 'function') {
88
+ // 函数类型重置为 undefined,因为函数不应该作为表单值
89
+ return undefined;
90
+ }
91
+ // 对于 null 值,保持为 null
92
+ if (value === null) {
93
+ return null;
94
+ }
95
+ // 处理普通对象(必须在所有 instanceof 检查之后)
96
+ if (_typeof(value) === 'object') {
97
+ return {};
98
+ }
99
+ // 其他类型(包括 undefined)默认返回 undefined
100
+ return undefined;
101
+ };
102
+ exports.getEmptyValueByType = getEmptyValueByType;
43
103
  exports.isValidField = isValidField;
44
104
  exports.mergeValues = mergeValues;
45
105
  exports.parse = parse;
@@ -10,7 +10,7 @@ import _typeof from "@babel/runtime/helpers/esm/typeof";
10
10
  */
11
11
  import _regeneratorRuntime from '@babel/runtime/regenerator';
12
12
  import { __rest, __awaiter } from 'tslib';
13
- import { stringify, parse, mergeValues, isValidField } from './utils/index.js';
13
+ import { stringify, parse, mergeValues, getEmptyValueByType, isValidField } from './utils/index.js';
14
14
  import React, { useMemo, useRef, useReducer, useCallback } from 'react';
15
15
  import scrollIntoView from 'scroll-into-view-if-needed';
16
16
  import { useLatestRef, useLatestCallback } from '@hi-ui/use-latest';
@@ -352,7 +352,7 @@ var useForm = function useForm(_a) {
352
352
  var onResetLatestRef = useLatestRef(onReset);
353
353
  var resetForm = useCallback(function (nextState) {
354
354
  return __awaiter(void 0, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
355
- var values, errors, touched, submitting, validating, dispatchFn;
355
+ var values, errors, touched, registeredKeys, formValues, submitting, validating, dispatchFn;
356
356
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
357
357
  while (1) {
358
358
  switch (_context2.prev = _context2.next) {
@@ -360,6 +360,32 @@ var useForm = function useForm(_a) {
360
360
  values = nextState && nextState.values ? nextState.values : initialValuesRef.current;
361
361
  errors = nextState && nextState.errors ? nextState.errors : initialErrorsRef.current;
362
362
  touched = nextState && nextState.touched ? nextState.touched : initialTouchedRef.current;
363
+ registeredKeys = getRegisteredKeys();
364
+ formValues = formState.values; // 处理缺失的字段:如果 registeredKeys 中的字段在 values 中不存在,
365
+ // 则根据 formValues 中对应字段的类型设置对应的空值
366
+ if (registeredKeys.length > 0) {
367
+ // 确保 values 是一个对象
368
+ if (!values || _typeof(values) !== 'object' || isArray(values)) {
369
+ values = {};
370
+ } else {
371
+ // 浅拷贝 values 避免修改原始对象
372
+ values = Object.assign({}, values);
373
+ }
374
+ registeredKeys.forEach(function (field) {
375
+ // 检查字段是否存在于 values 中
376
+ var valueInReset = getNested(values, field);
377
+ // 如果字段不存在(undefined),则根据 formValues 中的类型设置空值
378
+ if (valueInReset === undefined) {
379
+ var currentValue = getNested(formValues, field);
380
+ // 如果当前值存在(包括 null),根据其类型设置对应的空值
381
+ if (currentValue !== undefined) {
382
+ var emptyValue = getEmptyValueByType(currentValue);
383
+ // setNested 返回新对象,需要重新赋值
384
+ values = setNested(values, field, emptyValue);
385
+ }
386
+ }
387
+ });
388
+ }
363
389
  initialValuesRef.current = values;
364
390
  // @ts-ignore
365
391
  initialErrorsRef.current = errors;
@@ -379,25 +405,25 @@ var useForm = function useForm(_a) {
379
405
  });
380
406
  };
381
407
  if (!onResetLatestRef.current) {
382
- _context2.next = 15;
408
+ _context2.next = 18;
383
409
  break;
384
410
  }
385
- _context2.next = 12;
411
+ _context2.next = 15;
386
412
  return onResetLatestRef.current(formState.values);
387
- case 12:
413
+ case 15:
388
414
  dispatchFn();
389
- _context2.next = 16;
415
+ _context2.next = 19;
390
416
  break;
391
- case 15:
417
+ case 18:
392
418
  dispatchFn();
393
- case 16:
419
+ case 19:
394
420
  case "end":
395
421
  return _context2.stop();
396
422
  }
397
423
  }
398
424
  }, _callee2);
399
425
  }));
400
- }, [onResetLatestRef, formState.values]);
426
+ }, [formState.values, getRegisteredKeys, onResetLatestRef]);
401
427
  /**
402
428
  * 表单提交
403
429
  */
@@ -1,3 +1,4 @@
1
+ import _typeof from "@babel/runtime/helpers/esm/typeof";
1
2
  /** @LICENSE
2
3
  * @hi-ui/form
3
4
  * https://github.com/XiaoMi/hiui/tree/master/packages/ui/form#readme
@@ -35,4 +36,62 @@ var mergeValues = function mergeValues(source, override) {
35
36
  }
36
37
  return target;
37
38
  };
38
- export { isValidField, mergeValues, parse, stringify };
39
+ /**
40
+ * 根据值的类型返回对应的空值
41
+ */
42
+ var getEmptyValueByType = function getEmptyValueByType(value) {
43
+ // 优先处理特殊对象类型(instanceof 检查)
44
+ if (isArray(value)) {
45
+ return [];
46
+ }
47
+ if (value instanceof Date) {
48
+ return null;
49
+ }
50
+ if (value instanceof RegExp) {
51
+ return /(?:)/;
52
+ }
53
+ if (value instanceof Map) {
54
+ return new Map();
55
+ }
56
+ if (value instanceof Set) {
57
+ return new Set();
58
+ }
59
+ // 注意:WeakMap 和 WeakSet 无法创建空实例,返回 null
60
+ if (value instanceof WeakMap) {
61
+ return null;
62
+ }
63
+ if (value instanceof WeakSet) {
64
+ return null;
65
+ }
66
+ // 处理基本类型(typeof 检查)
67
+ if (_typeof(value) === 'symbol') {
68
+ return Symbol('');
69
+ }
70
+ if (typeof value === 'bigint') {
71
+ return BigInt(0);
72
+ }
73
+ if (typeof value === 'string') {
74
+ return '';
75
+ }
76
+ if (typeof value === 'number') {
77
+ return null;
78
+ }
79
+ if (typeof value === 'boolean') {
80
+ return false;
81
+ }
82
+ if (typeof value === 'function') {
83
+ // 函数类型重置为 undefined,因为函数不应该作为表单值
84
+ return undefined;
85
+ }
86
+ // 对于 null 值,保持为 null
87
+ if (value === null) {
88
+ return null;
89
+ }
90
+ // 处理普通对象(必须在所有 instanceof 检查之后)
91
+ if (_typeof(value) === 'object') {
92
+ return {};
93
+ }
94
+ // 其他类型(包括 undefined)默认返回 undefined
95
+ return undefined;
96
+ };
97
+ export { getEmptyValueByType, isValidField, mergeValues, parse, stringify };
@@ -3,3 +3,7 @@ export declare const stringify: (field: FormFieldPath) => string;
3
3
  export declare const parse: (fieldStr: string) => FormFieldPath;
4
4
  export declare const isValidField: (field: FormFieldPath | undefined) => field is FormFieldPath;
5
5
  export declare const mergeValues: <T extends Object, E extends T>(source: T, override: E | null | undefined) => T;
6
+ /**
7
+ * 根据值的类型返回对应的空值
8
+ */
9
+ export declare const getEmptyValueByType: (value: any) => any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hi-ui/form",
3
- "version": "4.3.3",
3
+ "version": "4.3.4",
4
4
  "description": "A sub-package for @hi-ui/hiui.",
5
5
  "keywords": [],
6
6
  "author": "HiUI <mi-hiui@xiaomi.com>",