@tmagic/form 1.5.0-beta.9 → 1.5.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.
- package/dist/{style.css → tmagic-form.css} +53 -2
- package/dist/tmagic-form.js +295 -181
- package/dist/tmagic-form.umd.cjs +294 -181
- package/package.json +10 -8
- package/src/Form.vue +29 -8
- package/src/FormBox.vue +11 -5
- package/src/FormDialog.vue +6 -4
- package/src/FormDrawer.vue +6 -4
- package/src/containers/Col.vue +6 -3
- package/src/containers/Container.vue +92 -34
- package/src/containers/Fieldset.vue +13 -12
- package/src/containers/GroupList.vue +26 -10
- package/src/containers/GroupListItem.vue +4 -2
- package/src/containers/Panel.vue +8 -3
- package/src/containers/Row.vue +8 -3
- package/src/containers/Step.vue +9 -4
- package/src/containers/Table.vue +32 -32
- package/src/containers/Tabs.vue +35 -20
- package/src/fields/DateTime.vue +2 -2
- package/src/fields/DynamicField.vue +4 -2
- package/src/fields/Text.vue +71 -36
- package/src/index.ts +3 -2
- package/src/schema.ts +30 -16
- package/src/theme/form.scss +2 -2
- package/src/theme/text.scss +56 -0
- package/types/index.d.ts +433 -657
|
@@ -48,7 +48,7 @@ import { CaretBottom, CaretRight, CaretTop, Delete } from '@element-plus/icons-v
|
|
|
48
48
|
|
|
49
49
|
import { TMagicButton, TMagicIcon } from '@tmagic/design';
|
|
50
50
|
|
|
51
|
-
import { FormState, GroupListConfig } from '../schema';
|
|
51
|
+
import type { ContainerChangeEventData, FormState, GroupListConfig } from '../schema';
|
|
52
52
|
import { filterFunction } from '../utils/form';
|
|
53
53
|
|
|
54
54
|
import Container from './Container.vue';
|
|
@@ -103,7 +103,9 @@ const itemExtra = computed(() => filterFunction(mForm, props.config.itemExtra, p
|
|
|
103
103
|
|
|
104
104
|
const removeHandler = () => emit('remove-item', props.index);
|
|
105
105
|
|
|
106
|
-
const changeHandler = () =>
|
|
106
|
+
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
|
|
107
|
+
emit('change', props.model, eventData);
|
|
108
|
+
};
|
|
107
109
|
|
|
108
110
|
const expandHandler = () => {
|
|
109
111
|
expand.value = !expand.value;
|
package/src/containers/Panel.vue
CHANGED
|
@@ -63,7 +63,7 @@ import { CaretBottom, CaretRight } from '@element-plus/icons-vue';
|
|
|
63
63
|
|
|
64
64
|
import { TMagicButton, TMagicCard } from '@tmagic/design';
|
|
65
65
|
|
|
66
|
-
import { FormState, PanelConfig } from '../schema';
|
|
66
|
+
import type { ContainerChangeEventData, FormState, PanelConfig } from '../schema';
|
|
67
67
|
import { filterFunction } from '../utils/form';
|
|
68
68
|
|
|
69
69
|
import Container from './Container.vue';
|
|
@@ -84,7 +84,10 @@ const props = defineProps<{
|
|
|
84
84
|
disabled?: boolean;
|
|
85
85
|
}>();
|
|
86
86
|
|
|
87
|
-
const emit = defineEmits
|
|
87
|
+
const emit = defineEmits<{
|
|
88
|
+
change: [v: any, eventData: ContainerChangeEventData];
|
|
89
|
+
addDiffCount: [];
|
|
90
|
+
}>();
|
|
88
91
|
|
|
89
92
|
const mForm = inject<FormState | undefined>('mForm');
|
|
90
93
|
|
|
@@ -94,6 +97,8 @@ const items = computed(() => props.config.items);
|
|
|
94
97
|
|
|
95
98
|
const filter = (config: any) => filterFunction(mForm, config, props);
|
|
96
99
|
|
|
97
|
-
const changeHandler = () =>
|
|
100
|
+
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
|
|
101
|
+
emit('change', props.model, eventData);
|
|
102
|
+
};
|
|
98
103
|
const onAddDiffCount = () => emit('addDiffCount');
|
|
99
104
|
</script>
|
package/src/containers/Row.vue
CHANGED
|
@@ -24,7 +24,7 @@ import { inject } from 'vue';
|
|
|
24
24
|
|
|
25
25
|
import { TMagicRow } from '@tmagic/design';
|
|
26
26
|
|
|
27
|
-
import { FormState, RowConfig } from '../schema';
|
|
27
|
+
import type { ContainerChangeEventData, FormState, RowConfig } from '../schema';
|
|
28
28
|
|
|
29
29
|
import Col from './Col.vue';
|
|
30
30
|
|
|
@@ -45,10 +45,15 @@ const props = defineProps<{
|
|
|
45
45
|
disabled?: boolean;
|
|
46
46
|
}>();
|
|
47
47
|
|
|
48
|
-
const emit = defineEmits
|
|
48
|
+
const emit = defineEmits<{
|
|
49
|
+
change: [v: any, eventData: ContainerChangeEventData];
|
|
50
|
+
addDiffCount: [];
|
|
51
|
+
}>();
|
|
49
52
|
|
|
50
53
|
const mForm = inject<FormState | undefined>('mForm');
|
|
51
54
|
|
|
52
|
-
const changeHandler = (
|
|
55
|
+
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
|
|
56
|
+
emit('change', props.name ? props.model[props.name] : props.model, eventData);
|
|
57
|
+
};
|
|
53
58
|
const onAddDiffCount = () => emit('addDiffCount');
|
|
54
59
|
</script>
|
package/src/containers/Step.vue
CHANGED
|
@@ -37,7 +37,7 @@ import { inject, ref, watchEffect } from 'vue';
|
|
|
37
37
|
|
|
38
38
|
import { TMagicStep, TMagicSteps } from '@tmagic/design';
|
|
39
39
|
|
|
40
|
-
import { FormState, StepConfig } from '../schema';
|
|
40
|
+
import type { ContainerChangeEventData, FormState, StepConfig } from '../schema';
|
|
41
41
|
|
|
42
42
|
import Container from './Container.vue';
|
|
43
43
|
|
|
@@ -48,6 +48,7 @@ defineOptions({
|
|
|
48
48
|
const props = withDefaults(
|
|
49
49
|
defineProps<{
|
|
50
50
|
model: any;
|
|
51
|
+
name?: string;
|
|
51
52
|
lastValues?: any;
|
|
52
53
|
isCompare?: boolean;
|
|
53
54
|
config: StepConfig;
|
|
@@ -61,7 +62,10 @@ const props = withDefaults(
|
|
|
61
62
|
},
|
|
62
63
|
);
|
|
63
64
|
|
|
64
|
-
const emit = defineEmits
|
|
65
|
+
const emit = defineEmits<{
|
|
66
|
+
change: [v: any, eventData: ContainerChangeEventData];
|
|
67
|
+
addDiffCount: [];
|
|
68
|
+
}>();
|
|
65
69
|
|
|
66
70
|
const mForm = inject<FormState | undefined>('mForm');
|
|
67
71
|
const active = ref(1);
|
|
@@ -75,8 +79,9 @@ const stepClick = (index: number) => {
|
|
|
75
79
|
mForm?.$emit('update:stepActive', active.value);
|
|
76
80
|
};
|
|
77
81
|
|
|
78
|
-
const changeHandler = () => {
|
|
79
|
-
emit('change', props.model);
|
|
82
|
+
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
|
|
83
|
+
emit('change', props.model, eventData);
|
|
80
84
|
};
|
|
85
|
+
|
|
81
86
|
const onAddDiffCount = () => emit('addDiffCount');
|
|
82
87
|
</script>
|
package/src/containers/Table.vue
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
@select="selectHandle"
|
|
19
19
|
@sort-change="sortChange"
|
|
20
20
|
>
|
|
21
|
-
<TMagicTableColumn v-if="config.itemExtra" :fixed="'left'" width="30" type="expand">
|
|
21
|
+
<TMagicTableColumn v-if="config.itemExtra && !config.dropSort" :fixed="'left'" width="30" type="expand">
|
|
22
22
|
<template v-slot="scope">
|
|
23
23
|
<span v-html="itemExtra(config.itemExtra, scope.$index)" class="m-form-tip"></span>
|
|
24
24
|
</template>
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
:lastValues="lastData[scope.$index]"
|
|
114
114
|
:is-compare="isCompare"
|
|
115
115
|
:size="size"
|
|
116
|
-
@change="
|
|
116
|
+
@change="changeHandler"
|
|
117
117
|
@addDiffCount="onAddDiffCount()"
|
|
118
118
|
></Container>
|
|
119
119
|
</template>
|
|
@@ -204,9 +204,9 @@ import {
|
|
|
204
204
|
TMagicUpload,
|
|
205
205
|
useZIndex,
|
|
206
206
|
} from '@tmagic/design';
|
|
207
|
-
import { asyncLoadJs
|
|
207
|
+
import { asyncLoadJs } from '@tmagic/utils';
|
|
208
208
|
|
|
209
|
-
import { FormState, SortProp, TableColumnConfig, TableConfig } from '../schema';
|
|
209
|
+
import type { ContainerChangeEventData, FormState, SortProp, TableColumnConfig, TableConfig } from '../schema';
|
|
210
210
|
import { display as displayFunc, initValue } from '../utils/form';
|
|
211
211
|
|
|
212
212
|
import Container from './Container.vue';
|
|
@@ -286,11 +286,6 @@ const sortChange = ({ prop, order }: SortProp) => {
|
|
|
286
286
|
}
|
|
287
287
|
};
|
|
288
288
|
|
|
289
|
-
const foreUpdate = () => {
|
|
290
|
-
updateKey.value += 1;
|
|
291
|
-
setTimeout(() => rowDrop());
|
|
292
|
-
};
|
|
293
|
-
|
|
294
289
|
const swapArray = (index1: number, index2: number) => {
|
|
295
290
|
props.model[modelName.value].splice(index1, 0, props.model[modelName.value].splice(index2, 1)[0]);
|
|
296
291
|
|
|
@@ -302,32 +297,25 @@ const swapArray = (index1: number, index2: number) => {
|
|
|
302
297
|
mForm?.$emit('field-change', props.prop, props.model[modelName.value]);
|
|
303
298
|
};
|
|
304
299
|
|
|
300
|
+
let sortable: Sortable | undefined;
|
|
305
301
|
const rowDrop = () => {
|
|
302
|
+
sortable?.destroy();
|
|
306
303
|
const tableEl = tMagicTable.value?.instance.$el;
|
|
307
304
|
const tBodyEl = tableEl?.querySelector('.el-table__body > tbody');
|
|
308
|
-
if (tBodyEl) {
|
|
309
|
-
|
|
310
|
-
const sortable = Sortable.create(tBodyEl, {
|
|
311
|
-
onEnd: ({ newIndex, oldIndex }: SortableEvent) => {
|
|
312
|
-
if (typeof newIndex === 'undefined') return;
|
|
313
|
-
if (typeof oldIndex === 'undefined') return;
|
|
314
|
-
swapArray(newIndex, oldIndex);
|
|
315
|
-
emit('change', props.model[modelName.value]);
|
|
316
|
-
foreUpdate();
|
|
317
|
-
sortable.destroy();
|
|
318
|
-
mForm?.$emit('field-change', props.prop, props.model[modelName.value]);
|
|
319
|
-
sleep(1000).then(() => {
|
|
320
|
-
const elTrs = tableEl.querySelectorAll('.el-table__body > tbody > tr');
|
|
321
|
-
if (elTrs?.[newIndex]) {
|
|
322
|
-
elTrs[newIndex].style.backgroundColor = 'rgba(243, 89, 59, 0.2)';
|
|
323
|
-
sleep(1000).then(() => {
|
|
324
|
-
elTrs[newIndex].style.backgroundColor = '';
|
|
325
|
-
});
|
|
326
|
-
}
|
|
327
|
-
});
|
|
328
|
-
},
|
|
329
|
-
});
|
|
305
|
+
if (!tBodyEl) {
|
|
306
|
+
return;
|
|
330
307
|
}
|
|
308
|
+
sortable = Sortable.create(tBodyEl, {
|
|
309
|
+
draggable: '.tmagic-design-table-row',
|
|
310
|
+
direction: 'vertical',
|
|
311
|
+
onEnd: ({ newIndex, oldIndex }: SortableEvent) => {
|
|
312
|
+
if (typeof newIndex === 'undefined') return;
|
|
313
|
+
if (typeof oldIndex === 'undefined') return;
|
|
314
|
+
swapArray(newIndex, oldIndex);
|
|
315
|
+
emit('change', props.model[modelName.value]);
|
|
316
|
+
mForm?.$emit('field-change', props.prop, props.model[modelName.value]);
|
|
317
|
+
},
|
|
318
|
+
});
|
|
331
319
|
};
|
|
332
320
|
|
|
333
321
|
const newHandler = async (row?: any) => {
|
|
@@ -395,7 +383,15 @@ const newHandler = async (row?: any) => {
|
|
|
395
383
|
}
|
|
396
384
|
|
|
397
385
|
props.model[modelName.value].push(inputs);
|
|
398
|
-
|
|
386
|
+
|
|
387
|
+
emit('change', props.model[modelName.value], {
|
|
388
|
+
changeRecords: [
|
|
389
|
+
{
|
|
390
|
+
propPath: `${props.prop}.${props.model[modelName.value].length - 1}`,
|
|
391
|
+
value: inputs,
|
|
392
|
+
},
|
|
393
|
+
],
|
|
394
|
+
});
|
|
399
395
|
};
|
|
400
396
|
|
|
401
397
|
onMounted(() => {
|
|
@@ -644,6 +640,10 @@ const getProp = (index: number) => {
|
|
|
644
640
|
|
|
645
641
|
const onAddDiffCount = () => emit('addDiffCount');
|
|
646
642
|
|
|
643
|
+
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
|
|
644
|
+
emit('change', props.model, eventData);
|
|
645
|
+
};
|
|
646
|
+
|
|
647
647
|
defineExpose({
|
|
648
648
|
toggleRowSelection,
|
|
649
649
|
});
|
package/src/containers/Tabs.vue
CHANGED
|
@@ -71,12 +71,12 @@
|
|
|
71
71
|
|
|
72
72
|
<script setup lang="ts">
|
|
73
73
|
import { computed, inject, ref, watchEffect } from 'vue';
|
|
74
|
-
import {
|
|
74
|
+
import { isEmpty } from 'lodash-es';
|
|
75
75
|
|
|
76
76
|
import { getDesignConfig, TMagicBadge } from '@tmagic/design';
|
|
77
77
|
|
|
78
|
-
import { FormState, TabConfig, TabPaneConfig } from '../schema';
|
|
79
|
-
import { display as displayFunc, filterFunction } from '../utils/form';
|
|
78
|
+
import type { ContainerChangeEventData, FormState, TabConfig, TabPaneConfig } from '../schema';
|
|
79
|
+
import { display as displayFunc, filterFunction, initValue } from '../utils/form';
|
|
80
80
|
|
|
81
81
|
import Container from './Container.vue';
|
|
82
82
|
|
|
@@ -137,7 +137,10 @@ const props = withDefaults(
|
|
|
137
137
|
},
|
|
138
138
|
);
|
|
139
139
|
|
|
140
|
-
const emit = defineEmits
|
|
140
|
+
const emit = defineEmits<{
|
|
141
|
+
change: [v: any, eventData?: ContainerChangeEventData];
|
|
142
|
+
addDiffCount: [];
|
|
143
|
+
}>();
|
|
141
144
|
|
|
142
145
|
const mForm = inject<FormState | undefined>('mForm');
|
|
143
146
|
const activeTabName = ref(getActive(mForm, props, ''));
|
|
@@ -166,8 +169,8 @@ const tabItems = (tab: TabPaneConfig) => (props.config.dynamic ? props.config.it
|
|
|
166
169
|
|
|
167
170
|
const tabClickHandler = (tab: any) => tabClick(mForm, tab, props);
|
|
168
171
|
|
|
169
|
-
const onTabAdd = () => {
|
|
170
|
-
if (!props.
|
|
172
|
+
const onTabAdd = async () => {
|
|
173
|
+
if (!props.name) throw new Error('dynamic tab 必须配置name');
|
|
171
174
|
|
|
172
175
|
if (typeof props.config.onTabAdd === 'function') {
|
|
173
176
|
props.config.onTabAdd(mForm, {
|
|
@@ -175,17 +178,32 @@ const onTabAdd = () => {
|
|
|
175
178
|
prop: props.prop,
|
|
176
179
|
config: props.config,
|
|
177
180
|
});
|
|
178
|
-
|
|
179
|
-
|
|
181
|
+
emit('change', props.model);
|
|
182
|
+
} else {
|
|
183
|
+
const newObj = await initValue(mForm, {
|
|
184
|
+
config: props.config.items,
|
|
185
|
+
initValues: {},
|
|
186
|
+
});
|
|
187
|
+
|
|
180
188
|
newObj.title = `标签${tabs.value.length + 1}`;
|
|
181
|
-
|
|
189
|
+
|
|
190
|
+
props.model[props.name].push(newObj);
|
|
191
|
+
|
|
192
|
+
emit('change', props.model[props.name], {
|
|
193
|
+
changeRecords: [
|
|
194
|
+
{
|
|
195
|
+
propPath: `${props.prop}.${props.model[props.name].length - 1}`,
|
|
196
|
+
value: newObj,
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
});
|
|
182
200
|
}
|
|
183
|
-
|
|
184
|
-
mForm?.$emit('field-change', props.prop, props.model[props.
|
|
201
|
+
|
|
202
|
+
mForm?.$emit('field-change', props.prop, props.model[props.name]);
|
|
185
203
|
};
|
|
186
204
|
|
|
187
205
|
const onTabRemove = (tabName: string) => {
|
|
188
|
-
if (!props.
|
|
206
|
+
if (!props.name) throw new Error('dynamic tab 必须配置name');
|
|
189
207
|
|
|
190
208
|
if (typeof props.config.onTabRemove === 'function') {
|
|
191
209
|
props.config.onTabRemove(mForm, tabName, {
|
|
@@ -194,23 +212,20 @@ const onTabRemove = (tabName: string) => {
|
|
|
194
212
|
config: props.config,
|
|
195
213
|
});
|
|
196
214
|
} else {
|
|
197
|
-
props.model[props.
|
|
215
|
+
props.model[props.name].splice(+tabName, 1);
|
|
198
216
|
|
|
199
217
|
// 防止删除后没有选中的问题
|
|
200
|
-
if (tabName < activeTabName.value || activeTabName.value >= props.model[props.
|
|
218
|
+
if (tabName < activeTabName.value || activeTabName.value >= props.model[props.name].length) {
|
|
201
219
|
activeTabName.value = (+activeTabName.value - 1).toString();
|
|
202
220
|
tabClick(mForm, { name: activeTabName.value }, props);
|
|
203
221
|
}
|
|
204
222
|
}
|
|
205
223
|
emit('change', props.model);
|
|
206
|
-
mForm?.$emit('field-change', props.prop, props.model[props.
|
|
224
|
+
mForm?.$emit('field-change', props.prop, props.model[props.name]);
|
|
207
225
|
};
|
|
208
226
|
|
|
209
|
-
const changeHandler = () => {
|
|
210
|
-
emit('change', props.model);
|
|
211
|
-
if (typeof props.config.onChange === 'function') {
|
|
212
|
-
props.config.onChange(mForm, { model: props.model, prop: props.prop, config: props.config });
|
|
213
|
-
}
|
|
227
|
+
const changeHandler = (v: any, eventData: ContainerChangeEventData) => {
|
|
228
|
+
emit('change', props.model, eventData);
|
|
214
229
|
};
|
|
215
230
|
|
|
216
231
|
// 在tabs组件中收集事件触发次数,即该tab下的差异数
|
package/src/fields/DateTime.vue
CHANGED
|
@@ -32,9 +32,9 @@ const emit = defineEmits<{
|
|
|
32
32
|
|
|
33
33
|
useAddField(props.prop);
|
|
34
34
|
|
|
35
|
-
const value = props.model?.[props.name]
|
|
35
|
+
const value = props.model?.[props.name]?.toString();
|
|
36
36
|
if (props.model) {
|
|
37
|
-
if (value === 'Invalid Date') {
|
|
37
|
+
if (!value || value === 'Invalid Date') {
|
|
38
38
|
props.model[props.name] = '';
|
|
39
39
|
} else {
|
|
40
40
|
props.model[props.name] = datetimeFormatter(
|
|
@@ -59,7 +59,7 @@ const changeFieldMap = async () => {
|
|
|
59
59
|
let oldVal = props.model?.[v.name] || '';
|
|
60
60
|
if (!oldVal && v.defaultValue !== undefined) {
|
|
61
61
|
oldVal = v.defaultValue;
|
|
62
|
-
emit('change', oldVal, v.name);
|
|
62
|
+
emit('change', oldVal, { modifyKey: v.name });
|
|
63
63
|
}
|
|
64
64
|
fieldMap.value[v.name] = oldVal;
|
|
65
65
|
fieldLabelMap.value[v.name] = v.label || '';
|
|
@@ -85,6 +85,8 @@ onBeforeUnmount(() => {
|
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
const inputChangeHandler = (key: string) => {
|
|
88
|
-
emit('change', fieldMap.value[key],
|
|
88
|
+
emit('change', fieldMap.value[key], {
|
|
89
|
+
modifyKey: key,
|
|
90
|
+
});
|
|
89
91
|
};
|
|
90
92
|
</script>
|
package/src/fields/Text.vue
CHANGED
|
@@ -1,43 +1,48 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
2
|
+
<div style="width: 100%">
|
|
3
|
+
<TMagicInput
|
|
4
|
+
v-model="model[name]"
|
|
5
|
+
ref="input"
|
|
6
|
+
clearable
|
|
7
|
+
:size="size"
|
|
8
|
+
:placeholder="config.placeholder"
|
|
9
|
+
:disabled="disabled"
|
|
10
|
+
@change="changeHandler"
|
|
11
|
+
@input="inputHandler"
|
|
12
|
+
@keyup="keyUpHandler($event)"
|
|
13
|
+
>
|
|
14
|
+
<template #append v-if="appendConfig">
|
|
15
|
+
<TMagicButton
|
|
16
|
+
v-if="appendConfig.type === 'button'"
|
|
17
|
+
style="color: #409eff"
|
|
18
|
+
:size="size"
|
|
19
|
+
@click.prevent="buttonClickHandler"
|
|
20
|
+
>
|
|
21
|
+
{{ appendConfig.text }}
|
|
22
|
+
</TMagicButton>
|
|
23
|
+
</template>
|
|
24
|
+
</TMagicInput>
|
|
25
|
+
|
|
26
|
+
<Teleport to="body">
|
|
27
|
+
<div v-if="popoverVisible" class="tmagic-form-text-popper m-form-item__content" ref="popoverEl">
|
|
28
|
+
<div class="m-form-validate__warning">输入内容前后有空格,是否移除空格?</div>
|
|
29
|
+
<div style="display: flex; justify-content: flex-end">
|
|
30
|
+
<TMagicButton link size="small" @click="popoverVisible = false">保持原样</TMagicButton>
|
|
31
|
+
<TMagicButton type="primary" size="small" @click="confirmTrimHandler">移除空格</TMagicButton>
|
|
32
|
+
</div>
|
|
33
|
+
<span class="tmagic-form-text-popper-arrow" data-popper-arrow></span>
|
|
32
34
|
</div>
|
|
33
|
-
</
|
|
34
|
-
</
|
|
35
|
+
</Teleport>
|
|
36
|
+
</div>
|
|
35
37
|
</template>
|
|
36
38
|
|
|
37
39
|
<script lang="ts" setup>
|
|
38
|
-
import { computed, inject, ref } from 'vue';
|
|
40
|
+
import { computed, inject, ref, shallowRef, watch } from 'vue';
|
|
41
|
+
import type { Instance } from '@popperjs/core';
|
|
42
|
+
import { createPopper } from '@popperjs/core';
|
|
43
|
+
import { debounce } from 'lodash-es';
|
|
39
44
|
|
|
40
|
-
import { TMagicButton, TMagicInput
|
|
45
|
+
import { TMagicButton, TMagicInput } from '@tmagic/design';
|
|
41
46
|
import { isNumber } from '@tmagic/utils';
|
|
42
47
|
|
|
43
48
|
import type { FieldProps, FormState, TextConfig } from '../schema';
|
|
@@ -85,11 +90,11 @@ const confirmTrimHandler = () => {
|
|
|
85
90
|
popoverVisible.value = false;
|
|
86
91
|
};
|
|
87
92
|
|
|
88
|
-
const checkWhiteSpace = (value: unknown) => {
|
|
93
|
+
const checkWhiteSpace = debounce((value: unknown) => {
|
|
89
94
|
if (typeof value === 'string' && !props.config.trim) {
|
|
90
95
|
popoverVisible.value = value.trim() !== value;
|
|
91
96
|
}
|
|
92
|
-
};
|
|
97
|
+
}, 300);
|
|
93
98
|
|
|
94
99
|
const changeHandler = (value: string) => {
|
|
95
100
|
emit('change', value);
|
|
@@ -167,4 +172,34 @@ const keyUpHandler = ($event: KeyboardEvent) => {
|
|
|
167
172
|
props.model[props.name] = `${num}${unit || ''}`;
|
|
168
173
|
emit('change', props.model[props.name]);
|
|
169
174
|
};
|
|
175
|
+
|
|
176
|
+
const popoverEl = ref<HTMLDivElement>();
|
|
177
|
+
const input = ref<InstanceType<typeof TMagicInput>>();
|
|
178
|
+
const instanceRef = shallowRef<Instance | undefined>();
|
|
179
|
+
|
|
180
|
+
watch(popoverEl, (el) => {
|
|
181
|
+
destroyPopover();
|
|
182
|
+
|
|
183
|
+
if (!input.value?.$el || !el) return;
|
|
184
|
+
|
|
185
|
+
instanceRef.value = createPopper(input.value.$el, el, {
|
|
186
|
+
placement: props.config.tooltip ? 'top' : 'bottom',
|
|
187
|
+
strategy: 'absolute',
|
|
188
|
+
modifiers: [
|
|
189
|
+
{
|
|
190
|
+
name: 'offset',
|
|
191
|
+
options: {
|
|
192
|
+
offset: [0, 10],
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const destroyPopover = () => {
|
|
200
|
+
if (!instanceRef.value) return;
|
|
201
|
+
|
|
202
|
+
instanceRef.value.destroy();
|
|
203
|
+
instanceRef.value = undefined;
|
|
204
|
+
};
|
|
170
205
|
</script>
|
package/src/index.ts
CHANGED
|
@@ -98,8 +98,8 @@ export interface FormInstallOptions {
|
|
|
98
98
|
const defaultInstallOpt: FormInstallOptions = {};
|
|
99
99
|
|
|
100
100
|
export default {
|
|
101
|
-
install(app: App, opt
|
|
102
|
-
const option = Object.assign(defaultInstallOpt, opt
|
|
101
|
+
install(app: App, opt: FormInstallOptions = {}) {
|
|
102
|
+
const option = Object.assign(defaultInstallOpt, opt);
|
|
103
103
|
|
|
104
104
|
// eslint-disable-next-line no-param-reassign
|
|
105
105
|
app.config.globalProperties.$MAGIC_FORM = option;
|
|
@@ -116,6 +116,7 @@ export default {
|
|
|
116
116
|
app.component('m-form-table', Table);
|
|
117
117
|
app.component('m-form-tab', Tabs);
|
|
118
118
|
app.component('m-fields-text', Text);
|
|
119
|
+
app.component('m-fields-img-upload', Text);
|
|
119
120
|
app.component('m-fields-number', Number);
|
|
120
121
|
app.component('m-fields-number-range', NumberRange);
|
|
121
122
|
app.component('m-fields-textarea', Textarea);
|
package/src/schema.ts
CHANGED
|
@@ -16,11 +16,23 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
+
import type { TMagicMessage, TMagicMessageBox } from '@tmagic/design';
|
|
20
|
+
|
|
19
21
|
export interface ValidateError {
|
|
20
22
|
message: string;
|
|
21
23
|
field: string;
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
export interface ChangeRecord {
|
|
27
|
+
propPath?: string;
|
|
28
|
+
value: any;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface ContainerChangeEventData {
|
|
32
|
+
modifyKey?: string;
|
|
33
|
+
changeRecords?: ChangeRecord[];
|
|
34
|
+
}
|
|
35
|
+
|
|
24
36
|
export interface FieldProps<T = any> {
|
|
25
37
|
config: T;
|
|
26
38
|
model: any;
|
|
@@ -49,6 +61,8 @@ export type FormState = {
|
|
|
49
61
|
setField: (prop: string, field: any) => void;
|
|
50
62
|
getField: (prop: string) => any;
|
|
51
63
|
deleteField: (prop: string) => any;
|
|
64
|
+
$messageBox: TMagicMessageBox;
|
|
65
|
+
$message: TMagicMessage;
|
|
52
66
|
[key: string]: any;
|
|
53
67
|
};
|
|
54
68
|
|
|
@@ -157,34 +171,34 @@ export interface Input {
|
|
|
157
171
|
export type TypeFunction = (
|
|
158
172
|
mForm: FormState | undefined,
|
|
159
173
|
data: {
|
|
160
|
-
model:
|
|
174
|
+
model: FormValue;
|
|
161
175
|
},
|
|
162
176
|
) => string;
|
|
163
177
|
|
|
164
178
|
export type FilterFunction<T = boolean> = (
|
|
165
179
|
mForm: FormState | undefined,
|
|
166
180
|
data: {
|
|
167
|
-
model:
|
|
168
|
-
values:
|
|
169
|
-
parent?:
|
|
170
|
-
formValue:
|
|
181
|
+
model: FormValue;
|
|
182
|
+
values: FormValue;
|
|
183
|
+
parent?: FormValue;
|
|
184
|
+
formValue: FormValue;
|
|
171
185
|
prop: string;
|
|
172
186
|
config: any;
|
|
173
187
|
index?: number;
|
|
174
188
|
},
|
|
175
189
|
) => T;
|
|
176
190
|
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
) => any;
|
|
191
|
+
export interface OnChangeHandlerData {
|
|
192
|
+
model: FormValue;
|
|
193
|
+
values?: FormValue;
|
|
194
|
+
parent?: FormValue;
|
|
195
|
+
formValue?: FormValue;
|
|
196
|
+
config: any;
|
|
197
|
+
prop: string;
|
|
198
|
+
changeRecords: ChangeRecord[];
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export type OnChangeHandler = (mForm: FormState | undefined, value: any, data: OnChangeHandlerData) => any;
|
|
188
202
|
|
|
189
203
|
type DefaultValueFunction = (mForm: FormState | undefined) => any;
|
|
190
204
|
|
package/src/theme/form.scss
CHANGED
|
@@ -29,13 +29,13 @@
|
|
|
29
29
|
margin-bottom: 10px;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
.el-form-item.hidden {
|
|
32
|
+
.el-form-item.tmagic-form-hidden {
|
|
33
33
|
> .el-form-item__label {
|
|
34
34
|
display: none;
|
|
35
35
|
}
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
.t-form__item.hidden {
|
|
38
|
+
.t-form__item.tmagic-form-hidden {
|
|
39
39
|
> .t-form__label {
|
|
40
40
|
display: none;
|
|
41
41
|
}
|