@tmagic/form 1.8.0-beta.24 → 1.8.0-beta.26

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.
Files changed (131) hide show
  1. package/dist/es/Form.vue_vue_type_script_setup_true_lang.js +47 -120
  2. package/dist/es/FormBox.vue_vue_type_script_setup_true_lang.js +3 -3
  3. package/dist/es/FormDialog.vue_vue_type_script_setup_true_lang.js +3 -3
  4. package/dist/es/FormDrawer.vue_vue_type_script_setup_true_lang.js +3 -3
  5. package/dist/es/containers/Col.vue_vue_type_script_setup_true_lang.js +3 -0
  6. package/dist/es/containers/Container.vue_vue_type_script_setup_true_lang.js +36 -51
  7. package/dist/es/containers/Fieldset.vue_vue_type_script_setup_true_lang.js +6 -0
  8. package/dist/es/containers/FlexLayout.vue_vue_type_script_setup_true_lang.js +4 -1
  9. package/dist/es/containers/GroupList.vue_vue_type_script_setup_true_lang.js +37 -15
  10. package/dist/es/containers/GroupListItem.vue_vue_type_script_setup_true_lang.js +109 -97
  11. package/dist/es/containers/Panel.vue_vue_type_script_setup_true_lang.js +7 -2
  12. package/dist/es/containers/Row.vue_vue_type_script_setup_true_lang.js +3 -0
  13. package/dist/es/containers/Step.vue_vue_type_script_setup_true_lang.js +4 -1
  14. package/dist/es/containers/Tabs.vue_vue_type_script_setup_true_lang.js +7 -0
  15. package/dist/es/containers/table/Table.vue_vue_type_script_setup_true_lang.js +7 -5
  16. package/dist/es/containers/table/useTableColumns.js +5 -13
  17. package/dist/es/containers/table-group-list/TableGroupList.vue_vue_type_script_setup_true_lang.js +71 -78
  18. package/dist/es/containers/table-group-list/useAdd.js +26 -16
  19. package/dist/es/containers/table-group-list/useScrollLastItemIntoView.js +72 -0
  20. package/dist/es/fields/Cascader.vue_vue_type_script_setup_true_lang.js +1 -1
  21. package/dist/es/fields/CheckboxGroup/Index.js +5 -0
  22. 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
  23. package/dist/es/fields/CheckboxGroup/effect.js +8 -0
  24. package/dist/es/fields/Date/Index.js +5 -0
  25. 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
  26. package/dist/es/fields/Date/effect.js +10 -0
  27. package/dist/es/fields/DateTime/Index.js +5 -0
  28. 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
  29. package/dist/es/fields/DateTime/effect.js +15 -0
  30. package/dist/es/fields/Display/Index.js +5 -0
  31. 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
  32. package/dist/es/fields/Display/effect.js +8 -0
  33. package/dist/es/fields/DynamicField/Index.js +5 -0
  34. 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
  35. package/dist/es/fields/DynamicField/effect.js +40 -0
  36. package/dist/es/fields/Link.vue_vue_type_script_setup_true_lang.js +1 -1
  37. package/dist/es/fields/Number.vue_vue_type_script_setup_true_lang.js +1 -1
  38. package/dist/es/fields/NumberRange/Index.js +5 -0
  39. 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
  40. package/dist/es/fields/NumberRange/effect.js +8 -0
  41. package/dist/es/fields/Select.vue_vue_type_script_setup_true_lang.js +2 -2
  42. package/dist/es/fields/Text.vue_vue_type_script_setup_true_lang.js +1 -1
  43. package/dist/es/headless.js +13 -0
  44. package/dist/es/index.js +17 -12
  45. package/dist/es/plugin.js +57 -41
  46. package/dist/es/schema.js +6 -8
  47. package/dist/es/style.css +85 -1
  48. package/dist/es/submitForm.js +44 -194
  49. package/dist/es/utils/builtInFields.js +49 -0
  50. package/dist/es/utils/collectFields.js +407 -0
  51. package/dist/es/utils/config.js +1 -8
  52. package/dist/es/utils/fieldInnerConfig.js +42 -0
  53. package/dist/es/utils/fieldValueEffects.js +80 -0
  54. package/dist/es/utils/form.js +96 -43
  55. package/dist/es/utils/formStateProxy.js +75 -0
  56. package/dist/es/utils/registerField.js +158 -0
  57. package/dist/es/utils/submitHeadless.js +54 -0
  58. package/dist/es/utils/tableGroupList.js +85 -0
  59. package/dist/es/utils/typeMatch.js +17 -19
  60. package/dist/es/utils/validateError.js +57 -0
  61. package/dist/es/utils/validateValues.js +115 -0
  62. package/dist/style.css +85 -1
  63. package/dist/themes/magic-admin.css +87 -7
  64. package/dist/tmagic-form-headless.umd.cjs +4044 -0
  65. package/dist/tmagic-form.umd.cjs +1975 -874
  66. package/package.json +10 -4
  67. package/src/Form.vue +49 -149
  68. package/src/FormBox.vue +5 -4
  69. package/src/FormDialog.vue +5 -5
  70. package/src/FormDrawer.vue +5 -5
  71. package/src/containers/Col.vue +2 -0
  72. package/src/containers/Container.vue +86 -157
  73. package/src/containers/Fieldset.vue +5 -0
  74. package/src/containers/FlexLayout.vue +2 -0
  75. package/src/containers/GroupList.vue +41 -11
  76. package/src/containers/GroupListItem.vue +83 -80
  77. package/src/containers/Panel.vue +3 -0
  78. package/src/containers/Row.vue +2 -0
  79. package/src/containers/Step.vue +2 -0
  80. package/src/containers/Tabs.vue +13 -0
  81. package/src/containers/table/ActionsColumn.vue +1 -1
  82. package/src/containers/table/Table.vue +4 -3
  83. package/src/containers/table/usePagination.ts +1 -1
  84. package/src/containers/table/useSortable.ts +1 -1
  85. package/src/containers/table/useTableColumns.ts +9 -19
  86. package/src/containers/table-group-list/TableGroupList.vue +43 -71
  87. package/src/containers/table-group-list/useAdd.ts +40 -25
  88. package/src/containers/table-group-list/useScrollLastItemIntoView.ts +94 -0
  89. package/src/fields/{CheckboxGroup.vue → CheckboxGroup/Index.vue} +3 -8
  90. package/src/fields/CheckboxGroup/effect.ts +27 -0
  91. package/src/fields/{Date.vue → Date/Index.vue} +2 -5
  92. package/src/fields/Date/effect.ts +29 -0
  93. package/src/fields/{DateTime.vue → DateTime/Index.vue} +2 -16
  94. package/src/fields/DateTime/effect.ts +36 -0
  95. package/src/fields/{Display.vue → Display/Index.vue} +3 -7
  96. package/src/fields/Display/effect.ts +28 -0
  97. package/src/fields/{DynamicField.vue → DynamicField/Index.vue} +11 -11
  98. package/src/fields/DynamicField/effect.ts +74 -0
  99. package/src/fields/{NumberRange.vue → NumberRange/Index.vue} +2 -6
  100. package/src/fields/NumberRange/effect.ts +27 -0
  101. package/src/headless.ts +78 -0
  102. package/src/index.ts +32 -15
  103. package/src/plugin.ts +63 -42
  104. package/src/schema.ts +6 -8
  105. package/src/submitForm.ts +81 -409
  106. package/src/theme/form-box.scss +5 -0
  107. package/src/theme/group-list.scss +107 -1
  108. package/src/theme/themes/magic-admin/index.scss +2 -8
  109. package/src/utils/builtInFields.ts +69 -0
  110. package/src/utils/collectFields.ts +561 -0
  111. package/src/utils/config.ts +1 -15
  112. package/src/utils/fieldInnerConfig.ts +127 -0
  113. package/src/utils/fieldValueEffects.ts +140 -0
  114. package/src/utils/form.ts +141 -75
  115. package/src/utils/formStateProxy.ts +104 -0
  116. package/src/utils/registerField.ts +308 -0
  117. package/src/utils/submitHeadless.ts +206 -0
  118. package/src/utils/tableGroupList.ts +120 -0
  119. package/src/utils/typeMatch.ts +19 -15
  120. package/src/utils/validateError.ts +92 -0
  121. package/src/utils/validateValues.ts +177 -0
  122. package/types/headless.d.ts +682 -0
  123. package/types/index.d.ts +631 -272
  124. package/dist/es/fields/CheckboxGroup.js +0 -5
  125. package/dist/es/fields/Date.js +0 -5
  126. package/dist/es/fields/DateTime.js +0 -5
  127. package/dist/es/fields/Display.js +0 -5
  128. package/dist/es/fields/DynamicField.js +0 -5
  129. package/dist/es/fields/NumberRange.js +0 -5
  130. package/dist/es/utils/silentLeafFieldTypes.js +0 -49
  131. package/src/utils/silentLeafFieldTypes.ts +0 -71
