rc-field-form
Advanced tools
Comparing version 1.37.0 to 1.38.0
import * as React from 'react'; | ||
import type { FormInstance, InternalNamePath, Meta, NamePath, Rule, Store, InternalFormInstance, StoreValue, EventArgs } from './interface'; | ||
import type { EventArgs, FormInstance, InternalFormInstance, InternalNamePath, Meta, NamePath, Rule, Store, StoreValue } from './interface'; | ||
export type ShouldUpdate<Values = any> = boolean | ((prevValues: Values, nextValues: Values, info: { | ||
@@ -27,2 +27,6 @@ source?: string; | ||
validateTrigger?: string | string[] | false; | ||
/** | ||
* Trigger will after configured milliseconds. | ||
*/ | ||
validateDebounce?: number; | ||
validateFirst?: boolean | 'parallel'; | ||
@@ -29,0 +33,0 @@ valuePropName?: string; |
280
es/Field.js
import _extends from "@babel/runtime/helpers/esm/extends"; | ||
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; | ||
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime"; | ||
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator"; | ||
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; | ||
@@ -11,12 +12,13 @@ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; | ||
import _createSuper from "@babel/runtime/helpers/esm/createSuper"; | ||
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
var _excluded = ["name"]; | ||
import toChildrenArray from "rc-util/es/Children/toArray"; | ||
import isEqual from "rc-util/es/isEqual"; | ||
import warning from "rc-util/es/warning"; | ||
import isEqual from "rc-util/es/isEqual"; | ||
import * as React from 'react'; | ||
import FieldContext, { HOOK_MARK } from './FieldContext'; | ||
import ListContext from './ListContext'; | ||
import { toArray } from './utils/typeUtil'; | ||
import { validateRules } from './utils/validateUtil'; | ||
import { containsNamePath, defaultGetValueFromEvent, getNamePath, getValue } from './utils/valueUtil'; | ||
import FieldContext, { HOOK_MARK } from "./FieldContext"; | ||
import ListContext from "./ListContext"; | ||
import { toArray } from "./utils/typeUtil"; | ||
import { validateRules } from "./utils/validateUtil"; | ||
import { containsNamePath, defaultGetValueFromEvent, getNamePath, getValue } from "./utils/valueUtil"; | ||
var EMPTY_ERRORS = []; | ||
@@ -31,2 +33,4 @@ function requireUpdate(shouldUpdate, prev, next, prevValue, nextValue, info) { | ||
} | ||
// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style | ||
// We use Class instead of Hooks here since it will cost much code by using Hooks. | ||
@@ -41,8 +45,9 @@ var Field = /*#__PURE__*/function (_React$Component) { | ||
_this = _super.call(this, props); | ||
// Register on init | ||
_this.state = { | ||
_defineProperty(_assertThisInitialized(_this), "state", { | ||
resetCount: 0 | ||
}; | ||
_this.cancelRegisterFunc = null; | ||
_this.mounted = false; | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "cancelRegisterFunc", null); | ||
_defineProperty(_assertThisInitialized(_this), "mounted", false); | ||
/** | ||
@@ -52,3 +57,3 @@ * Follow state should not management in State since it will async update by React. | ||
*/ | ||
_this.touched = false; | ||
_defineProperty(_assertThisInitialized(_this), "touched", false); | ||
/** | ||
@@ -59,8 +64,8 @@ * Mark when touched & validated. Currently only used for `dependencies`. | ||
*/ | ||
_this.dirty = false; | ||
_this.validatePromise = void 0; | ||
_this.prevValidating = void 0; | ||
_this.errors = EMPTY_ERRORS; | ||
_this.warnings = EMPTY_ERRORS; | ||
_this.cancelRegister = function () { | ||
_defineProperty(_assertThisInitialized(_this), "dirty", false); | ||
_defineProperty(_assertThisInitialized(_this), "validatePromise", void 0); | ||
_defineProperty(_assertThisInitialized(_this), "prevValidating", void 0); | ||
_defineProperty(_assertThisInitialized(_this), "errors", EMPTY_ERRORS); | ||
_defineProperty(_assertThisInitialized(_this), "warnings", EMPTY_ERRORS); | ||
_defineProperty(_assertThisInitialized(_this), "cancelRegister", function () { | ||
var _this$props = _this.props, | ||
@@ -74,5 +79,5 @@ preserve = _this$props.preserve, | ||
_this.cancelRegisterFunc = null; | ||
}; | ||
}); | ||
// ================================== Utils ================================== | ||
_this.getNamePath = function () { | ||
_defineProperty(_assertThisInitialized(_this), "getNamePath", function () { | ||
var _this$props2 = _this.props, | ||
@@ -84,4 +89,4 @@ name = _this$props2.name, | ||
return name !== undefined ? [].concat(_toConsumableArray(prefixName), _toConsumableArray(name)) : []; | ||
}; | ||
_this.getRules = function () { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "getRules", function () { | ||
var _this$props3 = _this.props, | ||
@@ -97,5 +102,6 @@ _this$props3$rules = _this$props3.rules, | ||
}); | ||
}; | ||
_this.refresh = function () { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "refresh", function () { | ||
if (!_this.mounted) return; | ||
/** | ||
@@ -110,22 +116,22 @@ * Clean up current node. | ||
}); | ||
}; | ||
}); | ||
// Event should only trigger when meta changed | ||
_this.metaCache = null; | ||
_this.triggerMetaEvent = function (destroy) { | ||
_defineProperty(_assertThisInitialized(_this), "metaCache", null); | ||
_defineProperty(_assertThisInitialized(_this), "triggerMetaEvent", function (destroy) { | ||
var onMetaChange = _this.props.onMetaChange; | ||
if (onMetaChange) { | ||
var meta = _objectSpread(_objectSpread({}, _this.getMeta()), {}, { | ||
var _meta = _objectSpread(_objectSpread({}, _this.getMeta()), {}, { | ||
destroy: destroy | ||
}); | ||
if (!isEqual(_this.metaCache, meta)) { | ||
onMetaChange(meta); | ||
if (!isEqual(_this.metaCache, _meta)) { | ||
onMetaChange(_meta); | ||
} | ||
_this.metaCache = meta; | ||
_this.metaCache = _meta; | ||
} else { | ||
_this.metaCache = null; | ||
} | ||
}; | ||
}); | ||
// ========================= Field Entity Interfaces ========================= | ||
// Trigger by store update. Check if need update the component | ||
_this.onStoreChange = function (prevStore, namePathList, info) { | ||
_defineProperty(_assertThisInitialized(_this), "onStoreChange", function (prevStore, namePathList, info) { | ||
var _this$props4 = _this.props, | ||
@@ -141,2 +147,3 @@ shouldUpdate = _this$props4.shouldUpdate, | ||
var namePathMatch = namePathList && containsNamePath(namePathList, namePath); | ||
// `setFieldsValue` is a quick access to update related status | ||
@@ -166,2 +173,3 @@ if (info.type === 'valueUpdate' && info.source === 'external' && prevValue !== curValue) { | ||
break; | ||
/** | ||
@@ -202,2 +210,3 @@ * In case field with `preserve = false` nest deps like: | ||
} | ||
// Handle update by `setField` with `shouldUpdate` | ||
@@ -247,4 +256,4 @@ if (shouldUpdate && !namePath.length && requireUpdate(shouldUpdate, prevStore, store, prevValue, curValue, info)) { | ||
} | ||
}; | ||
_this.validateRules = function (options) { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "validateRules", function (options) { | ||
// We should fixed namePath & value to avoid developer change then by form function | ||
@@ -257,53 +266,81 @@ var namePath = _this.getNamePath(); | ||
validateOnly = _ref2$validateOnly === void 0 ? false : _ref2$validateOnly; | ||
// Force change to async to avoid rule OOD under renderProps field | ||
var rootPromise = Promise.resolve().then(function () { | ||
if (!_this.mounted) { | ||
return []; | ||
} | ||
var _this$props5 = _this.props, | ||
_this$props5$validate = _this$props5.validateFirst, | ||
validateFirst = _this$props5$validate === void 0 ? false : _this$props5$validate, | ||
messageVariables = _this$props5.messageVariables; | ||
var filteredRules = _this.getRules(); | ||
if (triggerName) { | ||
filteredRules = filteredRules.filter(function (rule) { | ||
return rule; | ||
}).filter(function (rule) { | ||
var validateTrigger = rule.validateTrigger; | ||
if (!validateTrigger) { | ||
return true; | ||
} | ||
var triggerList = toArray(validateTrigger); | ||
return triggerList.includes(triggerName); | ||
}); | ||
} | ||
var promise = validateRules(namePath, currentValue, filteredRules, options, validateFirst, messageVariables); | ||
promise.catch(function (e) { | ||
return e; | ||
}).then(function () { | ||
var ruleErrors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : EMPTY_ERRORS; | ||
if (_this.validatePromise === rootPromise) { | ||
var _ruleErrors$forEach; | ||
_this.validatePromise = null; | ||
// Get errors & warnings | ||
var nextErrors = []; | ||
var nextWarnings = []; | ||
(_ruleErrors$forEach = ruleErrors.forEach) === null || _ruleErrors$forEach === void 0 ? void 0 : _ruleErrors$forEach.call(ruleErrors, function (_ref3) { | ||
var warningOnly = _ref3.rule.warningOnly, | ||
_ref3$errors = _ref3.errors, | ||
errors = _ref3$errors === void 0 ? EMPTY_ERRORS : _ref3$errors; | ||
if (warningOnly) { | ||
nextWarnings.push.apply(nextWarnings, _toConsumableArray(errors)); | ||
} else { | ||
nextErrors.push.apply(nextErrors, _toConsumableArray(errors)); | ||
var rootPromise = Promise.resolve().then( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() { | ||
var _this$props5, _this$props5$validate, validateFirst, messageVariables, validateDebounce, filteredRules, promise; | ||
return _regeneratorRuntime().wrap(function _callee$(_context) { | ||
while (1) switch (_context.prev = _context.next) { | ||
case 0: | ||
if (_this.mounted) { | ||
_context.next = 2; | ||
break; | ||
} | ||
}); | ||
_this.errors = nextErrors; | ||
_this.warnings = nextWarnings; | ||
_this.triggerMetaEvent(); | ||
_this.reRender(); | ||
return _context.abrupt("return", []); | ||
case 2: | ||
_this$props5 = _this.props, _this$props5$validate = _this$props5.validateFirst, validateFirst = _this$props5$validate === void 0 ? false : _this$props5$validate, messageVariables = _this$props5.messageVariables, validateDebounce = _this$props5.validateDebounce; // Start validate | ||
filteredRules = _this.getRules(); | ||
if (triggerName) { | ||
filteredRules = filteredRules.filter(function (rule) { | ||
return rule; | ||
}).filter(function (rule) { | ||
var validateTrigger = rule.validateTrigger; | ||
if (!validateTrigger) { | ||
return true; | ||
} | ||
var triggerList = toArray(validateTrigger); | ||
return triggerList.includes(triggerName); | ||
}); | ||
} | ||
// Wait for debounce. Skip if no `triggerName` since its from `validateFields / submit` | ||
if (!(validateDebounce && triggerName)) { | ||
_context.next = 10; | ||
break; | ||
} | ||
_context.next = 8; | ||
return new Promise(function (resolve) { | ||
setTimeout(resolve, validateDebounce); | ||
}); | ||
case 8: | ||
if (!(_this.validatePromise !== rootPromise)) { | ||
_context.next = 10; | ||
break; | ||
} | ||
return _context.abrupt("return", []); | ||
case 10: | ||
promise = validateRules(namePath, currentValue, filteredRules, options, validateFirst, messageVariables); | ||
promise.catch(function (e) { | ||
return e; | ||
}).then(function () { | ||
var ruleErrors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : EMPTY_ERRORS; | ||
if (_this.validatePromise === rootPromise) { | ||
var _ruleErrors$forEach; | ||
_this.validatePromise = null; | ||
// Get errors & warnings | ||
var nextErrors = []; | ||
var nextWarnings = []; | ||
(_ruleErrors$forEach = ruleErrors.forEach) === null || _ruleErrors$forEach === void 0 ? void 0 : _ruleErrors$forEach.call(ruleErrors, function (_ref4) { | ||
var warningOnly = _ref4.rule.warningOnly, | ||
_ref4$errors = _ref4.errors, | ||
errors = _ref4$errors === void 0 ? EMPTY_ERRORS : _ref4$errors; | ||
if (warningOnly) { | ||
nextWarnings.push.apply(nextWarnings, _toConsumableArray(errors)); | ||
} else { | ||
nextErrors.push.apply(nextErrors, _toConsumableArray(errors)); | ||
} | ||
}); | ||
_this.errors = nextErrors; | ||
_this.warnings = nextWarnings; | ||
_this.triggerMetaEvent(); | ||
_this.reRender(); | ||
} | ||
}); | ||
return _context.abrupt("return", promise); | ||
case 13: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
}); | ||
return promise; | ||
}); | ||
}, _callee); | ||
}))); | ||
if (validateOnly) { | ||
@@ -317,13 +354,14 @@ return rootPromise; | ||
_this.triggerMetaEvent(); | ||
// Force trigger re-render since we need sync renderProps with new meta | ||
_this.reRender(); | ||
return rootPromise; | ||
}; | ||
_this.isFieldValidating = function () { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "isFieldValidating", function () { | ||
return !!_this.validatePromise; | ||
}; | ||
_this.isFieldTouched = function () { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "isFieldTouched", function () { | ||
return _this.touched; | ||
}; | ||
_this.isFieldDirty = function () { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "isFieldDirty", function () { | ||
// Touched or validate or has initialValue | ||
@@ -333,2 +371,3 @@ if (_this.dirty || _this.props.initialValue !== undefined) { | ||
} | ||
// Form set initialValue | ||
@@ -342,20 +381,20 @@ var fieldContext = _this.props.fieldContext; | ||
return false; | ||
}; | ||
_this.getErrors = function () { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "getErrors", function () { | ||
return _this.errors; | ||
}; | ||
_this.getWarnings = function () { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "getWarnings", function () { | ||
return _this.warnings; | ||
}; | ||
_this.isListField = function () { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "isListField", function () { | ||
return _this.props.isListField; | ||
}; | ||
_this.isList = function () { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "isList", function () { | ||
return _this.props.isList; | ||
}; | ||
_this.isPreserve = function () { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "isPreserve", function () { | ||
return _this.props.preserve; | ||
}; | ||
}); | ||
// ============================= Child Component ============================= | ||
_this.getMeta = function () { | ||
_defineProperty(_assertThisInitialized(_this), "getMeta", function () { | ||
// Make error & validating in cache to save perf | ||
@@ -372,12 +411,13 @@ _this.prevValidating = _this.isFieldValidating(); | ||
return meta; | ||
}; | ||
}); | ||
// Only return validate child node. If invalidate, will do nothing about field. | ||
_this.getOnlyChild = function (children) { | ||
_defineProperty(_assertThisInitialized(_this), "getOnlyChild", function (children) { | ||
// Support render props | ||
if (typeof children === 'function') { | ||
var meta = _this.getMeta(); | ||
return _objectSpread(_objectSpread({}, _this.getOnlyChild(children(_this.getControlled(), meta, _this.props.fieldContext))), {}, { | ||
var _meta2 = _this.getMeta(); | ||
return _objectSpread(_objectSpread({}, _this.getOnlyChild(children(_this.getControlled(), _meta2, _this.props.fieldContext))), {}, { | ||
isFunction: true | ||
}); | ||
} | ||
// Filed element only | ||
@@ -395,10 +435,10 @@ var childList = toChildrenArray(children); | ||
}; | ||
}; | ||
}); | ||
// ============================== Field Control ============================== | ||
_this.getValue = function (store) { | ||
_defineProperty(_assertThisInitialized(_this), "getValue", function (store) { | ||
var getFieldsValue = _this.props.fieldContext.getFieldsValue; | ||
var namePath = _this.getNamePath(); | ||
return getValue(store || getFieldsValue(true), namePath); | ||
}; | ||
_this.getControlled = function () { | ||
}); | ||
_defineProperty(_assertThisInitialized(_this), "getControlled", function () { | ||
var childProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
@@ -423,5 +463,7 @@ var _this$props6 = _this.props, | ||
}; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
var originTriggerFunc = childProps[trigger]; | ||
var control = _objectSpread(_objectSpread({}, childProps), mergedGetValueProps(value)); | ||
// Add trigger | ||
@@ -454,2 +496,3 @@ control[trigger] = function () { | ||
}; | ||
// Add validateTrigger | ||
@@ -464,2 +507,3 @@ var validateTriggerList = toArray(mergedValidateTrigger || []); | ||
} | ||
// Always use latest rules | ||
@@ -479,3 +523,3 @@ var rules = _this.props.rules; | ||
return control; | ||
}; | ||
}); | ||
if (props.fieldContext) { | ||
@@ -496,2 +540,3 @@ var getInternalHooks = props.fieldContext.getInternalHooks; | ||
this.mounted = true; | ||
// Register on init | ||
@@ -504,2 +549,3 @@ if (fieldContext) { | ||
} | ||
// One more render for component in case fields not ready | ||
@@ -531,2 +577,3 @@ if (shouldUpdate === true) { | ||
isFunction = _this$getOnlyChild.isFunction; | ||
// Not need to `cloneElement` since user can handle this in render function self | ||
@@ -549,10 +596,10 @@ var returnChildNode; | ||
}(React.Component); | ||
Field.contextType = FieldContext; | ||
Field.defaultProps = { | ||
_defineProperty(Field, "contextType", FieldContext); | ||
_defineProperty(Field, "defaultProps", { | ||
trigger: 'onChange', | ||
valuePropName: 'value' | ||
}; | ||
function WrapperField(_ref5) { | ||
var name = _ref5.name, | ||
restProps = _objectWithoutProperties(_ref5, _excluded); | ||
}); | ||
function WrapperField(_ref6) { | ||
var name = _ref6.name, | ||
restProps = _objectWithoutProperties(_ref6, _excluded); | ||
var fieldContext = React.useContext(FieldContext); | ||
@@ -565,2 +612,3 @@ var listContext = React.useContext(ListContext); | ||
} | ||
// Warning if it's a directly list field. | ||
@@ -567,0 +615,0 @@ // We can still support multiple level field preserve. |
import warning from "rc-util/es/warning"; | ||
import * as React from 'react'; | ||
export var HOOK_MARK = 'RC_FORM_INTERNAL_HOOKS'; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
@@ -5,0 +6,0 @@ var warningFunc = function warningFunc() { |
@@ -7,7 +7,7 @@ import _extends from "@babel/runtime/helpers/esm/extends"; | ||
import * as React from 'react'; | ||
import useForm from './useForm'; | ||
import FieldContext, { HOOK_MARK } from './FieldContext'; | ||
import FormContext from './FormContext'; | ||
import { isSimilar } from './utils/valueUtil'; | ||
import ListContext from './ListContext'; | ||
import useForm from "./useForm"; | ||
import FieldContext, { HOOK_MARK } from "./FieldContext"; | ||
import FormContext from "./FormContext"; | ||
import { isSimilar } from "./utils/valueUtil"; | ||
import ListContext from "./ListContext"; | ||
var Form = function Form(_ref, ref) { | ||
@@ -31,2 +31,3 @@ var name = _ref.name, | ||
var formContext = React.useContext(FormContext); | ||
// We customize handle event since Context will makes all the consumer re-render: | ||
@@ -37,9 +38,10 @@ // https://reactjs.org/docs/context.html#contextprovider | ||
formInstance = _useForm2[0]; | ||
var _formInstance$getInte = formInstance.getInternalHooks(HOOK_MARK), | ||
useSubscribe = _formInstance$getInte.useSubscribe, | ||
setInitialValues = _formInstance$getInte.setInitialValues, | ||
setCallbacks = _formInstance$getInte.setCallbacks, | ||
setValidateMessages = _formInstance$getInte.setValidateMessages, | ||
setPreserve = _formInstance$getInte.setPreserve, | ||
destroyForm = _formInstance$getInte.destroyForm; | ||
var _getInternalHooks = formInstance.getInternalHooks(HOOK_MARK), | ||
useSubscribe = _getInternalHooks.useSubscribe, | ||
setInitialValues = _getInternalHooks.setInitialValues, | ||
setCallbacks = _getInternalHooks.setCallbacks, | ||
setValidateMessages = _getInternalHooks.setValidateMessages, | ||
setPreserve = _getInternalHooks.setPreserve, | ||
destroyForm = _getInternalHooks.destroyForm; | ||
// Pass ref with form instance | ||
@@ -49,2 +51,3 @@ React.useImperativeHandle(ref, function () { | ||
}); | ||
// Register form into Context | ||
@@ -57,2 +60,3 @@ React.useEffect(function () { | ||
}, [formContext, formInstance, name]); | ||
// Pass props to store | ||
@@ -80,2 +84,3 @@ setValidateMessages(_objectSpread(_objectSpread({}, formContext.validateMessages), validateMessages)); | ||
setPreserve(preserve); | ||
// Set initial value, init store value when first mount | ||
@@ -92,2 +97,3 @@ var mountRef = React.useRef(null); | ||
[]); | ||
// Prepare children by `children` type | ||
@@ -97,9 +103,11 @@ var childrenNode; | ||
if (childrenRenderProps) { | ||
var values = formInstance.getFieldsValue(true); | ||
childrenNode = children(values, formInstance); | ||
var _values = formInstance.getFieldsValue(true); | ||
childrenNode = children(_values, formInstance); | ||
} else { | ||
childrenNode = children; | ||
} | ||
// Not use subscribe when using render props | ||
useSubscribe(!childrenRenderProps); | ||
// Listen if fields provided. We use ref to save prev data here to avoid additional render | ||
@@ -106,0 +114,0 @@ var prevFieldsRef = React.useRef(); |
@@ -23,4 +23,4 @@ import * as React from 'react'; | ||
declare const RefForm: RefFormType; | ||
export { FormInstance, Field, List, useForm, FormProvider, FieldContext, ListContext, useWatch }; | ||
export type { FormProps }; | ||
export { Field, List, useForm, FormProvider, FieldContext, ListContext, useWatch }; | ||
export type { FormProps, FormInstance }; | ||
export default RefForm; |
import * as React from 'react'; | ||
import Field from './Field'; | ||
import List from './List'; | ||
import useForm from './useForm'; | ||
import FieldForm from './Form'; | ||
import { FormProvider } from './FormContext'; | ||
import FieldContext from './FieldContext'; | ||
import ListContext from './ListContext'; | ||
import useWatch from './useWatch'; | ||
import Field from "./Field"; | ||
import List from "./List"; | ||
import useForm from "./useForm"; | ||
import FieldForm from "./Form"; | ||
import { FormProvider } from "./FormContext"; | ||
import FieldContext from "./FieldContext"; | ||
import ListContext from "./ListContext"; | ||
import useWatch from "./useWatch"; | ||
var InternalForm = /*#__PURE__*/React.forwardRef(FieldForm); | ||
@@ -11,0 +11,0 @@ var RefForm = InternalForm; |
@@ -188,3 +188,3 @@ import type { ReactElement } from 'react'; | ||
isFieldValidating: (name: NamePath) => boolean; | ||
isFieldsValidating: (nameList: NamePath[]) => boolean; | ||
isFieldsValidating: (nameList?: NamePath[]) => boolean; | ||
resetFields: (fields?: NamePath[]) => void; | ||
@@ -191,0 +191,0 @@ setFields: (fields: FieldData[]) => void; |
@@ -5,6 +5,6 @@ import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; | ||
import warning from "rc-util/es/warning"; | ||
import FieldContext from './FieldContext'; | ||
import Field from './Field'; | ||
import { move as _move, getNamePath } from './utils/valueUtil'; | ||
import ListContext from './ListContext'; | ||
import FieldContext from "./FieldContext"; | ||
import Field from "./Field"; | ||
import { move as _move, getNamePath } from "./utils/valueUtil"; | ||
import ListContext from "./ListContext"; | ||
function List(_ref) { | ||
@@ -33,2 +33,3 @@ var name = _ref.name, | ||
}, [context, prefixName]); | ||
// List context | ||
@@ -44,2 +45,3 @@ var listContext = React.useMemo(function () { | ||
}, [prefixName]); | ||
// User should not pass `children` as other type. | ||
@@ -106,2 +108,3 @@ if (typeof children !== 'function') { | ||
}); | ||
// Trigger store change | ||
@@ -117,2 +120,3 @@ onChange(newValue.filter(function (_, valueIndex) { | ||
var newValue = getNewValue(); | ||
// Do not handle out of range | ||
@@ -123,2 +127,3 @@ if (from < 0 || from >= newValue.length || to < 0 || to >= newValue.length) { | ||
keyManager.keys = _move(keyManager.keys, from, to); | ||
// Trigger store change | ||
@@ -125,0 +130,0 @@ onChange(_move(newValue, from, to)); |
@@ -8,25 +8,26 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; | ||
import _classCallCheck from "@babel/runtime/helpers/esm/classCallCheck"; | ||
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
var _excluded = ["name"]; | ||
import warning from "rc-util/es/warning"; | ||
import * as React from 'react'; | ||
import { HOOK_MARK } from './FieldContext'; | ||
import { allPromiseFinish } from './utils/asyncUtil'; | ||
import { HOOK_MARK } from "./FieldContext"; | ||
import { allPromiseFinish } from "./utils/asyncUtil"; | ||
import { merge } from "rc-util/es/utils/set"; | ||
import { defaultValidateMessages } from './utils/messages'; | ||
import NameMap from './utils/NameMap'; | ||
import { cloneByNamePathList, containsNamePath, getNamePath, getValue, matchNamePath, setValue } from './utils/valueUtil'; | ||
import { defaultValidateMessages } from "./utils/messages"; | ||
import NameMap from "./utils/NameMap"; | ||
import { cloneByNamePathList, containsNamePath, getNamePath, getValue, matchNamePath, setValue } from "./utils/valueUtil"; | ||
export var FormStore = /*#__PURE__*/_createClass(function FormStore(forceRootUpdate) { | ||
var _this = this; | ||
_classCallCheck(this, FormStore); | ||
this.formHooked = false; | ||
this.forceRootUpdate = void 0; | ||
this.subscribable = true; | ||
this.store = {}; | ||
this.fieldEntities = []; | ||
this.initialValues = {}; | ||
this.callbacks = {}; | ||
this.validateMessages = null; | ||
this.preserve = null; | ||
this.lastValidatePromise = null; | ||
this.getForm = function () { | ||
_defineProperty(this, "formHooked", false); | ||
_defineProperty(this, "forceRootUpdate", void 0); | ||
_defineProperty(this, "subscribable", true); | ||
_defineProperty(this, "store", {}); | ||
_defineProperty(this, "fieldEntities", []); | ||
_defineProperty(this, "initialValues", {}); | ||
_defineProperty(this, "callbacks", {}); | ||
_defineProperty(this, "validateMessages", null); | ||
_defineProperty(this, "preserve", null); | ||
_defineProperty(this, "lastValidatePromise", null); | ||
_defineProperty(this, "getForm", function () { | ||
return { | ||
@@ -51,5 +52,5 @@ getFieldValue: _this.getFieldValue, | ||
}; | ||
}; | ||
}); | ||
// ======================== Internal Hooks ======================== | ||
this.getInternalHooks = function (key) { | ||
_defineProperty(this, "getInternalHooks", function (key) { | ||
if (key === HOOK_MARK) { | ||
@@ -74,6 +75,6 @@ _this.formHooked = true; | ||
return null; | ||
}; | ||
this.useSubscribe = function (subscribable) { | ||
}); | ||
_defineProperty(this, "useSubscribe", function (subscribable) { | ||
_this.subscribable = subscribable; | ||
}; | ||
}); | ||
/** | ||
@@ -83,7 +84,7 @@ * Record prev Form unmount fieldEntities which config preserve false. | ||
*/ | ||
this.prevWithoutPreserves = null; | ||
_defineProperty(this, "prevWithoutPreserves", null); | ||
/** | ||
* First time `setInitialValues` should update store with initial value | ||
*/ | ||
this.setInitialValues = function (initialValues, init) { | ||
_defineProperty(this, "setInitialValues", function (initialValues, init) { | ||
_this.initialValues = initialValues || {}; | ||
@@ -93,2 +94,3 @@ if (init) { | ||
var nextStore = merge(initialValues, _this.store); | ||
// We will take consider prev form unmount fields. | ||
@@ -104,4 +106,4 @@ // When the field is not `preserve`, we need fill this with initialValues instead of store. | ||
} | ||
}; | ||
this.destroyForm = function () { | ||
}); | ||
_defineProperty(this, "destroyForm", function () { | ||
var prevWithoutPreserves = new NameMap(); | ||
@@ -114,20 +116,21 @@ _this.getFieldEntities(true).forEach(function (entity) { | ||
_this.prevWithoutPreserves = prevWithoutPreserves; | ||
}; | ||
this.getInitialValue = function (namePath) { | ||
}); | ||
_defineProperty(this, "getInitialValue", function (namePath) { | ||
var initValue = getValue(_this.initialValues, namePath); | ||
// Not cloneDeep when without `namePath` | ||
return namePath.length ? merge(initValue) : initValue; | ||
}; | ||
this.setCallbacks = function (callbacks) { | ||
}); | ||
_defineProperty(this, "setCallbacks", function (callbacks) { | ||
_this.callbacks = callbacks; | ||
}; | ||
this.setValidateMessages = function (validateMessages) { | ||
}); | ||
_defineProperty(this, "setValidateMessages", function (validateMessages) { | ||
_this.validateMessages = validateMessages; | ||
}; | ||
this.setPreserve = function (preserve) { | ||
}); | ||
_defineProperty(this, "setPreserve", function (preserve) { | ||
_this.preserve = preserve; | ||
}; | ||
}); | ||
// ============================= Watch ============================ | ||
this.watchList = []; | ||
this.registerWatch = function (callback) { | ||
_defineProperty(this, "watchList", []); | ||
_defineProperty(this, "registerWatch", function (callback) { | ||
_this.watchList.push(callback); | ||
@@ -139,4 +142,4 @@ return function () { | ||
}; | ||
}; | ||
this.notifyWatch = function () { | ||
}); | ||
_defineProperty(this, "notifyWatch", function () { | ||
var namePath = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; | ||
@@ -151,6 +154,6 @@ // No need to cost perf when nothing need to watch | ||
} | ||
}; | ||
}); | ||
// ========================== Dev Warning ========================= | ||
this.timeoutId = null; | ||
this.warningUnhooked = function () { | ||
_defineProperty(this, "timeoutId", null); | ||
_defineProperty(this, "warningUnhooked", function () { | ||
if (process.env.NODE_ENV !== 'production' && !_this.timeoutId && typeof window !== 'undefined') { | ||
@@ -164,7 +167,7 @@ _this.timeoutId = setTimeout(function () { | ||
} | ||
}; | ||
}); | ||
// ============================ Store ============================= | ||
this.updateStore = function (nextStore) { | ||
_defineProperty(this, "updateStore", function (nextStore) { | ||
_this.store = nextStore; | ||
}; | ||
}); | ||
// ============================ Fields ============================ | ||
@@ -175,3 +178,3 @@ /** | ||
*/ | ||
this.getFieldEntities = function () { | ||
_defineProperty(this, "getFieldEntities", function () { | ||
var pure = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; | ||
@@ -184,4 +187,4 @@ if (!pure) { | ||
}); | ||
}; | ||
this.getFieldsMap = function () { | ||
}); | ||
_defineProperty(this, "getFieldsMap", function () { | ||
var pure = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; | ||
@@ -194,4 +197,4 @@ var cache = new NameMap(); | ||
return cache; | ||
}; | ||
this.getFieldEntitiesForNamePathList = function (nameList) { | ||
}); | ||
_defineProperty(this, "getFieldEntitiesForNamePathList", function (nameList) { | ||
if (!nameList) { | ||
@@ -207,5 +210,6 @@ return _this.getFieldEntities(true); | ||
}); | ||
}; | ||
this.getFieldsValue = function (nameList, filterFunc) { | ||
}); | ||
_defineProperty(this, "getFieldsValue", function (nameList, filterFunc) { | ||
_this.warningUnhooked(); | ||
// Fill args | ||
@@ -228,12 +232,13 @@ var mergedNameList; | ||
fieldEntities.forEach(function (entity) { | ||
var _entity$isListField; | ||
var _isListField, _ref3; | ||
var namePath = 'INVALIDATE_NAME_PATH' in entity ? entity.INVALIDATE_NAME_PATH : entity.getNamePath(); | ||
// Ignore when it's a list item and not specific the namePath, | ||
// since parent field is already take in count | ||
if (mergedStrict) { | ||
var _entity$isList; | ||
if ((_entity$isList = entity.isList) === null || _entity$isList === void 0 ? void 0 : _entity$isList.call(entity)) { | ||
var _isList, _ref2; | ||
if ((_isList = (_ref2 = entity).isList) !== null && _isList !== void 0 && _isList.call(_ref2)) { | ||
return; | ||
} | ||
} else if (!mergedNameList && ((_entity$isListField = entity.isListField) === null || _entity$isListField === void 0 ? void 0 : _entity$isListField.call(entity))) { | ||
} else if (!mergedNameList && (_isListField = (_ref3 = entity).isListField) !== null && _isListField !== void 0 && _isListField.call(_ref3)) { | ||
return; | ||
@@ -251,9 +256,9 @@ } | ||
return cloneByNamePathList(_this.store, filteredNameList.map(getNamePath)); | ||
}; | ||
this.getFieldValue = function (name) { | ||
}); | ||
_defineProperty(this, "getFieldValue", function (name) { | ||
_this.warningUnhooked(); | ||
var namePath = getNamePath(name); | ||
return getValue(_this.store, namePath); | ||
}; | ||
this.getFieldsError = function (nameList) { | ||
}); | ||
_defineProperty(this, "getFieldsError", function (nameList) { | ||
_this.warningUnhooked(); | ||
@@ -275,4 +280,4 @@ var fieldEntities = _this.getFieldEntitiesForNamePathList(nameList); | ||
}); | ||
}; | ||
this.getFieldError = function (name) { | ||
}); | ||
_defineProperty(this, "getFieldError", function (name) { | ||
_this.warningUnhooked(); | ||
@@ -282,4 +287,4 @@ var namePath = getNamePath(name); | ||
return fieldError.errors; | ||
}; | ||
this.getFieldWarning = function (name) { | ||
}); | ||
_defineProperty(this, "getFieldWarning", function (name) { | ||
_this.warningUnhooked(); | ||
@@ -289,4 +294,4 @@ var namePath = getNamePath(name); | ||
return fieldError.warnings; | ||
}; | ||
this.isFieldsTouched = function () { | ||
}); | ||
_defineProperty(this, "isFieldsTouched", function () { | ||
_this.warningUnhooked(); | ||
@@ -318,2 +323,3 @@ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | ||
}; | ||
// ===== Will get fully compare when not config namePathList ===== | ||
@@ -323,2 +329,3 @@ if (!namePathList) { | ||
} | ||
// Generate a nest tree for validate | ||
@@ -331,2 +338,3 @@ var map = new NameMap(); | ||
var fieldNamePath = field.getNamePath(); | ||
// Find matched entity and put into list | ||
@@ -343,2 +351,3 @@ namePathList.forEach(function (shortNamePath) { | ||
}); | ||
// Check if NameMap value is touched | ||
@@ -348,13 +357,13 @@ var isNamePathListTouched = function isNamePathListTouched(entities) { | ||
}; | ||
var namePathListEntities = map.map(function (_ref2) { | ||
var value = _ref2.value; | ||
var namePathListEntities = map.map(function (_ref4) { | ||
var value = _ref4.value; | ||
return value; | ||
}); | ||
return isAllFieldsTouched ? namePathListEntities.every(isNamePathListTouched) : namePathListEntities.some(isNamePathListTouched); | ||
}; | ||
this.isFieldTouched = function (name) { | ||
}); | ||
_defineProperty(this, "isFieldTouched", function (name) { | ||
_this.warningUnhooked(); | ||
return _this.isFieldsTouched([name]); | ||
}; | ||
this.isFieldsValidating = function (nameList) { | ||
}); | ||
_defineProperty(this, "isFieldsValidating", function (nameList) { | ||
_this.warningUnhooked(); | ||
@@ -372,7 +381,7 @@ var fieldEntities = _this.getFieldEntities(); | ||
}); | ||
}; | ||
this.isFieldValidating = function (name) { | ||
}); | ||
_defineProperty(this, "isFieldValidating", function (name) { | ||
_this.warningUnhooked(); | ||
return _this.isFieldsValidating([name]); | ||
}; | ||
}); | ||
/** | ||
@@ -382,3 +391,3 @@ * Reset Field with field `initialValue` prop. | ||
*/ | ||
this.resetWithFieldInitialValue = function () { | ||
_defineProperty(this, "resetWithFieldInitialValue", function () { | ||
var info = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
@@ -391,2 +400,3 @@ // Create cache | ||
var namePath = field.getNamePath(); | ||
// Record only if has `initialValue` | ||
@@ -402,2 +412,3 @@ if (initialValue !== undefined) { | ||
}); | ||
// Reset | ||
@@ -447,4 +458,4 @@ var resetWithFields = function resetWithFields(entities) { | ||
resetWithFields(requiredFieldEntities); | ||
}; | ||
this.resetFields = function (nameList) { | ||
}); | ||
_defineProperty(this, "resetFields", function (nameList) { | ||
_this.warningUnhooked(); | ||
@@ -461,2 +472,3 @@ var prevStore = _this.store; | ||
} | ||
// Reset by `nameList` | ||
@@ -475,4 +487,4 @@ var namePathList = nameList.map(getNamePath); | ||
_this.notifyWatch(namePathList); | ||
}; | ||
this.setFields = function (fields) { | ||
}); | ||
_defineProperty(this, "setFields", function (fields) { | ||
_this.warningUnhooked(); | ||
@@ -486,2 +498,3 @@ var prevStore = _this.store; | ||
namePathList.push(namePath); | ||
// Value | ||
@@ -497,4 +510,4 @@ if ('value' in data) { | ||
_this.notifyWatch(namePathList); | ||
}; | ||
this.getFields = function () { | ||
}); | ||
_defineProperty(this, "getFields", function () { | ||
var entities = _this.getFieldEntities(true); | ||
@@ -514,3 +527,3 @@ var fields = entities.map(function (field) { | ||
return fields; | ||
}; | ||
}); | ||
// =========================== Observer =========================== | ||
@@ -520,3 +533,3 @@ /** | ||
*/ | ||
this.initEntityValue = function (entity) { | ||
_defineProperty(this, "initEntityValue", function (entity) { | ||
var initialValue = entity.props.initialValue; | ||
@@ -530,11 +543,12 @@ if (initialValue !== undefined) { | ||
} | ||
}; | ||
this.isMergedPreserve = function (fieldPreserve) { | ||
}); | ||
_defineProperty(this, "isMergedPreserve", function (fieldPreserve) { | ||
var mergedPreserve = fieldPreserve !== undefined ? fieldPreserve : _this.preserve; | ||
return mergedPreserve !== null && mergedPreserve !== void 0 ? mergedPreserve : true; | ||
}; | ||
this.registerField = function (entity) { | ||
}); | ||
_defineProperty(this, "registerField", function (entity) { | ||
_this.fieldEntities.push(entity); | ||
var namePath = entity.getNamePath(); | ||
_this.notifyWatch([namePath]); | ||
// Set initial values | ||
@@ -552,2 +566,3 @@ if (entity.props.initialValue !== undefined) { | ||
} | ||
// un-register field callback | ||
@@ -559,2 +574,3 @@ return function (isListField, preserve) { | ||
}); | ||
// Clean up store value if not preserve | ||
@@ -571,2 +587,3 @@ if (!_this.isMergedPreserve(preserve) && (!isListField || subNamePath.length > 1)) { | ||
_this.updateStore(setValue(_prevStore, namePath, defaultValue, true)); | ||
// Notify that field is unmount | ||
@@ -576,2 +593,3 @@ _this.notifyObservers(_prevStore, [namePath], { | ||
}); | ||
// Dependencies update | ||
@@ -583,4 +601,4 @@ _this.triggerDependenciesUpdate(_prevStore, namePath); | ||
}; | ||
}; | ||
this.dispatch = function (action) { | ||
}); | ||
_defineProperty(this, "dispatch", function (action) { | ||
switch (action.type) { | ||
@@ -606,4 +624,4 @@ case 'updateValue': | ||
} | ||
}; | ||
this.notifyObservers = function (prevStore, namePathList, info) { | ||
}); | ||
_defineProperty(this, "notifyObservers", function (prevStore, namePathList, info) { | ||
if (_this.subscribable) { | ||
@@ -613,4 +631,4 @@ var mergedInfo = _objectSpread(_objectSpread({}, info), {}, { | ||
}); | ||
_this.getFieldEntities().forEach(function (_ref3) { | ||
var onStoreChange = _ref3.onStoreChange; | ||
_this.getFieldEntities().forEach(function (_ref5) { | ||
var onStoreChange = _ref5.onStoreChange; | ||
onStoreChange(prevStore, namePathList, mergedInfo); | ||
@@ -621,3 +639,3 @@ }); | ||
} | ||
}; | ||
}); | ||
/** | ||
@@ -627,3 +645,3 @@ * Notify dependencies children with parent update | ||
*/ | ||
this.triggerDependenciesUpdate = function (prevStore, namePath) { | ||
_defineProperty(this, "triggerDependenciesUpdate", function (prevStore, namePath) { | ||
var childrenFields = _this.getDependencyChildrenFields(namePath); | ||
@@ -638,4 +656,4 @@ if (childrenFields.length) { | ||
return childrenFields; | ||
}; | ||
this.updateValue = function (name, value) { | ||
}); | ||
_defineProperty(this, "updateValue", function (name, value) { | ||
var namePath = getNamePath(name); | ||
@@ -649,4 +667,6 @@ var prevStore = _this.store; | ||
_this.notifyWatch([namePath]); | ||
// Dependencies update | ||
var childrenFields = _this.triggerDependenciesUpdate(prevStore, namePath); | ||
// trigger callback function | ||
@@ -659,5 +679,5 @@ var onValuesChange = _this.callbacks.onValuesChange; | ||
_this.triggerOnFieldsChange([namePath].concat(_toConsumableArray(childrenFields))); | ||
}; | ||
}); | ||
// Let all child Field get update. | ||
this.setFieldsValue = function (store) { | ||
_defineProperty(this, "setFieldsValue", function (store) { | ||
_this.warningUnhooked(); | ||
@@ -674,4 +694,4 @@ var prevStore = _this.store; | ||
_this.notifyWatch(); | ||
}; | ||
this.setFieldValue = function (name, value) { | ||
}); | ||
_defineProperty(this, "setFieldValue", function (name, value) { | ||
_this.setFields([{ | ||
@@ -681,7 +701,8 @@ name: name, | ||
}]); | ||
}; | ||
this.getDependencyChildrenFields = function (rootNamePath) { | ||
}); | ||
_defineProperty(this, "getDependencyChildrenFields", function (rootNamePath) { | ||
var children = new Set(); | ||
var childrenFields = []; | ||
var dependencies2fields = new NameMap(); | ||
/** | ||
@@ -717,7 +738,8 @@ * Generate maps | ||
return childrenFields; | ||
}; | ||
this.triggerOnFieldsChange = function (namePathList, filedErrors) { | ||
}); | ||
_defineProperty(this, "triggerOnFieldsChange", function (namePathList, filedErrors) { | ||
var onFieldsChange = _this.callbacks.onFieldsChange; | ||
if (onFieldsChange) { | ||
var fields = _this.getFields(); | ||
/** | ||
@@ -728,5 +750,5 @@ * Fill errors since `fields` may be replaced by controlled fields | ||
var cache = new NameMap(); | ||
filedErrors.forEach(function (_ref4) { | ||
var name = _ref4.name, | ||
errors = _ref4.errors; | ||
filedErrors.forEach(function (_ref6) { | ||
var name = _ref6.name, | ||
errors = _ref6.errors; | ||
cache.set(name, errors); | ||
@@ -739,4 +761,4 @@ }); | ||
} | ||
var changedFields = fields.filter(function (_ref5) { | ||
var fieldName = _ref5.name; | ||
var changedFields = fields.filter(function (_ref7) { | ||
var fieldName = _ref7.name; | ||
return containsNamePath(namePathList, fieldName); | ||
@@ -748,5 +770,5 @@ }); | ||
} | ||
}; | ||
}); | ||
// =========================== Validate =========================== | ||
this.validateFields = function (arg1, arg2) { | ||
_defineProperty(this, "validateFields", function (arg1, arg2) { | ||
var _options; | ||
@@ -764,4 +786,6 @@ _this.warningUnhooked(); | ||
var namePathList = provideNameList ? nameList.map(getNamePath) : []; | ||
// Collect result in promise list | ||
var promiseList = []; | ||
// We temp save the path which need trigger for `onFieldsChange` | ||
@@ -776,2 +800,3 @@ var TMP_SPLIT = String(Date.now()); | ||
} | ||
// Skip if without rule | ||
@@ -783,2 +808,3 @@ if (!field.props.rules || !field.props.rules.length) { | ||
validateNamePathList.add(fieldNamePath.join(TMP_SPLIT)); | ||
// Add field validate rule in to promise list | ||
@@ -789,2 +815,3 @@ if (!provideNameList || containsNamePath(namePathList, fieldNamePath, recursive)) { | ||
}, options)); | ||
// Wrap promise with field | ||
@@ -801,5 +828,5 @@ promiseList.push(promise.then(function () { | ||
var mergedWarnings = []; | ||
(_ruleErrors$forEach = ruleErrors.forEach) === null || _ruleErrors$forEach === void 0 ? void 0 : _ruleErrors$forEach.call(ruleErrors, function (_ref6) { | ||
var warningOnly = _ref6.rule.warningOnly, | ||
errors = _ref6.errors; | ||
(_ruleErrors$forEach = ruleErrors.forEach) === null || _ruleErrors$forEach === void 0 ? void 0 : _ruleErrors$forEach.call(ruleErrors, function (_ref8) { | ||
var warningOnly = _ref8.rule.warningOnly, | ||
errors = _ref8.errors; | ||
if (warningOnly) { | ||
@@ -828,2 +855,3 @@ mergedWarnings.push.apply(mergedWarnings, _toConsumableArray(errors)); | ||
_this.lastValidatePromise = summaryPromise; | ||
// Notify fields with rule that validate has finished and need update | ||
@@ -833,4 +861,4 @@ summaryPromise.catch(function (results) { | ||
}).then(function (results) { | ||
var resultNamePathList = results.map(function (_ref7) { | ||
var name = _ref7.name; | ||
var resultNamePathList = results.map(function (_ref9) { | ||
var name = _ref9.name; | ||
return name; | ||
@@ -858,2 +886,3 @@ }); | ||
}); | ||
// Do not throw in console | ||
@@ -863,2 +892,3 @@ returnPromise.catch(function (e) { | ||
}); | ||
// `validating` changed. Trigger `onFieldsChange` | ||
@@ -870,5 +900,5 @@ var triggerNamePathList = namePathList.filter(function (namePath) { | ||
return returnPromise; | ||
}; | ||
}); | ||
// ============================ Submit ============================ | ||
this.submit = function () { | ||
_defineProperty(this, "submit", function () { | ||
_this.warningUnhooked(); | ||
@@ -891,3 +921,3 @@ _this.validateFields().then(function (values) { | ||
}); | ||
}; | ||
}); | ||
this.forceRootUpdate = forceRootUpdate; | ||
@@ -894,0 +924,0 @@ }); |
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; | ||
import warning from "rc-util/es/warning"; | ||
import FieldContext, { HOOK_MARK } from './FieldContext'; | ||
import { useState, useContext, useEffect, useRef, useMemo } from 'react'; | ||
import { getNamePath, getValue } from './utils/valueUtil'; | ||
import { isFormInstance } from './utils/typeUtil'; | ||
import { useContext, useEffect, useMemo, useRef, useState } from 'react'; | ||
import FieldContext, { HOOK_MARK } from "./FieldContext"; | ||
import { isFormInstance } from "./utils/typeUtil"; | ||
import { getNamePath, getValue } from "./utils/valueUtil"; | ||
export function stringify(value) { | ||
@@ -43,2 +43,3 @@ try { | ||
var isValidForm = formInstance && formInstance._init; | ||
// Warning if not exist form instance | ||
@@ -64,2 +65,3 @@ if (process.env.NODE_ENV !== 'production') { | ||
var nextValueStr = stringify(newValue); | ||
// Compare stringify in case it's nest object | ||
@@ -71,5 +73,11 @@ if (valueStrRef.current !== nextValueStr) { | ||
}); | ||
// TODO: We can improve this perf in future | ||
var initialValue = getValue(options.preserve ? getFieldsValue(true) : getFieldsValue(), namePathRef.current); | ||
setValue(initialValue); | ||
// React 18 has the bug that will queue update twice even the value is not changed | ||
// ref: https://github.com/facebook/react/issues/27213 | ||
if (value !== initialValue) { | ||
setValue(initialValue); | ||
} | ||
return cancelRegister; | ||
@@ -76,0 +84,0 @@ }, |
@@ -5,4 +5,6 @@ import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; | ||
import _createClass from "@babel/runtime/helpers/esm/createClass"; | ||
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; | ||
import _typeof from "@babel/runtime/helpers/esm/typeof"; | ||
var SPLIT = '__@field_split__'; | ||
/** | ||
@@ -18,2 +20,3 @@ * Convert name path into string to fast the fetch speed of Map. | ||
} | ||
/** | ||
@@ -25,3 +28,3 @@ * NameMap like a `Map` but accepts `string[]` as key. | ||
_classCallCheck(this, NameMap); | ||
this.kvs = new Map(); | ||
_defineProperty(this, "kvs", new Map()); | ||
} | ||
@@ -54,2 +57,3 @@ _createClass(NameMap, [{ | ||
} | ||
// Since we only use this in test, let simply realize this | ||
@@ -56,0 +60,0 @@ }, { |
@@ -9,6 +9,8 @@ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; | ||
import warning from "rc-util/es/warning"; | ||
import { defaultValidateMessages } from './messages'; | ||
import { defaultValidateMessages } from "./messages"; | ||
import { merge } from "rc-util/es/utils/set"; | ||
// Remove incorrect original ts define | ||
var AsyncValidator = RawAsyncValidator; | ||
/** | ||
@@ -42,2 +44,3 @@ * Replace with template. | ||
delete cloneRule.ruleIndex; | ||
// https://github.com/ant-design/ant-design/issues/40497#issuecomment-1422282378 | ||
@@ -58,2 +61,3 @@ AsyncValidator.warning = function () { | ||
} | ||
// We should special handle array validate | ||
@@ -127,2 +131,3 @@ subRuleField = null; | ||
var name = namePath.join('.'); | ||
// Fill rule with context | ||
@@ -134,2 +139,3 @@ var filledRules = rules.map(function (currentRule, ruleIndex) { | ||
}); | ||
// Replace validator if needed | ||
@@ -139,2 +145,3 @@ if (originValidatorFunc) { | ||
var hasPromise = false; | ||
// Wrap callback only accept when promise not provided | ||
@@ -153,5 +160,7 @@ var wrappedCallback = function wrappedCallback() { | ||
}; | ||
// Get promise | ||
var promise = originValidatorFunc(rule, val, wrappedCallback); | ||
hasPromise = promise && typeof promise.then === 'function' && typeof promise.catch === 'function'; | ||
/** | ||
@@ -186,2 +195,3 @@ * 1. Use promise as the first priority. | ||
}); | ||
// Do validate rules | ||
@@ -223,2 +233,3 @@ var summaryPromise; | ||
/* eslint-enable */ | ||
resolve([]); | ||
@@ -250,2 +261,3 @@ case 13: | ||
} | ||
// Internal catch error to avoid console error log. | ||
@@ -252,0 +264,0 @@ summaryPromise.catch(function (e) { |
@@ -5,4 +5,5 @@ import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; | ||
import setValue from "rc-util/es/utils/set"; | ||
import { toArray } from './typeUtil'; | ||
import { toArray } from "./typeUtil"; | ||
export { getValue, setValue }; | ||
/** | ||
@@ -26,2 +27,3 @@ * Convert name to internal supported format. | ||
} | ||
/** | ||
@@ -39,2 +41,3 @@ * Check if `namePathList` includes `namePath`. | ||
} | ||
/** | ||
@@ -58,2 +61,5 @@ * Check if `namePath` is super set or equal of `subNamePath`. | ||
} | ||
// Like `shallowEqual`, but we not check the data which may cause re-render | ||
export function isSimilar(source, target) { | ||
@@ -88,2 +94,3 @@ if (source === target) { | ||
} | ||
/** | ||
@@ -90,0 +97,0 @@ * Moves an array item from one position in an array to another. |
import * as React from 'react'; | ||
import type { FormInstance, InternalNamePath, Meta, NamePath, Rule, Store, InternalFormInstance, StoreValue, EventArgs } from './interface'; | ||
import type { EventArgs, FormInstance, InternalFormInstance, InternalNamePath, Meta, NamePath, Rule, Store, StoreValue } from './interface'; | ||
export type ShouldUpdate<Values = any> = boolean | ((prevValues: Values, nextValues: Values, info: { | ||
@@ -27,2 +27,6 @@ source?: string; | ||
validateTrigger?: string | string[] | false; | ||
/** | ||
* Trigger will after configured milliseconds. | ||
*/ | ||
validateDebounce?: number; | ||
validateFirst?: boolean | 'parallel'; | ||
@@ -29,0 +33,0 @@ valuePropName?: string; |
270
lib/Field.js
@@ -11,3 +11,4 @@ "use strict"; | ||
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); | ||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); | ||
var _regeneratorRuntime2 = _interopRequireDefault(require("@babel/runtime/helpers/regeneratorRuntime")); | ||
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator")); | ||
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2")); | ||
@@ -20,5 +21,6 @@ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); | ||
var _createSuper2 = _interopRequireDefault(require("@babel/runtime/helpers/createSuper")); | ||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); | ||
var _toArray = _interopRequireDefault(require("rc-util/lib/Children/toArray")); | ||
var _isEqual = _interopRequireDefault(require("rc-util/lib/isEqual")); | ||
var _warning = _interopRequireDefault(require("rc-util/lib/warning")); | ||
var _isEqual = _interopRequireDefault(require("rc-util/lib/isEqual")); | ||
var React = _interopRequireWildcard(require("react")); | ||
@@ -40,2 +42,4 @@ var _FieldContext = _interopRequireWildcard(require("./FieldContext")); | ||
} | ||
// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style | ||
// We use Class instead of Hooks here since it will cost much code by using Hooks. | ||
@@ -50,8 +54,9 @@ var Field = /*#__PURE__*/function (_React$Component) { | ||
_this = _super.call(this, props); | ||
// Register on init | ||
_this.state = { | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", { | ||
resetCount: 0 | ||
}; | ||
_this.cancelRegisterFunc = null; | ||
_this.mounted = false; | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "cancelRegisterFunc", null); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "mounted", false); | ||
/** | ||
@@ -61,3 +66,3 @@ * Follow state should not management in State since it will async update by React. | ||
*/ | ||
_this.touched = false; | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "touched", false); | ||
/** | ||
@@ -68,8 +73,8 @@ * Mark when touched & validated. Currently only used for `dependencies`. | ||
*/ | ||
_this.dirty = false; | ||
_this.validatePromise = void 0; | ||
_this.prevValidating = void 0; | ||
_this.errors = EMPTY_ERRORS; | ||
_this.warnings = EMPTY_ERRORS; | ||
_this.cancelRegister = function () { | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "dirty", false); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "validatePromise", void 0); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "prevValidating", void 0); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "errors", EMPTY_ERRORS); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "warnings", EMPTY_ERRORS); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "cancelRegister", function () { | ||
var _this$props = _this.props, | ||
@@ -83,5 +88,5 @@ preserve = _this$props.preserve, | ||
_this.cancelRegisterFunc = null; | ||
}; | ||
}); | ||
// ================================== Utils ================================== | ||
_this.getNamePath = function () { | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getNamePath", function () { | ||
var _this$props2 = _this.props, | ||
@@ -93,4 +98,4 @@ name = _this$props2.name, | ||
return name !== undefined ? [].concat((0, _toConsumableArray2.default)(prefixName), (0, _toConsumableArray2.default)(name)) : []; | ||
}; | ||
_this.getRules = function () { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getRules", function () { | ||
var _this$props3 = _this.props, | ||
@@ -106,5 +111,6 @@ _this$props3$rules = _this$props3.rules, | ||
}); | ||
}; | ||
_this.refresh = function () { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "refresh", function () { | ||
if (!_this.mounted) return; | ||
/** | ||
@@ -119,22 +125,22 @@ * Clean up current node. | ||
}); | ||
}; | ||
}); | ||
// Event should only trigger when meta changed | ||
_this.metaCache = null; | ||
_this.triggerMetaEvent = function (destroy) { | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "metaCache", null); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "triggerMetaEvent", function (destroy) { | ||
var onMetaChange = _this.props.onMetaChange; | ||
if (onMetaChange) { | ||
var meta = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, _this.getMeta()), {}, { | ||
var _meta = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, _this.getMeta()), {}, { | ||
destroy: destroy | ||
}); | ||
if (!(0, _isEqual.default)(_this.metaCache, meta)) { | ||
onMetaChange(meta); | ||
if (!(0, _isEqual.default)(_this.metaCache, _meta)) { | ||
onMetaChange(_meta); | ||
} | ||
_this.metaCache = meta; | ||
_this.metaCache = _meta; | ||
} else { | ||
_this.metaCache = null; | ||
} | ||
}; | ||
}); | ||
// ========================= Field Entity Interfaces ========================= | ||
// Trigger by store update. Check if need update the component | ||
_this.onStoreChange = function (prevStore, namePathList, info) { | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onStoreChange", function (prevStore, namePathList, info) { | ||
var _this$props4 = _this.props, | ||
@@ -150,2 +156,3 @@ shouldUpdate = _this$props4.shouldUpdate, | ||
var namePathMatch = namePathList && (0, _valueUtil.containsNamePath)(namePathList, namePath); | ||
// `setFieldsValue` is a quick access to update related status | ||
@@ -175,2 +182,3 @@ if (info.type === 'valueUpdate' && info.source === 'external' && prevValue !== curValue) { | ||
break; | ||
/** | ||
@@ -211,2 +219,3 @@ * In case field with `preserve = false` nest deps like: | ||
} | ||
// Handle update by `setField` with `shouldUpdate` | ||
@@ -256,4 +265,4 @@ if (shouldUpdate && !namePath.length && requireUpdate(shouldUpdate, prevStore, store, prevValue, curValue, info)) { | ||
} | ||
}; | ||
_this.validateRules = function (options) { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "validateRules", function (options) { | ||
// We should fixed namePath & value to avoid developer change then by form function | ||
@@ -266,53 +275,81 @@ var namePath = _this.getNamePath(); | ||
validateOnly = _ref2$validateOnly === void 0 ? false : _ref2$validateOnly; | ||
// Force change to async to avoid rule OOD under renderProps field | ||
var rootPromise = Promise.resolve().then(function () { | ||
if (!_this.mounted) { | ||
return []; | ||
} | ||
var _this$props5 = _this.props, | ||
_this$props5$validate = _this$props5.validateFirst, | ||
validateFirst = _this$props5$validate === void 0 ? false : _this$props5$validate, | ||
messageVariables = _this$props5.messageVariables; | ||
var filteredRules = _this.getRules(); | ||
if (triggerName) { | ||
filteredRules = filteredRules.filter(function (rule) { | ||
return rule; | ||
}).filter(function (rule) { | ||
var validateTrigger = rule.validateTrigger; | ||
if (!validateTrigger) { | ||
return true; | ||
} | ||
var triggerList = (0, _typeUtil.toArray)(validateTrigger); | ||
return triggerList.includes(triggerName); | ||
}); | ||
} | ||
var promise = (0, _validateUtil.validateRules)(namePath, currentValue, filteredRules, options, validateFirst, messageVariables); | ||
promise.catch(function (e) { | ||
return e; | ||
}).then(function () { | ||
var ruleErrors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : EMPTY_ERRORS; | ||
if (_this.validatePromise === rootPromise) { | ||
var _ruleErrors$forEach; | ||
_this.validatePromise = null; | ||
// Get errors & warnings | ||
var nextErrors = []; | ||
var nextWarnings = []; | ||
(_ruleErrors$forEach = ruleErrors.forEach) === null || _ruleErrors$forEach === void 0 ? void 0 : _ruleErrors$forEach.call(ruleErrors, function (_ref3) { | ||
var warningOnly = _ref3.rule.warningOnly, | ||
_ref3$errors = _ref3.errors, | ||
errors = _ref3$errors === void 0 ? EMPTY_ERRORS : _ref3$errors; | ||
if (warningOnly) { | ||
nextWarnings.push.apply(nextWarnings, (0, _toConsumableArray2.default)(errors)); | ||
} else { | ||
nextErrors.push.apply(nextErrors, (0, _toConsumableArray2.default)(errors)); | ||
var rootPromise = Promise.resolve().then( /*#__PURE__*/(0, _asyncToGenerator2.default)( /*#__PURE__*/(0, _regeneratorRuntime2.default)().mark(function _callee() { | ||
var _this$props5, _this$props5$validate, validateFirst, messageVariables, validateDebounce, filteredRules, promise; | ||
return (0, _regeneratorRuntime2.default)().wrap(function _callee$(_context) { | ||
while (1) switch (_context.prev = _context.next) { | ||
case 0: | ||
if (_this.mounted) { | ||
_context.next = 2; | ||
break; | ||
} | ||
}); | ||
_this.errors = nextErrors; | ||
_this.warnings = nextWarnings; | ||
_this.triggerMetaEvent(); | ||
_this.reRender(); | ||
return _context.abrupt("return", []); | ||
case 2: | ||
_this$props5 = _this.props, _this$props5$validate = _this$props5.validateFirst, validateFirst = _this$props5$validate === void 0 ? false : _this$props5$validate, messageVariables = _this$props5.messageVariables, validateDebounce = _this$props5.validateDebounce; // Start validate | ||
filteredRules = _this.getRules(); | ||
if (triggerName) { | ||
filteredRules = filteredRules.filter(function (rule) { | ||
return rule; | ||
}).filter(function (rule) { | ||
var validateTrigger = rule.validateTrigger; | ||
if (!validateTrigger) { | ||
return true; | ||
} | ||
var triggerList = (0, _typeUtil.toArray)(validateTrigger); | ||
return triggerList.includes(triggerName); | ||
}); | ||
} | ||
// Wait for debounce. Skip if no `triggerName` since its from `validateFields / submit` | ||
if (!(validateDebounce && triggerName)) { | ||
_context.next = 10; | ||
break; | ||
} | ||
_context.next = 8; | ||
return new Promise(function (resolve) { | ||
setTimeout(resolve, validateDebounce); | ||
}); | ||
case 8: | ||
if (!(_this.validatePromise !== rootPromise)) { | ||
_context.next = 10; | ||
break; | ||
} | ||
return _context.abrupt("return", []); | ||
case 10: | ||
promise = (0, _validateUtil.validateRules)(namePath, currentValue, filteredRules, options, validateFirst, messageVariables); | ||
promise.catch(function (e) { | ||
return e; | ||
}).then(function () { | ||
var ruleErrors = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : EMPTY_ERRORS; | ||
if (_this.validatePromise === rootPromise) { | ||
var _ruleErrors$forEach; | ||
_this.validatePromise = null; | ||
// Get errors & warnings | ||
var nextErrors = []; | ||
var nextWarnings = []; | ||
(_ruleErrors$forEach = ruleErrors.forEach) === null || _ruleErrors$forEach === void 0 ? void 0 : _ruleErrors$forEach.call(ruleErrors, function (_ref4) { | ||
var warningOnly = _ref4.rule.warningOnly, | ||
_ref4$errors = _ref4.errors, | ||
errors = _ref4$errors === void 0 ? EMPTY_ERRORS : _ref4$errors; | ||
if (warningOnly) { | ||
nextWarnings.push.apply(nextWarnings, (0, _toConsumableArray2.default)(errors)); | ||
} else { | ||
nextErrors.push.apply(nextErrors, (0, _toConsumableArray2.default)(errors)); | ||
} | ||
}); | ||
_this.errors = nextErrors; | ||
_this.warnings = nextWarnings; | ||
_this.triggerMetaEvent(); | ||
_this.reRender(); | ||
} | ||
}); | ||
return _context.abrupt("return", promise); | ||
case 13: | ||
case "end": | ||
return _context.stop(); | ||
} | ||
}); | ||
return promise; | ||
}); | ||
}, _callee); | ||
}))); | ||
if (validateOnly) { | ||
@@ -326,13 +363,14 @@ return rootPromise; | ||
_this.triggerMetaEvent(); | ||
// Force trigger re-render since we need sync renderProps with new meta | ||
_this.reRender(); | ||
return rootPromise; | ||
}; | ||
_this.isFieldValidating = function () { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isFieldValidating", function () { | ||
return !!_this.validatePromise; | ||
}; | ||
_this.isFieldTouched = function () { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isFieldTouched", function () { | ||
return _this.touched; | ||
}; | ||
_this.isFieldDirty = function () { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isFieldDirty", function () { | ||
// Touched or validate or has initialValue | ||
@@ -342,2 +380,3 @@ if (_this.dirty || _this.props.initialValue !== undefined) { | ||
} | ||
// Form set initialValue | ||
@@ -351,20 +390,20 @@ var fieldContext = _this.props.fieldContext; | ||
return false; | ||
}; | ||
_this.getErrors = function () { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getErrors", function () { | ||
return _this.errors; | ||
}; | ||
_this.getWarnings = function () { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getWarnings", function () { | ||
return _this.warnings; | ||
}; | ||
_this.isListField = function () { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isListField", function () { | ||
return _this.props.isListField; | ||
}; | ||
_this.isList = function () { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isList", function () { | ||
return _this.props.isList; | ||
}; | ||
_this.isPreserve = function () { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isPreserve", function () { | ||
return _this.props.preserve; | ||
}; | ||
}); | ||
// ============================= Child Component ============================= | ||
_this.getMeta = function () { | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getMeta", function () { | ||
// Make error & validating in cache to save perf | ||
@@ -381,12 +420,13 @@ _this.prevValidating = _this.isFieldValidating(); | ||
return meta; | ||
}; | ||
}); | ||
// Only return validate child node. If invalidate, will do nothing about field. | ||
_this.getOnlyChild = function (children) { | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getOnlyChild", function (children) { | ||
// Support render props | ||
if (typeof children === 'function') { | ||
var meta = _this.getMeta(); | ||
return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, _this.getOnlyChild(children(_this.getControlled(), meta, _this.props.fieldContext))), {}, { | ||
var _meta2 = _this.getMeta(); | ||
return (0, _objectSpread2.default)((0, _objectSpread2.default)({}, _this.getOnlyChild(children(_this.getControlled(), _meta2, _this.props.fieldContext))), {}, { | ||
isFunction: true | ||
}); | ||
} | ||
// Filed element only | ||
@@ -404,10 +444,10 @@ var childList = (0, _toArray.default)(children); | ||
}; | ||
}; | ||
}); | ||
// ============================== Field Control ============================== | ||
_this.getValue = function (store) { | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getValue", function (store) { | ||
var getFieldsValue = _this.props.fieldContext.getFieldsValue; | ||
var namePath = _this.getNamePath(); | ||
return (0, _valueUtil.getValue)(store || getFieldsValue(true), namePath); | ||
}; | ||
_this.getControlled = function () { | ||
}); | ||
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "getControlled", function () { | ||
var childProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
@@ -432,5 +472,7 @@ var _this$props6 = _this.props, | ||
}; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
var originTriggerFunc = childProps[trigger]; | ||
var control = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, childProps), mergedGetValueProps(value)); | ||
// Add trigger | ||
@@ -463,2 +505,3 @@ control[trigger] = function () { | ||
}; | ||
// Add validateTrigger | ||
@@ -473,2 +516,3 @@ var validateTriggerList = (0, _typeUtil.toArray)(mergedValidateTrigger || []); | ||
} | ||
// Always use latest rules | ||
@@ -488,3 +532,3 @@ var rules = _this.props.rules; | ||
return control; | ||
}; | ||
}); | ||
if (props.fieldContext) { | ||
@@ -505,2 +549,3 @@ var getInternalHooks = props.fieldContext.getInternalHooks; | ||
this.mounted = true; | ||
// Register on init | ||
@@ -513,2 +558,3 @@ if (fieldContext) { | ||
} | ||
// One more render for component in case fields not ready | ||
@@ -540,2 +586,3 @@ if (shouldUpdate === true) { | ||
isFunction = _this$getOnlyChild.isFunction; | ||
// Not need to `cloneElement` since user can handle this in render function self | ||
@@ -558,10 +605,10 @@ var returnChildNode; | ||
}(React.Component); | ||
Field.contextType = _FieldContext.default; | ||
Field.defaultProps = { | ||
(0, _defineProperty2.default)(Field, "contextType", _FieldContext.default); | ||
(0, _defineProperty2.default)(Field, "defaultProps", { | ||
trigger: 'onChange', | ||
valuePropName: 'value' | ||
}; | ||
function WrapperField(_ref5) { | ||
var name = _ref5.name, | ||
restProps = (0, _objectWithoutProperties2.default)(_ref5, _excluded); | ||
}); | ||
function WrapperField(_ref6) { | ||
var name = _ref6.name, | ||
restProps = (0, _objectWithoutProperties2.default)(_ref6, _excluded); | ||
var fieldContext = React.useContext(_FieldContext.default); | ||
@@ -574,2 +621,3 @@ var listContext = React.useContext(_ListContext.default); | ||
} | ||
// Warning if it's a directly list field. | ||
@@ -576,0 +624,0 @@ // We can still support multiple level field preserve. |
@@ -12,2 +12,3 @@ "use strict"; | ||
var HOOK_MARK = 'RC_FORM_INTERNAL_HOOKS'; | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
@@ -14,0 +15,0 @@ exports.HOOK_MARK = HOOK_MARK; |
@@ -38,2 +38,3 @@ "use strict"; | ||
var formContext = React.useContext(_FormContext.default); | ||
// We customize handle event since Context will makes all the consumer re-render: | ||
@@ -44,9 +45,10 @@ // https://reactjs.org/docs/context.html#contextprovider | ||
formInstance = _useForm2[0]; | ||
var _formInstance$getInte = formInstance.getInternalHooks(_FieldContext.HOOK_MARK), | ||
useSubscribe = _formInstance$getInte.useSubscribe, | ||
setInitialValues = _formInstance$getInte.setInitialValues, | ||
setCallbacks = _formInstance$getInte.setCallbacks, | ||
setValidateMessages = _formInstance$getInte.setValidateMessages, | ||
setPreserve = _formInstance$getInte.setPreserve, | ||
destroyForm = _formInstance$getInte.destroyForm; | ||
var _getInternalHooks = formInstance.getInternalHooks(_FieldContext.HOOK_MARK), | ||
useSubscribe = _getInternalHooks.useSubscribe, | ||
setInitialValues = _getInternalHooks.setInitialValues, | ||
setCallbacks = _getInternalHooks.setCallbacks, | ||
setValidateMessages = _getInternalHooks.setValidateMessages, | ||
setPreserve = _getInternalHooks.setPreserve, | ||
destroyForm = _getInternalHooks.destroyForm; | ||
// Pass ref with form instance | ||
@@ -56,2 +58,3 @@ React.useImperativeHandle(ref, function () { | ||
}); | ||
// Register form into Context | ||
@@ -64,2 +67,3 @@ React.useEffect(function () { | ||
}, [formContext, formInstance, name]); | ||
// Pass props to store | ||
@@ -87,2 +91,3 @@ setValidateMessages((0, _objectSpread2.default)((0, _objectSpread2.default)({}, formContext.validateMessages), validateMessages)); | ||
setPreserve(preserve); | ||
// Set initial value, init store value when first mount | ||
@@ -99,2 +104,3 @@ var mountRef = React.useRef(null); | ||
[]); | ||
// Prepare children by `children` type | ||
@@ -104,9 +110,11 @@ var childrenNode; | ||
if (childrenRenderProps) { | ||
var values = formInstance.getFieldsValue(true); | ||
childrenNode = children(values, formInstance); | ||
var _values = formInstance.getFieldsValue(true); | ||
childrenNode = children(_values, formInstance); | ||
} else { | ||
childrenNode = children; | ||
} | ||
// Not use subscribe when using render props | ||
useSubscribe(!childrenRenderProps); | ||
// Listen if fields provided. We use ref to save prev data here to avoid additional render | ||
@@ -113,0 +121,0 @@ var prevFieldsRef = React.useRef(); |
@@ -23,4 +23,4 @@ import * as React from 'react'; | ||
declare const RefForm: RefFormType; | ||
export { FormInstance, Field, List, useForm, FormProvider, FieldContext, ListContext, useWatch }; | ||
export type { FormProps }; | ||
export { Field, List, useForm, FormProvider, FieldContext, ListContext, useWatch }; | ||
export type { FormProps, FormInstance }; | ||
export default RefForm; |
@@ -188,3 +188,3 @@ import type { ReactElement } from 'react'; | ||
isFieldValidating: (name: NamePath) => boolean; | ||
isFieldsValidating: (nameList: NamePath[]) => boolean; | ||
isFieldsValidating: (nameList?: NamePath[]) => boolean; | ||
resetFields: (fields?: NamePath[]) => void; | ||
@@ -191,0 +191,0 @@ setFields: (fields: FieldData[]) => void; |
@@ -40,2 +40,3 @@ "use strict"; | ||
}, [context, prefixName]); | ||
// List context | ||
@@ -51,2 +52,3 @@ var listContext = React.useMemo(function () { | ||
}, [prefixName]); | ||
// User should not pass `children` as other type. | ||
@@ -113,2 +115,3 @@ if (typeof children !== 'function') { | ||
}); | ||
// Trigger store change | ||
@@ -124,2 +127,3 @@ onChange(newValue.filter(function (_, valueIndex) { | ||
var newValue = getNewValue(); | ||
// Do not handle out of range | ||
@@ -130,2 +134,3 @@ if (from < 0 || from >= newValue.length || to < 0 || to >= newValue.length) { | ||
keyManager.keys = (0, _valueUtil.move)(keyManager.keys, from, to); | ||
// Trigger store change | ||
@@ -132,0 +137,0 @@ onChange((0, _valueUtil.move)(newValue, from, to)); |
@@ -16,2 +16,3 @@ "use strict"; | ||
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); | ||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); | ||
var _warning = _interopRequireDefault(require("rc-util/lib/warning")); | ||
@@ -29,13 +30,13 @@ var React = _interopRequireWildcard(require("react")); | ||
(0, _classCallCheck2.default)(this, FormStore); | ||
this.formHooked = false; | ||
this.forceRootUpdate = void 0; | ||
this.subscribable = true; | ||
this.store = {}; | ||
this.fieldEntities = []; | ||
this.initialValues = {}; | ||
this.callbacks = {}; | ||
this.validateMessages = null; | ||
this.preserve = null; | ||
this.lastValidatePromise = null; | ||
this.getForm = function () { | ||
(0, _defineProperty2.default)(this, "formHooked", false); | ||
(0, _defineProperty2.default)(this, "forceRootUpdate", void 0); | ||
(0, _defineProperty2.default)(this, "subscribable", true); | ||
(0, _defineProperty2.default)(this, "store", {}); | ||
(0, _defineProperty2.default)(this, "fieldEntities", []); | ||
(0, _defineProperty2.default)(this, "initialValues", {}); | ||
(0, _defineProperty2.default)(this, "callbacks", {}); | ||
(0, _defineProperty2.default)(this, "validateMessages", null); | ||
(0, _defineProperty2.default)(this, "preserve", null); | ||
(0, _defineProperty2.default)(this, "lastValidatePromise", null); | ||
(0, _defineProperty2.default)(this, "getForm", function () { | ||
return { | ||
@@ -60,5 +61,5 @@ getFieldValue: _this.getFieldValue, | ||
}; | ||
}; | ||
}); | ||
// ======================== Internal Hooks ======================== | ||
this.getInternalHooks = function (key) { | ||
(0, _defineProperty2.default)(this, "getInternalHooks", function (key) { | ||
if (key === _FieldContext.HOOK_MARK) { | ||
@@ -83,6 +84,6 @@ _this.formHooked = true; | ||
return null; | ||
}; | ||
this.useSubscribe = function (subscribable) { | ||
}); | ||
(0, _defineProperty2.default)(this, "useSubscribe", function (subscribable) { | ||
_this.subscribable = subscribable; | ||
}; | ||
}); | ||
/** | ||
@@ -92,7 +93,7 @@ * Record prev Form unmount fieldEntities which config preserve false. | ||
*/ | ||
this.prevWithoutPreserves = null; | ||
(0, _defineProperty2.default)(this, "prevWithoutPreserves", null); | ||
/** | ||
* First time `setInitialValues` should update store with initial value | ||
*/ | ||
this.setInitialValues = function (initialValues, init) { | ||
(0, _defineProperty2.default)(this, "setInitialValues", function (initialValues, init) { | ||
_this.initialValues = initialValues || {}; | ||
@@ -102,2 +103,3 @@ if (init) { | ||
var nextStore = (0, _set.merge)(initialValues, _this.store); | ||
// We will take consider prev form unmount fields. | ||
@@ -113,4 +115,4 @@ // When the field is not `preserve`, we need fill this with initialValues instead of store. | ||
} | ||
}; | ||
this.destroyForm = function () { | ||
}); | ||
(0, _defineProperty2.default)(this, "destroyForm", function () { | ||
var prevWithoutPreserves = new _NameMap.default(); | ||
@@ -123,20 +125,21 @@ _this.getFieldEntities(true).forEach(function (entity) { | ||
_this.prevWithoutPreserves = prevWithoutPreserves; | ||
}; | ||
this.getInitialValue = function (namePath) { | ||
}); | ||
(0, _defineProperty2.default)(this, "getInitialValue", function (namePath) { | ||
var initValue = (0, _valueUtil.getValue)(_this.initialValues, namePath); | ||
// Not cloneDeep when without `namePath` | ||
return namePath.length ? (0, _set.merge)(initValue) : initValue; | ||
}; | ||
this.setCallbacks = function (callbacks) { | ||
}); | ||
(0, _defineProperty2.default)(this, "setCallbacks", function (callbacks) { | ||
_this.callbacks = callbacks; | ||
}; | ||
this.setValidateMessages = function (validateMessages) { | ||
}); | ||
(0, _defineProperty2.default)(this, "setValidateMessages", function (validateMessages) { | ||
_this.validateMessages = validateMessages; | ||
}; | ||
this.setPreserve = function (preserve) { | ||
}); | ||
(0, _defineProperty2.default)(this, "setPreserve", function (preserve) { | ||
_this.preserve = preserve; | ||
}; | ||
}); | ||
// ============================= Watch ============================ | ||
this.watchList = []; | ||
this.registerWatch = function (callback) { | ||
(0, _defineProperty2.default)(this, "watchList", []); | ||
(0, _defineProperty2.default)(this, "registerWatch", function (callback) { | ||
_this.watchList.push(callback); | ||
@@ -148,4 +151,4 @@ return function () { | ||
}; | ||
}; | ||
this.notifyWatch = function () { | ||
}); | ||
(0, _defineProperty2.default)(this, "notifyWatch", function () { | ||
var namePath = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : []; | ||
@@ -160,6 +163,6 @@ // No need to cost perf when nothing need to watch | ||
} | ||
}; | ||
}); | ||
// ========================== Dev Warning ========================= | ||
this.timeoutId = null; | ||
this.warningUnhooked = function () { | ||
(0, _defineProperty2.default)(this, "timeoutId", null); | ||
(0, _defineProperty2.default)(this, "warningUnhooked", function () { | ||
if (process.env.NODE_ENV !== 'production' && !_this.timeoutId && typeof window !== 'undefined') { | ||
@@ -173,7 +176,7 @@ _this.timeoutId = setTimeout(function () { | ||
} | ||
}; | ||
}); | ||
// ============================ Store ============================= | ||
this.updateStore = function (nextStore) { | ||
(0, _defineProperty2.default)(this, "updateStore", function (nextStore) { | ||
_this.store = nextStore; | ||
}; | ||
}); | ||
// ============================ Fields ============================ | ||
@@ -184,3 +187,3 @@ /** | ||
*/ | ||
this.getFieldEntities = function () { | ||
(0, _defineProperty2.default)(this, "getFieldEntities", function () { | ||
var pure = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; | ||
@@ -193,4 +196,4 @@ if (!pure) { | ||
}); | ||
}; | ||
this.getFieldsMap = function () { | ||
}); | ||
(0, _defineProperty2.default)(this, "getFieldsMap", function () { | ||
var pure = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; | ||
@@ -203,4 +206,4 @@ var cache = new _NameMap.default(); | ||
return cache; | ||
}; | ||
this.getFieldEntitiesForNamePathList = function (nameList) { | ||
}); | ||
(0, _defineProperty2.default)(this, "getFieldEntitiesForNamePathList", function (nameList) { | ||
if (!nameList) { | ||
@@ -216,5 +219,6 @@ return _this.getFieldEntities(true); | ||
}); | ||
}; | ||
this.getFieldsValue = function (nameList, filterFunc) { | ||
}); | ||
(0, _defineProperty2.default)(this, "getFieldsValue", function (nameList, filterFunc) { | ||
_this.warningUnhooked(); | ||
// Fill args | ||
@@ -237,12 +241,13 @@ var mergedNameList; | ||
fieldEntities.forEach(function (entity) { | ||
var _entity$isListField; | ||
var _isListField, _ref3; | ||
var namePath = 'INVALIDATE_NAME_PATH' in entity ? entity.INVALIDATE_NAME_PATH : entity.getNamePath(); | ||
// Ignore when it's a list item and not specific the namePath, | ||
// since parent field is already take in count | ||
if (mergedStrict) { | ||
var _entity$isList; | ||
if ((_entity$isList = entity.isList) === null || _entity$isList === void 0 ? void 0 : _entity$isList.call(entity)) { | ||
var _isList, _ref2; | ||
if ((_isList = (_ref2 = entity).isList) !== null && _isList !== void 0 && _isList.call(_ref2)) { | ||
return; | ||
} | ||
} else if (!mergedNameList && ((_entity$isListField = entity.isListField) === null || _entity$isListField === void 0 ? void 0 : _entity$isListField.call(entity))) { | ||
} else if (!mergedNameList && (_isListField = (_ref3 = entity).isListField) !== null && _isListField !== void 0 && _isListField.call(_ref3)) { | ||
return; | ||
@@ -260,9 +265,9 @@ } | ||
return (0, _valueUtil.cloneByNamePathList)(_this.store, filteredNameList.map(_valueUtil.getNamePath)); | ||
}; | ||
this.getFieldValue = function (name) { | ||
}); | ||
(0, _defineProperty2.default)(this, "getFieldValue", function (name) { | ||
_this.warningUnhooked(); | ||
var namePath = (0, _valueUtil.getNamePath)(name); | ||
return (0, _valueUtil.getValue)(_this.store, namePath); | ||
}; | ||
this.getFieldsError = function (nameList) { | ||
}); | ||
(0, _defineProperty2.default)(this, "getFieldsError", function (nameList) { | ||
_this.warningUnhooked(); | ||
@@ -284,4 +289,4 @@ var fieldEntities = _this.getFieldEntitiesForNamePathList(nameList); | ||
}); | ||
}; | ||
this.getFieldError = function (name) { | ||
}); | ||
(0, _defineProperty2.default)(this, "getFieldError", function (name) { | ||
_this.warningUnhooked(); | ||
@@ -291,4 +296,4 @@ var namePath = (0, _valueUtil.getNamePath)(name); | ||
return fieldError.errors; | ||
}; | ||
this.getFieldWarning = function (name) { | ||
}); | ||
(0, _defineProperty2.default)(this, "getFieldWarning", function (name) { | ||
_this.warningUnhooked(); | ||
@@ -298,4 +303,4 @@ var namePath = (0, _valueUtil.getNamePath)(name); | ||
return fieldError.warnings; | ||
}; | ||
this.isFieldsTouched = function () { | ||
}); | ||
(0, _defineProperty2.default)(this, "isFieldsTouched", function () { | ||
_this.warningUnhooked(); | ||
@@ -327,2 +332,3 @@ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { | ||
}; | ||
// ===== Will get fully compare when not config namePathList ===== | ||
@@ -332,2 +338,3 @@ if (!namePathList) { | ||
} | ||
// Generate a nest tree for validate | ||
@@ -340,2 +347,3 @@ var map = new _NameMap.default(); | ||
var fieldNamePath = field.getNamePath(); | ||
// Find matched entity and put into list | ||
@@ -352,2 +360,3 @@ namePathList.forEach(function (shortNamePath) { | ||
}); | ||
// Check if NameMap value is touched | ||
@@ -357,13 +366,13 @@ var isNamePathListTouched = function isNamePathListTouched(entities) { | ||
}; | ||
var namePathListEntities = map.map(function (_ref2) { | ||
var value = _ref2.value; | ||
var namePathListEntities = map.map(function (_ref4) { | ||
var value = _ref4.value; | ||
return value; | ||
}); | ||
return isAllFieldsTouched ? namePathListEntities.every(isNamePathListTouched) : namePathListEntities.some(isNamePathListTouched); | ||
}; | ||
this.isFieldTouched = function (name) { | ||
}); | ||
(0, _defineProperty2.default)(this, "isFieldTouched", function (name) { | ||
_this.warningUnhooked(); | ||
return _this.isFieldsTouched([name]); | ||
}; | ||
this.isFieldsValidating = function (nameList) { | ||
}); | ||
(0, _defineProperty2.default)(this, "isFieldsValidating", function (nameList) { | ||
_this.warningUnhooked(); | ||
@@ -381,7 +390,7 @@ var fieldEntities = _this.getFieldEntities(); | ||
}); | ||
}; | ||
this.isFieldValidating = function (name) { | ||
}); | ||
(0, _defineProperty2.default)(this, "isFieldValidating", function (name) { | ||
_this.warningUnhooked(); | ||
return _this.isFieldsValidating([name]); | ||
}; | ||
}); | ||
/** | ||
@@ -391,3 +400,3 @@ * Reset Field with field `initialValue` prop. | ||
*/ | ||
this.resetWithFieldInitialValue = function () { | ||
(0, _defineProperty2.default)(this, "resetWithFieldInitialValue", function () { | ||
var info = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; | ||
@@ -400,2 +409,3 @@ // Create cache | ||
var namePath = field.getNamePath(); | ||
// Record only if has `initialValue` | ||
@@ -411,2 +421,3 @@ if (initialValue !== undefined) { | ||
}); | ||
// Reset | ||
@@ -456,4 +467,4 @@ var resetWithFields = function resetWithFields(entities) { | ||
resetWithFields(requiredFieldEntities); | ||
}; | ||
this.resetFields = function (nameList) { | ||
}); | ||
(0, _defineProperty2.default)(this, "resetFields", function (nameList) { | ||
_this.warningUnhooked(); | ||
@@ -470,2 +481,3 @@ var prevStore = _this.store; | ||
} | ||
// Reset by `nameList` | ||
@@ -484,4 +496,4 @@ var namePathList = nameList.map(_valueUtil.getNamePath); | ||
_this.notifyWatch(namePathList); | ||
}; | ||
this.setFields = function (fields) { | ||
}); | ||
(0, _defineProperty2.default)(this, "setFields", function (fields) { | ||
_this.warningUnhooked(); | ||
@@ -495,2 +507,3 @@ var prevStore = _this.store; | ||
namePathList.push(namePath); | ||
// Value | ||
@@ -506,4 +519,4 @@ if ('value' in data) { | ||
_this.notifyWatch(namePathList); | ||
}; | ||
this.getFields = function () { | ||
}); | ||
(0, _defineProperty2.default)(this, "getFields", function () { | ||
var entities = _this.getFieldEntities(true); | ||
@@ -523,3 +536,3 @@ var fields = entities.map(function (field) { | ||
return fields; | ||
}; | ||
}); | ||
// =========================== Observer =========================== | ||
@@ -529,3 +542,3 @@ /** | ||
*/ | ||
this.initEntityValue = function (entity) { | ||
(0, _defineProperty2.default)(this, "initEntityValue", function (entity) { | ||
var initialValue = entity.props.initialValue; | ||
@@ -539,11 +552,12 @@ if (initialValue !== undefined) { | ||
} | ||
}; | ||
this.isMergedPreserve = function (fieldPreserve) { | ||
}); | ||
(0, _defineProperty2.default)(this, "isMergedPreserve", function (fieldPreserve) { | ||
var mergedPreserve = fieldPreserve !== undefined ? fieldPreserve : _this.preserve; | ||
return mergedPreserve !== null && mergedPreserve !== void 0 ? mergedPreserve : true; | ||
}; | ||
this.registerField = function (entity) { | ||
}); | ||
(0, _defineProperty2.default)(this, "registerField", function (entity) { | ||
_this.fieldEntities.push(entity); | ||
var namePath = entity.getNamePath(); | ||
_this.notifyWatch([namePath]); | ||
// Set initial values | ||
@@ -561,2 +575,3 @@ if (entity.props.initialValue !== undefined) { | ||
} | ||
// un-register field callback | ||
@@ -568,2 +583,3 @@ return function (isListField, preserve) { | ||
}); | ||
// Clean up store value if not preserve | ||
@@ -580,2 +596,3 @@ if (!_this.isMergedPreserve(preserve) && (!isListField || subNamePath.length > 1)) { | ||
_this.updateStore((0, _valueUtil.setValue)(_prevStore, namePath, defaultValue, true)); | ||
// Notify that field is unmount | ||
@@ -585,2 +602,3 @@ _this.notifyObservers(_prevStore, [namePath], { | ||
}); | ||
// Dependencies update | ||
@@ -592,4 +610,4 @@ _this.triggerDependenciesUpdate(_prevStore, namePath); | ||
}; | ||
}; | ||
this.dispatch = function (action) { | ||
}); | ||
(0, _defineProperty2.default)(this, "dispatch", function (action) { | ||
switch (action.type) { | ||
@@ -615,4 +633,4 @@ case 'updateValue': | ||
} | ||
}; | ||
this.notifyObservers = function (prevStore, namePathList, info) { | ||
}); | ||
(0, _defineProperty2.default)(this, "notifyObservers", function (prevStore, namePathList, info) { | ||
if (_this.subscribable) { | ||
@@ -622,4 +640,4 @@ var mergedInfo = (0, _objectSpread2.default)((0, _objectSpread2.default)({}, info), {}, { | ||
}); | ||
_this.getFieldEntities().forEach(function (_ref3) { | ||
var onStoreChange = _ref3.onStoreChange; | ||
_this.getFieldEntities().forEach(function (_ref5) { | ||
var onStoreChange = _ref5.onStoreChange; | ||
onStoreChange(prevStore, namePathList, mergedInfo); | ||
@@ -630,3 +648,3 @@ }); | ||
} | ||
}; | ||
}); | ||
/** | ||
@@ -636,3 +654,3 @@ * Notify dependencies children with parent update | ||
*/ | ||
this.triggerDependenciesUpdate = function (prevStore, namePath) { | ||
(0, _defineProperty2.default)(this, "triggerDependenciesUpdate", function (prevStore, namePath) { | ||
var childrenFields = _this.getDependencyChildrenFields(namePath); | ||
@@ -647,4 +665,4 @@ if (childrenFields.length) { | ||
return childrenFields; | ||
}; | ||
this.updateValue = function (name, value) { | ||
}); | ||
(0, _defineProperty2.default)(this, "updateValue", function (name, value) { | ||
var namePath = (0, _valueUtil.getNamePath)(name); | ||
@@ -658,4 +676,6 @@ var prevStore = _this.store; | ||
_this.notifyWatch([namePath]); | ||
// Dependencies update | ||
var childrenFields = _this.triggerDependenciesUpdate(prevStore, namePath); | ||
// trigger callback function | ||
@@ -668,5 +688,5 @@ var onValuesChange = _this.callbacks.onValuesChange; | ||
_this.triggerOnFieldsChange([namePath].concat((0, _toConsumableArray2.default)(childrenFields))); | ||
}; | ||
}); | ||
// Let all child Field get update. | ||
this.setFieldsValue = function (store) { | ||
(0, _defineProperty2.default)(this, "setFieldsValue", function (store) { | ||
_this.warningUnhooked(); | ||
@@ -683,4 +703,4 @@ var prevStore = _this.store; | ||
_this.notifyWatch(); | ||
}; | ||
this.setFieldValue = function (name, value) { | ||
}); | ||
(0, _defineProperty2.default)(this, "setFieldValue", function (name, value) { | ||
_this.setFields([{ | ||
@@ -690,7 +710,8 @@ name: name, | ||
}]); | ||
}; | ||
this.getDependencyChildrenFields = function (rootNamePath) { | ||
}); | ||
(0, _defineProperty2.default)(this, "getDependencyChildrenFields", function (rootNamePath) { | ||
var children = new Set(); | ||
var childrenFields = []; | ||
var dependencies2fields = new _NameMap.default(); | ||
/** | ||
@@ -726,7 +747,8 @@ * Generate maps | ||
return childrenFields; | ||
}; | ||
this.triggerOnFieldsChange = function (namePathList, filedErrors) { | ||
}); | ||
(0, _defineProperty2.default)(this, "triggerOnFieldsChange", function (namePathList, filedErrors) { | ||
var onFieldsChange = _this.callbacks.onFieldsChange; | ||
if (onFieldsChange) { | ||
var fields = _this.getFields(); | ||
/** | ||
@@ -737,5 +759,5 @@ * Fill errors since `fields` may be replaced by controlled fields | ||
var cache = new _NameMap.default(); | ||
filedErrors.forEach(function (_ref4) { | ||
var name = _ref4.name, | ||
errors = _ref4.errors; | ||
filedErrors.forEach(function (_ref6) { | ||
var name = _ref6.name, | ||
errors = _ref6.errors; | ||
cache.set(name, errors); | ||
@@ -748,4 +770,4 @@ }); | ||
} | ||
var changedFields = fields.filter(function (_ref5) { | ||
var fieldName = _ref5.name; | ||
var changedFields = fields.filter(function (_ref7) { | ||
var fieldName = _ref7.name; | ||
return (0, _valueUtil.containsNamePath)(namePathList, fieldName); | ||
@@ -757,5 +779,5 @@ }); | ||
} | ||
}; | ||
}); | ||
// =========================== Validate =========================== | ||
this.validateFields = function (arg1, arg2) { | ||
(0, _defineProperty2.default)(this, "validateFields", function (arg1, arg2) { | ||
var _options; | ||
@@ -773,4 +795,6 @@ _this.warningUnhooked(); | ||
var namePathList = provideNameList ? nameList.map(_valueUtil.getNamePath) : []; | ||
// Collect result in promise list | ||
var promiseList = []; | ||
// We temp save the path which need trigger for `onFieldsChange` | ||
@@ -785,2 +809,3 @@ var TMP_SPLIT = String(Date.now()); | ||
} | ||
// Skip if without rule | ||
@@ -792,2 +817,3 @@ if (!field.props.rules || !field.props.rules.length) { | ||
validateNamePathList.add(fieldNamePath.join(TMP_SPLIT)); | ||
// Add field validate rule in to promise list | ||
@@ -798,2 +824,3 @@ if (!provideNameList || (0, _valueUtil.containsNamePath)(namePathList, fieldNamePath, recursive)) { | ||
}, options)); | ||
// Wrap promise with field | ||
@@ -810,5 +837,5 @@ promiseList.push(promise.then(function () { | ||
var mergedWarnings = []; | ||
(_ruleErrors$forEach = ruleErrors.forEach) === null || _ruleErrors$forEach === void 0 ? void 0 : _ruleErrors$forEach.call(ruleErrors, function (_ref6) { | ||
var warningOnly = _ref6.rule.warningOnly, | ||
errors = _ref6.errors; | ||
(_ruleErrors$forEach = ruleErrors.forEach) === null || _ruleErrors$forEach === void 0 ? void 0 : _ruleErrors$forEach.call(ruleErrors, function (_ref8) { | ||
var warningOnly = _ref8.rule.warningOnly, | ||
errors = _ref8.errors; | ||
if (warningOnly) { | ||
@@ -837,2 +864,3 @@ mergedWarnings.push.apply(mergedWarnings, (0, _toConsumableArray2.default)(errors)); | ||
_this.lastValidatePromise = summaryPromise; | ||
// Notify fields with rule that validate has finished and need update | ||
@@ -842,4 +870,4 @@ summaryPromise.catch(function (results) { | ||
}).then(function (results) { | ||
var resultNamePathList = results.map(function (_ref7) { | ||
var name = _ref7.name; | ||
var resultNamePathList = results.map(function (_ref9) { | ||
var name = _ref9.name; | ||
return name; | ||
@@ -867,2 +895,3 @@ }); | ||
}); | ||
// Do not throw in console | ||
@@ -872,2 +901,3 @@ returnPromise.catch(function (e) { | ||
}); | ||
// `validating` changed. Trigger `onFieldsChange` | ||
@@ -879,5 +909,5 @@ var triggerNamePathList = namePathList.filter(function (namePath) { | ||
return returnPromise; | ||
}; | ||
}); | ||
// ============================ Submit ============================ | ||
this.submit = function () { | ||
(0, _defineProperty2.default)(this, "submit", function () { | ||
_this.warningUnhooked(); | ||
@@ -900,3 +930,3 @@ _this.validateFields().then(function (values) { | ||
}); | ||
}; | ||
}); | ||
this.forceRootUpdate = forceRootUpdate; | ||
@@ -903,0 +933,0 @@ }); |
@@ -12,6 +12,6 @@ "use strict"; | ||
var _warning = _interopRequireDefault(require("rc-util/lib/warning")); | ||
var _react = require("react"); | ||
var _FieldContext = _interopRequireWildcard(require("./FieldContext")); | ||
var _react = require("react"); | ||
var _typeUtil = require("./utils/typeUtil"); | ||
var _valueUtil = require("./utils/valueUtil"); | ||
var _typeUtil = require("./utils/typeUtil"); | ||
function stringify(value) { | ||
@@ -53,2 +53,3 @@ try { | ||
var isValidForm = formInstance && formInstance._init; | ||
// Warning if not exist form instance | ||
@@ -74,2 +75,3 @@ if (process.env.NODE_ENV !== 'production') { | ||
var nextValueStr = stringify(newValue); | ||
// Compare stringify in case it's nest object | ||
@@ -81,5 +83,11 @@ if (valueStrRef.current !== nextValueStr) { | ||
}); | ||
// TODO: We can improve this perf in future | ||
var initialValue = (0, _valueUtil.getValue)(options.preserve ? getFieldsValue(true) : getFieldsValue(), namePathRef.current); | ||
setValue(initialValue); | ||
// React 18 has the bug that will queue update twice even the value is not changed | ||
// ref: https://github.com/facebook/react/issues/27213 | ||
if (value !== initialValue) { | ||
setValue(initialValue); | ||
} | ||
return cancelRegister; | ||
@@ -86,0 +94,0 @@ }, |
@@ -12,4 +12,6 @@ "use strict"; | ||
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); | ||
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); | ||
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); | ||
var SPLIT = '__@field_split__'; | ||
/** | ||
@@ -25,2 +27,3 @@ * Convert name path into string to fast the fetch speed of Map. | ||
} | ||
/** | ||
@@ -32,3 +35,3 @@ * NameMap like a `Map` but accepts `string[]` as key. | ||
(0, _classCallCheck2.default)(this, NameMap); | ||
this.kvs = new Map(); | ||
(0, _defineProperty2.default)(this, "kvs", new Map()); | ||
} | ||
@@ -61,2 +64,3 @@ (0, _createClass2.default)(NameMap, [{ | ||
} | ||
// Since we only use this in test, let simply realize this | ||
@@ -63,0 +67,0 @@ }, { |
@@ -21,2 +21,3 @@ "use strict"; | ||
var AsyncValidator = _asyncValidator.default; | ||
/** | ||
@@ -50,2 +51,3 @@ * Replace with template. | ||
delete cloneRule.ruleIndex; | ||
// https://github.com/ant-design/ant-design/issues/40497#issuecomment-1422282378 | ||
@@ -66,2 +68,3 @@ AsyncValidator.warning = function () { | ||
} | ||
// We should special handle array validate | ||
@@ -135,2 +138,3 @@ subRuleField = null; | ||
var name = namePath.join('.'); | ||
// Fill rule with context | ||
@@ -142,2 +146,3 @@ var filledRules = rules.map(function (currentRule, ruleIndex) { | ||
}); | ||
// Replace validator if needed | ||
@@ -147,2 +152,3 @@ if (originValidatorFunc) { | ||
var hasPromise = false; | ||
// Wrap callback only accept when promise not provided | ||
@@ -161,5 +167,7 @@ var wrappedCallback = function wrappedCallback() { | ||
}; | ||
// Get promise | ||
var promise = originValidatorFunc(rule, val, wrappedCallback); | ||
hasPromise = promise && typeof promise.then === 'function' && typeof promise.catch === 'function'; | ||
/** | ||
@@ -194,2 +202,3 @@ * 1. Use promise as the first priority. | ||
}); | ||
// Do validate rules | ||
@@ -231,2 +240,3 @@ var summaryPromise; | ||
/* eslint-enable */ | ||
resolve([]); | ||
@@ -258,2 +268,3 @@ case 13: | ||
} | ||
// Internal catch error to avoid console error log. | ||
@@ -260,0 +271,0 @@ summaryPromise.catch(function (e) { |
@@ -49,2 +49,3 @@ "use strict"; | ||
} | ||
/** | ||
@@ -62,2 +63,3 @@ * Check if `namePathList` includes `namePath`. | ||
} | ||
/** | ||
@@ -81,2 +83,5 @@ * Check if `namePath` is super set or equal of `subNamePath`. | ||
} | ||
// Like `shallowEqual`, but we not check the data which may cause re-render | ||
function isSimilar(source, target) { | ||
@@ -111,2 +116,3 @@ if (source === target) { | ||
} | ||
/** | ||
@@ -113,0 +119,0 @@ * Moves an array item from one position in an array to another. |
{ | ||
"name": "rc-field-form", | ||
"version": "1.37.0", | ||
"version": "1.38.0", | ||
"description": "React Form Component", | ||
@@ -37,6 +37,6 @@ "typings": "es/index.d.ts", | ||
"docs:deploy": "gh-pages -d docs-dist", | ||
"compile": "father-build", | ||
"compile": "father build", | ||
"deploy": "npm run docs:build && npm run docs:deploy", | ||
"prettier": "prettier --write \"**/*.{js,jsx,tsx,ts,less,md,json}\"", | ||
"test": "father test", | ||
"test": "rc-test", | ||
"test:coverage": "umi-test --coverage", | ||
@@ -58,5 +58,5 @@ "prepublishOnly": "npm run compile && np --no-cleanup --yolo --no-publish", | ||
"devDependencies": { | ||
"@testing-library/jest-dom": "^5.16.4", | ||
"@testing-library/react": "^12.1.5", | ||
"@types/enzyme": "^3.10.5", | ||
"@rc-component/father-plugin": "^1.0.0", | ||
"@testing-library/jest-dom": "^5.17.0", | ||
"@testing-library/react": "^14.0.0", | ||
"@types/jest": "^29.2.5", | ||
@@ -67,22 +67,18 @@ "@types/lodash": "^4.14.135", | ||
"@umijs/fabric": "^2.5.2", | ||
"@umijs/test": "^3.2.27", | ||
"dumi": "^1.1.0", | ||
"enzyme": "^3.1.0", | ||
"enzyme-adapter-react-16": "^1.0.2", | ||
"enzyme-to-json": "^3.1.4", | ||
"dumi": "^2.0.0", | ||
"eslint": "^7.18.0", | ||
"father": "^2.13.6", | ||
"father-build": "^1.18.6", | ||
"father": "^4.0.0", | ||
"gh-pages": "^3.1.0", | ||
"jest": "^29.3.1", | ||
"jest": "^29.0.0", | ||
"np": "^5.0.3", | ||
"prettier": "^2.1.2", | ||
"react": "^16.14.0", | ||
"rc-test": "^7.0.15", | ||
"react": "^18.0.0", | ||
"react-dnd": "^8.0.3", | ||
"react-dnd-html5-backend": "^8.0.3", | ||
"react-dom": "^16.14.0", | ||
"react-redux": "^4.4.10", | ||
"redux": "^3.7.2", | ||
"react-dom": "^18.0.0", | ||
"react-redux": "^8.1.2", | ||
"redux": "^4.2.1", | ||
"typescript": "^5.1.6" | ||
} | ||
} |
286668
23
75
6640
16