@tmagic/form 1.8.0-beta.25 → 1.8.0-beta.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +13 -6
  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 +81 -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 +111 -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 +81 -1
  63. package/dist/themes/magic-admin.css +83 -7
  64. package/dist/tmagic-form-headless.umd.cjs +4080 -0
  65. package/dist/tmagic-form.umd.cjs +2020 -876
  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/fields/Select.vue +13 -4
  102. package/src/headless.ts +78 -0
  103. package/src/index.ts +32 -15
  104. package/src/plugin.ts +63 -42
  105. package/src/schema.ts +6 -8
  106. package/src/submitForm.ts +81 -409
  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 +149 -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
@@ -0,0 +1,57 @@
1
+ //#region packages/form/src/utils/validateError.ts
2
+ /**
3
+ * 通过 name 从 config 中查找对应的 text
4
+ *
5
+ * @param name - 字段名,支持点分隔的路径格式,如 'a.b.c'
6
+ * @param config - 表单配置数组
7
+ * @returns 找到的 text 值,如果未找到则返回 undefined
8
+ */
9
+ var getTextByName = (name, config = []) => {
10
+ if (!name || !Array.isArray(config)) return void 0;
11
+ const nameParts = name.split(".");
12
+ const findInConfig = (configs, parts) => {
13
+ if (parts.length === 0) return void 0;
14
+ const [currentPart, ...remainingParts] = parts;
15
+ for (const item of configs) {
16
+ if (item.name === currentPart) {
17
+ if (remainingParts.length === 0) return typeof item.text === "string" ? item.text : void 0;
18
+ if ("items" in item && Array.isArray(item.items)) {
19
+ const result = findInConfig(item.items, remainingParts);
20
+ if (result !== void 0) return result;
21
+ }
22
+ }
23
+ if ("items" in item && Array.isArray(item.items)) {
24
+ const result = findInConfig(item.items, parts);
25
+ if (result !== void 0) return result;
26
+ }
27
+ }
28
+ };
29
+ return findInConfig(config, nameParts);
30
+ };
31
+ /**
32
+ * 将校验返回的 invalidFields 汇总为可读的错误文案(多条以 `<br>` 拼接)。
33
+ *
34
+ * `useFieldTextInError` 为 `true`(默认)时用字段的 text 文案作为错误前缀,找不到则回退为字段 name。
35
+ *
36
+ * 由渲染式校验(Form.vue 的 `submitForm` / `validate`)与无渲染校验(`validateValues`)共用,
37
+ * 保证两条校验链路产出的错误文案格式完全一致。
38
+ *
39
+ * @param invalidFields - async-validator 产出的字段错误表
40
+ * @param [options] - 文案选项
41
+ * @param [options.config] - 用于查找 text 的表单配置
42
+ * @param [options.useFieldTextInError=true] - 错误前缀是否使用字段 text
43
+ * @returns 拼接后的错误文案;无错误时为空串
44
+ */
45
+ var formatValidateError = (invalidFields, { config = [], useFieldTextInError = true } = {}) => {
46
+ const error = [];
47
+ Object.entries(invalidFields).forEach(([prop, validateError]) => {
48
+ validateError.forEach(({ field, message }) => {
49
+ const name = field || prop;
50
+ const text = (useFieldTextInError ? getTextByName(name, config) : void 0) || name;
51
+ error.push(`${text} -> ${message}`);
52
+ });
53
+ });
54
+ return error.join("<br>");
55
+ };
56
+ //#endregion
57
+ export { formatValidateError, getTextByName };
@@ -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
@@ -269,6 +269,21 @@ fieldset.m-fieldset .m-form-tip {
269
269
  margin-left: 5px;
270
270
  }
271
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
+ }
272
287
  .m-fields-group-list .m-fields-group-list-item.tmagic-design-card--flat:last-child {
273
288
  border: 0;
274
289
  }
@@ -284,22 +299,87 @@ fieldset.m-fieldset .m-form-tip {
284
299
  transform: rotate(90deg);
285
300
  }
