@tmagic/form 1.5.1 → 1.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{tmagic-form.css → style.css} +0 -4
- package/dist/tmagic-form.js +234 -82
- package/dist/tmagic-form.umd.cjs +231 -79
- package/package.json +3 -3
- package/src/containers/Container.vue +8 -10
- package/src/containers/GroupList.vue +9 -1
- package/src/containers/GroupListItem.vue +91 -17
- package/src/containers/Table.vue +40 -7
- package/src/fields/RadioGroup.vue +29 -5
- package/src/schema.ts +6 -0
- package/src/theme/table.scss +0 -5
- package/types/index.d.ts +6 -0
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
:disabled="disabled"
|
|
21
21
|
:group-model="model[name]"
|
|
22
22
|
@remove-item="removeHandler"
|
|
23
|
+
@copy-item="copyHandler"
|
|
23
24
|
@swap-item="swapHandler"
|
|
24
25
|
@change="changeHandler"
|
|
25
26
|
@addDiffCount="onAddDiffCount()"
|
|
@@ -41,6 +42,7 @@
|
|
|
41
42
|
<script setup lang="ts">
|
|
42
43
|
import { computed, inject } from 'vue';
|
|
43
44
|
import { Grid } from '@element-plus/icons-vue';
|
|
45
|
+
import { cloneDeep } from 'lodash-es';
|
|
44
46
|
|
|
45
47
|
import { TMagicButton } from '@tmagic/design';
|
|
46
48
|
|
|
@@ -131,11 +133,17 @@ const removeHandler = (index: number) => {
|
|
|
131
133
|
emit('change', props.model[props.name]);
|
|
132
134
|
};
|
|
133
135
|
|
|
136
|
+
const copyHandler = (index: number) => {
|
|
137
|
+
props.model[props.name].push(cloneDeep(props.model[props.name][index]));
|
|
138
|
+
};
|
|
139
|
+
|
|
134
140
|
const swapHandler = (idx1: number, idx2: number) => {
|
|
135
141
|
if (!props.name) return false;
|
|
136
142
|
|
|
143
|
+
const { length } = props.model[props.name];
|
|
144
|
+
|
|
137
145
|
const [currRow] = props.model[props.name].splice(idx1, 1);
|
|
138
|
-
props.model[props.name].splice(idx2, 0, currRow);
|
|
146
|
+
props.model[props.name].splice(Math.min(Math.max(idx2, 0), length - 1), 0, currRow);
|
|
139
147
|
emit('change', props.model[props.name]);
|
|
140
148
|
};
|
|
141
149
|
|
|
@@ -6,23 +6,83 @@
|
|
|
6
6
|
</TMagicButton>
|
|
7
7
|
|
|
8
8
|
<TMagicButton
|
|
9
|
-
v-show="showDelete
|
|
10
|
-
|
|
9
|
+
v-show="showDelete"
|
|
10
|
+
type="danger"
|
|
11
|
+
size="small"
|
|
11
12
|
link
|
|
12
13
|
:icon="Delete"
|
|
13
14
|
:disabled="disabled"
|
|
14
15
|
@click="removeHandler"
|
|
15
16
|
></TMagicButton>
|
|
16
17
|
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
<TMagicButton
|
|
19
|
+
v-if="copyable"
|
|
20
|
+
link
|
|
21
|
+
size="small"
|
|
22
|
+
type="primary"
|
|
23
|
+
:icon="DocumentCopy"
|
|
24
|
+
:disabled="disabled"
|
|
25
|
+
@click="copyHandler"
|
|
26
|
+
>复制</TMagicButton
|
|
27
|
+
>
|
|
28
|
+
|
|
29
|
+
<template v-if="movable">
|
|
30
|
+
<TMagicButton
|
|
31
|
+
v-show="index !== 0"
|
|
32
|
+
link
|
|
33
|
+
size="small"
|
|
34
|
+
:disabled="disabled"
|
|
35
|
+
:icon="CaretTop"
|
|
36
|
+
@click="changeOrder(-1)"
|
|
37
|
+
>上移</TMagicButton
|
|
38
|
+
>
|
|
39
|
+
<TMagicButton
|
|
40
|
+
v-show="index !== length - 1"
|
|
41
|
+
link
|
|
42
|
+
size="small"
|
|
43
|
+
:disabled="disabled"
|
|
44
|
+
:icon="CaretBottom"
|
|
45
|
+
@click="changeOrder(1)"
|
|
46
|
+
>下移</TMagicButton
|
|
47
|
+
>
|
|
24
48
|
</template>
|
|
25
49
|
|
|
50
|
+
<TMagicPopover
|
|
51
|
+
v-if="config.moveSpecifyLocation"
|
|
52
|
+
trigger="click"
|
|
53
|
+
placement="top"
|
|
54
|
+
width="200"
|
|
55
|
+
:visible="moveSpecifyLocationVisible"
|
|
56
|
+
>
|
|
57
|
+
<template #reference>
|
|
58
|
+
<TMagicButton
|
|
59
|
+
link
|
|
60
|
+
size="small"
|
|
61
|
+
type="primary"
|
|
62
|
+
:icon="Position"
|
|
63
|
+
:disabled="disabled"
|
|
64
|
+
@click="moveSpecifyLocationVisible = true"
|
|
65
|
+
>移动至</TMagicButton
|
|
66
|
+
>
|
|
67
|
+
</template>
|
|
68
|
+
<div>
|
|
69
|
+
<div>
|
|
70
|
+
第<TMagicInputNumber
|
|
71
|
+
style="margin: 0 5px"
|
|
72
|
+
v-model="moveSpecifyLocationIndex"
|
|
73
|
+
size="small"
|
|
74
|
+
:min="1"
|
|
75
|
+
:disabled="disabled"
|
|
76
|
+
></TMagicInputNumber
|
|
77
|
+
>行
|
|
78
|
+
</div>
|
|
79
|
+
<div style="text-align: right; margin-top: 20px">
|
|
80
|
+
<TMagicButton size="small" text @click="moveSpecifyLocationVisible = false">取消</TMagicButton>
|
|
81
|
+
<TMagicButton size="small" type="primary" @click="moveSpecifyLocationHandler">确认</TMagicButton>
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</TMagicPopover>
|
|
85
|
+
|
|
26
86
|
<span v-if="itemExtra" v-html="itemExtra" class="m-form-tip"></span>
|
|
27
87
|
</div>
|
|
28
88
|
|
|
@@ -44,9 +104,9 @@
|
|
|
44
104
|
|
|
45
105
|
<script setup lang="ts">
|
|
46
106
|
import { computed, inject, ref } from 'vue';
|
|
47
|
-
import { CaretBottom, CaretRight, CaretTop, Delete } from '@element-plus/icons-vue';
|
|
107
|
+
import { CaretBottom, CaretRight, CaretTop, Delete, DocumentCopy, Position } from '@element-plus/icons-vue';
|
|
48
108
|
|
|
49
|
-
import { TMagicButton, TMagicIcon } from '@tmagic/design';
|
|
109
|
+
import { TMagicButton, TMagicIcon, TMagicInputNumber, TMagicPopover } from '@tmagic/design';
|
|
50
110
|
|
|
51
111
|
import type { ContainerChangeEventData, FormState, GroupListConfig } from '../schema';
|
|
52
112
|
import { filterFunction } from '../utils/form';
|
|
@@ -70,7 +130,7 @@ const props = defineProps<{
|
|
|
70
130
|
disabled?: boolean;
|
|
71
131
|
}>();
|
|
72
132
|
|
|
73
|
-
const emit = defineEmits(['swap-item', 'remove-item', 'change', 'addDiffCount']);
|
|
133
|
+
const emit = defineEmits(['swap-item', 'remove-item', 'change', 'addDiffCount', 'copy-item']);
|
|
74
134
|
|
|
75
135
|
const mForm = inject<FormState | undefined>('mForm');
|
|
76
136
|
const expand = ref(props.config.expandAll || !props.index);
|
|
@@ -112,18 +172,18 @@ const expandHandler = () => {
|
|
|
112
172
|
};
|
|
113
173
|
|
|
114
174
|
// 希望支持单行可控制是否显示删除按钮,不会影响现有逻辑
|
|
115
|
-
const showDelete = (
|
|
175
|
+
const showDelete = computed(() => {
|
|
116
176
|
const deleteFunc = props.config.delete;
|
|
117
177
|
if (deleteFunc && typeof deleteFunc === 'function') {
|
|
118
|
-
return deleteFunc(props.model, index, mForm?.values);
|
|
178
|
+
return deleteFunc(props.model, props.index, mForm?.values);
|
|
119
179
|
}
|
|
120
180
|
return true;
|
|
121
|
-
};
|
|
181
|
+
});
|
|
122
182
|
|
|
123
183
|
// 调换顺序
|
|
124
184
|
const changeOrder = (offset = 0) => emit('swap-item', props.index, props.index + offset);
|
|
125
185
|
|
|
126
|
-
const movable = () => {
|
|
186
|
+
const movable = computed(() => {
|
|
127
187
|
const { movable } = props.config;
|
|
128
188
|
|
|
129
189
|
// 没有设置时,默认可移动
|
|
@@ -132,6 +192,20 @@ const movable = () => {
|
|
|
132
192
|
return movable(mForm, props.index || 0, props.model, props.groupModel);
|
|
133
193
|
}
|
|
134
194
|
return movable;
|
|
135
|
-
};
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const copyable = computed(() => filterFunction<boolean>(mForm, props.config.copyable, props));
|
|
136
198
|
const onAddDiffCount = () => emit('addDiffCount');
|
|
199
|
+
|
|
200
|
+
const copyHandler = () => {
|
|
201
|
+
emit('copy-item', props.index);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const moveSpecifyLocationVisible = ref(false);
|
|
205
|
+
const moveSpecifyLocationIndex = ref(1);
|
|
206
|
+
|
|
207
|
+
const moveSpecifyLocationHandler = () => {
|
|
208
|
+
moveSpecifyLocationVisible.value = false;
|
|
209
|
+
emit('swap-item', props.index, moveSpecifyLocationIndex.value - 1);
|
|
210
|
+
};
|
|
137
211
|
</script>
|
package/src/containers/Table.vue
CHANGED
|
@@ -26,18 +26,32 @@
|
|
|
26
26
|
|
|
27
27
|
<TMagicTableColumn
|
|
28
28
|
label="操作"
|
|
29
|
-
:width="config.operateColWidth ||
|
|
29
|
+
:width="config.operateColWidth || 100"
|
|
30
30
|
align="center"
|
|
31
31
|
:fixed="config.fixed === false ? undefined : 'left'"
|
|
32
32
|
>
|
|
33
33
|
<template v-slot="scope">
|
|
34
34
|
<slot name="operateCol" :scope="scope"></slot>
|
|
35
|
-
<
|
|
35
|
+
<TMagicButton
|
|
36
36
|
v-show="showDelete(scope.$index + 1 + pagecontext * pagesize - 1)"
|
|
37
|
-
|
|
37
|
+
size="small"
|
|
38
|
+
type="danger"
|
|
39
|
+
link
|
|
40
|
+
title="删除"
|
|
41
|
+
:icon="Delete"
|
|
38
42
|
@click="removeHandler(scope.$index + 1 + pagecontext * pagesize - 1)"
|
|
39
|
-
|
|
40
|
-
|
|
43
|
+
></TMagicButton>
|
|
44
|
+
|
|
45
|
+
<TMagicButton
|
|
46
|
+
v-if="copyable(scope.$index + 1 + pagecontext * pagesize - 1)"
|
|
47
|
+
link
|
|
48
|
+
size="small"
|
|
49
|
+
type="primary"
|
|
50
|
+
title="复制"
|
|
51
|
+
:icon="DocumentCopy"
|
|
52
|
+
:disabled="disabled"
|
|
53
|
+
@click="copyHandler(scope.$index + 1 + pagecontext * pagesize - 1)"
|
|
54
|
+
></TMagicButton>
|
|
41
55
|
</template>
|
|
42
56
|
</TMagicTableColumn>
|
|
43
57
|
|
|
@@ -189,13 +203,12 @@
|
|
|
189
203
|
|
|
190
204
|
<script setup lang="ts">
|
|
191
205
|
import { computed, inject, onMounted, ref, toRefs, watchEffect } from 'vue';
|
|
192
|
-
import { ArrowDown, ArrowUp, Delete, FullScreen, Grid } from '@element-plus/icons-vue';
|
|
206
|
+
import { ArrowDown, ArrowUp, Delete, DocumentCopy, FullScreen, Grid } from '@element-plus/icons-vue';
|
|
193
207
|
import { cloneDeep } from 'lodash-es';
|
|
194
208
|
import Sortable, { SortableEvent } from 'sortablejs';
|
|
195
209
|
|
|
196
210
|
import {
|
|
197
211
|
TMagicButton,
|
|
198
|
-
TMagicIcon,
|
|
199
212
|
tMagicMessage,
|
|
200
213
|
TMagicPagination,
|
|
201
214
|
TMagicTable,
|
|
@@ -550,6 +563,22 @@ const showDelete = (index: number) => {
|
|
|
550
563
|
return true;
|
|
551
564
|
};
|
|
552
565
|
|
|
566
|
+
const copyable = (index: number) => {
|
|
567
|
+
const copyableFunc = props.config.copyable;
|
|
568
|
+
if (copyableFunc && typeof copyableFunc === 'function') {
|
|
569
|
+
return copyableFunc(mForm, {
|
|
570
|
+
values: mForm?.initValues || {},
|
|
571
|
+
model: props.model,
|
|
572
|
+
parent: mForm?.parentValues || {},
|
|
573
|
+
formValue: mForm?.values || props.model,
|
|
574
|
+
prop: props.prop,
|
|
575
|
+
config: props.config,
|
|
576
|
+
index,
|
|
577
|
+
});
|
|
578
|
+
}
|
|
579
|
+
return true;
|
|
580
|
+
};
|
|
581
|
+
|
|
553
582
|
const clearHandler = () => {
|
|
554
583
|
const len = props.model[modelName.value].length;
|
|
555
584
|
props.model[modelName.value].splice(0, len);
|
|
@@ -594,6 +623,10 @@ const handleCurrentChange = (val: number) => {
|
|
|
594
623
|
pagecontext.value = val - 1;
|
|
595
624
|
};
|
|
596
625
|
|
|
626
|
+
const copyHandler = (index: number) => {
|
|
627
|
+
props.model[modelName.value].push(cloneDeep(props.model[modelName.value][index]));
|
|
628
|
+
};
|
|
629
|
+
|
|
597
630
|
const toggleMode = () => {
|
|
598
631
|
const calcLabelWidth = (label: string) => {
|
|
599
632
|
if (!label) return '0px';
|
|
@@ -1,13 +1,30 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<TMagicRadioGroup v-if="model" v-model="model[name]" :size="size" :disabled="disabled"
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
<TMagicRadioGroup v-if="model" v-model="model[name]" :size="size" :disabled="disabled">
|
|
3
|
+
<component
|
|
4
|
+
:is="itemComponent"
|
|
5
|
+
v-for="option in config.options"
|
|
6
|
+
:value="option.value"
|
|
7
|
+
:key="`${option.value}`"
|
|
8
|
+
@click.prevent="clickHandler(option.value)"
|
|
9
|
+
>
|
|
10
|
+
<TMagicTooltip v-if="option.tooltip" placement="top-start" :content="option.tooltip">
|
|
11
|
+
<div>
|
|
12
|
+
<TMagicIcon v-if="option.icon" :size="'16'"><component :is="option.icon"></component></TMagicIcon>
|
|
13
|
+
<span>{{ option.text }}</span>
|
|
14
|
+
</div>
|
|
15
|
+
</TMagicTooltip>
|
|
16
|
+
<div v-else>
|
|
17
|
+
<TMagicIcon v-if="option.icon" :size="'16'"><component :is="option.icon"></component></TMagicIcon>
|
|
18
|
+
<span>{{ option.text }}</span>
|
|
19
|
+
</div>
|
|
20
|
+
</component>
|
|
6
21
|
</TMagicRadioGroup>
|
|
7
22
|
</template>
|
|
8
23
|
|
|
9
24
|
<script lang="ts" setup>
|
|
10
|
-
import {
|
|
25
|
+
import { computed } from 'vue';
|
|
26
|
+
|
|
27
|
+
import { TMagicIcon, TMagicRadio, TMagicRadioButton, TMagicRadioGroup, TMagicTooltip } from '@tmagic/design';
|
|
11
28
|
|
|
12
29
|
import type { FieldProps, RadioGroupConfig } from '../schema';
|
|
13
30
|
import { useAddField } from '../utils/useAddField';
|
|
@@ -18,11 +35,18 @@ defineOptions({
|
|
|
18
35
|
|
|
19
36
|
const props = defineProps<FieldProps<RadioGroupConfig>>();
|
|
20
37
|
|
|
38
|
+
const itemComponent = computed(() => (props.config.childType === 'button' ? TMagicRadioButton : TMagicRadio));
|
|
39
|
+
|
|
21
40
|
const emit = defineEmits(['change']);
|
|
22
41
|
|
|
23
42
|
const changeHandler = (value: number) => {
|
|
24
43
|
emit('change', value);
|
|
25
44
|
};
|
|
26
45
|
|
|
46
|
+
const clickHandler = (item: any) => {
|
|
47
|
+
props.model[props.name] = props.model[props.name] === item ? '' : item;
|
|
48
|
+
changeHandler(props.model[props.name]);
|
|
49
|
+
};
|
|
50
|
+
|
|
27
51
|
useAddField(props.prop);
|
|
28
52
|
</script>
|
package/src/schema.ts
CHANGED
|
@@ -438,9 +438,12 @@ export interface SwitchConfig extends FormItem {
|
|
|
438
438
|
*/
|
|
439
439
|
export interface RadioGroupConfig extends FormItem {
|
|
440
440
|
type: 'radio-group';
|
|
441
|
+
childType?: 'default' | 'button';
|
|
441
442
|
options: {
|
|
442
443
|
value: string | number | boolean;
|
|
443
444
|
text: string;
|
|
445
|
+
icon?: any;
|
|
446
|
+
tooltip?: string;
|
|
444
447
|
}[];
|
|
445
448
|
}
|
|
446
449
|
|
|
@@ -681,6 +684,7 @@ export interface TableConfig extends FormItem {
|
|
|
681
684
|
addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
|
|
682
685
|
/** 是否显示删除按钮 */
|
|
683
686
|
delete?: (model: any, index: number, values: any) => boolean | boolean;
|
|
687
|
+
copyable?: (model: any, data: any) => boolean | boolean;
|
|
684
688
|
/** 是否显示导入按钮 */
|
|
685
689
|
importable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
|
|
686
690
|
/** 是否显示checkbox */
|
|
@@ -715,12 +719,14 @@ export interface GroupListConfig extends FormItem {
|
|
|
715
719
|
addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
|
|
716
720
|
defaultAdd?: (mForm: FormState | undefined, data: any) => any;
|
|
717
721
|
delete?: (model: any, index: number | string | symbol, values: any) => boolean | boolean;
|
|
722
|
+
copyable?: FilterFunction<boolean>;
|
|
718
723
|
movable?: (
|
|
719
724
|
mForm: FormState | undefined,
|
|
720
725
|
index: number | string | symbol,
|
|
721
726
|
model: any,
|
|
722
727
|
groupModel: any,
|
|
723
728
|
) => boolean | boolean;
|
|
729
|
+
moveSpecifyLocation?: boolean;
|
|
724
730
|
[key: string]: any;
|
|
725
731
|
}
|
|
726
732
|
|
package/src/theme/table.scss
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -359,9 +359,12 @@ interface SwitchConfig extends FormItem {
|
|
|
359
359
|
*/
|
|
360
360
|
interface RadioGroupConfig extends FormItem {
|
|
361
361
|
type: 'radio-group';
|
|
362
|
+
childType?: 'default' | 'button';
|
|
362
363
|
options: {
|
|
363
364
|
value: string | number | boolean;
|
|
364
365
|
text: string;
|
|
366
|
+
icon?: any;
|
|
367
|
+
tooltip?: string;
|
|
365
368
|
}[];
|
|
366
369
|
}
|
|
367
370
|
/**
|
|
@@ -571,6 +574,7 @@ interface TableConfig extends FormItem {
|
|
|
571
574
|
addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
|
|
572
575
|
/** 是否显示删除按钮 */
|
|
573
576
|
delete?: (model: any, index: number, values: any) => boolean | boolean;
|
|
577
|
+
copyable?: (model: any, data: any) => boolean | boolean;
|
|
574
578
|
/** 是否显示导入按钮 */
|
|
575
579
|
importable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
|
|
576
580
|
/** 是否显示checkbox */
|
|
@@ -604,7 +608,9 @@ interface GroupListConfig extends FormItem {
|
|
|
604
608
|
addable?: (mForm: FormState | undefined, data: any) => boolean | 'undefined' | boolean;
|
|
605
609
|
defaultAdd?: (mForm: FormState | undefined, data: any) => any;
|
|
606
610
|
delete?: (model: any, index: number | string | symbol, values: any) => boolean | boolean;
|
|
611
|
+
copyable?: FilterFunction<boolean>;
|
|
607
612
|
movable?: (mForm: FormState | undefined, index: number | string | symbol, model: any, groupModel: any) => boolean | boolean;
|
|
613
|
+
moveSpecifyLocation?: boolean;
|
|
608
614
|
[key: string]: any;
|
|
609
615
|
}
|
|
610
616
|
interface StepItemConfig extends FormItem, ContainerCommonConfig {
|