@tmagic/form 1.8.0-beta.10 → 1.8.0-beta.12

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.
@@ -7,7 +7,7 @@
7
7
  padding: 0 20px;
8
8
  }
9
9
 
10
- .el-table .m-form-item .el-form-item {
10
+ .el-table .m-form-item .el-form-item:not(.is-error) {
11
11
  margin-bottom: 0;
12
12
  }
13
13
  }
@@ -26,6 +26,16 @@
26
26
  }
27
27
  }
28
28
 
29
+ .el-form-item {
30
+ .m-fields-table {
31
+ .el-form-item {
32
+ &.is-error {
33
+ margin-bottom: 18px;
34
+ }
35
+ }
36
+ }
37
+ }
38
+
29
39
  .m-fields-table {
30
40
  width: 100%;
31
41
 
@@ -62,7 +72,7 @@
62
72
  }
63
73
  }
64
74
 
65
- .el-form-item {
75
+ .el-form-item:not(.is-error) {
66
76
  margin-bottom: 0;
67
77
  }
68
78
 
package/src/utils/form.ts CHANGED
@@ -16,11 +16,12 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { readonly } from 'vue';
19
+ import { ComputedRef, readonly } from 'vue';
20
20
  import dayjs from 'dayjs';
21
21
  import utc from 'dayjs/plugin/utc';
22
22
  import { cloneDeep } from 'lodash-es';
23
23
 
24
+ import { getDesignConfig } from '@tmagic/design';
24
25
  import { getValueByKeyPath } from '@tmagic/utils';
25
26
 
26
27
  import type {
@@ -39,6 +40,58 @@ import type {
39
40
  TypeFunction,
40
41
  } from '../schema';
41
42
 
43
+ import { createTypeMatchValidator } from './typeMatch';
44
+
45
+ type AsyncValidatorFn = (rule: any, value: any, callback: Function, source?: any, options?: any) => any;
46
+
47
+ const isTDesignAdapter = () => getDesignConfig('adapterType') === 'tdesign-vue-next';
48
+
49
+ /**
50
+ * 将 async-validator(Element Plus)风格的 validator 适配到当前 UI 库。
51
+ * TDesign 调用签名为 `(val) => boolean | CustomValidateObj | Promise`,无 callback。
52
+ */
53
+ export const adaptFormValidator = (validator: AsyncValidatorFn): AsyncValidatorFn => {
54
+ return (arg1: any, arg2?: any, arg3?: any, arg4?: any, arg5?: any) => {
55
+ if (!isTDesignAdapter()) {
56
+ return validator(arg1, arg2, arg3, arg4, arg5);
57
+ }
58
+
59
+ // TDesign: validator(val)
60
+ const value = arg1;
61
+ return new Promise((resolve) => {
62
+ let settled = false;
63
+ const callback = (error?: Error | string) => {
64
+ if (settled) return;
65
+ settled = true;
66
+ if (error) {
67
+ resolve({
68
+ result: false,
69
+ message: typeof error === 'string' ? error : error.message,
70
+ });
71
+ } else {
72
+ resolve(true);
73
+ }
74
+ };
75
+
76
+ try {
77
+ const result = validator(undefined, value, callback);
78
+ if (result !== null && typeof (result as PromiseLike<unknown>).then === 'function') {
79
+ Promise.resolve(result).then(
80
+ () => {
81
+ if (!settled) callback();
82
+ },
83
+ (err) => {
84
+ callback(err instanceof Error ? err : new Error(String(err)));
85
+ },
86
+ );
87
+ }
88
+ } catch (e) {
89
+ callback(e instanceof Error ? e : new Error(String(e)));
90
+ }
91
+ });
92
+ };
93
+ };
94
+
42
95
  interface DefaultItem {
43
96
  defaultValue: any;
44
97
  type: string;
@@ -253,36 +306,54 @@ export const display = function (mForm: FormState | undefined, config: any, prop
253
306
  return true;
254
307
  };
255
308
 
256
- export const getRules = function (mForm: FormState | undefined, rules: Rule[] | Rule = [], props: any) {
257
- rules = cloneDeep(rules);
309
+ export const getRules = function (
310
+ mForm: FormState | undefined,
311
+ r: Rule[] | Rule = [],
312
+ props: any,
313
+ typeMatchValid?: ComputedRef<boolean>,
314
+ ) {
315
+ let rules = cloneDeep(r);
258
316
 
259
317
  if (typeof rules === 'object' && !Array.isArray(rules)) {
260
318
  rules = [rules];
261
319
  }
262
320
 
321
+ if (typeMatchValid?.value && !rules.some((r) => typeof r.typeMatch !== 'undefined')) {
322
+ rules.push({
323
+ typeMatch: true,
324
+ });
325
+ }
326
+
263
327
  return rules.map((item) => {
328
+ if (item.typeMatch) {
329
+ (item as any).validator = adaptFormValidator(createTypeMatchValidator(mForm, props, item));
330
+ return item;
331
+ }
332
+
264
333
  if (typeof item.validator === 'function') {
265
334
  const fnc = item.validator;
266
335
 
267
- (item as any).validator = (rule: any, value: any, callback: Function, source: any, options: any) =>
268
- fnc(
269
- {
270
- rule,
271
- value: props.config.names ? props.model : value,
272
- callback,
273
- source,
274
- options,
275
- },
276
- {
277
- values: mForm?.initValues || {},
278
- model: props.model,
279
- parent: mForm?.parentValues || {},
280
- formValue: mForm?.values || props.model,
281
- prop: props.prop,
282
- config: props.config,
283
- },
284
- mForm,
285
- );
336
+ (item as any).validator = adaptFormValidator(
337
+ (rule: any, value: any, callback: Function, source: any, options: any) =>
338
+ fnc(
339
+ {
340
+ rule,
341
+ value: props.config.names ? props.model : value,
342
+ callback,
343
+ source,
344
+ options,
345
+ },
346
+ {
347
+ values: mForm?.initValues || {},
348
+ model: props.model,
349
+ parent: mForm?.parentValues || {},
350
+ formValue: mForm?.values || props.model,
351
+ prop: props.prop,
352
+ config: props.config,
353
+ },
354
+ mForm,
355
+ ),
356
+ );
286
357
  }
287
358
  return item;
288
359
  });