286
301
  .m-fields-group-list .m-fields-group-list-item {
302
+ overflow: visible;
287
303
  border-bottom: 1px solid #ebeef5;
288
304
  margin-bottom: 7px;
289
305
  }
290
306
  .m-fields-group-list .m-fields-group-list-item:last-of-type {
291
307
  border-bottom: 0;
292
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
+ }
293
321
  .m-fields-group-list .m-fields-group-list-item .m-fields-group-list-item-header {
294
322
  display: flex;
295
323
  align-items: center;
296
324
  gap: 8px;
297
325
  }
298
- .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 > .el-card__header,
337
+ .m-fields-group-list .m-fields-group-list-item > .t-card__header {
338
+ position: sticky;
339
+ top: var(--m-group-list-header-sticky-top, 0px);
340
+ z-index: 7;
341
+ background-color: var(--m-group-list-header-bg, #fff);
342
+ }
343
+ .m-fields-group-list .m-fields-group-list-item .m-fields-group-list-item > .el-card__header,
344
+ .m-fields-group-list .m-fields-group-list-item .m-fields-group-list-item > .t-card__header {
345
+ top: calc(var(--m-group-list-header-sticky-top, 0px) + var(--m-group-list-header-height));
346
+ z-index: 6;
347
+ }
348
+ .m-fields-group-list .el-table__empty-block {
349
+ width: 100%;
350
+ min-height: 0;
351
+ }
352
+ .m-fields-group-list .el-table__empty-text {
353
+ display: block;
354
+ box-sizing: border-box;
355
+ width: 100%;
356
+ }
357
+ .m-fields-group-list > .m-fields-group-list-footer {
358
+ display: flex;
299
359
  justify-content: space-between;
300
360
  margin-top: 10px;
301
361
  margin-bottom: 16px;
302
362
  }
363
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full {
364
+ position: sticky;
365
+ bottom: 0;
366
+ z-index: 7;
367
+ margin-bottom: 0;
368
+ padding: var(--m-group-list-footer-padding-top) 0 var(--m-group-list-footer-padding-bottom);
369
+ background-color: var(--m-group-list-footer-bg);
370
+ }
371
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full > div {
372
+ justify-content: stretch;
373
+ }
374
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full .el-button,
375
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full .tmagic-design-button {
376
+ width: 100%;
377
+ height: var(--m-group-list-footer-button-height);
378
+ }
379
+ .m-fields-group-list .m-fields-group-list-item .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full {
380
+ bottom: var(--m-group-list-footer-height);
381
+ z-index: 7;
382
+ }
303
383
 
304
384
  /** 最外层的groupList需要每个item需要增加空白区域界限时,增加outer-gorup_list可以实现 */
305
385
  .m-container-group-list.outer-gorup_list > .m-fields-group-list > .m-fields-group-list-item {
@@ -269,6 +269,21 @@ fieldset.m-fieldset .m-form-tip {
269
269
  margin-left: 5px;
270
270
  }
271
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
+ }
272
287
  .m-fields-group-list .m-fields-group-list-item.tmagic-design-card--flat:last-child {
273
288
  border: 0;
274
289
  }
@@ -284,22 +299,87 @@ fieldset.m-fieldset .m-form-tip {
284
299
  transform: rotate(90deg);
285
300
  }
286
301
  .m-fields-group-list .m-fields-group-list-item {
302
+ overflow: visible;
287
303
  border-bottom: 1px solid #ebeef5;
288
304
  margin-bottom: 7px;
289
305
  }
290
306
  .m-fields-group-list .m-fields-group-list-item:last-of-type {
291
307
  border-bottom: 0;
292
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
+ }
293
321
  .m-fields-group-list .m-fields-group-list-item .m-fields-group-list-item-header {
294
322
  display: flex;
295
323
  align-items: center;
296
324
  gap: 8px;
297
325
  }
298
- .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 > .el-card__header,
337
+ .m-fields-group-list .m-fields-group-list-item > .t-card__header {
338
+ position: sticky;
339
+ top: var(--m-group-list-header-sticky-top, 0px);
340
+ z-index: 7;
341
+ background-color: var(--m-group-list-header-bg, #fff);
342
+ }
343
+ .m-fields-group-list .m-fields-group-list-item .m-fields-group-list-item > .el-card__header,
344
+ .m-fields-group-list .m-fields-group-list-item .m-fields-group-list-item > .t-card__header {
345
+ top: calc(var(--m-group-list-header-sticky-top, 0px) + var(--m-group-list-header-height));
346
+ z-index: 6;
347
+ }
348
+ .m-fields-group-list .el-table__empty-block {
349
+ width: 100%;
350
+ min-height: 0;
351
+ }
352
+ .m-fields-group-list .el-table__empty-text {
353
+ display: block;
354
+ box-sizing: border-box;
355
+ width: 100%;
356
+ }
357
+ .m-fields-group-list > .m-fields-group-list-footer {
358
+ display: flex;
299
359
  justify-content: space-between;
300
360
  margin-top: 10px;
301
361
  margin-bottom: 16px;
302
362
  }
363
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full {
364
+ position: sticky;
365
+ bottom: 0;
366
+ z-index: 7;
367
+ margin-bottom: 0;
368
+ padding: var(--m-group-list-footer-padding-top) 0 var(--m-group-list-footer-padding-bottom);
369
+ background-color: var(--m-group-list-footer-bg);
370
+ }
371
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full > div {
372
+ justify-content: stretch;
373
+ }
374
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full .el-button,
375
+ .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full .tmagic-design-button {
376
+ width: 100%;
377
+ height: var(--m-group-list-footer-button-height);
378
+ }
379
+ .m-fields-group-list .m-fields-group-list-item .m-fields-group-list > .m-fields-group-list-footer.is-sticky-full {
380
+ bottom: var(--m-group-list-footer-height);
381
+ z-index: 7;
382
+ }
303
383
 
304
384
  /** 最外层的groupList需要每个item需要增加空白区域界限时,增加outer-gorup_list可以实现 */
305
385
  .m-container-group-list.outer-gorup_list > .m-fields-group-list > .m-fields-group-list-item {
@@ -457,7 +537,8 @@ fieldset.m-fieldset .m-form-tip {
457
537
  .m-form.m-form--magic-admin [class="m-container-fieldset m-form-container"] {
458
538
  margin-top: 15px;
459
539
  }
460
- .m-form.m-form--magic-admin .m-container-tab:not(.magic-right-panel-tabs-top):not(.magic-form-dynamic-tab) > .tmagic-design-tabs:not(.el-tabs--border-card) > .el-tabs__content {
540
+ .m-form.m-form--magic-admin .m-container-tab:not(.magic-right-panel-tabs-top):not(.magic-form-dynamic-tab) > .tmagic-design-tabs:not(.el-tabs--border-card) > .el-tabs__content,
541
+ .m-form.m-form--magic-admin .m-container-tab:not(.magic-right-panel-tabs-top):not(.magic-form-dynamic-tab) > .tmagic-design-tabs:not(.el-tabs--border-card) > .t-tabs__content {
461
542
  background-color: #fff;
462
543
  padding: 16px 16px 0 16px;
463
544
  border-radius: 4px;
@@ -494,12 +575,7 @@ fieldset.m-fieldset .m-form-tip {
494
575
  .m-form.m-form--magic-admin .m-fields-group-list-item.tmagic-design-card--flat .el-card__body .m-fields-table-wrap .m-fields-table .el-table__header-wrapper thead {
495
576
  height: 48px;
496
577
  }
497
- .m-form.m-form--magic-admin .m-fields-group-list-item.tmagic-design-card--flat .m-fields-group-list-item-header {
498
- position: relative;
499
- }
500
578
  .m-form.m-form--magic-admin .m-fields-group-list-item.tmagic-design-card--flat .m-fields-group-list-item-header .delete-button {
501
- position: absolute;
502
- right: 0;
503
579
  color: #0f1113;
504
580
  }
505
581
  .m-form.m-form--magic-admin .m-form-container .m-form-container-expand {