@@ -1,11 +1,13 @@
1
- import { FORM_DIFF_CONFIG_KEY, FORM_TYPE_MATCH_VALID_KEY } from "./schema.js";
2
- import { applyExtendState, initValue } from "./utils/form.js";
3
- import { getConfig } from "./utils/config.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, nextTick, normalizeClass, normalizeStyle, openBlock, provide, reactive, ref, renderList, renderSlot, shallowRef, toRaw, unref, useTemplateRef, watch, watchEffect, withCtx } from "vue";
6
- import { cloneDeep, isEqual } from "lodash-es";
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
12
  var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
11
13
  name: "MForm",
@@ -44,7 +46,7 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
44
46
  type: Boolean,
45
47
  default: true
46
48
  },
47
- extendState: {},
49
+ context: {},
48
50
  showDiff: {},
49
51
  selfDiffFieldTypes: {},
50
52
  theme: {}
@@ -64,8 +66,6 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
64
66
  const initialized = ref(false);
65
67
  const values = ref({});
66
68
  const lastValuesProcessed = ref({});
67
- const fields = /* @__PURE__ */ new Map();
68
- const requestFuc = getConfig("request");
69
69
  /**
70
70
  * 当前表单生效的主题名称:
71
71
  * - 优先用本组件自己的 `props.theme`;
@@ -95,18 +95,14 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
95
95
  * 2. `values` / `lastValuesProcessed` 是 ref,Vue 的 `reactive` 会自动解包,因此每次
96
96
  * 访问 `formState.values` / `formState.lastValuesProcessed` 也都是当前 ref 值。
97
97
  *
98
- * 3. `extendState` 注入的字段在下方的 `watchEffect` 中合并到 `formState`:
99
- * - data 描述符(普通字段)通过 `formState[key] = value` 写入,走 reactive proxy 的
100
- * set,触发依赖通知;`extendState` 同步段读到的响应式数据变化时会自动重跑,
101
- * 把最新值刷进 formState。
102
- * - accessor 描述符(`{ get stage() { return ... } }`)按原样写入,调用方可以控制
103
- * 读时求值,每次读取都会重新执行 getter。
98
+ * 3. 宿主业务上下文不再 merge 进 coreState,而是单独放在 `contextRef` 上,由读穿
99
+ * Proxy 在 miss 时落到 context。核心字段结构性优先,`mForm.xxx` 永久兼容旧读法。
104
100
  *
105
101
  * 4. `popperClass` 会自动拼接 `themeClass`:调用方传入的 `popperClass` + 当前主题
106
102
  * 修饰类(含祖先 `<MEditor>` provide 的主题)。这样所有透传到 Element Plus 弹层
107
103
  * `popper-class` 的字段(Select / DateTime / Cascader 等)能自带主题作用域。
108
104
  */
