@tmagic/form 1.8.0-beta.25 → 1.8.0-beta.27
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/es/Form.vue_vue_type_script_setup_true_lang.js +47 -120
- package/dist/es/FormBox.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/FormDialog.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/FormDrawer.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/containers/Col.vue_vue_type_script_setup_true_lang.js +3 -0
- package/dist/es/containers/Container.vue_vue_type_script_setup_true_lang.js +36 -51
- package/dist/es/containers/Fieldset.vue_vue_type_script_setup_true_lang.js +6 -0
- package/dist/es/containers/FlexLayout.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/es/containers/GroupList.vue_vue_type_script_setup_true_lang.js +37 -15
- package/dist/es/containers/GroupListItem.vue_vue_type_script_setup_true_lang.js +109 -97
- package/dist/es/containers/Panel.vue_vue_type_script_setup_true_lang.js +7 -2
- package/dist/es/containers/Row.vue_vue_type_script_setup_true_lang.js +3 -0
- package/dist/es/containers/Step.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/es/containers/Tabs.vue_vue_type_script_setup_true_lang.js +7 -0
- package/dist/es/containers/table/Table.vue_vue_type_script_setup_true_lang.js +7 -5
- package/dist/es/containers/table/useTableColumns.js +5 -13
- package/dist/es/containers/table-group-list/TableGroupList.vue_vue_type_script_setup_true_lang.js +71 -78
- package/dist/es/containers/table-group-list/useAdd.js +26 -16
- package/dist/es/containers/table-group-list/useScrollLastItemIntoView.js +72 -0
- package/dist/es/fields/Cascader.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/CheckboxGroup/Index.js +5 -0
- package/dist/es/fields/{CheckboxGroup.vue_vue_type_script_setup_true_lang.js → CheckboxGroup/Index.vue_vue_type_script_setup_true_lang.js} +6 -7
- package/dist/es/fields/CheckboxGroup/effect.js +8 -0
- package/dist/es/fields/Date/Index.js +5 -0
- package/dist/es/fields/{Date.vue_vue_type_script_setup_true_lang.js → Date/Index.vue_vue_type_script_setup_true_lang.js} +5 -7
- package/dist/es/fields/Date/effect.js +10 -0
- package/dist/es/fields/DateTime/Index.js +5 -0
- package/dist/es/fields/{DateTime.vue_vue_type_script_setup_true_lang.js → DateTime/Index.vue_vue_type_script_setup_true_lang.js} +5 -9
- package/dist/es/fields/DateTime/effect.js +15 -0
- package/dist/es/fields/Display/Index.js +5 -0
- package/dist/es/fields/{Display.vue_vue_type_script_setup_true_lang.js → Display/Index.vue_vue_type_script_setup_true_lang.js} +6 -7
- package/dist/es/fields/Display/effect.js +8 -0
- package/dist/es/fields/DynamicField/Index.js +5 -0
- package/dist/es/fields/{DynamicField.vue_vue_type_script_setup_true_lang.js → DynamicField/Index.vue_vue_type_script_setup_true_lang.js} +11 -15
- package/dist/es/fields/DynamicField/effect.js +40 -0
- package/dist/es/fields/Link.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Number.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/NumberRange/Index.js +5 -0
- package/dist/es/fields/{NumberRange.vue_vue_type_script_setup_true_lang.js → NumberRange/Index.vue_vue_type_script_setup_true_lang.js} +5 -6
- package/dist/es/fields/NumberRange/effect.js +8 -0
- package/dist/es/fields/Select.vue_vue_type_script_setup_true_lang.js +13 -6
- package/dist/es/fields/Text.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/headless.js +13 -0
- package/dist/es/index.js +17 -12
- package/dist/es/plugin.js +57 -41
- package/dist/es/schema.js +6 -8
- package/dist/es/style.css +81 -1
- package/dist/es/submitForm.js +44 -194
- package/dist/es/utils/builtInFields.js +49 -0
- package/dist/es/utils/collectFields.js +407 -0
- package/dist/es/utils/config.js +1 -8
- package/dist/es/utils/fieldInnerConfig.js +42 -0
- package/dist/es/utils/fieldValueEffects.js +80 -0
- package/dist/es/utils/form.js +96 -43
- package/dist/es/utils/formStateProxy.js +111 -0
- package/dist/es/utils/registerField.js +158 -0
- package/dist/es/utils/submitHeadless.js +54 -0
- package/dist/es/utils/tableGroupList.js +85 -0
- package/dist/es/utils/typeMatch.js +17 -19
- package/dist/es/utils/validateError.js +57 -0
- package/dist/es/utils/validateValues.js +115 -0
- package/dist/style.css +81 -1
- package/dist/themes/magic-admin.css +83 -7
- package/dist/tmagic-form-headless.umd.cjs +4080 -0
- package/dist/tmagic-form.umd.cjs +2020 -876
- package/package.json +10 -4
- package/src/Form.vue +49 -149
- package/src/FormBox.vue +5 -4
- package/src/FormDialog.vue +5 -5
- package/src/FormDrawer.vue +5 -5
- package/src/containers/Col.vue +2 -0
- package/src/containers/Container.vue +86 -157
- package/src/containers/Fieldset.vue +5 -0
- package/src/containers/FlexLayout.vue +2 -0
- package/src/containers/GroupList.vue +41 -11
- package/src/containers/GroupListItem.vue +83 -80
- package/src/containers/Panel.vue +3 -0
- package/src/containers/Row.vue +2 -0
- package/src/containers/Step.vue +2 -0
- package/src/containers/Tabs.vue +13 -0
- package/src/containers/table/ActionsColumn.vue +1 -1
- package/src/containers/table/Table.vue +4 -3
- package/src/containers/table/usePagination.ts +1 -1
- package/src/containers/table/useSortable.ts +1 -1
- package/src/containers/table/useTableColumns.ts +9 -19
- package/src/containers/table-group-list/TableGroupList.vue +43 -71
- package/src/containers/table-group-list/useAdd.ts +40 -25
- package/src/containers/table-group-list/useScrollLastItemIntoView.ts +94 -0
- package/src/fields/{CheckboxGroup.vue → CheckboxGroup/Index.vue} +3 -8
- package/src/fields/CheckboxGroup/effect.ts +27 -0
- package/src/fields/{Date.vue → Date/Index.vue} +2 -5
- package/src/fields/Date/effect.ts +29 -0
- package/src/fields/{DateTime.vue → DateTime/Index.vue} +2 -16
- package/src/fields/DateTime/effect.ts +36 -0
- package/src/fields/{Display.vue → Display/Index.vue} +3 -7
- package/src/fields/Display/effect.ts +28 -0
- package/src/fields/{DynamicField.vue → DynamicField/Index.vue} +11 -11
- package/src/fields/DynamicField/effect.ts +74 -0
- package/src/fields/{NumberRange.vue → NumberRange/Index.vue} +2 -6
- package/src/fields/NumberRange/effect.ts +27 -0
- package/src/fields/Select.vue +13 -4
- package/src/headless.ts +78 -0
- package/src/index.ts +32 -15
- package/src/plugin.ts +63 -42
- package/src/schema.ts +6 -8
- package/src/submitForm.ts +81 -409
- package/src/theme/group-list.scss +107 -1
- package/src/theme/themes/magic-admin/index.scss +2 -8
- package/src/utils/builtInFields.ts +69 -0
- package/src/utils/collectFields.ts +561 -0
- package/src/utils/config.ts +1 -15
- package/src/utils/fieldInnerConfig.ts +127 -0
- package/src/utils/fieldValueEffects.ts +140 -0
- package/src/utils/form.ts +141 -75
- package/src/utils/formStateProxy.ts +149 -0
- package/src/utils/registerField.ts +308 -0
- package/src/utils/submitHeadless.ts +206 -0
- package/src/utils/tableGroupList.ts +120 -0
- package/src/utils/typeMatch.ts +19 -15
- package/src/utils/validateError.ts +92 -0
- package/src/utils/validateValues.ts +177 -0
- package/types/headless.d.ts +682 -0
- package/types/index.d.ts +631 -272
- package/dist/es/fields/CheckboxGroup.js +0 -5
- package/dist/es/fields/Date.js +0 -5
- package/dist/es/fields/DateTime.js +0 -5
- package/dist/es/fields/Display.js +0 -5
- package/dist/es/fields/DynamicField.js +0 -5
- package/dist/es/fields/NumberRange.js +0 -5
- package/dist/es/utils/silentLeafFieldTypes.js +0 -49
- package/src/utils/silentLeafFieldTypes.ts +0 -71
package/dist/es/submitForm.js
CHANGED
|
@@ -1,40 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { applyExtendState } from "./utils/form.js";
|
|
1
|
+
import { submitForm as submitForm$1, validateForm as validateForm$1 } from "./utils/submitHeadless.js";
|
|
3
2
|
import Form_default from "./Form.js";
|
|
4
|
-
import { createApp, defineComponent, h, nextTick,
|
|
3
|
+
import { createApp, defineComponent, h, nextTick, ref } from "vue";
|
|
5
4
|
//#region packages/form/src/submitForm.ts
|
|
6
|
-
/** 未指定或传入非正数 timeout 时的兜底超时(毫秒),保证非 debug 挂载始终能被清理 */
|
|
7
|
-
var DEFAULT_MOUNT_TIMEOUT = 1e4;
|
|
8
5
|
/**
|
|
9
|
-
* submitForm / validateForm 的公共脚手架:
|
|
6
|
+
* `dialog: true` 时 submitForm / validateForm 的公共脚手架:
|
|
10
7
|
*
|
|
11
|
-
* 创建临时容器 → 挂载一个 wrapper 组件(内含 MForm)→ 提供统一的 cleanup /
|
|
8
|
+
* 创建临时容器 → 挂载一个 wrapper 组件(内含 MForm)→ 提供统一的 cleanup / appContext 继承 →
|
|
12
9
|
* 由 `createWrapper` 决定「何时调用 MForm 的哪个方法、如何 resolve/reject」。
|
|
13
10
|
*
|
|
14
|
-
*
|
|
15
|
-
* 容器创建、卸载、超时、上下文注入等模板代码在此统一收口。
|
|
11
|
+
* 挂载出来的表单等待人工点击,因此没有超时兜底,靠「确定」/「取消」/`signal` 结束。
|
|
16
12
|
*/
|
|
17
13
|
var mountFormInstance = (options) => {
|
|
18
|
-
const { formProps, appContext,
|
|
14
|
+
const { formProps, appContext, signal, createWrapper } = options;
|
|
19
15
|
return new Promise((resolve, reject) => {
|
|
20
16
|
if (signal?.aborted) {
|
|
21
17
|
reject(signal.reason ?? /* @__PURE__ */ new Error("mountFormInstance aborted"));
|
|
22
18
|
return;
|
|
23
19
|
}
|
|
24
20
|
let cleaned = false;
|
|
25
|
-
let timer = null;
|
|
26
21
|
let onAbort = null;
|
|
27
22
|
const instance = { app: null };
|
|
28
23
|
const container = document.createElement("div");
|
|
29
|
-
if (hidden) container.style.display = "none";
|
|
30
24
|
document.body.appendChild(container);
|
|
31
25
|
const cleanup = () => {
|
|
32
26
|
if (cleaned) return;
|
|
33
27
|
cleaned = true;
|
|
34
|
-
if (timer) {
|
|
35
|
-
clearTimeout(timer);
|
|
36
|
-
timer = null;
|
|
37
|
-
}
|
|
38
28
|
if (signal && onAbort) {
|
|
39
29
|
signal.removeEventListener("abort", onAbort);
|
|
40
30
|
onAbort = null;
|
|
@@ -54,53 +44,16 @@ var mountFormInstance = (options) => {
|
|
|
54
44
|
}
|
|
55
45
|
try {
|
|
56
46
|
const formRef = ref(null);
|
|
57
|
-
const
|
|
58
|
-
const userWrapper = createWrapper({
|
|
47
|
+
const wrapperComponent = createWrapper({
|
|
59
48
|
formRef,
|
|
60
|
-
formProps
|
|
49
|
+
formProps,
|
|
61
50
|
cleanup,
|
|
62
51
|
resolve,
|
|
63
52
|
reject
|
|
64
53
|
});
|
|
65
|
-
const
|
|
66
|
-
name: "MFormExtendStateInjector",
|
|
67
|
-
setup() {
|
|
68
|
-
watch(() => formRef.value, (form) => {
|
|
69
|
-
if (!form) return;
|
|
70
|
-
let result;
|
|
71
|
-
try {
|
|
72
|
-
result = extendState(form.formState);
|
|
73
|
-
} catch (e) {
|
|
74
|
-
console.error("[MForm] extendState failed:", e);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const reservedStateKeys = new Set(Reflect.ownKeys(form.formState));
|
|
78
|
-
const apply = (state) => applyExtendState(form.formState, state, reservedStateKeys);
|
|
79
|
-
if (result && typeof result.then === "function") result.then(apply, (e) => console.error("[MForm] extendState failed:", e));
|
|
80
|
-
else apply(result);
|
|
81
|
-
}, {
|
|
82
|
-
flush: "sync",
|
|
83
|
-
immediate: true
|
|
84
|
-
});
|
|
85
|
-
return () => h(userWrapper);
|
|
86
|
-
}
|
|
87
|
-
}) : userWrapper;
|
|
88
|
-
const rootComponent = hidden ? defineComponent({
|
|
89
|
-
name: "MFormSilentProvider",
|
|
90
|
-
setup() {
|
|
91
|
-
provide(FORM_SILENT_MODE_KEY, true);
|
|
92
|
-
return () => h(wrapperComponent);
|
|
93
|
-
}
|
|
94
|
-
}) : wrapperComponent;
|
|
95
|
-
const app = createApp(rootComponent);
|
|
54
|
+
const app = createApp(wrapperComponent);
|
|
96
55
|
instance.app = app;
|
|
97
56
|
if (appContext) Object.assign(app._context, appContext);
|
|
98
|
-
if (!skipTimeout) timer = setTimeout(() => {
|
|
99
|
-
if (!cleaned) {
|
|
100
|
-
reject(new Error(timeoutMessage));
|
|
101
|
-
cleanup();
|
|
102
|
-
}
|
|
103
|
-
}, timeout > 0 ? timeout : DEFAULT_MOUNT_TIMEOUT);
|
|
104
57
|
app.mount(container);
|
|
105
58
|
} catch (err) {
|
|
106
59
|
reject(err);
|
|
@@ -109,12 +62,12 @@ var mountFormInstance = (options) => {
|
|
|
109
62
|
});
|
|
110
63
|
};
|
|
111
64
|
/**
|
|
112
|
-
*
|
|
65
|
+
* 构造可见弹层 wrapper:以 fixed 遮罩居中渲染 MForm,提供「确定 / 取消」按钮与错误展示区。
|
|
113
66
|
*
|
|
114
|
-
* submitForm 与 validateForm
|
|
67
|
+
* submitForm 与 validateForm 的弹层 UI 完全一致,仅「确定」时调用的实例方法、错误处理与取消文案不同,
|
|
115
68
|
* 这些差异通过 `onConfirm` / `onCancel` 注入,弹层结构在此统一收口。
|
|
116
69
|
*/
|
|
117
|
-
var
|
|
70
|
+
var createDialogWrapper = (options) => {
|
|
118
71
|
const { formRef, formProps, title, name, onConfirm, onCancel } = options;
|
|
119
72
|
const btnBase = {
|
|
120
73
|
padding: "8px 20px",
|
|
@@ -197,57 +150,17 @@ var createDebugWrapper = (options) => {
|
|
|
197
150
|
});
|
|
198
151
|
};
|
|
199
152
|
/**
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
* 类似 ElMessage 的用法:传入 props(包含 `config`/`initValues` 等),函数内部会临时挂载
|
|
203
|
-
* 一个不可见的 Form 组件实例,等待初始化完成后调用其 `submitForm` 方法,
|
|
204
|
-
* 校验通过则 resolve 表单值,校验失败则 reject 错误信息,最后自动卸载实例。
|
|
205
|
-
*
|
|
206
|
-
* @example
|
|
207
|
-
* ```ts
|
|
208
|
-
* import { submitForm } from '@tmagic/form';
|
|
153
|
+
* 可见弹层提交:把表单渲染在弹层里,点击「确定」才调用挂载实例的 `submitForm`。
|
|
209
154
|
*
|
|
210
|
-
*
|
|
211
|
-
* const values = await submitForm({
|
|
212
|
-
* config: [...],
|
|
213
|
-
* initValues: { name: 'foo' },
|
|
214
|
-
* });
|
|
215
|
-
* console.log(values);
|
|
216
|
-
* } catch (e) {
|
|
217
|
-
* console.error(e);
|
|
218
|
-
* }
|
|
219
|
-
*
|
|
220
|
-
* // 需要同时获取变更记录时:
|
|
221
|
-
* const { values, changeRecords } = await submitForm({
|
|
222
|
-
* config: [...],
|
|
223
|
-
* initValues: { name: 'foo' },
|
|
224
|
-
* returnChangeRecords: true,
|
|
225
|
-
* });
|
|
226
|
-
*
|
|
227
|
-
* // 调试模式:可见地渲染表单,点击「确定」才提交:
|
|
228
|
-
* const values = await submitForm({
|
|
229
|
-
* config: [...],
|
|
230
|
-
* initValues: { name: 'foo' },
|
|
231
|
-
* debug: true,
|
|
232
|
-
* });
|
|
233
|
-
* ```
|
|
155
|
+
* 用于需要用户填写/确认的场景;默认路径仍是无渲染校验(见 `submitForm` 的说明)。
|
|
234
156
|
*/
|
|
235
|
-
var
|
|
236
|
-
const { native, appContext,
|
|
157
|
+
var submitFormByDialogRender = (options) => {
|
|
158
|
+
const { native, appContext, returnChangeRecords, signal, dialog, title, ...formProps } = options;
|
|
237
159
|
return mountFormInstance({
|
|
238
160
|
formProps,
|
|
239
161
|
appContext,
|
|
240
|
-
timeout,
|
|
241
162
|
signal,
|
|
242
|
-
hidden: !debug,
|
|
243
|
-
skipTimeout: debug,
|
|
244
|
-
timeoutMessage: `submitForm timeout after ${timeout}ms: form is not initialized.`,
|
|
245
163
|
createWrapper: ({ formRef, formProps, cleanup, resolve, reject }) => {
|
|
246
|
-
/**
|
|
247
|
-
* 执行一次提交:nextTick 等待子组件渲染 → 快照 changeRecords → 调用实例 submitForm → resolve。
|
|
248
|
-
* 校验失败时交给 `onValidateError` 决定「保留弹层展示错误(debug)」还是「reject 并清理(普通)」,
|
|
249
|
-
* 从而让 debug 与普通模式共享同一份提交逻辑。
|
|
250
|
-
*/
|
|
251
164
|
const doSubmit = async (onValidateError) => {
|
|
252
165
|
try {
|
|
253
166
|
await nextTick();
|
|
@@ -262,39 +175,19 @@ var submitForm = (options) => {
|
|
|
262
175
|
onValidateError(err);
|
|
263
176
|
}
|
|
264
177
|
};
|
|
265
|
-
|
|
178
|
+
return createDialogWrapper({
|
|
266
179
|
formRef,
|
|
267
180
|
formProps,
|
|
268
181
|
name: "MFormSubmitWrapper",
|
|
269
|
-
title: "submitForm
|
|
182
|
+
title: title ?? "submitForm",
|
|
270
183
|
onConfirm: (setError) => doSubmit((err) => {
|
|
271
184
|
setError(err instanceof Error ? err.message : String(err));
|
|
272
185
|
}),
|
|
273
186
|
onCancel: () => {
|
|
274
|
-
reject(/* @__PURE__ */ new Error("submitForm canceled
|
|
187
|
+
reject(/* @__PURE__ */ new Error("submitForm canceled."));
|
|
275
188
|
cleanup();
|
|
276
189
|
}
|
|
277
190
|
});
|
|
278
|
-
return defineComponent({
|
|
279
|
-
name: "MFormSubmitWrapper",
|
|
280
|
-
setup() {
|
|
281
|
-
const stop = watch(() => formRef.value?.initialized, (initialized) => {
|
|
282
|
-
if (!initialized) return;
|
|
283
|
-
stop();
|
|
284
|
-
doSubmit((err) => {
|
|
285
|
-
reject(err);
|
|
286
|
-
cleanup();
|
|
287
|
-
});
|
|
288
|
-
}, {
|
|
289
|
-
flush: "post",
|
|
290
|
-
immediate: true
|
|
291
|
-
});
|
|
292
|
-
return () => h(Form_default, {
|
|
293
|
-
...formProps,
|
|
294
|
-
ref: formRef
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
});
|
|
298
191
|
}
|
|
299
192
|
});
|
|
300
193
|
};
|
|
@@ -338,61 +231,20 @@ var stripTabItemsLazy = (config) => {
|
|
|
338
231
|
return cloned;
|
|
339
232
|
};
|
|
340
233
|
/**
|
|
341
|
-
*
|
|
342
|
-
*
|
|
343
|
-
* 与 `submitForm` 类似,内部会临时挂载一个不可见的 MForm 实例,等待其初始化完成后调用
|
|
344
|
-
* 实例的 `validate` 方法,返回汇总后的错误文案,随后自动卸载实例。
|
|
345
|
-
*
|
|
346
|
-
* 与 `submitForm` 的区别:
|
|
347
|
-
* - 「静默」:校验失败不抛异常、不触发 `error` 事件、不返回表单值;
|
|
348
|
-
* - 仅用于「探测」配置是否合法,适合源码保存后校验、批量校验组件配置等场景。
|
|
234
|
+
* 可见弹层校验:把表单渲染在弹层里,点击「确定」才调用挂载实例的 `validate`。
|
|
349
235
|
*
|
|
350
|
-
*
|
|
351
|
-
* 页面上正在展示的表单状态。
|
|
352
|
-
*
|
|
353
|
-
* @returns 校验通过返回空字符串 `''`,否则返回以 `<br>` 拼接的错误文案。
|
|
354
|
-
* 仅在初始化超时或挂载失败等异常情况下才会 reject。
|
|
355
|
-
*
|
|
356
|
-
* @example
|
|
357
|
-
* ```ts
|
|
358
|
-
* import { validateForm } from '@tmagic/form';
|
|
359
|
-
*
|
|
360
|
-
* const error = await validateForm({
|
|
361
|
-
* config: [...],
|
|
362
|
-
* initValues: { name: 'foo' },
|
|
363
|
-
* appContext: getCurrentInstance()?.appContext,
|
|
364
|
-
* });
|
|
365
|
-
* if (error) {
|
|
366
|
-
* // 配置不合法,error 为错误文案
|
|
367
|
-
* }
|
|
368
|
-
*
|
|
369
|
-
* // 调试模式:可见地渲染表单,点击「确定」才校验,校验失败保留弹层可修正重试:
|
|
370
|
-
* const error = await validateForm({
|
|
371
|
-
* config: [...],
|
|
372
|
-
* initValues: { name: 'foo' },
|
|
373
|
-
* debug: true,
|
|
374
|
-
* });
|
|
375
|
-
* ```
|
|
236
|
+
* 用于需要用户填写/确认的场景;默认路径仍是无渲染校验(见 `validateForm` 的说明)。
|
|
376
237
|
*/
|
|
377
|
-
var
|
|
378
|
-
const { appContext,
|
|
238
|
+
var validateFormByDialogRender = (options) => {
|
|
239
|
+
const { appContext, config, signal, dialog, title, ...rest } = options;
|
|
379
240
|
return mountFormInstance({
|
|
380
241
|
formProps: {
|
|
381
242
|
...rest,
|
|
382
243
|
config: stripTabItemsLazy(config)
|
|
383
244
|
},
|
|
384
245
|
appContext,
|
|
385
|
-
timeout,
|
|
386
246
|
signal,
|
|
387
|
-
hidden: !debug,
|
|
388
|
-
skipTimeout: debug,
|
|
389
|
-
timeoutMessage: `validateForm timeout after ${timeout}ms: form is not initialized.`,
|
|
390
247
|
createWrapper: ({ formRef, formProps, cleanup, resolve, reject }) => {
|
|
391
|
-
/**
|
|
392
|
-
* 执行一次校验:nextTick 等待子组件渲染 → 调用实例 validate → 通过则 resolve ''。
|
|
393
|
-
* 校验失败(返回非空错误文案)时交给 `onInvalid` 决定「静默 resolve 错误文案(普通)」
|
|
394
|
-
* 还是「在弹层展示错误并保留供重试(debug)」,从而让两种模式共享同一份校验逻辑。
|
|
395
|
-
*/
|
|
396
248
|
const doValidate = async (onInvalid) => {
|
|
397
249
|
try {
|
|
398
250
|
await nextTick();
|
|
@@ -407,41 +259,39 @@ var validateForm = (options) => {
|
|
|
407
259
|
cleanup();
|
|
408
260
|
}
|
|
409
261
|
};
|
|
410
|
-
|
|
262
|
+
return createDialogWrapper({
|
|
411
263
|
formRef,
|
|
412
264
|
formProps,
|
|
413
265
|
name: "MFormValidateWrapper",
|
|
414
|
-
title: "validateForm
|
|
266
|
+
title: title ?? "validateForm",
|
|
415
267
|
onConfirm: (setError) => doValidate((error) => {
|
|
416
268
|
setError(error);
|
|
417
269
|
}),
|
|
418
270
|
onCancel: () => {
|
|
419
|
-
reject(/* @__PURE__ */ new Error("validateForm canceled
|
|
271
|
+
reject(/* @__PURE__ */ new Error("validateForm canceled."));
|
|
420
272
|
cleanup();
|
|
421
273
|
}
|
|
422
274
|
});
|
|
423
|
-
return defineComponent({
|
|
424
|
-
name: "MFormValidateWrapper",
|
|
425
|
-
setup() {
|
|
426
|
-
const stop = watch(() => formRef.value?.initialized, (initialized) => {
|
|
427
|
-
if (!initialized) return;
|
|
428
|
-
stop();
|
|
429
|
-
doValidate((error) => {
|
|
430
|
-
resolve(error);
|
|
431
|
-
cleanup();
|
|
432
|
-
});
|
|
433
|
-
}, {
|
|
434
|
-
flush: "post",
|
|
435
|
-
immediate: true
|
|
436
|
-
});
|
|
437
|
-
return () => h(Form_default, {
|
|
438
|
-
...formProps,
|
|
439
|
-
ref: formRef
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
});
|
|
443
275
|
}
|
|
444
276
|
});
|
|
445
277
|
};
|
|
278
|
+
/**
|
|
279
|
+
* 以命令式方式对一份「表单配置 + 值」做一次校验并取回表单值。
|
|
280
|
+
*
|
|
281
|
+
* 默认走无渲染实现(见 `@tmagic/form/headless`)。`dialog: true` 会把表单以弹层渲染出来。
|
|
282
|
+
*/
|
|
283
|
+
var submitForm = async (options) => {
|
|
284
|
+
if (options.dialog) return submitFormByDialogRender(options);
|
|
285
|
+
return submitForm$1(options);
|
|
286
|
+
};
|
|
287
|
+
/**
|
|
288
|
+
* 以命令式方式对一份「表单配置 + 值」做一次静默校验。
|
|
289
|
+
*
|
|
290
|
+
* 默认走无渲染实现。`dialog: true` 的处理详见 `submitForm`。
|
|
291
|
+
*/
|
|
292
|
+
var validateForm = async (options) => {
|
|
293
|
+
if (options.dialog) return validateFormByDialogRender(options);
|
|
294
|
+
return validateForm$1(options);
|
|
295
|
+
};
|
|
446
296
|
//#endregion
|
|
447
297
|
export { stripTabItemsLazy, submitForm, validateForm };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { expandFieldset, expandPanel, expandRow, expandStep, expandTab, expandTableGroupList } from "./collectFields.js";
|
|
2
|
+
import { effect } from "../fields/DynamicField/effect.js";
|
|
3
|
+
import { effect as effect$1 } from "../fields/CheckboxGroup/effect.js";
|
|
4
|
+
import { effect as effect$2 } from "../fields/Date/effect.js";
|
|
5
|
+
import { effect as effect$3 } from "../fields/DateTime/effect.js";
|
|
6
|
+
import { effect as effect$4 } from "../fields/Display/effect.js";
|
|
7
|
+
import { effect as effect$5 } from "../fields/NumberRange/effect.js";
|
|
8
|
+
//#region packages/form/src/utils/builtInFields.ts
|
|
9
|
+
/**
|
|
10
|
+
* 内置字段的无渲染登记表(不含 Vue 组件)。
|
|
11
|
+
*
|
|
12
|
+
* 本模块只导出数据,不登记。调用方自行 `registerBuiltInFields(builtInFields)`,
|
|
13
|
+
* 或 `app.use(MagicForm)`(install 里会登记叠上 Vue 组件后的表)。
|
|
14
|
+
*/
|
|
15
|
+
var builtInFields = {
|
|
16
|
+
text: {},
|
|
17
|
+
"img-upload": {},
|
|
18
|
+
number: {},
|
|
19
|
+
"number-range": { effect: effect$5 },
|
|
20
|
+
textarea: {},
|
|
21
|
+
hidden: {},
|
|
22
|
+
date: { effect: effect$2 },
|
|
23
|
+
datetime: { effect: effect$3 },
|
|
24
|
+
daterange: {},
|
|
25
|
+
timerange: {},
|
|
26
|
+
time: {},
|
|
27
|
+
checkbox: {},
|
|
28
|
+
switch: {},
|
|
29
|
+
"color-picker": {},
|
|
30
|
+
"checkbox-group": { effect: effect$1 },
|
|
31
|
+
"radio-group": {},
|
|
32
|
+
display: { effect: effect$4 },
|
|
33
|
+
link: {},
|
|
34
|
+
select: {},
|
|
35
|
+
cascader: {},
|
|
36
|
+
"dynamic-field": { effect },
|
|
37
|
+
component: {},
|
|
38
|
+
tab: { walk: expandTab },
|
|
39
|
+
row: { walk: expandRow },
|
|
40
|
+
"flex-layout": { walk: expandRow },
|
|
41
|
+
fieldset: { walk: expandFieldset },
|
|
42
|
+
panel: { walk: expandPanel },
|
|
43
|
+
step: { walk: expandStep },
|
|
44
|
+
table: { walk: expandTableGroupList },
|
|
45
|
+
"group-list": { walk: expandTableGroupList },
|
|
46
|
+
"table-group-list": { walk: expandTableGroupList }
|
|
47
|
+
};
|
|
48
|
+
//#endregion
|
|
49
|
+
export { builtInFields };
|