@tmagic/form 1.8.0-manmanyu.9 → 1.8.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/es/Form.vue_vue_type_script_setup_true_lang.js +88 -107
- package/dist/es/FormBox.vue_vue_type_script_setup_true_lang.js +21 -5
- package/dist/es/FormDialog.vue_vue_type_script_setup_true_lang.js +21 -5
- package/dist/es/FormDrawer.vue_vue_type_script_setup_true_lang.js +46 -12
- package/dist/es/containers/Col.vue_vue_type_script_setup_true_lang.js +6 -2
- package/dist/es/containers/Container.vue_vue_type_script_setup_true_lang.js +44 -47
- package/dist/es/containers/Fieldset.vue_vue_type_script_setup_true_lang.js +7 -1
- package/dist/es/containers/FlexLayout.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/containers/FormLabel.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/containers/GroupList.vue_vue_type_script_setup_true_lang.js +59 -22
- package/dist/es/containers/GroupListItem.vue_vue_type_script_setup_true_lang.js +118 -100
- package/dist/es/containers/Panel.vue_vue_type_script_setup_true_lang.js +8 -3
- package/dist/es/containers/Row.vue_vue_type_script_setup_true_lang.js +4 -1
- package/dist/es/containers/Step.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/containers/Tabs.vue_vue_type_script_setup_true_lang.js +8 -1
- package/dist/es/containers/table/ActionsColumn.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/containers/table/SortColumn.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/containers/table/Table.vue_vue_type_script_setup_true_lang.js +14 -10
- package/dist/es/containers/table/useTableColumns.js +10 -15
- package/dist/es/containers/table-group-list/TableGroupList.vue_vue_type_script_setup_true_lang.js +72 -79
- 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 +2 -2
- package/dist/es/fields/Checkbox.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/ColorPicker.vue_vue_type_script_setup_true_lang.js +1 -1
- 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/Daterange.vue_vue_type_script_setup_true_lang.js +2 -2
- 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/Hidden.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Link.vue_vue_type_script_setup_true_lang.js +4 -4
- package/dist/es/fields/Number.vue_vue_type_script_setup_true_lang.js +4 -2
- 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/RadioGroup.vue_vue_type_script_setup_true_lang.js +5 -2
- package/dist/es/fields/Select.vue_vue_type_script_setup_true_lang.js +14 -6
- package/dist/es/fields/Switch.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Text.vue_vue_type_script_setup_true_lang.js +13 -10
- package/dist/es/fields/Textarea.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Time.vue_vue_type_script_setup_true_lang.js +1 -1
- package/dist/es/fields/Timerange.vue_vue_type_script_setup_true_lang.js +3 -3
- package/dist/es/headless.js +13 -0
- package/dist/es/index.js +19 -12
- package/dist/es/plugin.js +57 -39
- package/dist/es/schema.js +11 -2
- package/dist/es/style.css +123 -3
- package/dist/es/submitForm.js +270 -72
- package/dist/es/utils/builtInFields.js +49 -0
- package/dist/es/utils/collectFields.js +407 -0
- package/dist/es/utils/config.js +4 -8
- package/dist/es/utils/fieldInnerConfig.js +42 -0
- package/dist/es/utils/fieldValueEffects.js +80 -0
- package/dist/es/utils/form.js +154 -19
- 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 +104 -0
- package/dist/es/utils/typeMatch.js +532 -0
- package/dist/es/utils/validateError.js +57 -0
- package/dist/es/utils/validateValues.js +115 -0
- package/dist/style.css +123 -3
- package/dist/themes/magic-admin.css +576 -14
- package/dist/tmagic-form-headless.umd.cjs +4515 -0
- package/dist/tmagic-form.umd.cjs +3444 -983
- package/package.json +16 -10
- package/src/Form.vue +113 -129
- package/src/FormBox.vue +16 -4
- package/src/FormDialog.vue +16 -5
- package/src/FormDrawer.vue +41 -13
- package/src/containers/Col.vue +3 -0
- package/src/containers/Container.vue +40 -45
- package/src/containers/Fieldset.vue +5 -0
- package/src/containers/FlexLayout.vue +2 -0
- package/src/containers/GroupList.vue +64 -13
- package/src/containers/GroupListItem.vue +88 -81
- 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 +5 -3
- package/src/containers/table/usePagination.ts +1 -1
- package/src/containers/table/useSortable.ts +1 -1
- package/src/containers/table/useTableColumns.ts +15 -22
- package/src/containers/table-group-list/TableGroupList.vue +46 -72
- 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/Link.vue +3 -4
- package/src/fields/Number.vue +2 -1
- package/src/fields/{NumberRange.vue → NumberRange/Index.vue} +2 -6
- package/src/fields/NumberRange/effect.ts +27 -0
- package/src/fields/RadioGroup.vue +13 -1
- package/src/fields/Select.vue +13 -4
- package/src/headless.ts +78 -0
- package/src/index.ts +46 -9
- package/src/plugin.ts +68 -37
- package/src/schema.ts +13 -2
- package/src/submitForm.ts +410 -131
- package/src/theme/fieldset.scss +1 -0
- package/src/theme/form-box.scss +5 -0
- package/src/theme/form-dialog.scss +1 -1
- package/src/theme/group-list.scss +143 -2
- package/src/theme/table.scss +11 -1
- package/src/theme/themes/magic-admin/index.scss +27 -16
- package/src/utils/builtInFields.ts +69 -0
- package/src/utils/collectFields.ts +561 -0
- package/src/utils/config.ts +7 -15
- package/src/utils/fieldInnerConfig.ts +127 -0
- package/src/utils/fieldValueEffects.ts +140 -0
- package/src/utils/form.ts +230 -30
- 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 +147 -0
- package/src/utils/typeMatch.ts +948 -0
- 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 +900 -180
- package/dist/es/_virtual/_rolldown/runtime.js +0 -27
- 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
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { FORM_DIFF_CONFIG_KEY } from "./schema.js";
|
|
2
|
-
import {
|
|
3
|
-
import { initValue } from "./utils/form.js";
|
|
1
|
+
import { FORM_CONTEXT_KEY, FORM_DIFF_CONFIG_KEY, FORM_TYPE_MATCH_VALID_KEY } from "./schema.js";
|
|
2
|
+
import { createFormStateProxy, mergeFormContexts } from "./utils/formStateProxy.js";
|
|
3
|
+
import { createFormStateBase, initValue } from "./utils/form.js";
|
|
4
|
+
import { applyMountValueEffects } from "./utils/collectFields.js";
|
|
5
|
+
import { formatValidateError, getTextByName } from "./utils/validateError.js";
|
|
4
6
|
import Container_default from "./containers/Container.js";
|
|
5
|
-
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createSlots, defineComponent, inject, mergeProps, normalizeClass, normalizeStyle, openBlock, provide, reactive, ref, renderList, renderSlot, shallowRef, toRaw, unref, useTemplateRef, watch,
|
|
6
|
-
import { cloneDeep,
|
|
7
|
-
import { M_THEME_KEY, TMagicForm, tMagicMessage, tMagicMessageBox } from "@tmagic/design";
|
|
7
|
+
import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createSlots, defineComponent, inject, mergeProps, nextTick, normalizeClass, normalizeStyle, openBlock, provide, reactive, ref, renderList, renderSlot, shallowRef, toRaw, unref, useTemplateRef, watch, withCtx } from "vue";
|
|
8
|
+
import { cloneDeep, isEqualWith } from "lodash-es";
|
|
8
9
|
import { setValueByKeyPath } from "@tmagic/utils";
|
|
10
|
+
import { M_THEME_KEY, TMagicForm, tMagicMessage, tMagicMessageBox } from "@tmagic/design";
|
|
9
11
|
//#region packages/form/src/Form.vue?vue&type=script&setup=true&lang.ts
|
|
10
|
-
var Form_vue_vue_type_script_setup_true_lang_default =
|
|
12
|
+
var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
11
13
|
name: "MForm",
|
|
12
14
|
__name: "Form",
|
|
13
15
|
props: {
|
|
@@ -20,6 +22,11 @@ var Form_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
20
22
|
},
|
|
21
23
|
parentValues: { default: () => ({}) },
|
|
22
24
|
labelWidth: { default: "200px" },
|
|
25
|
+
typeMatchValid: { type: Boolean },
|
|
26
|
+
validateOnInit: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
default: false
|
|
29
|
+
},
|
|
23
30
|
disabled: {
|
|
24
31
|
type: Boolean,
|
|
25
32
|
default: false
|
|
@@ -35,7 +42,11 @@ var Form_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
35
42
|
keyProp: { default: "__key" },
|
|
36
43
|
popperClass: {},
|
|
37
44
|
preventSubmitDefault: { type: Boolean },
|
|
38
|
-
|
|
45
|
+
useFieldTextInError: {
|
|
46
|
+
type: Boolean,
|
|
47
|
+
default: true
|
|
48
|
+
},
|
|
49
|
+
context: {},
|
|
39
50
|
showDiff: {},
|
|
40
51
|
selfDiffFieldTypes: {},
|
|
41
52
|
theme: {}
|
|
@@ -50,12 +61,11 @@ var Form_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
50
61
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
51
62
|
const props = __props;
|
|
52
63
|
const emit = __emit;
|
|
64
|
+
provide(FORM_TYPE_MATCH_VALID_KEY, computed(() => props.typeMatchValid));
|
|
53
65
|
const tMagicFormRef = useTemplateRef("tMagicForm");
|
|
54
66
|
const initialized = ref(false);
|
|
55
67
|
const values = ref({});
|
|
56
68
|
const lastValuesProcessed = ref({});
|
|
57
|
-
const fields = /* @__PURE__ */ new Map();
|
|
58
|
-
const requestFuc = getConfig("request");
|
|
59
69
|
/**
|
|
60
70
|
* 当前表单生效的主题名称:
|
|
61
71
|
* - 优先用本组件自己的 `props.theme`;
|
|
@@ -85,18 +95,14 @@ var Form_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
85
95
|
* 2. `values` / `lastValuesProcessed` 是 ref,Vue 的 `reactive` 会自动解包,因此每次
|
|
86
96
|
* 访问 `formState.values` / `formState.lastValuesProcessed` 也都是当前 ref 值。
|
|
87
97
|
*
|
|
88
|
-
* 3.
|
|
89
|
-
*
|
|
90
|
-
* set,触发依赖通知;`extendState` 同步段读到的响应式数据变化时会自动重跑,
|
|
91
|
-
* 把最新值刷进 formState。
|
|
92
|
-
* - accessor 描述符(`{ get stage() { return ... } }`)按原样写入,调用方可以控制
|
|
93
|
-
* 读时求值,每次读取都会重新执行 getter。
|
|
98
|
+
* 3. 宿主业务上下文不再 merge 进 coreState,而是单独放在 `contextRef` 上,由读穿
|
|
99
|
+
* Proxy 在 miss 时落到 context。核心字段结构性优先,`mForm.xxx` 永久兼容旧读法。
|
|
94
100
|
*
|
|
95
101
|
* 4. `popperClass` 会自动拼接 `themeClass`:调用方传入的 `popperClass` + 当前主题
|
|
96
102
|
* 修饰类(含祖先 `<MEditor>` provide 的主题)。这样所有透传到 Element Plus 弹层
|
|
97
103
|
* `popper-class` 的字段(Select / DateTime / Cascader 等)能自带主题作用域。
|
|
98
104
|
*/
|
|
99
|
-
const
|
|
105
|
+
const coreState = reactive({
|
|
100
106
|
get keyProp() {
|
|
101
107
|
return props.keyProp;
|
|
102
108
|
},
|
|
@@ -125,68 +131,27 @@ var Form_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
125
131
|
values,
|
|
126
132
|
lastValuesProcessed,
|
|
127
133
|
$emit: emit,
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
$messageBox: tMagicMessageBox,
|
|
133
|
-
$message: tMagicMessage,
|
|
134
|
-
post: (options) => {
|
|
135
|
-
if (requestFuc) return requestFuc({
|
|
136
|
-
method: "POST",
|
|
137
|
-
...options
|
|
138
|
-
});
|
|
139
|
-
}
|
|
134
|
+
...createFormStateBase({
|
|
135
|
+
$message: tMagicMessage,
|
|
136
|
+
$messageBox: tMagicMessageBox
|
|
137
|
+
})
|
|
140
138
|
});
|
|
139
|
+
const ancestorContext = inject(FORM_CONTEXT_KEY, void 0);
|
|
141
140
|
/**
|
|
142
|
-
* `
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* extendState: (formState) => ({
|
|
146
|
-
* username: store.username, // 同步读 store,会被跟踪
|
|
147
|
-
* env: store.env,
|
|
148
|
-
* })
|
|
149
|
-
*
|
|
150
|
-
* 当 `store.username` 变化时,整个 effect 重跑,新值会被刷进 `formState`。
|
|
151
|
-
*
|
|
152
|
-
* prop 派生字段(initValues / config / ...)已经在上方用 getter 定义,
|
|
153
|
-
* 这里不再重复同步;因此 `props.initValues` 这类高频变化也不会再触发
|
|
154
|
-
* `extendState` 重跑(旧版的性能问题修复点)。
|
|
155
|
-
*
|
|
156
|
-
* 实现细节:
|
|
157
|
-
* - data 描述符:通过 `formState[key] = value` 走 reactive proxy 的 set,
|
|
158
|
-
* 触发依赖通知;与旧版「逐项赋值」语义完全等价。
|
|
159
|
-
* - accessor 描述符(`{ get stage() {...} }`)按原样写入 formState,调用方
|
|
160
|
-
* 可以自行控制读时求值;强制 `configurable: true` 以便下一次重跑可再 define。
|
|
141
|
+
* 宿主业务上下文:`props.context` 覆盖祖先注入的同名字段。
|
|
142
|
+
* 嵌套表单(Link / FormBox / FormDialog)通过下面的 provide 自动继承。
|
|
161
143
|
*/
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
if (typeof extendState !== "function") return;
|
|
165
|
-
let stale = false;
|
|
166
|
-
onCleanup(() => {
|
|
167
|
-
stale = true;
|
|
168
|
-
});
|
|
169
|
-
let state = {};
|
|
170
|
-
try {
|
|
171
|
-
state = await extendState(formState) || {};
|
|
172
|
-
} catch (e) {
|
|
173
|
-
console.error("[MForm] extendState failed:", e);
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
176
|
-
if (stale) return;
|
|
177
|
-
for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(state))) if ("value" in descriptor) formState[key] = state[key];
|
|
178
|
-
else {
|
|
179
|
-
descriptor.configurable = true;
|
|
180
|
-
Object.defineProperty(formState, key, descriptor);
|
|
181
|
-
}
|
|
182
|
-
});
|
|
144
|
+
const contextRef = computed(() => mergeFormContexts(ancestorContext?.value, props.context));
|
|
145
|
+
const formState = createFormStateProxy(coreState, () => contextRef.value);
|
|
183
146
|
provide("mForm", formState);
|
|
147
|
+
provide(FORM_CONTEXT_KEY, contextRef);
|
|
184
148
|
/**
|
|
185
149
|
* 把生效主题(自身或祖先)再 provide 出去,供 form 子树内含 `Teleport` 的组件
|
|
186
150
|
* (如 `TMagicPopover`)在传送目标上挂 `m-theme--<theme>` 类。
|
|
187
151
|
* 详见 `@tmagic/design/theme.ts`。
|
|
188
152
|
*/
|
|
189
153
|
provide(M_THEME_KEY, effectiveTheme);
|
|
154
|
+
provide("formInline", props.inline);
|
|
190
155
|
provide(FORM_DIFF_CONFIG_KEY, {
|
|
191
156
|
get showDiff() {
|
|
192
157
|
return props.showDiff;
|
|
@@ -196,21 +161,35 @@ var Form_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
196
161
|
}
|
|
197
162
|
});
|
|
198
163
|
const changeRecords = shallowRef([]);
|
|
199
|
-
|
|
164
|
+
/**
|
|
165
|
+
* 两份配置的结构是否一致;函数一律视为相等。
|
|
166
|
+
*
|
|
167
|
+
* 宿主(如编辑器属性面板)往往在每次节点更新后整份重新生成配置,其中的
|
|
168
|
+
* `display` / `options` / `onChange` 都是新闭包,深比较必然判不等。若据此把 `initialized`
|
|
169
|
+
* 置 false,整棵表单会卸载重挂,滚动位置、展开态、输入焦点全部丢失。
|
|
170
|
+
* 配置是响应式 prop,闭包换了照样生效,只有结构变化(增删字段、换组件类型)才需要重挂。
|
|
171
|
+
*/
|
|
172
|
+
const isSameConfigShape = (config, preConfig) => isEqualWith(config, preConfig, (a, b) => typeof a === "function" && typeof b === "function" ? true : void 0);
|
|
173
|
+
watch([() => props.config, () => props.initValues], async ([config], [preConfig]) => {
|
|
200
174
|
changeRecords.value = [];
|
|
201
|
-
if (!
|
|
175
|
+
if (!isSameConfigShape(toRaw(config), toRaw(preConfig))) initialized.value = false;
|
|
202
176
|
initValue(formState, {
|
|
203
177
|
initValues: props.initValues,
|
|
204
178
|
config: props.config
|
|
205
179
|
}).then((value) => {
|
|
206
180
|
values.value = value;
|
|
181
|
+
applyMountValueEffects(formState, props.config, values.value);
|
|
207
182
|
initialized.value = !props.isCompare;
|
|
183
|
+
if (props.validateOnInit) nextTick(() => {
|
|
184
|
+
tMagicFormRef.value?.validate();
|
|
185
|
+
});
|
|
208
186
|
});
|
|
209
187
|
if (props.isCompare) initValue(formState, {
|
|
210
188
|
initValues: props.lastValues,
|
|
211
189
|
config: props.config
|
|
212
190
|
}).then((value) => {
|
|
213
191
|
lastValuesProcessed.value = value;
|
|
192
|
+
applyMountValueEffects(formState, props.config, lastValuesProcessed.value);
|
|
214
193
|
initialized.value = true;
|
|
215
194
|
});
|
|
216
195
|
}, { immediate: true });
|
|
@@ -228,34 +207,17 @@ var Form_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
228
207
|
const submitHandler = (e) => {
|
|
229
208
|
if (props.preventSubmitDefault) e.preventDefault();
|
|
230
209
|
};
|
|
210
|
+
const getTextByName$1 = (name, config = props.config) => getTextByName(name, config);
|
|
231
211
|
/**
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
212
|
+
* 将校验返回的 invalidFields 汇总为可读的错误文案(多条以 `<br>` 拼接)。
|
|
213
|
+
*
|
|
214
|
+
* 实现收口在 `utils/validateError`,供渲染式校验(本组件的 `submitForm` / `validate`)与
|
|
215
|
+
* 无渲染校验(`validateValues`)共用,保证两条链路产出的错误文案格式完全一致。
|
|
236
216
|
*/
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
if (parts.length === 0) return void 0;
|
|
242
|
-
const [currentPart, ...remainingParts] = parts;
|
|
243
|
-
for (const item of configs) {
|
|
244
|
-
if (item.name === currentPart) {
|
|
245
|
-
if (remainingParts.length === 0) return typeof item.text === "string" ? item.text : void 0;
|
|
246
|
-
if ("items" in item && Array.isArray(item.items)) {
|
|
247
|
-
const result = findInConfig(item.items, remainingParts);
|
|
248
|
-
if (result !== void 0) return result;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
if ("items" in item && Array.isArray(item.items)) {
|
|
252
|
-
const result = findInConfig(item.items, parts);
|
|
253
|
-
if (result !== void 0) return result;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
};
|
|
257
|
-
return findInConfig(config, nameParts);
|
|
258
|
-
};
|
|
217
|
+
const formatValidateError$1 = (invalidFields) => formatValidateError(invalidFields, {
|
|
218
|
+
config: props.config,
|
|
219
|
+
useFieldTextInError: props.useFieldTextInError
|
|
220
|
+
});
|
|
259
221
|
__expose({
|
|
260
222
|
values,
|
|
261
223
|
lastValuesProcessed,
|
|
@@ -275,18 +237,35 @@ var Form_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
275
237
|
return native ? values.value : cloneDeep(toRaw(values.value));
|
|
276
238
|
} catch (invalidFields) {
|
|
277
239
|
emit("error", invalidFields);
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
240
|
+
throw new Error(formatValidateError$1(invalidFields));
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
/**
|
|
244
|
+
* 校验:对表单当前值执行校验,返回汇总后的错误文案。
|
|
245
|
+
*
|
|
246
|
+
* 与 `submitForm` 的区别:
|
|
247
|
+
* - 校验失败时不抛异常、不触发 `error` 事件,而是以返回值形式给出错误文案;
|
|
248
|
+
* - 不重置 `changeRecords`,不改变提交语义,仅用于「探测」当前配置是否合法。
|
|
249
|
+
*
|
|
250
|
+
* 注意:本方法只改变「校验结果的返回方式」,并不负责「不污染页面表单状态」——
|
|
251
|
+
* 若需对一份独立的「配置 + 值」做完全不影响页面上已渲染表单的校验,请使用 `validateForm`
|
|
252
|
+
* (内部会新建一个隐藏的 MForm 实例,通过 `initValues` 传入待校验值,用完即卸载)。
|
|
253
|
+
*
|
|
254
|
+
* 典型用途:作为 `validateForm` 内部复用的校验实现;也可在已渲染的表单实例上主动调用,
|
|
255
|
+
* 根据返回的错误文案自行决定后续处理(如记录节点错误状态)。
|
|
256
|
+
*
|
|
257
|
+
* @returns 校验通过返回空字符串 `''`,否则返回以 `<br>` 拼接的错误文案。
|
|
258
|
+
*/
|
|
259
|
+
validate: async () => {
|
|
260
|
+
try {
|
|
261
|
+
const result = await tMagicFormRef.value?.validate();
|
|
262
|
+
if (result !== true) throw result;
|
|
263
|
+
return "";
|
|
264
|
+
} catch (invalidFields) {
|
|
265
|
+
return formatValidateError$1(invalidFields);
|
|
287
266
|
}
|
|
288
267
|
},
|
|
289
|
-
getTextByName
|
|
268
|
+
getTextByName: getTextByName$1
|
|
290
269
|
});
|
|
291
270
|
return (_ctx, _cache) => {
|
|
292
271
|
return openBlock(), createBlock(unref(TMagicForm), {
|
|
@@ -312,6 +291,7 @@ var Form_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
312
291
|
"last-values": lastValuesProcessed.value,
|
|
313
292
|
"is-compare": __props.isCompare,
|
|
314
293
|
"label-width": item.labelWidth || __props.labelWidth,
|
|
294
|
+
"label-position": item.labelPosition || __props.labelPosition,
|
|
315
295
|
"step-active": __props.stepActive,
|
|
316
296
|
size: __props.size,
|
|
317
297
|
onChange: changeHandler
|
|
@@ -326,6 +306,7 @@ var Form_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineCom
|
|
|
326
306
|
"last-values",
|
|
327
307
|
"is-compare",
|
|
328
308
|
"label-width",
|
|
309
|
+
"label-position",
|
|
329
310
|
"step-active",
|
|
330
311
|
"size"
|
|
331
312
|
]);
|
|
@@ -3,7 +3,7 @@ import { computed, createElementBlock, createElementVNode, createTextVNode, crea
|
|
|
3
3
|
import { TMagicButton, TMagicScrollbar } from "@tmagic/design";
|
|
4
4
|
//#region packages/form/src/FormBox.vue?vue&type=script&setup=true&lang.ts
|
|
5
5
|
var footerHeight = 60;
|
|
6
|
-
var FormBox_vue_vue_type_script_setup_true_lang_default =
|
|
6
|
+
var FormBox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
7
7
|
name: "MFormBox",
|
|
8
8
|
__name: "FormBox",
|
|
9
9
|
props: {
|
|
@@ -13,13 +13,22 @@ var FormBox_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
13
13
|
width: {},
|
|
14
14
|
height: {},
|
|
15
15
|
labelWidth: {},
|
|
16
|
+
typeMatchValid: { type: Boolean },
|
|
17
|
+
validateOnInit: {
|
|
18
|
+
type: Boolean,
|
|
19
|
+
default: false
|
|
20
|
+
},
|
|
16
21
|
disabled: { type: Boolean },
|
|
17
22
|
size: {},
|
|
18
23
|
confirmText: { default: "确定" },
|
|
19
24
|
inline: { type: Boolean },
|
|
20
25
|
labelPosition: {},
|
|
21
26
|
preventSubmitDefault: { type: Boolean },
|
|
22
|
-
|
|
27
|
+
useFieldTextInError: {
|
|
28
|
+
type: Boolean,
|
|
29
|
+
default: true
|
|
30
|
+
},
|
|
31
|
+
context: {}
|
|
23
32
|
},
|
|
24
33
|
emits: [
|
|
25
34
|
"change",
|
|
@@ -45,7 +54,8 @@ var FormBox_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
45
54
|
const submitHandler = async () => {
|
|
46
55
|
try {
|
|
47
56
|
const changeRecords = form.value?.changeRecords;
|
|
48
|
-
|
|
57
|
+
const values = await form.value?.submitForm();
|
|
58
|
+
emit("submit", values, { changeRecords });
|
|
49
59
|
} catch (e) {
|
|
50
60
|
emit("error", e);
|
|
51
61
|
}
|
|
@@ -81,7 +91,10 @@ var FormBox_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
81
91
|
"label-position": __props.labelPosition,
|
|
82
92
|
inline: __props.inline,
|
|
83
93
|
"prevent-submit-default": __props.preventSubmitDefault,
|
|
84
|
-
"
|
|
94
|
+
"use-field-text-in-error": __props.useFieldTextInError,
|
|
95
|
+
context: __props.context,
|
|
96
|
+
"type-match-valid": __props.typeMatchValid,
|
|
97
|
+
"validate-on-init": __props.validateOnInit,
|
|
85
98
|
onChange: changeHandler
|
|
86
99
|
}, null, 8, [
|
|
87
100
|
"size",
|
|
@@ -93,7 +106,10 @@ var FormBox_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ define
|
|
|
93
106
|
"label-position",
|
|
94
107
|
"inline",
|
|
95
108
|
"prevent-submit-default",
|
|
96
|
-
"
|
|
109
|
+
"use-field-text-in-error",
|
|
110
|
+
"context",
|
|
111
|
+
"type-match-valid",
|
|
112
|
+
"validate-on-init"
|
|
97
113
|
]), renderSlot(_ctx.$slots, "default")]),
|
|
98
114
|
_: 3
|
|
99
115
|
})], 4), createElementVNode("div", {
|
|
@@ -3,7 +3,7 @@ import { computed, createBlock, createCommentVNode, createElementBlock, createEl
|
|
|
3
3
|
import { M_THEME_KEY, TMagicButton, TMagicCol, TMagicDialog, TMagicRow } from "@tmagic/design";
|
|
4
4
|
//#region packages/form/src/FormDialog.vue?vue&type=script&setup=true&lang.ts
|
|
5
5
|
var _hoisted_1 = { style: { "min-height": "1px" } };
|
|
6
|
-
var FormDialog_vue_vue_type_script_setup_true_lang_default =
|
|
6
|
+
var FormDialog_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
7
7
|
name: "MFormDialog",
|
|
8
8
|
__name: "FormDialog",
|
|
9
9
|
props: {
|
|
@@ -12,6 +12,11 @@ var FormDialog_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
12
12
|
parentValues: {},
|
|
13
13
|
width: {},
|
|
14
14
|
labelWidth: {},
|
|
15
|
+
typeMatchValid: { type: Boolean },
|
|
16
|
+
validateOnInit: {
|
|
17
|
+
type: Boolean,
|
|
18
|
+
default: false
|
|
19
|
+
},
|
|
15
20
|
fullscreen: { type: Boolean },
|
|
16
21
|
disabled: { type: Boolean },
|
|
17
22
|
title: {},
|
|
@@ -41,7 +46,11 @@ var FormDialog_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
41
46
|
type: Boolean,
|
|
42
47
|
default: true
|
|
43
48
|
},
|
|
44
|
-
|
|
49
|
+
useFieldTextInError: {
|
|
50
|
+
type: Boolean,
|
|
51
|
+
default: true
|
|
52
|
+
},
|
|
53
|
+
context: {},
|
|
45
54
|
theme: {}
|
|
46
55
|
},
|
|
47
56
|
emits: [
|
|
@@ -78,7 +87,8 @@ var FormDialog_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
78
87
|
const save = async () => {
|
|
79
88
|
try {
|
|
80
89
|
const changeRecords = [...form.value?.changeRecords || []];
|
|
81
|
-
|
|
90
|
+
const values = await form.value?.submitForm();
|
|
91
|
+
emit("submit", values, { changeRecords });
|
|
82
92
|
} catch (e) {
|
|
83
93
|
emit("error", e);
|
|
84
94
|
}
|
|
@@ -195,7 +205,10 @@ var FormDialog_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
195
205
|
"label-position": __props.labelPosition,
|
|
196
206
|
inline: __props.inline,
|
|
197
207
|
"prevent-submit-default": __props.preventSubmitDefault,
|
|
198
|
-
"
|
|
208
|
+
"use-field-text-in-error": __props.useFieldTextInError,
|
|
209
|
+
"type-match-valid": __props.typeMatchValid,
|
|
210
|
+
"validate-on-init": __props.validateOnInit,
|
|
211
|
+
context: __props.context,
|
|
199
212
|
theme: effectiveTheme.value,
|
|
200
213
|
onChange: changeHandler
|
|
201
214
|
}, null, 8, [
|
|
@@ -209,7 +222,10 @@ var FormDialog_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
209
222
|
"label-position",
|
|
210
223
|
"inline",
|
|
211
224
|
"prevent-submit-default",
|
|
212
|
-
"
|
|
225
|
+
"use-field-text-in-error",
|
|
226
|
+
"type-match-valid",
|
|
227
|
+
"validate-on-init",
|
|
228
|
+
"context",
|
|
213
229
|
"theme"
|
|
214
230
|
]), renderSlot(_ctx.$slots, "default")], 4)) : createCommentVNode("v-if", true)]),
|
|
215
231
|
_: 3
|
|
@@ -3,8 +3,8 @@ import { computed, createBlock, createCommentVNode, createElementBlock, createEl
|
|
|
3
3
|
import { M_THEME_KEY, TMagicButton, TMagicCol, TMagicDrawer, TMagicRow } from "@tmagic/design";
|
|
4
4
|
//#region packages/form/src/FormDrawer.vue?vue&type=script&setup=true&lang.ts
|
|
5
5
|
var _hoisted_1 = { style: { "min-height": "1px" } };
|
|
6
|
-
var FormDrawer_vue_vue_type_script_setup_true_lang_default =
|
|
7
|
-
name: "
|
|
6
|
+
var FormDrawer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
7
|
+
name: "MFormDrawer",
|
|
8
8
|
__name: "FormDrawer",
|
|
9
9
|
props: {
|
|
10
10
|
config: { default: () => [] },
|
|
@@ -12,6 +12,11 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
12
12
|
parentValues: {},
|
|
13
13
|
width: {},
|
|
14
14
|
labelWidth: {},
|
|
15
|
+
typeMatchValid: { type: Boolean },
|
|
16
|
+
validateOnInit: {
|
|
17
|
+
type: Boolean,
|
|
18
|
+
default: false
|
|
19
|
+
},
|
|
15
20
|
disabled: { type: Boolean },
|
|
16
21
|
closeOnPressEscape: {
|
|
17
22
|
type: Boolean,
|
|
@@ -24,8 +29,12 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
24
29
|
inline: { type: Boolean },
|
|
25
30
|
labelPosition: {},
|
|
26
31
|
preventSubmitDefault: { type: Boolean },
|
|
32
|
+
useFieldTextInError: {
|
|
33
|
+
type: Boolean,
|
|
34
|
+
default: true
|
|
35
|
+
},
|
|
27
36
|
beforeClose: {},
|
|
28
|
-
|
|
37
|
+
context: {},
|
|
29
38
|
theme: {}
|
|
30
39
|
},
|
|
31
40
|
emits: [
|
|
@@ -46,7 +55,7 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
46
55
|
const drawer = ref();
|
|
47
56
|
const form = ref();
|
|
48
57
|
const drawerBody = ref();
|
|
49
|
-
const
|
|
58
|
+
const dialogVisible = ref(false);
|
|
50
59
|
const saveFetch = ref(false);
|
|
51
60
|
const bodyHeight = ref(0);
|
|
52
61
|
watchEffect(() => {
|
|
@@ -55,7 +64,8 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
55
64
|
const submitHandler = async () => {
|
|
56
65
|
try {
|
|
57
66
|
const changeRecords = form.value?.changeRecords;
|
|
58
|
-
|
|
67
|
+
const values = await form.value?.submitForm();
|
|
68
|
+
emit("submit", values, { changeRecords });
|
|
59
69
|
} catch (e) {
|
|
60
70
|
emit("error", e);
|
|
61
71
|
}
|
|
@@ -76,21 +86,39 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
76
86
|
emit("closed");
|
|
77
87
|
};
|
|
78
88
|
const show = () => {
|
|
79
|
-
|
|
89
|
+
dialogVisible.value = true;
|
|
80
90
|
};
|
|
81
91
|
const hide = () => {
|
|
82
|
-
|
|
92
|
+
dialogVisible.value = false;
|
|
93
|
+
};
|
|
94
|
+
const close = () => {
|
|
95
|
+
dialogVisible.value = false;
|
|
96
|
+
};
|
|
97
|
+
const cancel = () => {
|
|
98
|
+
hide();
|
|
83
99
|
};
|
|
84
100
|
/** 用于关闭 Drawer, 该方法会调用传入的 before-close 方法 */
|
|
85
101
|
const handleClose = () => {
|
|
86
102
|
drawer.value?.handleClose();
|
|
87
103
|
};
|
|
104
|
+
const save = async () => {
|
|
105
|
+
try {
|
|
106
|
+
const changeRecords = [...form.value?.changeRecords || []];
|
|
107
|
+
const values = await form.value?.submitForm();
|
|
108
|
+
emit("submit", values, { changeRecords });
|
|
109
|
+
} catch (e) {
|
|
110
|
+
emit("error", e);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
88
113
|
__expose({
|
|
89
114
|
form,
|
|
90
115
|
saveFetch,
|
|
91
116
|
bodyHeight,
|
|
117
|
+
close,
|
|
92
118
|
show,
|
|
93
119
|
hide,
|
|
120
|
+
save,
|
|
121
|
+
cancel,
|
|
94
122
|
handleClose
|
|
95
123
|
});
|
|
96
124
|
return (_ctx, _cache) => {
|
|
@@ -98,8 +126,8 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
98
126
|
class: normalizeClass(["m-form-drawer", effectiveTheme.value ? `m-theme--${effectiveTheme.value}` : ""]),
|
|
99
127
|
ref_key: "drawer",
|
|
100
128
|
ref: drawer,
|
|
101
|
-
modelValue:
|
|
102
|
-
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) =>
|
|
129
|
+
modelValue: dialogVisible.value,
|
|
130
|
+
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => dialogVisible.value = $event),
|
|
103
131
|
title: __props.title,
|
|
104
132
|
"close-on-press-escape": __props.closeOnPressEscape,
|
|
105
133
|
"append-to-body": true,
|
|
@@ -137,7 +165,7 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
137
165
|
})]),
|
|
138
166
|
_: 3
|
|
139
167
|
})]),
|
|
140
|
-
default: withCtx(() => [
|
|
168
|
+
default: withCtx(() => [dialogVisible.value ? (openBlock(), createElementBlock("div", {
|
|
141
169
|
key: 0,
|
|
142
170
|
ref_key: "drawerBody",
|
|
143
171
|
ref: drawerBody,
|
|
@@ -154,7 +182,10 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
154
182
|
"label-position": __props.labelPosition,
|
|
155
183
|
inline: __props.inline,
|
|
156
184
|
"prevent-submit-default": __props.preventSubmitDefault,
|
|
157
|
-
"
|
|
185
|
+
"use-field-text-in-error": __props.useFieldTextInError,
|
|
186
|
+
"type-match-valid": __props.typeMatchValid,
|
|
187
|
+
"validate-on-init": __props.validateOnInit,
|
|
188
|
+
context: __props.context,
|
|
158
189
|
theme: effectiveTheme.value,
|
|
159
190
|
onChange: changeHandler
|
|
160
191
|
}, null, 8, [
|
|
@@ -167,7 +198,10 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ def
|
|
|
167
198
|
"label-position",
|
|
168
199
|
"inline",
|
|
169
200
|
"prevent-submit-default",
|
|
170
|
-
"
|
|
201
|
+
"use-field-text-in-error",
|
|
202
|
+
"type-match-valid",
|
|
203
|
+
"validate-on-init",
|
|
204
|
+
"context",
|
|
171
205
|
"theme"
|
|
172
206
|
]), renderSlot(_ctx.$slots, "default")], 512)) : createCommentVNode("v-if", true)]),
|
|
173
207
|
_: 3
|
|
@@ -3,7 +3,7 @@ import Container_default from "./Container.js";
|
|
|
3
3
|
import { computed, createBlock, createVNode, defineComponent, inject, openBlock, unref, vShow, withCtx, withDirectives } from "vue";
|
|
4
4
|
import { TMagicCol } from "@tmagic/design";
|
|
5
5
|
//#region packages/form/src/containers/Col.vue?vue&type=script&setup=true&lang.ts
|
|
6
|
-
var Col_vue_vue_type_script_setup_true_lang_default =
|
|
6
|
+
var Col_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
7
7
|
name: "MFormCol",
|
|
8
8
|
__name: "Col",
|
|
9
9
|
props: {
|
|
@@ -12,6 +12,7 @@ var Col_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComp
|
|
|
12
12
|
isCompare: { type: Boolean },
|
|
13
13
|
config: {},
|
|
14
14
|
labelWidth: {},
|
|
15
|
+
labelPosition: {},
|
|
15
16
|
expandMore: { type: Boolean },
|
|
16
17
|
span: {},
|
|
17
18
|
size: {},
|
|
@@ -36,11 +37,13 @@ var Col_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComp
|
|
|
36
37
|
config: __props.config,
|
|
37
38
|
prop: __props.prop,
|
|
38
39
|
"label-width": __props.config.labelWidth || __props.labelWidth,
|
|
40
|
+
"label-position": __props.config.labelPosition || __props.labelPosition,
|
|
39
41
|
"expand-more": __props.expandMore,
|
|
40
42
|
size: __props.size,
|
|
41
43
|
disabled: __props.disabled,
|
|
42
44
|
onChange: changeHandler,
|
|
43
|
-
onAddDiffCount
|
|
45
|
+
onAddDiffCount,
|
|
46
|
+
"is-in-row": true
|
|
44
47
|
}, null, 8, [
|
|
45
48
|
"model",
|
|
46
49
|
"lastValues",
|
|
@@ -48,6 +51,7 @@ var Col_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ defineComp
|
|
|
48
51
|
"config",
|
|
49
52
|
"prop",
|
|
50
53
|
"label-width",
|
|
54
|
+
"label-position",
|
|
51
55
|
"expand-more",
|
|
52
56
|
"size",
|
|
53
57
|
"disabled"
|