@tmagic/form 1.7.10 → 1.7.12

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 (38) hide show
  1. package/dist/es/containers/GroupList.vue_vue_type_script_setup_true_lang.js +5 -69
  2. package/dist/es/{table → containers/table}/ActionsColumn.js +1 -1
  3. package/dist/es/{table → containers/table}/ActionsColumn.vue_vue_type_script_setup_true_lang.js +1 -1
  4. package/dist/es/{table → containers/table}/SortColumn.js +1 -1
  5. package/dist/es/{table → containers/table}/SortColumn.vue_vue_type_script_setup_true_lang.js +1 -1
  6. package/dist/es/{table → containers/table}/Table.js +1 -1
  7. package/dist/es/{table → containers/table}/Table.vue_vue_type_script_setup_true_lang.js +13 -60
  8. package/dist/es/containers/table/useFullscreen.js +22 -0
  9. package/dist/es/{table → containers/table}/useImport.js +3 -5
  10. package/dist/es/{table → containers/table}/usePagination.js +2 -2
  11. package/dist/es/{table → containers/table}/useSelection.js +1 -1
  12. package/dist/es/{table → containers/table}/useSortable.js +2 -2
  13. package/dist/es/{table → containers/table}/useTableColumns.js +5 -5
  14. package/dist/es/containers/table-group-list/TableGroupList.js +5 -0
  15. package/dist/es/containers/table-group-list/TableGroupList.vue_vue_type_script_setup_true_lang.js +161 -0
  16. package/dist/es/{table → containers/table-group-list}/useAdd.js +6 -4
  17. package/dist/es/index.js +2 -3
  18. package/dist/es/plugin.js +3 -4
  19. package/dist/tmagic-form.umd.cjs +732 -677
  20. package/package.json +6 -6
  21. package/src/containers/GroupList.vue +5 -80
  22. package/src/{table → containers/table}/ActionsColumn.vue +1 -1
  23. package/src/{table → containers/table}/Table.vue +11 -56
  24. package/src/{table → containers/table}/type.ts +0 -1
  25. package/src/containers/table/useFullscreen.ts +31 -0
  26. package/src/{table → containers/table}/useImport.ts +2 -5
  27. package/src/{table → containers/table}/usePagination.ts +1 -1
  28. package/src/{table → containers/table}/useSortable.ts +1 -1
  29. package/src/{table → containers/table}/useTableColumns.ts +8 -5
  30. package/src/containers/table-group-list/TableGroupList.vue +173 -0
  31. package/src/{table → containers/table-group-list}/useAdd.ts +17 -7
  32. package/src/index.ts +3 -2
  33. package/src/plugin.ts +3 -4
  34. package/types/index.d.ts +245 -286
  35. package/dist/es/table/useFullscreen.js +0 -15
  36. package/src/table/useFullscreen.ts +0 -18
  37. /package/src/{table → containers/table}/SortColumn.vue +0 -0
  38. /package/src/{table → containers/table}/useSelection.ts +0 -0
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.7.10",
2
+ "version": "1.7.12",
3
3
  "name": "@tmagic/form",
4
4
  "type": "module",
5
5
  "sideEffects": [
@@ -50,11 +50,11 @@
50
50
  "@vue/test-utils": "^2.4.6"
51
51
  },
52
52
  "peerDependencies": {
53
- "vue": "^3.5.24",
54
- "typescript": "^6.0.2",
55
- "@tmagic/design": "1.7.10",
56
- "@tmagic/form-schema": "1.7.10",
57
- "@tmagic/utils": "1.7.10"
53
+ "vue": "^3.5.33",
54
+ "typescript": "^6.0.3",
55
+ "@tmagic/design": "1.7.12",
56
+ "@tmagic/form-schema": "1.7.12",
57
+ "@tmagic/utils": "1.7.12"
58
58
  },
