@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.
Files changed (149) hide show
  1. package/dist/es/Form.vue_vue_type_script_setup_true_lang.js +88 -107
  2. package/dist/es/FormBox.vue_vue_type_script_setup_true_lang.js +21 -5
  3. package/dist/es/FormDialog.vue_vue_type_script_setup_true_lang.js +21 -5
  4. package/dist/es/FormDrawer.vue_vue_type_script_setup_true_lang.js +46 -12
  5. package/dist/es/containers/Col.vue_vue_type_script_setup_true_lang.js +6 -2
  6. package/dist/es/containers/Container.vue_vue_type_script_setup_true_lang.js +44 -47
  7. package/dist/es/containers/Fieldset.vue_vue_type_script_setup_true_lang.js +7 -1
  8. package/dist/es/containers/FlexLayout.vue_vue_type_script_setup_true_lang.js +5 -2
  9. package/dist/es/containers/FormLabel.vue_vue_type_script_setup_true_lang.js +1 -1
  10. package/dist/es/containers/GroupList.vue_vue_type_script_setup_true_lang.js +59 -22
  11. package/dist/es/containers/GroupListItem.vue_vue_type_script_setup_true_lang.js +118 -100
  12. package/dist/es/containers/Panel.vue_vue_type_script_setup_true_lang.js +8 -3
  13. package/dist/es/containers/Row.vue_vue_type_script_setup_true_lang.js +4 -1
  14. package/dist/es/containers/Step.vue_vue_type_script_setup_true_lang.js +5 -2
  15. package/dist/es/containers/Tabs.vue_vue_type_script_setup_true_lang.js +8 -1
  16. package/dist/es/containers/table/ActionsColumn.vue_vue_type_script_setup_true_lang.js +1 -1
  17. package/dist/es/containers/table/SortColumn.vue_vue_type_script_setup_true_lang.js +1 -1
  18. package/dist/es/containers/table/Table.vue_vue_type_script_setup_true_lang.js +14 -10
  19. package/dist/es/containers/table/useTableColumns.js +10 -15
  20. package/dist/es/containers/table-group-list/TableGroupList.vue_vue_type_script_setup_true_lang.js +72 -79
  21. package/dist/es/containers/table-group-list/useAdd.js +26 -16
  22. package/dist/es/containers/table-group-list/useScrollLastItemIntoView.js +72 -0
  23. package/dist/es/fields/Cascader.vue_vue_type_script_setup_true_lang.js +2 -2
  24. package/dist/es/fields/Checkbox.vue_vue_type_script_setup_true_lang.js +1 -1
  25. package/dist/es/fields/CheckboxGroup/Index.js +5 -0
  26. 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
  27. package/dist/es/fields/CheckboxGroup/effect.js +8 -0
  28. package/dist/es/fields/ColorPicker.vue_vue_type_script_setup_true_lang.js +1 -1
  29. package/dist/es/fields/Date/Index.js +5 -0
  30. 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
  31. package/dist/es/fields/Date/effect.js +10 -0
  32. package/dist/es/fields/DateTime/Index.js +5 -0
  33. 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
  34. package/dist/es/fields/DateTime/effect.js +15 -0
  35. package/dist/es/fields/Daterange.vue_vue_type_script_setup_true_lang.js +2 -2
  36. package/dist/es/fields/Display/Index.js +5 -0
  37. 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
  38. package/dist/es/fields/Display/effect.js +8 -0
  39. package/dist/es/fields/DynamicField/Index.js +5 -0
  40. 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
  41. package/dist/es/fields/DynamicField/effect.js +40 -0
  42. package/dist/es/fields/Hidden.vue_vue_type_script_setup_true_lang.js +1 -1
  43. package/dist/es/fields/Link.vue_vue_type_script_setup_true_lang.js +4 -4
  44. package/dist/es/fields/Number.vue_vue_type_script_setup_true_lang.js +4 -2
  45. package/dist/es/fields/NumberRange/Index.js +5 -0
  46. 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
  47. package/dist/es/fields/NumberRange/effect.js +8 -0
  48. package/dist/es/fields/RadioGroup.vue_vue_type_script_setup_true_lang.js +5 -2
  49. package/dist/es/fields/Select.vue_vue_type_script_setup_true_lang.js +14 -6
  50. package/dist/es/fields/Switch.vue_vue_type_script_setup_true_lang.js +1 -1
  51. package/dist/es/fields/Text.vue_vue_type_script_setup_true_lang.js +13 -10
  52. package/dist/es/fields/Textarea.vue_vue_type_script_setup_true_lang.js +1 -1
  53. package/dist/es/fields/Time.vue_vue_type_script_setup_true_lang.js +1 -1
  54. package/dist/es/fields/Timerange.vue_vue_type_script_setup_true_lang.js +3 -3
  55. package/dist/es/headless.js +13 -0
  56. package/dist/es/index.js +19 -12
  57. package/dist/es/plugin.js +57 -39
  58. package/dist/es/schema.js +11 -2
  59. package/dist/es/style.css +123 -3
  60. package/dist/es/submitForm.js +270 -72
  61. package/dist/es/utils/builtInFields.js +49 -0
  62. package/dist/es/utils/collectFields.js +407 -0
  63. package/dist/es/utils/config.js +4 -8
  64. package/dist/es/utils/fieldInnerConfig.js +42 -0
  65. package/dist/es/utils/fieldValueEffects.js +80 -0
  66. package/dist/es/utils/form.js +154 -19
  67. package/dist/es/utils/formStateProxy.js +111 -0
  68. package/dist/es/utils/registerField.js +158 -0
  69. package/dist/es/utils/submitHeadless.js +54 -0
  70. package/dist/es/utils/tableGroupList.js +104 -0
  71. package/dist/es/utils/typeMatch.js +532 -0
  72. package/dist/es/utils/validateError.js +57 -0
  73. package/dist/es/utils/validateValues.js +115 -0
  74. package/dist/style.css +123 -3
  75. package/dist/themes/magic-admin.css +576 -14
  76. package/dist/tmagic-form-headless.umd.cjs +4515 -0
  77. package/dist/tmagic-form.umd.cjs +3444 -983
  78. package/package.json +16 -10
  79. package/src/Form.vue +113 -129
  80. package/src/FormBox.vue +16 -4
  81. package/src/FormDialog.vue +16 -5
  82. package/src/FormDrawer.vue +41 -13
  83. package/src/containers/Col.vue +3 -0
  84. package/src/containers/Container.vue +40 -45
  85. package/src/containers/Fieldset.vue +5 -0
  86. package/src/containers/FlexLayout.vue +2 -0
  87. package/src/containers/GroupList.vue +64 -13
  88. package/src/containers/GroupListItem.vue +88 -81
  89. package/src/containers/Panel.vue +3 -0
  90. package/src/containers/Row.vue +2 -0
  91. package/src/containers/Step.vue +2 -0
  92. package/src/containers/Tabs.vue +13 -0
  93. package/src/containers/table/ActionsColumn.vue +1 -1
  94. package/src/containers/table/Table.vue +5 -3
  95. package/src/containers/table/usePagination.ts +1 -1
  96. package/src/containers/table/useSortable.ts +1 -1
  97. package/src/containers/table/useTableColumns.ts +15 -22
  98. package/src/containers/table-group-list/TableGroupList.vue +46 -72
  99. package/src/containers/table-group-list/useAdd.ts +40 -25
  100. package/src/containers/table-group-list/useScrollLastItemIntoView.ts +94 -0
  101. package/src/fields/{CheckboxGroup.vue → CheckboxGroup/Index.vue} +3 -8
  102. package/src/fields/CheckboxGroup/effect.ts +27 -0
  103. package/src/fields/{Date.vue → Date/Index.vue} +2 -5
  104. package/src/fields/Date/effect.ts +29 -0
  105. package/src/fields/{DateTime.vue → DateTime/Index.vue} +2 -16
  106. package/src/fields/DateTime/effect.ts +36 -0
  107. package/src/fields/{Display.vue → Display/Index.vue} +3 -7
  108. package/src/fields/Display/effect.ts +28 -0
  109. package/src/fields/{DynamicField.vue → DynamicField/Index.vue} +11 -11
  110. package/src/fields/DynamicField/effect.ts +74 -0
  111. package/src/fields/Link.vue +3 -4
  112. package/src/fields/Number.vue +2 -1
  113. package/src/fields/{NumberRange.vue → NumberRange/Index.vue} +2 -6
  114. package/src/fields/NumberRange/effect.ts +27 -0
  115. package/src/fields/RadioGroup.vue +13 -1
  116. package/src/fields/Select.vue +13 -4
  117. package/src/headless.ts +78 -0
  118. package/src/index.ts +46 -9
  119. package/src/plugin.ts +68 -37
  120. package/src/schema.ts +13 -2
  121. package/src/submitForm.ts +410 -131
  122. package/src/theme/fieldset.scss +1 -0
  123. package/src/theme/form-box.scss +5 -0
  124. package/src/theme/form-dialog.scss +1 -1
  125. package/src/theme/group-list.scss +143 -2
  126. package/src/theme/table.scss +11 -1
  127. package/src/theme/themes/magic-admin/index.scss +27 -16
  128. package/src/utils/builtInFields.ts +69 -0
  129. package/src/utils/collectFields.ts +561 -0
  130. package/src/utils/config.ts +7 -15
  131. package/src/utils/fieldInnerConfig.ts +127 -0
  132. package/src/utils/fieldValueEffects.ts +140 -0
  133. package/src/utils/form.ts +230 -30
  134. package/src/utils/formStateProxy.ts +149 -0
  135. package/src/utils/registerField.ts +308 -0
  136. package/src/utils/submitHeadless.ts +206 -0
  137. package/src/utils/tableGroupList.ts +147 -0
  138. package/src/utils/typeMatch.ts +948 -0
  139. package/src/utils/validateError.ts +92 -0
  140. package/src/utils/validateValues.ts +177 -0
  141. package/types/headless.d.ts +682 -0
  142. package/types/index.d.ts +900 -180
  143. package/dist/es/_virtual/_rolldown/runtime.js +0 -27
  144. package/dist/es/fields/CheckboxGroup.js +0 -5
  145. package/dist/es/fields/Date.js +0 -5
  146. package/dist/es/fields/DateTime.js +0 -5
  147. package/dist/es/fields/Display.js +0 -5
  148. package/dist/es/fields/DynamicField.js +0 -5
  149. package/dist/es/fields/NumberRange.js +0 -5