109
- const formState = reactive({
105
+ const coreState = reactive({
110
106
  get keyProp() {
111
107
  return props.keyProp;
112
108
  },
@@ -135,68 +131,20 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
135
131
  values,
136
132
  lastValuesProcessed,
137
133
  $emit: emit,
138
- fields,
139
- setField: (prop, field) => fields.set(prop, field),
140
- getField: (prop) => fields.get(prop),
141
- deleteField: (prop) => fields.delete(prop),
142
- $messageBox: tMagicMessageBox,
143
- $message: tMagicMessage,
144
- post: (options) => {
145
- if (requestFuc) return requestFuc({
146
- method: "POST",
147
- ...options
148
- });
149
- }
134
+ ...createFormStateBase({
135
+ $message: tMagicMessage,
136
+ $messageBox: tMagicMessageBox
137
+ })
150
138
  });
139
+ const ancestorContext = inject(FORM_CONTEXT_KEY, void 0);
151
140
  /**
152
- * formState 的内置 key 快照(keyProp / values / $emit / fields / post 等)。
153
- *
154
- * 在 `extendState` 首次合并前捕获,`applyExtendState` 会据此禁止 `extendState`
155
- * 覆盖这些已有字段(只能新增字段),避免表单核心状态被外部意外改写。
156
- *
157
- * 之所以在此处(effect 之外)捕获而不是在 `applyExtendState` 内动态取:
158
- * `watchEffect` 会在依赖变化时重跑,若动态取,`extendState` 自己新增的字段在第二次
159
- * 合并时也会被当成「已有 key」而拒绝刷新;这里只锁定内置字段即可规避该问题。
141
+ * 宿主业务上下文:`props.context` 覆盖祖先注入的同名字段。
142
+ * 嵌套表单(Link / FormBox / FormDialog)通过下面的 provide 自动继承。
160
143
  */
161
- const reservedStateKeys = new Set(Reflect.ownKeys(formState));
162
- /**
163
- * `extendState` 的同步段(直到第一个 `await` 之前)所访问的任何响应式数据,
164
- * 都会被 `watchEffect` 自动跟踪。这样可以兼容历史用法 ——
165
- *
166
- * extendState: (formState) => ({
167
- * username: store.username, // 同步读 store,会被跟踪
168
- * env: store.env,
169
- * })
170
- *
171
- * 当 `store.username` 变化时,整个 effect 重跑,新值会被刷进 `formState`。
172
- *
173
- * prop 派生字段(initValues / config / ...)已经在上方用 getter 定义,
174
- * 这里不再重复同步;因此 `props.initValues` 这类高频变化也不会再触发
175
- * `extendState` 重跑(旧版的性能问题修复点)。
176
- *
177
- * 实现细节:合并逻辑统一收口在 `applyExtendState`(utils/form)——
178
- * data 描述符走 reactive proxy 的 set 触发依赖通知(与旧版「逐项赋值」语义等价),
179
- * accessor 描述符按原样 defineProperty 支持读时求值;
180
- * props 派生的只读 getter 字段(keyProp 等)以普通字段形式返回时会被跳过并告警。
181
- */
182
- watchEffect(async (onCleanup) => {
183
- const { extendState } = props;
184
- if (typeof extendState !== "function") return;
185
- let stale = false;
186
- onCleanup(() => {
187
- stale = true;
188
- });
189
- let state = {};
190
- try {
191
- state = await extendState(formState) || {};
192
- } catch (e) {
193
- console.error("[MForm] extendState failed:", e);
194
- return;
195
- }
196
- if (stale) return;
197
- applyExtendState(formState, state, reservedStateKeys);
198
- });
144
+ const contextRef = computed(() => mergeFormContexts(ancestorContext?.value, props.context));
145
+ const formState = createFormStateProxy(coreState, () => contextRef.value);
199
146
  provide("mForm", formState);
147
+ provide(FORM_CONTEXT_KEY, contextRef);
200
148
  /**
201
149
  * 把生效主题(自身或祖先)再 provide 出去,供 form 子树内含 `Teleport` 的组件
202
150
  * (如 `TMagicPopover`)在传送目标上挂 `m-theme--<theme>` 类。
@@ -213,14 +161,24 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
213
161
  }
214
162
  });
215
163
  const changeRecords = shallowRef([]);
216
- watch([() => props.config, () => props.initValues], ([config], [preConfig]) => {
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]) => {
217
174
  changeRecords.value = [];
218
- if (!isEqual(toRaw(config), toRaw(preConfig))) initialized.value = false;
175
+ if (!isSameConfigShape(toRaw(config), toRaw(preConfig))) initialized.value = false;
219
176
  initValue(formState, {
220
177
  initValues: props.initValues,
221
178
  config: props.config
222
179
  }).then((value) => {
223
180
  values.value = value;
181
+ applyMountValueEffects(formState, props.config, values.value);
224
182
  initialized.value = !props.isCompare;
225
183
  if (props.validateOnInit) nextTick(() => {
226
184
  tMagicFormRef.value?.validate();
@@ -231,6 +189,7 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
231
189
  config: props.config
232
190
  }).then((value) => {
233
191
  lastValuesProcessed.value = value;
192
+ applyMountValueEffects(formState, props.config, lastValuesProcessed.value);
234
193
  initialized.value = true;
235
194
  });
236
195
  }, { immediate: true });
@@ -248,51 +207,17 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
248
207
  const submitHandler = (e) => {
249
208
  if (props.preventSubmitDefault) e.preventDefault();
250
209
  };
251
- /**
252
- * 通过 name 从 config 中查找对应的 text
253
- * @param name - 字段名,支持点分隔的路径格式,如 'a.b.c'
254
- * @param config - 表单配置数组
255
- * @returns 找到的 text 值,如果未找到则返回 undefined
256
- */
257
- const getTextByName = (name, config = props.config) => {
258
- if (!name || !Array.isArray(config)) return void 0;
259
- const nameParts = name.split(".");
260
- const findInConfig = (configs, parts) => {
261
- if (parts.length === 0) return void 0;
262
- const [currentPart, ...remainingParts] = parts;
263
- for (const item of configs) {
264
- if (item.name === currentPart) {
265
- if (remainingParts.length === 0) return typeof item.text === "string" ? item.text : void 0;
266
- if ("items" in item && Array.isArray(item.items)) {
267
- const result = findInConfig(item.items, remainingParts);
268
- if (result !== void 0) return result;
269
- }
270
- }
271
- if ("items" in item && Array.isArray(item.items)) {
272
- const result = findInConfig(item.items, parts);
273
- if (result !== void 0) return result;
274
- }
275
- }
276
- };
277
- return findInConfig(config, nameParts);
278
- };
210
+ const getTextByName$1 = (name, config = props.config) => getTextByName(name, config);
279
211
  /**
280
212
  * 将校验返回的 invalidFields 汇总为可读的错误文案(多条以 `<br>` 拼接)。
281
213
  *
282
- * 抽离为独立方法,供 `submitForm`(提交校验)与 `validate`(返回错误文案的校验)复用,
283
- * 保证两种校验入口产出的错误文案格式完全一致。
214
+ * 实现收口在 `utils/validateError`,供渲染式校验(本组件的 `submitForm` / `validate`)与
215
+ * 无渲染校验(`validateValues`)共用,保证两条链路产出的错误文案格式完全一致。
284
216
  */
285
- const formatValidateError = (invalidFields) => {
286
- const error = [];
287
- Object.entries(invalidFields).forEach(([prop, validateError]) => {
288
- validateError.forEach(({ field, message }) => {
289
- const name = field || prop;
290
- const text = (props.useFieldTextInError ? getTextByName(name, props.config) : void 0) || name;
291
- error.push(`${text} -> ${message}`);
292
- });
293
- });
294
- return error.join("<br>");
295
- };
217
+ const formatValidateError$1 = (invalidFields) => formatValidateError(invalidFields, {
218
+ config: props.config,
219
+ useFieldTextInError: props.useFieldTextInError
220
+ });
296
221
  __expose({
297
222
  values,
298
223
  lastValuesProcessed,
@@ -312,7 +237,7 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
312
237
  return native ? values.value : cloneDeep(toRaw(values.value));
313
238
  } catch (invalidFields) {
314
239
  emit("error", invalidFields);
315
- throw new Error(formatValidateError(invalidFields));
240
+ throw new Error(formatValidateError$1(invalidFields));
316
241
  }
317
242
  },
318
243
  /**
@@ -337,10 +262,10 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
337
262
  if (result !== true) throw result;
338
263
  return "";
339
264
  } catch (invalidFields) {
340
- return formatValidateError(invalidFields);
265
+ return formatValidateError$1(invalidFields);
341
266
  }
342
267
  },
343
- getTextByName
268
+ getTextByName: getTextByName$1
344
269
  });
345
270
  return (_ctx, _cache) => {
346
271
  return openBlock(), createBlock(unref(TMagicForm), {
@@ -366,6 +291,7 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
366
291
  "last-values": lastValuesProcessed.value,
367
292
  "is-compare": __props.isCompare,
368
293
  "label-width": item.labelWidth || __props.labelWidth,
294
+ "label-position": item.labelPosition || __props.labelPosition,
369
295
  "step-active": __props.stepActive,
370
296
  size: __props.size,
371
297
  onChange: changeHandler
@@ -380,6 +306,7 @@ var Form_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompo
380
306
  "last-values",
381
307
  "is-compare",
382
308
  "label-width",
309
+ "label-position",
383
310
  "step-active",
384
311
  "size"
385
312
  ]);
@@ -28,7 +28,7 @@ var FormBox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
28
28
  type: Boolean,
29
29
  default: true
30
30
  },
31
- extendState: {}
31
+ context: {}
32
32
  },
33
33
  emits: [
34
34
  "change",
@@ -92,7 +92,7 @@ var FormBox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
92
92
  inline: __props.inline,
93
93
  "prevent-submit-default": __props.preventSubmitDefault,
94
94
  "use-field-text-in-error": __props.useFieldTextInError,
95
- "extend-state": __props.extendState,
95
+ context: __props.context,
96
96
  "type-match-valid": __props.typeMatchValid,
97
97
  "validate-on-init": __props.validateOnInit,
98
98
  onChange: changeHandler
@@ -107,7 +107,7 @@ var FormBox_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCo
107
107
  "inline",
108
108
  "prevent-submit-default",
109
109
  "use-field-text-in-error",
110
- "extend-state",
110
+ "context",
111
111
  "type-match-valid",
112
112
  "validate-on-init"
113
113
  ]), renderSlot(_ctx.$slots, "default")]),
@@ -50,7 +50,7 @@ var FormDialog_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
50
50
  type: Boolean,
51
51
  default: true
52
52
  },
53
- extendState: {},
53
+ context: {},
54
54
  theme: {}
55
55
  },
56
56
  emits: [
@@ -208,7 +208,7 @@ var FormDialog_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
208
208
  "use-field-text-in-error": __props.useFieldTextInError,
209
209
  "type-match-valid": __props.typeMatchValid,
210
210
  "validate-on-init": __props.validateOnInit,
211
- "extend-state": __props.extendState,
211
+ context: __props.context,
212
212
  theme: effectiveTheme.value,
213
213
  onChange: changeHandler
214
214
  }, null, 8, [
@@ -225,7 +225,7 @@ var FormDialog_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
225
225
  "use-field-text-in-error",
226
226
  "type-match-valid",
227
227
  "validate-on-init",
228
- "extend-state",
228
+ "context",
229
229
  "theme"
230
230
  ]), renderSlot(_ctx.$slots, "default")], 4)) : createCommentVNode("v-if", true)]),
231
231
  _: 3
@@ -34,7 +34,7 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
34
34
  default: true
35
35
  },
36
36
  beforeClose: {},
37
- extendState: {},
37
+ context: {},
38
38
  theme: {}
39
39
  },
40
40
  emits: [
@@ -185,7 +185,7 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
185
185
  "use-field-text-in-error": __props.useFieldTextInError,
186
186
  "type-match-valid": __props.typeMatchValid,
187
187
  "validate-on-init": __props.validateOnInit,
188
- "extend-state": __props.extendState,
188
+ context: __props.context,
189
189
  theme: effectiveTheme.value,
190
190
  onChange: changeHandler
191
191
  }, null, 8, [
@@ -201,7 +201,7 @@ var FormDrawer_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defin
201
201
  "use-field-text-in-error",
202
202
  "type-match-valid",
203
203
  "validate-on-init",
204
- "extend-state",
204
+ "context",
205
205
  "theme"
206
206
  ]), renderSlot(_ctx.$slots, "default")], 512)) : createCommentVNode("v-if", true)]),
207
207
  _: 3
@@ -12,6 +12,7 @@ var Col_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompon
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,6 +37,7 @@ var Col_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompon
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,
@@ -49,6 +51,7 @@ var Col_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineCompon
49
51
  "config",
50
52
  "prop",
51
53
  "label-width",
54
+ "label-position",
52
55
  "expand-more",
53
56
  "size",
54
57
  "disabled"
@@ -1,13 +1,12 @@
1
- import { FORM_DIFF_CONFIG_KEY, FORM_SILENT_MODE_KEY, FORM_TYPE_MATCH_VALID_KEY } from "../schema.js";
2
- import { createObjectProp, display, filterFunction, getRules } from "../utils/form.js";
1
+ import { FORM_DIFF_CONFIG_KEY, FORM_TYPE_MATCH_VALID_KEY } from "../schema.js";
2
+ import { createObjectProp, display, filterFunction, getItemProp, getRules, isValidName, resolveItemType } from "../utils/form.js";
3
3
  import Hidden_default from "../fields/Hidden.js";
4
- import { getField } from "../utils/config.js";
5
- import { getSilentLeafFieldTypes } from "../utils/silentLeafFieldTypes.js";
4
+ import { getField } from "../utils/registerField.js";
6
5
  import FormLabel_default from "./FormLabel.js";
7
6
  import { Fragment, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createSlots, createTextVNode, createVNode, defineComponent, inject, mergeProps, normalizeClass, normalizeStyle, openBlock, provide, readonly, ref, renderList, renderSlot, resolveComponent, resolveDynamicComponent, toDisplayString, toRaw, unref, watch, watchEffect, withCtx } from "vue";
8
7
  import { isEqual } from "lodash-es";
9
- import { TMagicButton, TMagicFormItem, TMagicIcon, TMagicTooltip } from "@tmagic/design";
10
8
  import { getValueByKeyPath } from "@tmagic/utils";
9
+ import { TMagicButton, TMagicFormItem, TMagicIcon, TMagicTooltip } from "@tmagic/design";
11
10
  import { ArrowDown, ArrowUp, WarningFilled } from "@element-plus/icons-vue";
12
11
  //#region packages/form/src/containers/Container.vue?vue&type=script&setup=true&lang.ts
13
12
  var _hoisted_1 = ["data-tmagic-id", "data-tmagic-form-item-prop"];
@@ -36,6 +35,7 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
36
35
  prop: { default: "" },
37
36
  disabled: { type: Boolean },
38
37
  labelWidth: {},
38
+ labelPosition: {},
39
39
  expandMore: {
40
40
  type: Boolean,
41
41
  default: false
@@ -71,20 +71,8 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
71
71
  return !isEqual(curValue, lastValue);
72
72
  });
73
73
  const items = computed(() => props.config.items);
74
- const itemProp = computed(() => {
75
- let n = "";
76
- if (name.value) n = name.value;
77
- else return props.prop;
78
- if (typeof props.prop !== "undefined" && props.prop !== "") return `${props.prop}.${n}`;
79
- return `${n}`;
80
- });
81
- const type = computed(() => {
82
- let type = "type" in props.config ? props.config.type : "";
83
- type = type && filterFunction(mForm, type, props);
84
- if (type === "form") return "";
85
- if (type === "container") return "";
86
- return type?.replace(/([A-Z])/g, "-$1").toLowerCase() || (items.value ? "" : "text");
87
- });
74
+ const itemProp = computed(() => getItemProp(props.prop, name.value));
75
+ const type = computed(() => resolveItemType(mForm, props.config, props));
88
76
  const tagName = computed(() => {
89
77
  if (type.value === "component" && props.config.component) return props.config.component;
90
78
  return getField(type.value || "container") || `m-${items.value ? "form" : "fields"}-${type.value}`;
@@ -118,8 +106,6 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
118
106
  return new Set(DEFAULT_SELF_DIFF_FIELD_TYPES);
119
107
  });
120
108
  const isSelfDiffField = computed(() => effectiveSelfDiffFieldTypes.value.has(type.value));
121
- const silentMode = inject(FORM_SILENT_MODE_KEY, false);
122
- const shouldRenderLeafField = computed(() => !silentMode || !getSilentLeafFieldTypes().has(type.value));
123
109
  const disabled = computed(() => props.disabled || filterFunction(mForm, props.config.disabled, props));
124
110
  const text = computed(() => filterFunction(mForm, props.config.text, props));
125
111
  const tooltip = computed(() => {
@@ -151,12 +137,13 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
151
137
  const formItemProps = computed(() => ({
152
138
  prop: itemProp.value,
153
139
  labelWidth: itemLabelWidth.value,
154
- labelPosition: props.config.labelPosition,
140
+ labelPosition: itemLabelPosition.value,
155
141
  rules: rule.value,
156
142
  extra: filterFunction(mForm, props.config.extra, props),
157
143
  extraTips: props.config.extraTips
158
144
  }));
159
145
  const itemLabelWidth = computed(() => props.config.labelWidth ?? props.labelWidth);
146
+ const itemLabelPosition = computed(() => props.config.labelPosition ?? props.labelPosition);
160
147
  watchEffect(() => {
161
148
  expand.value = props.expandMore;
162
149
  });
@@ -185,13 +172,7 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
185
172
  };
186
173
  const onAddDiffCount = () => emit("addDiffCount");
187
174
  const hasModifyKey = (eventDataItem) => typeof eventDataItem?.modifyKey !== "undefined" && eventDataItem.modifyKey !== "";
188
- const isValidName = () => {
189
- const valueType = typeof name.value;
190
- if (valueType !== "string" && valueType !== "symbol" && valueType !== "number") return false;
191
- if (name.value === "") return false;
192
- if (typeof name.value === "number") return name.value >= 0;
193
- return true;
194
- };
175
+ const isValidName$1 = () => isValidName(name.value);
195
176
  const createModelProxy = (target, setModelFn, pathPrefix = "") => {
196
177
  return new Proxy(target, {
197
178
  get: (obj, key) => {
@@ -283,6 +264,7 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
283
264
  "step-active": __props.stepActive,
284
265
  "expand-more": expand.value,
285
266
  "label-width": itemLabelWidth.value,
267
+ "label-position": itemLabelPosition.value,
286
268
  style: __props.config.fieldStyle,
287
269
  onChange: onChangeHandler,
288
270
  onAddDiffCount
@@ -293,9 +275,10 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
293
275
  "step-active",
294
276
  "expand-more",
295
277
  "label-width",
278
+ "label-position",
296
279
  "style"
297
280
  ])) : type.value && display$1.value && !showDiff.value ? (openBlock(), createElementBlock(Fragment, { key: 2 }, [createVNode(unref(TMagicFormItem), mergeProps(formItemProps.value, { class: { "tmagic-form-hidden": `${itemLabelWidth.value}` === "0" || !text.value } }), {
298
- label: withCtx(() => [shouldRenderLeafField.value ? renderSlot(_ctx.$slots, "label", {
281
+ label: withCtx(() => [renderSlot(_ctx.$slots, "label", {
299
282
  config: __props.config,
300
283
  type: type.value,
301
284
  text: text.value,
@@ -313,8 +296,8 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
313
296
  "use-label",
314
297
  "label-title",
315
298
  "text"
316
- ]), __props.config.titleExtra && __props.config.labelPosition === "top" ? (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(__props.config.titleExtra), 1)) : createCommentVNode("v-if", true)], void 0, 0) : createCommentVNode("v-if", true)]),
317
- default: withCtx(() => [shouldRenderLeafField.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [tooltip.value.text ? (openBlock(), createBlock(unref(TMagicTooltip), {
299
+ ]), __props.config.titleExtra && itemLabelPosition.value === "top" ? (openBlock(), createElementBlock("span", _hoisted_2, toDisplayString(__props.config.titleExtra), 1)) : createCommentVNode("v-if", true)])]),
300
+ default: withCtx(() => [tooltip.value.text ? (openBlock(), createBlock(unref(TMagicTooltip), {
318
301
  key: 0,
319
302
  placement: tooltip.value.placement
320
303
  }, {
@@ -341,9 +324,9 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
341
324
  "model",
342
325
  "last-values",
343
326
  "is-compare"
344
- ]))], 64)) : createCommentVNode("v-if", true)]),
327
+ ]))]),
345
328
  _: 3
346
- }, 16, ["class"]), shouldRenderLeafField.value && __props.config.tip && type.value === "checkbox" && !__props.config.useLabel ? (openBlock(), createBlock(unref(TMagicTooltip), {
329
+ }, 16, ["class"]), __props.config.tip && type.value === "checkbox" && !__props.config.useLabel ? (openBlock(), createBlock(unref(TMagicTooltip), {
347
330
  key: 0,
348
331
  placement: "top"
349
332
  }, {
@@ -363,7 +346,7 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
363
346
  "tmagic-form-hidden": `${itemLabelWidth.value}` === "0" || !text.value,
364
347
  "self-diff": true
365
348
  } }), {
366
- label: withCtx(() => [shouldRenderLeafField.value ? renderSlot(_ctx.$slots, "label", {
349
+ label: withCtx(() => [renderSlot(_ctx.$slots, "label", {
367
350
  config: __props.config,
368
351
  type: type.value,
369
352
  text: text.value,
@@ -381,8 +364,8 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
381
364
  "use-label",
382
365
  "label-title",
383
366
  "text"
384
- ])], void 0, 0) : createCommentVNode("v-if", true)]),
385
- default: withCtx(() => [shouldRenderLeafField.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [tooltip.value.text ? (openBlock(), createBlock(unref(TMagicTooltip), {
367
+ ])])]),
368
+ default: withCtx(() => [tooltip.value.text ? (openBlock(), createBlock(unref(TMagicTooltip), {
386
369
  key: 0,
387
370
  placement: tooltip.value.placement
388
371
  }, {
@@ -407,7 +390,7 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
407
390
  "model",
408
391
  "last-values",
409
392
  "is-compare"
410
- ]))], 64)) : createCommentVNode("v-if", true)]),
393
+ ]))]),
411
394
  _: 3
412
395
  }, 16, ["class"])) : (openBlock(), createElementBlock(Fragment, { key: 1 }, [
413
396
  createCommentVNode(" 普通字段:渲染前后两份独立的组件用于对比 "),
@@ -416,7 +399,7 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
416
399
  "tmagic-form-hidden": `${itemLabelWidth.value}` === "0" || !text.value,
417
400
  "show-before-diff": true
418
401
  } }), {
419
- label: withCtx(() => [shouldRenderLeafField.value ? renderSlot(_ctx.$slots, "label", {
402
+ label: withCtx(() => [renderSlot(_ctx.$slots, "label", {
420
403
  config: __props.config,
421
404
  type: type.value,
422
405
  text: text.value,
@@ -434,8 +417,8 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
434
417
  "use-label",
435
418
  "label-title",
436
419
  "text"
437
- ])], void 0, 0) : createCommentVNode("v-if", true)]),
438
- default: withCtx(() => [shouldRenderLeafField.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [tooltip.value.text ? (openBlock(), createBlock(unref(TMagicTooltip), {
420
+ ])])]),
421
+ default: withCtx(() => [tooltip.value.text ? (openBlock(), createBlock(unref(TMagicTooltip), {
439
422
  key: 0,
440
423
  placement: tooltip.value.placement
441
424
  }, {
@@ -448,10 +431,10 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
448
431
  }, 8, ["placement"])) : (openBlock(), createBlock(resolveDynamicComponent(tagName.value), mergeProps({ key: 1 }, fieldsProps.value, {
449
432
  model: __props.lastValues,
450
433
  onChange: onChangeHandler
451
- }), null, 16, ["model"]))], 64)) : createCommentVNode("v-if", true)]),
434
+ }), null, 16, ["model"]))]),
452
435
  _: 3
453
436
  }, 16, ["class"]),
454
- shouldRenderLeafField.value && __props.config.tip && type.value === "checkbox" && !__props.config.useLabel ? (openBlock(), createBlock(unref(TMagicTooltip), {
437
+ __props.config.tip && type.value === "checkbox" && !__props.config.useLabel ? (openBlock(), createBlock(unref(TMagicTooltip), {
455
438
  key: 0,
456
439
  placement: "top"
457
440
  }, {
@@ -473,7 +456,7 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
473
456
  "show-after-diff": true
474
457
  }
475
458
  }), {
476
- label: withCtx(() => [shouldRenderLeafField.value ? renderSlot(_ctx.$slots, "label", {
459
+ label: withCtx(() => [renderSlot(_ctx.$slots, "label", {
477
460
  config: __props.config,
478
461
  type: type.value,
479
462
  text: text.value,
@@ -491,8 +474,8 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
491
474
  "use-label",
492
475
  "label-title",
493
476
  "text"
494
- ])], void 0, 0) : createCommentVNode("v-if", true)]),
495
- default: withCtx(() => [shouldRenderLeafField.value ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [tooltip.value.text ? (openBlock(), createBlock(unref(TMagicTooltip), {
477
+ ])])]),
478
+ default: withCtx(() => [tooltip.value.text ? (openBlock(), createBlock(unref(TMagicTooltip), {
496
479
  key: 0,
497
480
  placement: tooltip.value.placement
498
481
  }, {
@@ -505,10 +488,10 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
505
488
  }, 8, ["placement"])) : (openBlock(), createBlock(resolveDynamicComponent(tagName.value), mergeProps({ key: 1 }, fieldsProps.value, {
506
489
  model: __props.model,
507
490
  onChange: onChangeHandler
508
- }), null, 16, ["model"]))], 64)) : createCommentVNode("v-if", true)]),
491
+ }), null, 16, ["model"]))]),
509
492
  _: 3
510
493
  }, 16, ["style", "class"]),
511
- shouldRenderLeafField.value && __props.config.tip && type.value === "checkbox" && !__props.config.useLabel ? (openBlock(), createBlock(unref(TMagicTooltip), {
494
+ __props.config.tip && type.value === "checkbox" && !__props.config.useLabel ? (openBlock(), createBlock(unref(TMagicTooltip), {
512
495
  key: 1,
513
496
  placement: "top"
514
497
  }, {
@@ -523,11 +506,11 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
523
506
  _: 1
524
507
  })) : createCommentVNode("v-if", true)
525
508
  ], 64))
526
- ], 64)) : items.value && display$1.value ? (openBlock(), createElementBlock(Fragment, { key: 4 }, [(isValidName() ? __props.model[name.value] : __props.model) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(items.value, (item) => {
509
+ ], 64)) : items.value && display$1.value ? (openBlock(), createElementBlock(Fragment, { key: 4 }, [(isValidName$1() ? __props.model[name.value] : __props.model) ? (openBlock(true), createElementBlock(Fragment, { key: 0 }, renderList(items.value, (item) => {
527
510
  return openBlock(), createBlock(_component_Container, {
528
511
  key: key(item),
529
- model: isValidName() ? __props.model[name.value] : __props.model,
530
- "last-values": isValidName() ? __props.lastValues[name.value] || {} : __props.lastValues,
512
+ model: isValidName$1() ? __props.model[name.value] : __props.model,
513
+ "last-values": isValidName$1() ? __props.lastValues[name.value] || {} : __props.lastValues,
531
514
  "is-compare": __props.isCompare,
532
515
  config: item,
533
516
  size: __props.size,
@@ -535,6 +518,7 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
535
518
  "step-active": __props.stepActive,
536
519
  "expand-more": expand.value,
537
520
  "label-width": itemLabelWidth.value,
521
+ "label-position": itemLabelPosition.value,
538
522
  prop: itemProp.value,
539
523
  onChange: onChangeHandler,
540
524
  onAddDiffCount
@@ -552,6 +536,7 @@ var Container_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
552
536
  "step-active",
553
537
  "expand-more",
554
538
  "label-width",
539
+ "label-position",
555
540
  "prop"
556
541
  ]);
557
542
  }), 128)) : createCommentVNode("v-if", true)], 64)) : createCommentVNode("v-if", true), __props.config.expand && type.value !== "fieldset" ? (openBlock(), createElementBlock("div", _hoisted_10, [createVNode(unref(TMagicButton), {