59
59
  "peerDependenciesMeta": {
60
60
  "typescript": {
@@ -10,7 +10,7 @@
10
10
  v-for="(item, index) in model[name]"
11
11
  :key="index"
12
12
  :model="item"
13
- :lastValues="getLastValues(lastValues[name], Number(index))"
13
+ :lastValues="getLastValues(lastValues?.[name], Number(index))"
14
14
  :is-compare="isCompare"
15
15
  :config="config"
16
16
  :prop="prop"
@@ -27,33 +27,18 @@
27
27
  ></MFieldsGroupListItem>
28
28
 
29
29
  <div class="m-fields-group-list-footer">
30
- <TMagicButton v-if="config.enableToggleMode" :icon="Grid" size="small" @click="toggleMode"
31
- >切换为表格</TMagicButton
32
- >
30
+ <slot name="toggle-button"></slot>
33
31
  <div style="display: flex; justify-content: flex-end; flex: 1">
34
- <TMagicButton
35
- v-if="addable"
36
- :size="config.enableToggleMode ? 'small' : 'default'"
37
- :icon="Plus"
38
- v-bind="config.addButtonConfig?.props || { type: 'primary' }"
39
- :disabled="disabled"
40
- @click="addHandler"
41
- >{{ config.addButtonConfig?.text || '新增' }}</TMagicButton
42
- >
32
+ <slot name="add-button"></slot>
43
33
  </div>
44
34
  </div>
45
35
  </div>
46
36
  </template>
47
37
 
48
38
  <script setup lang="ts">
49
- import { computed, inject } from 'vue';
50
- import { Grid, Plus } from '@element-plus/icons-vue';
51
39
  import { cloneDeep } from 'lodash-es';
52
40
 
53
- import { TMagicButton } from '@tmagic/design';
54
-
55
- import type { ContainerChangeEventData, FormState, GroupListConfig } from '../schema';
56
- import { initValue } from '../utils/form';
41
+ import type { ContainerChangeEventData, GroupListConfig } from '../schema';
57
42
 
58
43
  import MFieldsGroupListItem from './GroupListItem.vue';
59
44
 
@@ -71,6 +56,7 @@ const props = defineProps<{
71
56
  prop?: string;
72
57
  size?: string;
73
58
  disabled?: boolean;
59
+ showIndex?: boolean;
74
60
  }>();
75
61
 
76
62
  const emit = defineEmits<{
@@ -78,60 +64,10 @@ const emit = defineEmits<{
78
64
  addDiffCount: [];
79
65
  }>();
80
66
 
81
- const mForm = inject<FormState | undefined>('mForm');
82
-
83
- const addable = computed(() => {
84
- if (!props.name) return false;
85
-
86
- if (typeof props.config.addable === 'function') {
87
- return props.config.addable(mForm, {
88
- model: props.model[props.name],
89
- formValue: mForm?.values,
90
- prop: props.prop,
91
- config: props.config,
92
- });
93
- }
94
-
95
- return typeof props.config.addable === 'undefined' ? true : props.config.addable;
96
- });
97
-
98
67
  const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
99
68
  emit('change', props.model, eventData);
100
69
  };
101
70
 
102
- const addHandler = async () => {
103
- if (!props.name) return false;
104
-
105
- let initValues = {};
106
-
107
- if (typeof props.config.defaultAdd === 'function') {
108
- initValues = await props.config.defaultAdd(mForm, {
109
- model: props.model[props.name],
110
- formValue: mForm?.values,
111
- prop: props.prop,
112
- config: props.config,
113
- });
114
- } else if (props.config.defaultAdd) {
115
- initValues = props.config.defaultAdd;
116
- }
117
-
118
- const groupValue = await initValue(mForm, {
119
- config: props.config.items,
120
- initValues,
121
- });
122
-
123
- props.model[props.name].push(groupValue);
124
-
125
- emit('change', props.model[props.name], {
126
- changeRecords: [
127
- {
128
- propPath: `${props.prop}.${props.model[props.name].length - 1}`,
129
- value: groupValue,
130
- },
131
- ],
132
- });
133
- };
134
-
135
71
  const removeHandler = (index: number) => {
136
72
  if (!props.name) return false;
137
73
 
@@ -153,17 +89,6 @@ const swapHandler = (idx1: number, idx2: number) => {
153
89
  emit('change', props.model[props.name]);
154
90
  };
155
91
 
156
- const toggleMode = () => {
157
- props.config.type = 'table';
158
- props.config.groupItems = props.config.items;
159
- props.config.items = (props.config.tableItems ||
160
- props.config.items.map((item: any) => ({
161
- ...item,
162
- label: item.label || item.text,
163
- text: null,
164
- }))) as any;
165
- };
166
-
167
92
  const onAddDiffCount = () => emit('addDiffCount');
168
93
 
169
94
  const getLastValues = (item: any, index: number) => item?.[index] || {};
@@ -38,7 +38,7 @@ import { cloneDeep } from 'lodash-es';
38
38
 
39
39
  import { TMagicButton, TMagicTooltip } from '@tmagic/design';
40
40
 
41
- import type { FormState, TableConfig } from '../schema';
41
+ import type { FormState, TableConfig } from '../../schema';
42
42
 
43
43
  const emit = defineEmits(['change']);
44
44
 
@@ -4,7 +4,7 @@
4
4
  v-bind="$attrs"
5
5
  class="m-fields-table-wrap"
6
6
  :class="{ fixed: isFullscreen }"
7
- :style="isFullscreen ? `z-index: ${nextZIndex()}` : ''"
7
+ :style="isFullscreen ? `z-index: ${fullscreenZIndex}` : ''"
8
8
  >
9
9
  <div class="m-fields-table" :class="{ 'm-fields-table-item-extra': config.itemExtra }">
10
10
  <span v-if="config.extra" style="color: rgba(0, 0, 0, 0.45)" v-html="config.extra"></span>
@@ -34,13 +34,7 @@
34
34
 
35
35
  <div style="display: flex; justify-content: space-between; margin: 10px 0">
36
36
  <div style="display: flex">
37
- <TMagicButton
38
- :icon="Grid"
39
- size="small"
40
- @click="toggleMode"
41
- v-if="enableToggleMode && config.enableToggleMode !== false && !isFullscreen"
42
- >展开配置</TMagicButton
43
- >
37
+ <slot name="toggle-button" v-if="!isFullscreen"></slot>
44
38
  <TMagicButton
45
39
  :icon="FullScreen"
46
40
  size="small"
@@ -64,17 +58,7 @@
64
58
  >清空</TMagicButton
65
59
  >
66
60
  </div>
67
- <TMagicButton
68
- v-if="addable"
69
- class="m-form-table-add-button"
70
- size="small"
71
- plain
72
- :icon="Plus"
73
- v-bind="config.addButtonConfig?.props || { type: 'primary' }"
74
- :disabled="disabled"
75
- @click="newHandler()"
76
- >{{ config.addButtonConfig?.text || '新增一行' }}</TMagicButton
77
- >
61
+ <slot name="add-button"></slot>
78
62
  </div>
79
63
 
80
64
  <div class="bottom" style="text-align: right" v-if="config.pagination">
@@ -97,15 +81,14 @@
97
81
 
98
82
  <script setup lang="ts">
99
83
  import { computed, ref, useTemplateRef } from 'vue';
100
- import { FullScreen, Grid, Plus } from '@element-plus/icons-vue';
84
+ import { FullScreen } from '@element-plus/icons-vue';
101
85
 
102
- import { TMagicButton, TMagicPagination, TMagicTable, TMagicTooltip, TMagicUpload, useZIndex } from '@tmagic/design';
86
+ import { TMagicButton, TMagicPagination, TMagicTable, TMagicTooltip, TMagicUpload } from '@tmagic/design';
103
87
 
104
- import type { SortProp } from '../schema';
105
- import { sortChange } from '../utils/form';
88
+ import type { SortProp } from '../../schema';
89
+ import { sortChange } from '../../utils/form';
106
90
 
107
91
  import type { TableProps } from './type';
108
- import { useAdd } from './useAdd';
109
92
  import { useFullscreen } from './useFullscreen';
110
93
  import { useImport } from './useImport';
111
94
  import { usePagination } from './usePagination';
@@ -120,13 +103,12 @@ defineOptions({
120
103
  const props = withDefaults(defineProps<TableProps>(), {
121
104
  prop: '',
122
105
  sortKey: '',
123
- enableToggleMode: true,
124
106
  showIndex: true,
125
107
  lastValues: () => ({}),
126
108
  isCompare: false,
127
109
  });
128
110
 
129
- const emit = defineEmits(['change', 'select', 'addDiffCount']);
111
+ const emit = defineEmits(['change', 'select', 'addDiffCount', 'add']);
130
112
 
131
113
  const modelName = computed(() => props.name || props.config.name || '');
132
114
  const tMagicTableRef = useTemplateRef<InstanceType<typeof TMagicTable>>('tMagicTable');
@@ -136,44 +118,17 @@ const { pageSize, currentPage, paginationData, handleSizeChange, handleCurrentCh
136
118
  modelName,
137
119
  );
138
120
 
139
- const { nextZIndex } = useZIndex();
140
121
  const updateKey = ref(1);
141
122
 
142
- const { addable, newHandler } = useAdd(props, emit);
143
123
  const { columns } = useTableColumns(props, emit, currentPage, pageSize, modelName);
144
124
  useSortable(props, emit, tMagicTableRef, modelName, updateKey);
145
- const { isFullscreen, toggleFullscreen } = useFullscreen();
146
- const { importable, excelHandler, clearHandler } = useImport(props, emit, newHandler);
125
+ const { isFullscreen, fullscreenZIndex, toggleFullscreen } = useFullscreen();
126
+
127
+ const { importable, excelHandler, clearHandler } = useImport(props, emit);
147
128
  const { selectHandle, toggleRowSelection } = useSelection(props, emit, tMagicTableRef);
148
129
 
149
130
  const data = computed(() => (props.config.pagination ? paginationData.value : props.model[modelName.value]));
150
131
 
151
- const toggleMode = () => {
152
- const calcLabelWidth = (label: string) => {
153
- if (!label) return '0px';
154
- const zhLength = label.match(/[^\x00-\xff]/g)?.length || 0;
155
- const chLength = label.length - zhLength;
156
- return `${Math.max(chLength * 8 + zhLength * 20, 80)}px`;
157
- };
158
-
159
- // 切换为groupList的形式
160
- props.config.type = 'groupList';
161
- props.config.enableToggleMode = true;
162
- props.config.tableItems = props.config.items;
163
- props.config.items =
164
- props.config.groupItems ||
165
- props.config.items.map((item: any) => {
166
- const text = item.text || item.label;
167
- const labelWidth = calcLabelWidth(text);
168
- return {
169
- ...item,
170
- text,
171
- labelWidth,
172
- span: item.span || 12,
173
- };
174
- });
175
- };
176
-
177
132
  const sortChangeHandler = (sortOptions: SortProp) => {
178
133
  const modelName = props.name || props.config.name || '';
179
134
  sortChange(props.model[modelName], sortOptions);
@@ -13,6 +13,5 @@ export interface TableProps {
13
13
  sortKey?: string;
14
14
  text?: string;
15
15
  size?: string;
16
- enableToggleMode?: boolean;
17
16
  showIndex?: boolean;
18
17
  }
@@ -0,0 +1,31 @@
1
+ import { ref, watch } from 'vue';
2
+
3
+ import { useZIndex } from '@tmagic/design';
4
+
5
+ export const useFullscreen = () => {
6
+ const { nextZIndex } = useZIndex();
7
+
8
+ const fullscreenZIndex = ref(nextZIndex());
9
+
10
+ const isFullscreen = ref(false);
11
+
12
+ const toggleFullscreen = () => {
13
+ if (isFullscreen.value) {
14
+ isFullscreen.value = false;
15
+ } else {
16
+ isFullscreen.value = true;
17
+ }
18
+ };
19
+
20
+ watch(isFullscreen, (value) => {
21
+ if (value) {
22
+ fullscreenZIndex.value = nextZIndex();
23
+ }
24
+ });
25
+
26
+ return {
27
+ isFullscreen,
28
+ fullscreenZIndex,
29
+ toggleFullscreen,
30
+ };
31
+ };
@@ -8,8 +8,7 @@ import type { TableProps } from './type';
8
8
 
9
9
  export const useImport = (
10
10
  props: TableProps,
11
- emit: (event: 'select' | 'change' | 'addDiffCount', ...args: any[]) => void,
12
- newHandler: (row: any) => void,
11
+ emit: (event: 'select' | 'change' | 'addDiffCount' | 'add', ...args: any[]) => void,
13
12
  ) => {
14
13
  const mForm = inject<FormState | undefined>('mForm');
15
14
  const modelName = computed(() => props.name || props.config.name || '');
@@ -41,9 +40,7 @@ export const useImport = (
41
40
  pdata.SheetNames.forEach((sheetName: string) => {
42
41
  const arr = (globalThis as any).XLSX.utils.sheet_to_json(pdata.Sheets[sheetName], { header: 1 });
43
42
  if (arr?.[0]) {
44
- arr.forEach((row: any) => {
45
- newHandler(row);
46
- });
43
+ emit('add', arr);
47
44
  }
48
45
  setTimeout(() => {
49
46
  excelBtn.value?.clearFiles();
@@ -1,6 +1,6 @@
1
1
  import { computed, type Ref, ref } from 'vue';
2
2
 
3
- import { getDataByPage } from '../utils/form';
3
+ import { getDataByPage } from '../../utils/form';
4
4
 
5
5
  import type { TableProps } from './type';
6
6
 
@@ -4,7 +4,7 @@ import type { default as SortableType, SortableEvent } from 'sortablejs';
4
4
  import { type TMagicTable } from '@tmagic/design';
5
5
  import type { FormState } from '@tmagic/form-schema';
6
6
 
7
- import { sortArray } from '../utils/form';
7
+ import { sortArray } from '../../utils/form';
8
8
 
9
9
  import type { TableProps } from './type';
10
10
 
@@ -5,9 +5,9 @@ import { cloneDeep } from 'lodash-es';
5
5
  import { type TableColumnOptions, TMagicIcon, TMagicTooltip } from '@tmagic/design';
6
6
  import type { FormItemConfig, FormState, TableColumnConfig } from '@tmagic/form-schema';
7
7
 
8
- import Container from '../containers/Container.vue';
9
- import type { ContainerChangeEventData } from '../schema';
10
- import { display as displayFunc, getDataByPage, sortArray } from '../utils/form';
8
+ import type { ContainerChangeEventData } from '../../schema';
9
+ import { display as displayFunc, getDataByPage, sortArray } from '../../utils/form';
10
+ import Container from '../Container.vue';
11
11
 
12
12
  import ActionsColumn from './ActionsColumn.vue';
13
13
  import SortColumn from './SortColumn.vue';
@@ -187,7 +187,7 @@ export const useTableColumns = (
187
187
  columns.push({
188
188
  props: {
189
189
  prop: column.name,
190
- label: column.label,
190
+ label: column.label || column.text,
191
191
  width: column.width,
192
192
  sortable: column.sortable,
193
193
  sortOrders: ['ascending', 'descending'],
@@ -223,7 +223,10 @@ export const useTableColumns = (
223
223
  gap: '5px',
224
224
  },
225
225
  },
226
- [h('span', column.label), h(TMagicIcon, {}, { default: () => h(WarningFilled) })],
226
+ [
227
+ h('span', column.label || column.text),
228
+ h(TMagicIcon, {}, { default: () => h(WarningFilled) }),
229
+ ],
227
230
  ),
228
231
  content: () =>
229
232
  h('div', {
@@ -0,0 +1,173 @@
1
+ <template>
2
+ <component
3
+ :is="displayMode === 'table' ? MFormTable : MFormGroupList"
4
+ ref="tableGroupList"
5
+ v-bind="$attrs"
6
+ :model="model"
7
+ :name="`${name}`"
8
+ :config="currentConfig"
9
+ :disabled="disabled"
10
+ :size="size"
11
+ :is-compare="isCompare"
12
+ :last-values="lastValues"
13
+ :prop="prop"
14
+ :label-width="labelWidth"
15
+ :show-index="showIndex"
16
+ :sort-key="sortKey"
17
+ :sort="sort"
18
+ @change="onChange"
19
+ @select="onSelect"
20
+ @addDiffCount="onAddDiffCount"
21
+ @add="onAdd"
22
+ >
23
+ <template #toggle-button>
24
+ <TMagicButton
25
+ v-if="config.enableToggleMode || enableToggleMode"
26
+ :icon="Grid"
27
+ size="small"
28
+ @click="toggleDisplayMode"
29
+ >
30
+ {{ displayMode === 'table' ? '展开配置' : '切换为表格' }}
31
+ </TMagicButton>
32
+ </template>
33
+
34
+ <template #add-button v-if="addable">
35
+ <TMagicButton
36
+ :class="displayMode === 'table' ? 'm-form-table-add-button' : ''"
37
+ :size="addButtonSize"
38
+ :plain="displayMode === 'table'"
39
+ :icon="Plus"
40
+ :disabled="disabled"
41
+ v-bind="currentConfig.addButtonConfig?.props || { type: 'primary' }"
42
+ @click="newHandler"
43
+ >
44
+ {{ currentConfig.addButtonConfig?.text || (displayMode === 'table' ? '新增一行' : '新增') }}
45
+ </TMagicButton>
46
+ </template>
47
+ </component>
48
+ </template>
49
+
50
+ <script setup lang="ts">
51
+ import { computed, ref, useTemplateRef } from 'vue';
52
+ import { Grid, Plus } from '@element-plus/icons-vue';
53
+
54
+ import { TMagicButton } from '@tmagic/design';
55
+ import type { GroupListConfig, TableConfig } from '@tmagic/form-schema';
56
+
57
+ import type { ContainerChangeEventData } from '../../schema';
58
+ import MFormGroupList from '../GroupList.vue';
59
+ import MFormTable from '../table/Table.vue';
60
+
61
+ import { useAdd } from './useAdd';
62
+
63
+ defineOptions({
64
+ name: 'MFormTableGroupList',
65
+ inheritAttrs: false,
66
+ });
67
+
68
+ const props = defineProps<{
69
+ model: any;
70
+ lastValues?: any;
71
+ isCompare?: boolean;
72
+ config: TableConfig | GroupListConfig;
73
+ name: string;
74
+ prop?: string;
75
+ labelWidth?: string;
76
+ disabled?: boolean;
77
+ size?: string;
78
+ enableToggleMode?: true;
79
+ showIndex?: boolean;
80
+ sortKey?: string;
81
+ sort?: boolean;
82
+ }>();
83
+
84
+ const emit = defineEmits(['change', 'select', 'addDiffCount']);
85
+
86
+ const { addable, newHandler } = useAdd(props, emit);
87
+
88
+ const isGroupListType = (type: string | undefined) => type === 'groupList' || type === 'group-list';
89
+
90
+ const displayMode = ref<'table' | 'groupList'>(isGroupListType(props.config.type) ? 'groupList' : 'table');
91
+
92
+ const calcLabelWidth = (label: string) => {
93
+ if (!label) return '0px';
94
+ const zhLength = label.match(/[^\x00-\xff]/g)?.length || 0;
95
+ const chLength = label.length - zhLength;
96
+ return `${Math.max(chLength * 8 + zhLength * 20, 80)}px`;
97
+ };
98
+
99
+ // 当原始 config 是 table 形态时,table 模式直接透传;
100
+ // 若原始是 groupList,则基于它派生出 table 所需的 config
101
+ const tableConfig = computed<TableConfig>(() => {
102
+ if (!isGroupListType(props.config.type)) {
103
+ return props.config as TableConfig;
104
+ }
105
+
106
+ const source = props.config as GroupListConfig;
107
+ return {
108
+ ...props.config,
109
+ type: 'table',
110
+ groupItems: source.items,
111
+ items:
112
+ source.tableItems ||
113
+ (source.items as any[]).map((item: any) => ({
114
+ ...item,
115
+ label: item.label || item.text,
116
+ text: null,
117
+ })),
118
+ } as any as TableConfig;
119
+ });
120
+
121
+ // 反向派生 groupList 所需的 config
122
+ const groupListConfig = computed<GroupListConfig>(() => {
123
+ if (isGroupListType(props.config.type)) {
124
+ return props.config as GroupListConfig;
125
+ }
126
+
127
+ const source = props.config as TableConfig;
128
+ return {
129
+ ...props.config,
130
+ type: 'groupList',
131
+ tableItems: source.items,
132
+ items:
133
+ source.groupItems ||
134
+ (source.items as any[]).map((item: any) => {
135
+ const text = item.text || item.label;
136
+ return {
137
+ ...item,
138
+ text,
139
+ labelWidth: calcLabelWidth(text),
140
+ span: item.span || 12,
141
+ };
142
+ }),
143
+ } as any as GroupListConfig;
144
+ });
145
+
146
+ // 运行时类型由 displayMode 决定,`<component :is>` 无法做联合类型收窄,统一转 any 交给子组件处理
147
+ const currentConfig = computed<any>(() => (displayMode.value === 'table' ? tableConfig.value : groupListConfig.value));
148
+
149
+ // 保持原 Table/GroupList 模式下新增按钮的不同尺寸策略
150
+ const addButtonSize = computed(() => {
151
+ if (displayMode.value === 'table') return 'small';
152
+ return props.config.enableToggleMode !== false ? 'small' : 'default';
153
+ });
154
+
155
+ const toggleDisplayMode = () => {
156
+ displayMode.value = displayMode.value === 'table' ? 'groupList' : 'table';
157
+ };
158
+
159
+ const onChange = (v: any, eventData?: ContainerChangeEventData) => emit('change', v, eventData);
160
+ const onSelect = (...args: any[]) => emit('select', ...args);
161
+ const onAddDiffCount = () => emit('addDiffCount');
162
+ const onAdd = (rows: any[]) => {
163
+ rows.forEach((row: any) => {
164
+ newHandler(row);
165
+ });
166
+ };
167
+
168
+ const tableGroupListRef = useTemplateRef<InstanceType<typeof MFormTable>>('tableGroupList');
169
+
170
+ defineExpose({
171
+ toggleRowSelection: (row: any, selected: boolean) => tableGroupListRef.value?.toggleRowSelection?.(row, selected),
172
+ });
173
+ </script>
@@ -1,30 +1,40 @@
1
1
  import { computed, inject } from 'vue';
2
2
 
3
3
  import { tMagicMessage } from '@tmagic/design';
4
- import type { FormConfig, FormState } from '@tmagic/form-schema';
4
+ import type { FormConfig, FormState, TableConfig, TableGroupListCommonConfig } from '@tmagic/form-schema';
5
5
 
6
- import { initValue } from '../utils/form';
7
-
8
- import type { TableProps } from './type';
6
+ import { initValue } from '../../utils/form';
7
+ import type { TableProps } from '../table/type';
9
8
 
10
9
  export const useAdd = (
11
- props: TableProps,
12
- emit: (event: 'select' | 'change' | 'addDiffCount', ...args: any[]) => void,
10
+ props: Pick<TableProps, 'name' | 'model' | 'prop' | 'sortKey'> & {
11
+ config: Pick<TableGroupListCommonConfig, 'addable' | 'max' | 'beforeAddRow' | 'defaultAdd' | 'enum'> &
12
+ Pick<TableConfig, 'key' | 'name'> & {
13
+ items: { name?: string | number }[];
14
+ };
15
+ },
16
+ emit: (event: 'change', ...args: any[]) => void,
13
17
  ) => {
14
18
  const mForm = inject<FormState | undefined>('mForm');
15
19
 
16
20
  const addable = computed(() => {
17
21
  const modelName = props.name || props.config.name || '';
22
+
23
+ if (!modelName) return false;
24
+
18
25
  if (!props.model[modelName].length) {
19
26
  return true;
20
27
  }
28
+
21
29
  if (typeof props.config.addable === 'function') {
22
30
  return props.config.addable(mForm, {
23
31
  model: props.model[modelName],
24
32
  formValue: mForm?.values,
25
33
  prop: props.prop,
34
+ config: props.config,
26
35
  });
27
36
  }
37
+
28
38
  return typeof props.config.addable === 'undefined' ? true : props.config.addable;
29
39
  });
30
40
 
@@ -37,7 +47,7 @@ export const useAdd = (
37
47
  }
38
48
 
39
49
  if (typeof props.config.beforeAddRow === 'function') {
40
- const beforeCheckRes = props.config.beforeAddRow(mForm, {
50
+ const beforeCheckRes = await props.config.beforeAddRow(mForm, {
41
51
  model: props.model[modelName],
42
52
  formValue: mForm?.values,
43
53
  prop: props.prop,
package/src/index.ts CHANGED
@@ -32,8 +32,9 @@ export { default as MFlexLayout } from './containers/FlexLayout.vue';
32
32
  export { default as MPanel } from './containers/Panel.vue';
33
33
  export { default as MRow } from './containers/Row.vue';
34
34
  export { default as MTabs } from './containers/Tabs.vue';
35
- export { default as MTable } from './table/Table.vue';
36
- export { default as MGroupList } from './containers/GroupList.vue';
35
+ export { default as MTable } from './containers/table-group-list/TableGroupList.vue';
36
+ export { default as MGroupList } from './containers/table-group-list/TableGroupList.vue';
37
+ export { default as MTableGroupList } from './containers/table-group-list/TableGroupList.vue';
37
38
  export { default as MText } from './fields/Text.vue';
38
39
  export { default as MNumber } from './fields/Number.vue';
39
40
  export { default as MNumberRange } from './fields/NumberRange.vue';