@@ -0,0 +1,115 @@
1
+ import { createFormStateProxy } from "./formStateProxy.js";
2
+ import { createFormStateBase, initValue } from "./form.js";
3
+ import { applyMountValueEffects, collectValidatableFields } from "./collectFields.js";
4
+ import { formatValidateError } from "./validateError.js";
5
+ import { reactive } from "vue";
6
+ import Schema from "async-validator";
7
+ //#region packages/form/src/utils/validateValues.ts
8
+ /**
9
+ * 构造一个不依赖组件实例的 `formState`。
10
+ *
11
+ * 字段结构与 `Form.vue` 中 provide 给子树的 `mForm` 保持一致,使配置里的
12
+ * `display` / `rules.validator` / `filter` 等回调拿到的上下文与渲染式校验相同。
13
+ *
14
+ * 差异:没有真实的表单实例,因此 `$emit` 为空实现、`fields` 注册表始终为空
15
+ * (该注册表在整个仓库中只写不读,不参与校验)。
16
+ */
17
+ var createHeadlessFormState = (options) => {
18
+ const context = options.context ?? {};
19
+ const state = {
20
+ keyProp: options.keyProp ?? "__key",
21
+ popperClass: options.popperClass ?? "",
22
+ config: options.config,
23
+ initValues: options.initValues ?? {},
24
+ isCompare: false,
25
+ lastValues: {},
26
+ parentValues: options.parentValues ?? {},
27
+ values: {},
28
+ lastValuesProcessed: {},
29
+ $emit: () => void 0,
30
+ ...createFormStateBase()
31
+ };
32
+ return createFormStateProxy(reactive(state), () => context);
33
+ };
34
+ /**
35
+ * 按 prop 路径从表单值中取字段值,路径中断时返回 `undefined`。
36
+ *
37
+ * 不复用 `@tmagic/utils` 的 `getValueByKeyPath`:后者在路径中断时抛错,
38
+ * 而 Element Plus 的 FormItem 取值是宽松的(拿不到就是 `undefined`),此处与之对齐。
39
+ */
40
+ var getFieldValue = (prop, values) => {
41
+ if (!prop) return void 0;
42
+ return prop.split(".").reduce((acc, key) => {
43
+ if (acc === null || typeof acc !== "object") return void 0;
44
+ return acc[key];
45
+ }, values);
46
+ };
47
+ /**
48
+ * 校验单个字段,返回 async-validator 的 `fields` 错误映射(通过则返回 `null`)。
49
+ *
50
+ * 与 Element Plus 的 FormItem 逐字段校验保持一致:
51
+ * 每个字段独立构造一个 `Schema({ [prop]: rules })`,以字段自身的值为 source,
52
+ * 并开启 `firstFields` 只取每个字段的首条错误;`trigger` 是 FormItem 用来筛选规则的
53
+ * 元信息,交给 async-validator 前必须剔除,否则会改变规则的匹配方式。
54
+ */
55
+ var validateField = async (field, values) => {
56
+ const rules = field.rules.map(({ trigger, ...rule }) => rule);
57
+ if (!rules.length) return null;
58
+ const value = getFieldValue(field.prop, values);
59
+ try {
60
+ await new Schema({ [field.prop]: rules }).validate({ [field.prop]: value }, { firstFields: true });
61
+ return null;
62
+ } catch (err) {
63
+ if (err?.fields) return err.fields;
64
+ return { [field.prop]: [{
65
+ field: field.prop,
66
+ message: err?.message ?? `${err}`
67
+ }] };
68
+ }
69
+ };
70
+ /**
71
+ * 不挂载任何组件,纯逻辑地对「一份 config + 一份值」执行一次完整校验。
72
+ *
73
+ * 流程与渲染式校验一一对应,但不需要 DOM,也不会实例化任何字段组件:
74
+ *
75
+ * 1. 构造 headless `formState` 并挂上 `context` 读穿;
76
+ * 2. `initValue` 初始化表单值(默认值、嵌套结构、`onInitValue` 等);
77
+ * 3. `applyMountValueEffects` 执行字段登记的值初始化写入(与渲染式共用同一份登记表);
78
+ * 4. 遍历 config 树收集所有带规则的字段(等价于渲染出的 FormItem 集合);
79
+ * 5. 逐字段交给 async-validator 执行,汇总错误文案。
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * const { error, values } = await validateValues({
84
+ * config: [...],
85
+ * initValues: { name: '' },
86
+ * typeMatchValid: true,
87
+ * });
88
+ * ```
89
+ */
90
+ var validateValues = async (options) => {
91
+ const { config, initValues = {}, typeMatchValid, useFieldTextInError = true } = options;
92
+ const formState = createHeadlessFormState(options);
93
+ const values = await initValue(formState, {
94
+ initValues,
95
+ config
96
+ });
97
+ formState.values = values;
98
+ applyMountValueEffects(formState, config, values);
99
+ const fields = collectValidatableFields(formState, config, values, Boolean(typeMatchValid));
100
+ const invalidFields = {};
101
+ for (const field of fields) {
102
+ const fieldErrors = await validateField(field, values);
103
+ if (fieldErrors) Object.assign(invalidFields, fieldErrors);
104
+ }
105
+ return {
106
+ values,
107
+ invalidFields,
108
+ error: formatValidateError(invalidFields, {
109
+ config,
110
+ useFieldTextInError
111
+ })
112
+ };
113
+ };
114
+ //#endregion
115
+ export { createHeadlessFormState, validateValues };
package/dist/style.css CHANGED
@@ -26,7 +26,7 @@
26
26
  .m-form-dialog .m-dialog-body {
27
27
  padding: 0 20px;
28
28
  }
