@rainbow-oh/yee-c 0.8.20 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Form/Field.js +6 -6
- package/dist/cjs/Form/demo/async-validate.js +2 -2
- package/dist/cjs/Form/demo/field-status.d.ts +3 -0
- package/dist/cjs/Form/demo/field-status.js +116 -0
- package/dist/cjs/Form/demo/validate.js +2 -2
- package/dist/cjs/Form/form-store.d.ts +6 -1
- package/dist/cjs/Form/form-store.js +93 -8
- package/dist/cjs/Form/index.d.ts +1 -1
- package/dist/cjs/Form/interface.d.ts +26 -3
- package/dist/cjs/Form/style/index.less +26 -0
- package/dist/cjs/Form/utils/path.js +1 -1
- package/dist/cjs/TreeSelect/tree-select.js +14 -4
- package/dist/cjs/style/themes.css +1 -1
- package/dist/cjs/style/variables.css +1 -1
- package/dist/cjs/version.d.ts +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/Form/Field.js +6 -6
- package/dist/esm/Form/demo/async-validate.js +2 -2
- package/dist/esm/Form/demo/field-status.d.ts +3 -0
- package/dist/esm/Form/demo/field-status.js +104 -0
- package/dist/esm/Form/demo/validate.js +2 -2
- package/dist/esm/Form/form-store.d.ts +6 -1
- package/dist/esm/Form/form-store.js +118 -13
- package/dist/esm/Form/hooks/useForm.js +0 -175
- package/dist/esm/Form/index.d.ts +1 -1
- package/dist/esm/Form/interface.d.ts +26 -3
- package/dist/esm/Form/style/index.less +26 -0
- package/dist/esm/Form/utils/path.js +2 -1
- package/dist/esm/TreeSelect/tree-select.js +20 -6
- package/dist/esm/style/themes.css +1 -1
- package/dist/esm/style/variables.css +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/dist/umd/yee-c.min.css +1 -1
- package/dist/umd/yee-c.min.js +1 -1
- package/package.json +1 -1
- package/src/Form/Field.tsx +7 -8
- package/src/Form/demo/async-validate.tsx +3 -2
- package/src/Form/demo/field-status.tsx +108 -0
- package/src/Form/demo/validate.tsx +3 -2
- package/src/Form/form-store.test.ts +156 -0
- package/src/Form/form-store.ts +117 -8
- package/src/Form/hooks/useForm.ts +0 -175
- package/src/Form/index.en-US.md +93 -88
- package/src/Form/index.ts +3 -0
- package/src/Form/index.zh-CN.md +56 -51
- package/src/Form/interface.ts +28 -3
- package/src/Form/style/index.less +26 -0
- package/src/Form/utils/path.ts +2 -1
- package/src/TreeSelect/tree-select.tsx +21 -4
- package/src/version.ts +1 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
4
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
5
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
7
|
+
import { Button, Form, Input, Space } from "../..";
|
|
8
|
+
import React, { useState } from 'react';
|
|
9
|
+
export default (function () {
|
|
10
|
+
var _Form$useForm = Form.useForm(),
|
|
11
|
+
_Form$useForm2 = _slicedToArray(_Form$useForm, 1),
|
|
12
|
+
form = _Form$useForm2[0];
|
|
13
|
+
var _useState = useState(null),
|
|
14
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
15
|
+
currentStatus = _useState2[0],
|
|
16
|
+
setCurrentStatus = _useState2[1];
|
|
17
|
+
var _useState3 = useState(''),
|
|
18
|
+
_useState4 = _slicedToArray(_useState3, 2),
|
|
19
|
+
submitResult = _useState4[0],
|
|
20
|
+
setSubmitResult = _useState4[1];
|
|
21
|
+
var applyStatus = function applyStatus(status) {
|
|
22
|
+
form.setFieldStatus('username', status);
|
|
23
|
+
setCurrentStatus(form.getFieldStatus('username'));
|
|
24
|
+
setSubmitResult('');
|
|
25
|
+
};
|
|
26
|
+
return /*#__PURE__*/React.createElement(Form, {
|
|
27
|
+
form: form,
|
|
28
|
+
initialValues: {
|
|
29
|
+
username: 'demo-user'
|
|
30
|
+
},
|
|
31
|
+
onFinish: function onFinish() {
|
|
32
|
+
return setSubmitResult('Submit succeeded');
|
|
33
|
+
},
|
|
34
|
+
onFinishFailed: function onFinishFailed() {
|
|
35
|
+
return setSubmitResult('Submit blocked by the blocking error');
|
|
36
|
+
}
|
|
37
|
+
}, /*#__PURE__*/React.createElement(Form.Field, {
|
|
38
|
+
name: "username",
|
|
39
|
+
label: "Username",
|
|
40
|
+
rules: [{
|
|
41
|
+
required: true,
|
|
42
|
+
message: 'Please input your username!'
|
|
43
|
+
}]
|
|
44
|
+
}, /*#__PURE__*/React.createElement(Input, {
|
|
45
|
+
placeholder: "Please input your username"
|
|
46
|
+
})), /*#__PURE__*/React.createElement(Space, {
|
|
47
|
+
style: {
|
|
48
|
+
marginTop: 28,
|
|
49
|
+
flexWrap: 'wrap'
|
|
50
|
+
}
|
|
51
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
52
|
+
onClick: function onClick() {
|
|
53
|
+
return applyStatus({
|
|
54
|
+
status: 'error',
|
|
55
|
+
message: 'This username is unavailable'
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}, "Error"), /*#__PURE__*/React.createElement(Button, {
|
|
59
|
+
onClick: function onClick() {
|
|
60
|
+
return applyStatus({
|
|
61
|
+
status: 'error',
|
|
62
|
+
message: 'This error prevents submission',
|
|
63
|
+
blocking: true
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}, "Blocking error"), /*#__PURE__*/React.createElement(Button, {
|
|
67
|
+
onClick: function onClick() {
|
|
68
|
+
return applyStatus({
|
|
69
|
+
status: 'warning',
|
|
70
|
+
message: 'This username is commonly used'
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}, "Warning"), /*#__PURE__*/React.createElement(Button, {
|
|
74
|
+
onClick: function onClick() {
|
|
75
|
+
return applyStatus({
|
|
76
|
+
status: 'success',
|
|
77
|
+
message: 'This username is available'
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}, "Success"), /*#__PURE__*/React.createElement(Button, {
|
|
81
|
+
onClick: function onClick() {
|
|
82
|
+
return applyStatus({
|
|
83
|
+
status: 'info',
|
|
84
|
+
message: 'The username can be changed later'
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
}, "Info"), /*#__PURE__*/React.createElement(Button, {
|
|
88
|
+
onClick: function onClick() {
|
|
89
|
+
return applyStatus(null);
|
|
90
|
+
}
|
|
91
|
+
}, "Clear"), /*#__PURE__*/React.createElement(Button, {
|
|
92
|
+
type: "primary",
|
|
93
|
+
htmlType: "submit"
|
|
94
|
+
}, "Submit")), /*#__PURE__*/React.createElement("pre", {
|
|
95
|
+
style: {
|
|
96
|
+
marginTop: 16
|
|
97
|
+
}
|
|
98
|
+
}, "Current status: ", JSON.stringify(currentStatus, null, 2)), submitResult ? /*#__PURE__*/React.createElement("div", null, submitResult) : null, /*#__PURE__*/React.createElement("div", {
|
|
99
|
+
style: {
|
|
100
|
+
marginTop: 8,
|
|
101
|
+
color: '#999'
|
|
102
|
+
}
|
|
103
|
+
}, "Tip: set Success, then clear the input \u2014 the rule error takes display precedence over the manually set status."));
|
|
104
|
+
});
|
|
@@ -13,8 +13,8 @@ export default (function () {
|
|
|
13
13
|
var onFinish = function onFinish(values) {
|
|
14
14
|
console.log('Received values:', values);
|
|
15
15
|
};
|
|
16
|
-
var onFinishFailed = function onFinishFailed(
|
|
17
|
-
console.log('Failed:',
|
|
16
|
+
var onFinishFailed = function onFinishFailed(errors) {
|
|
17
|
+
console.log('Failed:', errors);
|
|
18
18
|
};
|
|
19
19
|
return /*#__PURE__*/React.createElement(Form, {
|
|
20
20
|
form: form,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import type { Callbacks, FieldEntity, FormInstance, FormListField, FormListOperation, GroupEntity, Name, NamePath, Store, TRIGGER, ValidateMessage } from './interface';
|
|
1
|
+
import type { Callbacks, FieldEntity, FieldStatusData, FormInstance, FormListField, FormListOperation, GroupEntity, Name, NamePath, Store, TRIGGER, ValidateMessage } from './interface';
|
|
2
2
|
export declare class FormStore {
|
|
3
3
|
private store;
|
|
4
4
|
private callbacks;
|
|
5
5
|
private fieldEntities;
|
|
6
6
|
private fieldMap;
|
|
7
7
|
private validateMessages;
|
|
8
|
+
private fieldStatuses;
|
|
8
9
|
private initialized;
|
|
9
10
|
private initialValues;
|
|
10
11
|
private listKeyManagers;
|
|
@@ -23,6 +24,10 @@ export declare class FormStore {
|
|
|
23
24
|
private getValueByPath;
|
|
24
25
|
getFieldValue: (name: Name) => any;
|
|
25
26
|
getFieldValidate: (name: Name) => ValidateMessage | null;
|
|
27
|
+
getFieldStatus: (name: NamePath) => FieldStatusData | null;
|
|
28
|
+
setFieldStatus: (name: NamePath, status: FieldStatusData | null) => void;
|
|
29
|
+
private deleteRelatedEntries;
|
|
30
|
+
private clearFieldStatuses;
|
|
26
31
|
setFieldsValue: (newStore: Store, trigger?: TRIGGER) => void;
|
|
27
32
|
resetFields: (name?: Name[]) => void;
|
|
28
33
|
clearFields: (name?: Name[]) => void;
|
|
@@ -46,6 +46,7 @@ export var FormStore = /*#__PURE__*/function () {
|
|
|
46
46
|
_defineProperty(this, "fieldEntities", []);
|
|
47
47
|
_defineProperty(this, "fieldMap", new Map());
|
|
48
48
|
_defineProperty(this, "validateMessages", new Map());
|
|
49
|
+
_defineProperty(this, "fieldStatuses", new Map());
|
|
49
50
|
_defineProperty(this, "initialized", false);
|
|
50
51
|
_defineProperty(this, "initialValues", {});
|
|
51
52
|
// List key manager
|
|
@@ -109,10 +110,72 @@ export var FormStore = /*#__PURE__*/function () {
|
|
|
109
110
|
}
|
|
110
111
|
return null;
|
|
111
112
|
});
|
|
113
|
+
_defineProperty(this, "getFieldStatus", function (name) {
|
|
114
|
+
var _this$validateMessage;
|
|
115
|
+
var normalizedName = stringifyPath(getNamePath(name));
|
|
116
|
+
var manualStatus = _this.fieldStatuses.get(normalizedName);
|
|
117
|
+
var validateMessage = (_this$validateMessage = _this.validateMessages.get(normalizedName)) === null || _this$validateMessage === void 0 ? void 0 : _this$validateMessage[0];
|
|
118
|
+
|
|
119
|
+
// Rule errors reflect the current value and auto-clear once validation
|
|
120
|
+
// passes, so they always take display precedence — a stale manually set
|
|
121
|
+
// status must never hide why submission failed.
|
|
122
|
+
if ((validateMessage === null || validateMessage === void 0 ? void 0 : validateMessage.status) === 'error') {
|
|
123
|
+
return {
|
|
124
|
+
status: 'error',
|
|
125
|
+
message: validateMessage.message
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (manualStatus) {
|
|
129
|
+
return _objectSpread({}, manualStatus);
|
|
130
|
+
}
|
|
131
|
+
if (validateMessage) {
|
|
132
|
+
return {
|
|
133
|
+
status: validateMessage.status,
|
|
134
|
+
message: validateMessage.message
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return null;
|
|
138
|
+
});
|
|
139
|
+
_defineProperty(this, "setFieldStatus", function (name, status) {
|
|
140
|
+
var _this$fieldMap$get;
|
|
141
|
+
var normalizedName = stringifyPath(getNamePath(name));
|
|
142
|
+
if (!normalizedName) return;
|
|
143
|
+
if (status) {
|
|
144
|
+
_this.fieldStatuses.set(normalizedName, _objectSpread({}, status));
|
|
145
|
+
} else {
|
|
146
|
+
_this.fieldStatuses.delete(normalizedName);
|
|
147
|
+
}
|
|
148
|
+
(_this$fieldMap$get = _this.fieldMap.get(normalizedName)) === null || _this$fieldMap$get === void 0 || _this$fieldMap$get.onStoreChange();
|
|
149
|
+
});
|
|
150
|
+
// Delete entries whose key equals or nests under one of `names`
|
|
151
|
+
// (no names = delete all). Keeps rule messages and manual statuses in
|
|
152
|
+
// sync with the fields that reset/clear actually touched.
|
|
153
|
+
_defineProperty(this, "deleteRelatedEntries", function (entries, names) {
|
|
154
|
+
if (!names) {
|
|
155
|
+
entries.clear();
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
var normalizedNames = names.map(function (name) {
|
|
159
|
+
return stringifyPath(getNamePath(name));
|
|
160
|
+
});
|
|
161
|
+
Array.from(entries.keys()).forEach(function (fieldName) {
|
|
162
|
+
if (normalizedNames.some(function (name) {
|
|
163
|
+
return isRelatedNamePath(fieldName, name);
|
|
164
|
+
})) {
|
|
165
|
+
entries.delete(fieldName);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
});
|
|
169
|
+
_defineProperty(this, "clearFieldStatuses", function (names) {
|
|
170
|
+
_this.deleteRelatedEntries(_this.fieldStatuses, names);
|
|
171
|
+
});
|
|
112
172
|
_defineProperty(this, "setFieldsValue", function (newStore) {
|
|
113
173
|
var trigger = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'onChange';
|
|
114
174
|
if (trigger === 'reset' || trigger === 'clear') {
|
|
115
|
-
|
|
175
|
+
// 'reset' replaces the whole store; 'clear' merges the given keys
|
|
176
|
+
// (typically undefined) over the store so a partial clear never
|
|
177
|
+
// wipes values of unrelated fields.
|
|
178
|
+
_this.store = trigger === 'reset' ? newStore : _objectSpread(_objectSpread({}, _this.store), newStore);
|
|
116
179
|
if (trigger === 'reset') {
|
|
117
180
|
var _this$callbacks, _this$callbacks$onRes;
|
|
118
181
|
(_this$callbacks = _this.callbacks) === null || _this$callbacks === void 0 || (_this$callbacks$onRes = _this$callbacks.onReset) === null || _this$callbacks$onRes === void 0 || _this$callbacks$onRes.call(_this$callbacks);
|
|
@@ -189,19 +252,43 @@ export var FormStore = /*#__PURE__*/function () {
|
|
|
189
252
|
});
|
|
190
253
|
}
|
|
191
254
|
(_this$callbacks4 = _this.callbacks) === null || _this$callbacks4 === void 0 || (_this$callbacks4$onRe = _this$callbacks4.onReset) === null || _this$callbacks4$onRe === void 0 || _this$callbacks4$onRe.call(_this$callbacks4);
|
|
192
|
-
|
|
255
|
+
// A named reset only clears rule messages of the fields it touched;
|
|
256
|
+
// unrelated fields keep their (still valid) validation state.
|
|
257
|
+
_this.deleteRelatedEntries(_this.validateMessages, name);
|
|
258
|
+
_this.clearFieldStatuses(name);
|
|
193
259
|
_this.groupEntities.forEach(function (entity) {
|
|
194
260
|
return entity.reset();
|
|
195
261
|
});
|
|
196
262
|
_this.refreshField();
|
|
197
263
|
});
|
|
198
264
|
_defineProperty(this, "clearFields", function (name) {
|
|
265
|
+
var _this$callbacks5, _this$callbacks5$onCl;
|
|
199
266
|
var names = name || Object.keys(_this.store);
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
},
|
|
204
|
-
|
|
267
|
+
|
|
268
|
+
// Merge undefined over the current store (nested paths included) —
|
|
269
|
+
// unrelated fields keep their values.
|
|
270
|
+
var clearStore = _objectSpread({}, _this.store);
|
|
271
|
+
names.forEach(function (n) {
|
|
272
|
+
var parsedPath = parsePath(n);
|
|
273
|
+
if (parsedPath.length > 1) {
|
|
274
|
+
clearStore = setValueByPath(clearStore, parsedPath, undefined);
|
|
275
|
+
} else {
|
|
276
|
+
clearStore[n] = undefined;
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
_this.deleteRelatedEntries(_this.validateMessages, name);
|
|
280
|
+
_this.clearFieldStatuses(name);
|
|
281
|
+
_this.store = clearStore;
|
|
282
|
+
(_this$callbacks5 = _this.callbacks) === null || _this$callbacks5 === void 0 || (_this$callbacks5$onCl = _this$callbacks5.onClear) === null || _this$callbacks5$onCl === void 0 || _this$callbacks5$onCl.call(_this$callbacks5);
|
|
283
|
+
|
|
284
|
+
// clearStore carries the whole store (nested paths must materialize
|
|
285
|
+
// it), so derive the refresh scope from `names` — only cleared
|
|
286
|
+
// fields re-render, not the entire form.
|
|
287
|
+
_this.getRelatedFieldNames(names).forEach(function (fieldName) {
|
|
288
|
+
var _this$fieldMap$get2;
|
|
289
|
+
(_this$fieldMap$get2 = _this.fieldMap.get(fieldName)) === null || _this$fieldMap$get2 === void 0 || _this$fieldMap$get2.onStoreChange();
|
|
290
|
+
});
|
|
291
|
+
_this.notifyWatchers(names);
|
|
205
292
|
});
|
|
206
293
|
_defineProperty(this, "validateField", /*#__PURE__*/function () {
|
|
207
294
|
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(name, trigger) {
|
|
@@ -347,8 +434,8 @@ export var FormStore = /*#__PURE__*/function () {
|
|
|
347
434
|
var changedKeys = Object.keys(newStore);
|
|
348
435
|
var fieldNames = relatedFieldNames !== null && relatedFieldNames !== void 0 ? relatedFieldNames : _this.getRelatedFieldNames(changedKeys);
|
|
349
436
|
fieldNames.forEach(function (fieldName) {
|
|
350
|
-
var _this$fieldMap$
|
|
351
|
-
(_this$fieldMap$
|
|
437
|
+
var _this$fieldMap$get3;
|
|
438
|
+
(_this$fieldMap$get3 = _this.fieldMap.get(fieldName)) === null || _this$fieldMap$get3 === void 0 || _this$fieldMap$get3.onStoreChange();
|
|
352
439
|
});
|
|
353
440
|
_this.notifyWatchers(changedKeys);
|
|
354
441
|
} else {
|
|
@@ -577,11 +664,11 @@ export var FormStore = /*#__PURE__*/function () {
|
|
|
577
664
|
};
|
|
578
665
|
});
|
|
579
666
|
_defineProperty(this, "submit", /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4() {
|
|
580
|
-
var _this$
|
|
667
|
+
var _this$callbacks6, onFinish, onFinishFailed, fieldErrors, groupErrors, statusErrors, allErrors;
|
|
581
668
|
return _regeneratorRuntime().wrap(function _callee4$(_context4) {
|
|
582
669
|
while (1) switch (_context4.prev = _context4.next) {
|
|
583
670
|
case 0:
|
|
584
|
-
_this$
|
|
671
|
+
_this$callbacks6 = _this.callbacks, onFinish = _this$callbacks6.onFinish, onFinishFailed = _this$callbacks6.onFinishFailed;
|
|
585
672
|
_context4.next = 3;
|
|
586
673
|
return _this.validateFields();
|
|
587
674
|
case 3:
|
|
@@ -590,7 +677,23 @@ export var FormStore = /*#__PURE__*/function () {
|
|
|
590
677
|
return _this.validateGroups(true);
|
|
591
678
|
case 6:
|
|
592
679
|
groupErrors = _context4.sent;
|
|
593
|
-
|
|
680
|
+
statusErrors = Array.from(_this.fieldStatuses.entries()).filter(function (_ref9) {
|
|
681
|
+
var _ref10 = _slicedToArray(_ref9, 2),
|
|
682
|
+
status = _ref10[1];
|
|
683
|
+
return status.status === 'error' && status.blocking === true;
|
|
684
|
+
}).map(function (_ref11) {
|
|
685
|
+
var _status$message;
|
|
686
|
+
var _ref12 = _slicedToArray(_ref11, 2),
|
|
687
|
+
name = _ref12[0],
|
|
688
|
+
status = _ref12[1];
|
|
689
|
+
return {
|
|
690
|
+
name: name,
|
|
691
|
+
message: (_status$message = status.message) !== null && _status$message !== void 0 ? _status$message : '',
|
|
692
|
+
value: _this.getFieldValue(name),
|
|
693
|
+
status: 'error'
|
|
694
|
+
};
|
|
695
|
+
});
|
|
696
|
+
allErrors = [].concat(_toConsumableArray(fieldErrors), _toConsumableArray(groupErrors), _toConsumableArray(statusErrors));
|
|
594
697
|
if (allErrors.length === 0) {
|
|
595
698
|
onFinish === null || onFinish === void 0 || onFinish(_this.getFieldsValue());
|
|
596
699
|
} else {
|
|
@@ -598,7 +701,7 @@ export var FormStore = /*#__PURE__*/function () {
|
|
|
598
701
|
}
|
|
599
702
|
_this.refreshField();
|
|
600
703
|
return _context4.abrupt("return", allErrors);
|
|
601
|
-
case
|
|
704
|
+
case 12:
|
|
602
705
|
case "end":
|
|
603
706
|
return _context4.stop();
|
|
604
707
|
}
|
|
@@ -647,6 +750,8 @@ export var FormStore = /*#__PURE__*/function () {
|
|
|
647
750
|
value: function getForm() {
|
|
648
751
|
return {
|
|
649
752
|
getFieldValidate: this.getFieldValidate,
|
|
753
|
+
getFieldStatus: this.getFieldStatus,
|
|
754
|
+
setFieldStatus: this.setFieldStatus,
|
|
650
755
|
getFieldsValue: this.getFieldsValue,
|
|
651
756
|
getFieldValue: this.getFieldValue,
|
|
652
757
|
setFieldsValue: this.setFieldsValue,
|
|
@@ -1,178 +1,3 @@
|
|
|
1
|
-
// import { useRef } from 'react';
|
|
2
|
-
// import type {
|
|
3
|
-
// Callbacks,
|
|
4
|
-
// FieldEntity,
|
|
5
|
-
// FormInstance,
|
|
6
|
-
// NamePath,
|
|
7
|
-
// Store,
|
|
8
|
-
// validateMessage,
|
|
9
|
-
// } from './interface';
|
|
10
|
-
// import validate from './utils/validate';
|
|
11
|
-
|
|
12
|
-
// class FormStore {
|
|
13
|
-
// private store: Store = {};
|
|
14
|
-
// private callbacks: Callbacks = {};
|
|
15
|
-
// private fieldEntities: FieldEntity[] = [];
|
|
16
|
-
// private validateMessages: validateMessage[] = [];
|
|
17
|
-
// private initialized = false;
|
|
18
|
-
// // 初始化form实例
|
|
19
|
-
// initialize = ({
|
|
20
|
-
// initialValues,
|
|
21
|
-
// callbacks,
|
|
22
|
-
// }: {
|
|
23
|
-
// initialValues?: Store;
|
|
24
|
-
// callbacks?: Callbacks;
|
|
25
|
-
// }) => {
|
|
26
|
-
// if (!this.initialized) {
|
|
27
|
-
// this.initialized = true;
|
|
28
|
-
|
|
29
|
-
// if (initialValues) {
|
|
30
|
-
// this.store = initialValues;
|
|
31
|
-
// } else {
|
|
32
|
-
// this.store = {};
|
|
33
|
-
// }
|
|
34
|
-
|
|
35
|
-
// if (callbacks) {
|
|
36
|
-
// this.setCallbacks(callbacks);
|
|
37
|
-
// }
|
|
38
|
-
// }
|
|
39
|
-
// };
|
|
40
|
-
|
|
41
|
-
// getFieldsValue = () => {
|
|
42
|
-
// return { ...this.store };
|
|
43
|
-
// };
|
|
44
|
-
|
|
45
|
-
// getFieldValue = (name: NamePath) => {
|
|
46
|
-
// return this.store[name];
|
|
47
|
-
// };
|
|
48
|
-
|
|
49
|
-
// getFieldValidate = (name: NamePath) => {
|
|
50
|
-
// return this.validateMessages?.find((item) => item.name === name);
|
|
51
|
-
// };
|
|
52
|
-
|
|
53
|
-
// resetFields = (name?: NamePath[]) => {
|
|
54
|
-
// if (name) {
|
|
55
|
-
// name.forEach((n) => {
|
|
56
|
-
// this.setFieldsValue({ [n]: undefined });
|
|
57
|
-
// });
|
|
58
|
-
// } else {
|
|
59
|
-
// Object.keys(this.store).forEach((key) => {
|
|
60
|
-
// this.setFieldsValue({ [key]: undefined });
|
|
61
|
-
// });
|
|
62
|
-
// }
|
|
63
|
-
// };
|
|
64
|
-
|
|
65
|
-
// validateFields = () => {
|
|
66
|
-
// const err: validateMessage[] = [];
|
|
67
|
-
// this.fieldEntities.forEach((entity) => {
|
|
68
|
-
// const { name, rules, required } = entity.props;
|
|
69
|
-
// const value: NamePath = name && this.getFieldValue(name);
|
|
70
|
-
|
|
71
|
-
// const mergedRules = rules || [];
|
|
72
|
-
|
|
73
|
-
// if (required) {
|
|
74
|
-
// mergedRules.push({
|
|
75
|
-
// required: true,
|
|
76
|
-
// message: 'This is required field.',
|
|
77
|
-
// });
|
|
78
|
-
// }
|
|
79
|
-
|
|
80
|
-
// mergedRules.forEach((rule) => {
|
|
81
|
-
// const mark = validate(rule, value);
|
|
82
|
-
// if (name && !mark) {
|
|
83
|
-
// err.push({
|
|
84
|
-
// name: name,
|
|
85
|
-
// status: 'error',
|
|
86
|
-
// value,
|
|
87
|
-
// ...rule
|
|
88
|
-
// });
|
|
89
|
-
// }
|
|
90
|
-
// });
|
|
91
|
-
// });
|
|
92
|
-
// return err;
|
|
93
|
-
// };
|
|
94
|
-
|
|
95
|
-
// setFieldsValue = (newStore: Store, isChange?: boolean) => {
|
|
96
|
-
// // const { onValuesChange } = this.callbacks;
|
|
97
|
-
// this.store = {
|
|
98
|
-
// ...this.store,
|
|
99
|
-
// ...newStore,
|
|
100
|
-
// };
|
|
101
|
-
// // onValuesChange?.(newStore, this.store);
|
|
102
|
-
// this.refreshField(newStore, isChange);
|
|
103
|
-
// };
|
|
104
|
-
|
|
105
|
-
// refreshField = (newStore?: Store, isChange?: boolean) => {
|
|
106
|
-
// if (newStore) {
|
|
107
|
-
// this.fieldEntities.forEach((entity) => {
|
|
108
|
-
// Object.keys(newStore).forEach((k) => {
|
|
109
|
-
// if (k === entity.props.name) {
|
|
110
|
-
// if (isChange) {
|
|
111
|
-
// this.validateMessages = this.validateFields();
|
|
112
|
-
// }
|
|
113
|
-
// entity.onStoreChange();
|
|
114
|
-
// }
|
|
115
|
-
// });
|
|
116
|
-
// });
|
|
117
|
-
// } else {
|
|
118
|
-
// this.fieldEntities.forEach((entity) => {
|
|
119
|
-
// if (entity.props.rules || entity.props.required) {
|
|
120
|
-
// entity?.onStoreChange();
|
|
121
|
-
// }
|
|
122
|
-
// });
|
|
123
|
-
// }
|
|
124
|
-
// };
|
|
125
|
-
|
|
126
|
-
// setCallbacks = (callbacks: Callbacks) => {
|
|
127
|
-
// this.callbacks = { ...this.callbacks, ...callbacks };
|
|
128
|
-
// };
|
|
129
|
-
|
|
130
|
-
// getCallbacks = () => {
|
|
131
|
-
// return this.callbacks;
|
|
132
|
-
// };
|
|
133
|
-
|
|
134
|
-
// // 订阅与取消订阅
|
|
135
|
-
// registerFieldEntities = (entity: FieldEntity) => {
|
|
136
|
-
// this.fieldEntities.push(entity);
|
|
137
|
-
// if (entity.props.name) {
|
|
138
|
-
// this.store = { ...this.store, [entity.props.name]: undefined };
|
|
139
|
-
// }
|
|
140
|
-
// return () => {
|
|
141
|
-
// this.fieldEntities = this.fieldEntities.filter((item) => item !== entity);
|
|
142
|
-
// const { name } = entity.props;
|
|
143
|
-
// if (name) {
|
|
144
|
-
// delete this.store[name];
|
|
145
|
-
// }
|
|
146
|
-
// };
|
|
147
|
-
// };
|
|
148
|
-
|
|
149
|
-
// submit = () => {
|
|
150
|
-
// const { onFinish, onFinishFailed } = this.callbacks;
|
|
151
|
-
// this.validateMessages = this.validateFields();
|
|
152
|
-
// if (this.validateMessages.length === 0) {
|
|
153
|
-
// onFinish?.(this.getFieldsValue());
|
|
154
|
-
// } else {
|
|
155
|
-
// onFinishFailed?.(this.validateMessages);
|
|
156
|
-
// }
|
|
157
|
-
// this.refreshField();
|
|
158
|
-
// };
|
|
159
|
-
|
|
160
|
-
// getForm(): FormInstance {
|
|
161
|
-
// return {
|
|
162
|
-
// getFieldValidate: this.getFieldValidate,
|
|
163
|
-
// getFieldsValue: this.getFieldsValue,
|
|
164
|
-
// getFieldValue: this.getFieldValue,
|
|
165
|
-
// setFieldsValue: this.setFieldsValue,
|
|
166
|
-
// resetFields: this.resetFields,
|
|
167
|
-
// submit: this.submit,
|
|
168
|
-
// setCallbacks: this.setCallbacks,
|
|
169
|
-
// getCallbacks: this.getCallbacks,
|
|
170
|
-
// registerFieldEntities: this.registerFieldEntities,
|
|
171
|
-
// initialize: this.initialize,
|
|
172
|
-
// };
|
|
173
|
-
// }
|
|
174
|
-
// }
|
|
175
|
-
|
|
176
1
|
import { useRef } from 'react';
|
|
177
2
|
import { useLocale } from "../../locale";
|
|
178
3
|
import { FormStore } from "../form-store";
|
package/dist/esm/Form/index.d.ts
CHANGED
|
@@ -16,5 +16,5 @@ type FormInterface = typeof InternalForm & {
|
|
|
16
16
|
List: typeof List;
|
|
17
17
|
};
|
|
18
18
|
declare const Form: FormInterface;
|
|
19
|
-
export type { FieldGroupProps, FormInstance, FormListProps, FormProps, } from './interface';
|
|
19
|
+
export type { FieldGroupProps, FieldStatus, FieldStatusData, FormInstance, FormListProps, FormProps, ValidateMessage, } from './interface';
|
|
20
20
|
export default Form;
|
|
@@ -2,6 +2,11 @@
|
|
|
2
2
|
import type { TooltipProps } from '../Tooltip';
|
|
3
3
|
import type { DataAttributeProps } from '../utils/types';
|
|
4
4
|
export type StoreValue = any;
|
|
5
|
+
/**
|
|
6
|
+
* Form values keyed by field name. Nested-path fields (e.g.
|
|
7
|
+
* name="user.name") hold their values in nested objects:
|
|
8
|
+
* `{ user: { name: 'tom' } }`
|
|
9
|
+
*/
|
|
5
10
|
export type Store = Record<string, StoreValue>;
|
|
6
11
|
export type Name = string;
|
|
7
12
|
export type NamePath = string | string[] | number | (string | number)[];
|
|
@@ -37,7 +42,9 @@ export interface FormProps<Values = any> extends DataAttributeProps {
|
|
|
37
42
|
*/
|
|
38
43
|
disabled?: boolean;
|
|
39
44
|
/**
|
|
40
|
-
* Initial values
|
|
45
|
+
* Initial values, keyed by field name. Nested-path fields (e.g.
|
|
46
|
+
* name="user.name") take their values from nested objects:
|
|
47
|
+
* `{ user: { name: 'tom' } }`
|
|
41
48
|
*/
|
|
42
49
|
initialValues?: Store;
|
|
43
50
|
/**
|
|
@@ -81,7 +88,7 @@ export interface Callbacks<Values = any> {
|
|
|
81
88
|
/**
|
|
82
89
|
* Triggered on failed form submit
|
|
83
90
|
* */
|
|
84
|
-
onFinishFailed?: (
|
|
91
|
+
onFinishFailed?: (errors: ValidateMessage[]) => void;
|
|
85
92
|
/**
|
|
86
93
|
* Triggered on form reset
|
|
87
94
|
* */
|
|
@@ -96,6 +103,15 @@ export interface FormInstance<Values = any> {
|
|
|
96
103
|
* Get field validation info
|
|
97
104
|
*/
|
|
98
105
|
getFieldValidate: (name: Name) => ValidateMessage | null;
|
|
106
|
+
/**
|
|
107
|
+
* Get the displayed field status. Rule validation errors take display
|
|
108
|
+
* precedence; otherwise a manually set status overrides validation.
|
|
109
|
+
*/
|
|
110
|
+
getFieldStatus: (name: NamePath) => FieldStatusData | null;
|
|
111
|
+
/**
|
|
112
|
+
* Set or clear a field's displayed status. Pass null to clear it.
|
|
113
|
+
*/
|
|
114
|
+
setFieldStatus: (name: NamePath, status: FieldStatusData | null) => void;
|
|
99
115
|
/**
|
|
100
116
|
* Get field value
|
|
101
117
|
*/
|
|
@@ -225,11 +241,18 @@ export type Rule = {
|
|
|
225
241
|
*/
|
|
226
242
|
validateTrigger?: 'onBlur' | 'onChange' | 'onSubmit' | 'reset' | Array<'onBlur' | 'onChange' | 'onSubmit'>;
|
|
227
243
|
};
|
|
244
|
+
export type FieldStatus = 'error' | 'success' | 'warning' | 'info';
|
|
245
|
+
export type FieldStatusData = {
|
|
246
|
+
status: FieldStatus;
|
|
247
|
+
message?: string;
|
|
248
|
+
/** Whether an error status should prevent form submission. */
|
|
249
|
+
blocking?: boolean;
|
|
250
|
+
};
|
|
228
251
|
export type ValidateMessage = {
|
|
229
252
|
name: NamePath | NamePath[] | undefined;
|
|
230
253
|
message: string;
|
|
231
254
|
value: unknown;
|
|
232
|
-
status:
|
|
255
|
+
status: FieldStatus;
|
|
233
256
|
};
|
|
234
257
|
export type FieldConfigurableTooltip = Omit<TooltipProps, 'children'> & {
|
|
235
258
|
/**
|
|
@@ -79,6 +79,18 @@
|
|
|
79
79
|
&-error {
|
|
80
80
|
color: var(--yee-error-color);
|
|
81
81
|
}
|
|
82
|
+
|
|
83
|
+
&-warning {
|
|
84
|
+
color: var(--yee-warning-color);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
&-success {
|
|
88
|
+
color: var(--yee-success-color);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
&-info {
|
|
92
|
+
color: var(--yee-info-color);
|
|
93
|
+
}
|
|
82
94
|
}
|
|
83
95
|
|
|
84
96
|
// 表单校验态:在此重定义控件读取的 border / box-shadow 变量,
|
|
@@ -97,5 +109,19 @@
|
|
|
97
109
|
--yee-input-focus-bs-color: var(--yee-warning-color-border);
|
|
98
110
|
--yee-checkbox-border-color: var(--yee-warning-color);
|
|
99
111
|
}
|
|
112
|
+
|
|
113
|
+
&&-success {
|
|
114
|
+
--yee-input-border-color: var(--yee-success-color);
|
|
115
|
+
--yee-input-hover-border-color: var(--yee-success-color-hover);
|
|
116
|
+
--yee-input-focus-bs-color: var(--yee-success-color-border);
|
|
117
|
+
--yee-checkbox-border-color: var(--yee-success-color);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
&&-info {
|
|
121
|
+
--yee-input-border-color: var(--yee-info-color);
|
|
122
|
+
--yee-input-hover-border-color: var(--yee-info-color-hover);
|
|
123
|
+
--yee-input-focus-bs-color: var(--yee-info-color-border);
|
|
124
|
+
--yee-checkbox-border-color: var(--yee-info-color);
|
|
125
|
+
}
|
|
100
126
|
}
|
|
101
127
|
}
|
|
@@ -73,7 +73,8 @@ export function setValueByPath(store, path, value) {
|
|
|
73
73
|
var current = newStore;
|
|
74
74
|
for (var i = 0; i < path.length - 1; i++) {
|
|
75
75
|
var key = String(path[i]);
|
|
76
|
-
|
|
76
|
+
// eslint-disable-next-line eqeqeq
|
|
77
|
+
if (current[key] == null) {
|
|
77
78
|
// 根据下一个键的类型创建容器
|
|
78
79
|
current[key] = typeof path[i + 1] === 'number' ? [] : {};
|
|
79
80
|
}
|