29
- .m-form-dialog .el-table .m-form-item .el-form-item {
29
+ .m-form-dialog .el-table .m-form-item .el-form-item:not(.is-error) {
30
30
  margin-bottom: 0;
31
31
  }
32
32
 
@@ -226,6 +226,7 @@ a.magic-admin-link i {
226
226
  .m-container-fieldset.fieldset-in-card-fit > fieldset.m-fieldset legend {
227
227
  position: relative;
228
228
  top: 10px;
229
+ background-color: transparent;
229
230
  }
230
231
  .m-container-fieldset.fieldset-in-card-fit.fieldset-in-card-fit-last {
231
232
  padding-bottom: 0 !important;
@@ -268,6 +269,21 @@ fieldset.m-fieldset .m-form-tip {
268
269
  margin-left: 5px;
269
270
  }
270
271
 
272
+ .m-fields-group-list {
273
+ --m-group-list-footer-padding-top: 12px;
274
+ --m-group-list-footer-padding-bottom: 16px;
275
+ --m-group-list-footer-button-height: 32px;
276
+ --m-group-list-footer-height: calc(
277
+ var(--m-group-list-footer-padding-top) +
278
+ var(--m-group-list-footer-button-height) +
279
+ var(--m-group-list-footer-padding-bottom)
280
+ );
281
+ --m-group-list-footer-bg: var(--el-bg-color, #fff);
282
+ --m-group-list-header-height: 65px;
283
+ --m-group-list-header-bg: #fff;
284
+ width: 100%;
285
+ min-width: 0;
286
+ }
271
287
  .m-fields-group-list .m-fields-group-list-item.tmagic-design-card--flat:last-child {
272
288
  border: 0;
273
289
  }
@@ -283,21 +299,117 @@ fieldset.m-fieldset .m-form-tip {
283
299
  transform: rotate(90deg);
284
300
  }
285
301
  .m-fields-group-list .m-fields-group-list-item {
302
+ overflow: visible;
286
303
  border-bottom: 1px solid #ebeef5;
287
304
  margin-bottom: 7px;
288
305
  }
289
306
  .m-fields-group-list .m-fields-group-list-item:last-of-type {
290
307
  border-bottom: 0;
291
308
  }
309
+ .m-fields-group-list .m-fields-group-list-item .el-card__body,
310
+ .m-fields-group-list .m-fields-group-list-item .t-card__body {
311
+ overflow: visible;
312
+ }
313
+ .m-fields-group-list .m-fields-group-list-item .el-card__body > .m-container-row,
314
+ .m-fields-group-list .m-fields-group-list-item .t-card__body > .m-container-row {
315
+ overflow: visible;
316
+ }
317
+ .m-fields-group-list .m-fields-group-list-item .el-card__body .tmagic-design-form-item,
318
+ .m-fields-group-list .m-fields-group-list-item .t-card__body .tmagic-design-form-item {
319
+ margin-bottom: 16px;
320
+ }
292
321
  .m-fields-group-list .m-fields-group-list-item .m-fields-group-list-item-header {
293
322
  display: flex;
294
323
  align-items: center;
295
324
  gap: 8px;
296
325
  }
297
- .m-fields-group-list .m-fields-group-list-footer {
326
+ .m-fields-group-list .m-fields-group-list-item .m-fields-group-list-item-title {
327
+ flex: 1;
328
+ min-width: 0;
329
+ }
330
+ .m-fields-group-list .m-fields-group-list-item .m-fields-group-list-item-actions {
331
+ display: flex;
332
+ align-items: center;
333
+ flex-shrink: 0;
334
+ gap: 8px;
335
+ }
336
+ .m-fields-group-list > .m-fields-group-list-item {
337
+ --m-group-list-item-footer-bottom: var(
338
+ --m-group-list-nested-footer-bottom,
339
+ 0px
340
+ );
341
+ }
342
+ .m-fields-group-list.is-footer-sticky > .m-fields-group-list-item {
343
+ --m-group-list-item-footer-bottom: calc(
344
+ var(--m-group-list-nested-footer-bottom, 0px) +
345
+ var(--m-group-list-footer-height)
346
+ );
347
+ }
348
+ .m-fields-group-list .m-fields-group-list-item .m-fields-group-list {
349
+ --m-group-list-nested-footer-bottom: var(
350
+ --m-group-list-item-footer-bottom,
351
+ 0px
352
+ );
353
+ }
354
+ .m-fields-group-list.is-header-sticky {
355
+ --m-group-list-nested-sticky-top: var(--m-group-list-child-list-sticky-top);
356
+ --m-group-list-nested-header-z: var(--m-group-list-child-list-header-z);
357
+ }
358
+ .m-fields-group-list.is-header-sticky > .m-fields-group-list-item {
359
+ --m-group-list-item-sticky-top: var(
360
+ --m-group-list-nested-sticky-top,
361
+ var(--m-group-list-header-sticky-top, 0px)
362
+ );
363
+ --m-group-list-item-header-z: var(--m-group-list-nested-header-z, 7);
364
+ --m-group-list-child-list-sticky-top: calc(
365
+ var(--m-group-list-item-sticky-top) + var(--m-group-list-header-height)
366
+ );
367
+ --m-group-list-child-list-header-z: calc(
368
+ var(--m-group-list-item-header-z) - 1
369
+ );
370
+ }
371
+ .m-fields-group-list.is-header-sticky > .m-fields-group-list-item > .el-card__header,
372
+ .m-fields-group-list.is-header-sticky > .m-fields-group-list-item > .t-card__header {
373
+ position: sticky;
374
+ top: var(--m-group-list-item-sticky-top);
375
+ z-index: var(--m-group-list-item-header-z);
376
+ background-color: var(--m-group-list-header-bg, #fff);
377
+ }
378
+ .m-fields-group-list .el-table__empty-block {
379
+ width: 100%;
380
+ min-height: 0;
381
+ }
382
+ .m-fields-group-list .el-table__empty-text {
383
+ display: block;
384
+ box-sizing: border-box;
385
+ width: 100%;
386
+ }
387
+ .m-fields-group-list > .m-fields-group-list-footer {
298
388
  display: flex;
299
389
  justify-content: space-between;
300
390
  margin-top: 10px;
391
+ margin-bottom: 16px;
392
+ }
393
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full {
394
+ position: sticky;
395
+ bottom: var(--m-group-list-nested-footer-bottom, 0px);
396
+ z-index: 7;
397
+ margin-bottom: 0;
398
+ padding: var(--m-group-list-footer-padding-top) 0 var(--m-group-list-footer-padding-bottom);
399
+ background-color: var(--m-group-list-footer-bg);
400
+ }
401
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full > div {
402
+ justify-content: stretch;
403
+ }
404
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full .el-button,
405
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full .tmagic-design-button {
406
+ width: 100%;
407
+ height: var(--m-group-list-footer-button-height);
408
+ }
409
+
410
+ /** 最外层的groupList需要每个item需要增加空白区域界限时,增加outer-gorup_list可以实现 */
411
+ .m-container-group-list.outer-gorup_list > .m-fields-group-list > .m-fields-group-list-item {
412
+ margin-bottom: 10px;
301
413
  }
302
414
 
303
415
  .m-form-panel .el-card__header:hover {
@@ -343,6 +455,10 @@ fieldset.m-fieldset .m-form-tip {
343
455
  width: 95vw !important;
344
456
  }
345
457
 
458
+ .el-form-item .m-fields-table .el-form-item.is-error {
459
+ margin-bottom: 18px;
460
+ }
461
+
346
462
  .m-fields-table {
347
463
  width: 100%;
348
464
  }
@@ -365,7 +481,7 @@ fieldset.m-fieldset .m-form-tip {
365
481
  .m-fields-table .el-table__expanded-cell .m-form-tip {
366
482
  margin-left: 80px;
367
483
  }
368
- .m-fields-table .el-form-item {
484
+ .m-fields-table .el-form-item:not(.is-error) {
369
485
  margin-bottom: 0;
370
486
  }
371
487
  .m-fields-table .tmagic-form-table-drag-target {
@@ -417,7 +533,11 @@ fieldset.m-fieldset .m-form-tip {
417
533
  .m-form-box .el-box__header {
418
534
  margin: 0;
419
535
  }
536
+ .m-form-box .m-box-body {
537
+ min-height: 0;
538
+ }
420
539
  .m-form-box .dialog-footer {
540
+ flex-shrink: 0;
421
541
  display: flex;
422
542
  align-items: center;
423
543
  justify-content: space-between;