@tmagic/form 1.3.0-alpha.9 → 1.3.0-beta.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 +21 -0
- package/dist/tmagic-form.js +716 -388
- package/dist/tmagic-form.js.map +1 -1
- package/dist/tmagic-form.umd.cjs +744 -413
- package/dist/tmagic-form.umd.cjs.map +1 -1
- package/package.json +4 -4
- package/src/Form.vue +12 -4
- package/src/FormDialog.vue +19 -5
- package/src/FormDrawer.vue +159 -0
- package/src/containers/Container.vue +11 -10
- package/src/containers/GroupList.vue +1 -0
- package/src/containers/GroupListItem.vue +8 -2
- package/src/containers/Table.vue +148 -150
- package/src/fields/Cascader.vue +2 -12
- package/src/fields/Checkbox.vue +2 -12
- package/src/fields/CheckboxGroup.vue +2 -12
- package/src/fields/ColorPicker.vue +5 -13
- package/src/fields/Date.vue +6 -14
- package/src/fields/DateTime.vue +7 -15
- package/src/fields/Daterange.vue +2 -12
- package/src/fields/Display.vue +2 -10
- package/src/fields/DynamicField.vue +3 -13
- package/src/fields/Hidden.vue +2 -10
- package/src/fields/Link.vue +2 -12
- package/src/fields/Number.vue +7 -14
- package/src/fields/NumberRange.vue +50 -0
- package/src/fields/RadioGroup.vue +2 -12
- package/src/fields/Select.vue +2 -12
- package/src/fields/Switch.vue +6 -14
- package/src/fields/Text.vue +7 -14
- package/src/fields/Textarea.vue +7 -14
- package/src/fields/Time.vue +5 -13
- package/src/fields/Timerange.vue +76 -0
- package/src/index.ts +7 -0
- package/src/schema.ts +23 -2
- package/src/theme/form-drawer.scss +11 -0
- package/src/theme/index.scss +2 -0
- package/src/theme/number-range.scss +8 -0
- package/src/theme/panel.scss +6 -0
- package/src/utils/config.ts +1 -1
- package/src/utils/form.ts +2 -1
- package/types/Form.vue.d.ts +13 -11
- package/types/FormDialog.vue.d.ts +30 -17
- package/types/FormDrawer.vue.d.ts +348 -0
- package/types/fields/Cascader.vue.d.ts +2 -22
- package/types/fields/Checkbox.vue.d.ts +2 -22
- package/types/fields/CheckboxGroup.vue.d.ts +2 -22
- package/types/fields/ColorPicker.vue.d.ts +2 -24
- package/types/fields/Date.vue.d.ts +2 -24
- package/types/fields/DateTime.vue.d.ts +2 -24
- package/types/fields/Daterange.vue.d.ts +2 -22
- package/types/fields/Display.vue.d.ts +2 -18
- package/types/fields/DynamicField.vue.d.ts +2 -22
- package/types/fields/Hidden.vue.d.ts +2 -18
- package/types/fields/Link.vue.d.ts +2 -22
- package/types/fields/Number.vue.d.ts +2 -25
- package/types/fields/NumberRange.vue.d.ts +12 -0
- package/types/fields/RadioGroup.vue.d.ts +2 -22
- package/types/fields/Select.vue.d.ts +2 -22
- package/types/fields/Switch.vue.d.ts +2 -24
- package/types/fields/Text.vue.d.ts +2 -25
- package/types/fields/Textarea.vue.d.ts +2 -25
- package/types/fields/Time.vue.d.ts +2 -24
- package/types/fields/Timerange.vue.d.ts +14 -0
- package/types/index.d.ts +3 -0
- package/types/schema.d.ts +21 -2
- package/types/utils/config.d.ts +1 -1
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.3.0-
|
|
2
|
+
"version": "1.3.0-beta.1",
|
|
3
3
|
"name": "@tmagic/form",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": [
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@element-plus/icons-vue": "^2.0.9",
|
|
39
|
-
"@tmagic/design": "1.3.0-
|
|
40
|
-
"@tmagic/utils": "1.3.0-
|
|
39
|
+
"@tmagic/design": "1.3.0-beta.1",
|
|
40
|
+
"@tmagic/utils": "1.3.0-beta.1",
|
|
41
41
|
"lodash-es": "^4.17.21",
|
|
42
42
|
"sortablejs": "^1.14.0",
|
|
43
43
|
"vue": "^3.3.4"
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"rimraf": "^3.0.2",
|
|
57
57
|
"sass": "^1.35.1",
|
|
58
58
|
"typescript": "^5.0.4",
|
|
59
|
-
"vite": "^4.
|
|
59
|
+
"vite": "^4.4.4",
|
|
60
60
|
"vue-tsc": "^1.6.5"
|
|
61
61
|
}
|
|
62
62
|
}
|
package/src/Form.vue
CHANGED
|
@@ -47,12 +47,12 @@ const props = withDefaults(
|
|
|
47
47
|
/** 表单配置 */
|
|
48
48
|
config: FormConfig;
|
|
49
49
|
/** 表单值 */
|
|
50
|
-
initValues:
|
|
50
|
+
initValues: Record<string, any>;
|
|
51
51
|
/** 需对比的值(开启对比模式时传入) */
|
|
52
|
-
lastValues?:
|
|
52
|
+
lastValues?: Record<string, any>;
|
|
53
53
|
/** 是否开启对比模式 */
|
|
54
54
|
isCompare?: boolean;
|
|
55
|
-
parentValues?:
|
|
55
|
+
parentValues?: Record<string, any>;
|
|
56
56
|
labelWidth?: string;
|
|
57
57
|
disabled?: boolean;
|
|
58
58
|
height?: string;
|
|
@@ -62,6 +62,7 @@ const props = withDefaults(
|
|
|
62
62
|
labelPosition?: string;
|
|
63
63
|
keyProp?: string;
|
|
64
64
|
popperClass?: string;
|
|
65
|
+
extendState?: (state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
|
65
66
|
}>(),
|
|
66
67
|
{
|
|
67
68
|
config: () => [],
|
|
@@ -114,7 +115,7 @@ const formState: FormState = reactive<FormState>({
|
|
|
114
115
|
},
|
|
115
116
|
});
|
|
116
117
|
|
|
117
|
-
watchEffect(() => {
|
|
118
|
+
watchEffect(async () => {
|
|
118
119
|
formState.initValues = props.initValues;
|
|
119
120
|
formState.lastValues = props.lastValues;
|
|
120
121
|
formState.isCompare = props.isCompare;
|
|
@@ -122,6 +123,13 @@ watchEffect(() => {
|
|
|
122
123
|
formState.keyProp = props.keyProp;
|
|
123
124
|
formState.popperClass = props.popperClass;
|
|
124
125
|
formState.parentValues = props.parentValues;
|
|
126
|
+
|
|
127
|
+
if (typeof props.extendState === 'function') {
|
|
128
|
+
const state = (await props.extendState(formState)) || {};
|
|
129
|
+
Object.entries(state).forEach(([key, value]) => {
|
|
130
|
+
formState[key] = value;
|
|
131
|
+
});
|
|
132
|
+
}
|
|
125
133
|
});
|
|
126
134
|
|
|
127
135
|
provide('mForm', formState);
|
package/src/FormDialog.vue
CHANGED
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
:init-values="values"
|
|
26
26
|
:parent-values="parentValues"
|
|
27
27
|
:label-width="labelWidth"
|
|
28
|
+
:label-position="labelPosition"
|
|
29
|
+
:inline="inline"
|
|
28
30
|
@change="changeHandler"
|
|
29
31
|
></Form>
|
|
30
32
|
<slot></slot>
|
|
@@ -46,7 +48,7 @@
|
|
|
46
48
|
<TMagicButton v-if="hasStep && stepCount > stepActive" type="info" size="small" @click="nextStep"
|
|
47
49
|
>下一步</TMagicButton
|
|
48
50
|
>
|
|
49
|
-
<TMagicButton v-else type="primary" size="small" :loading="saveFetch" @click="save">{{
|
|
51
|
+
<TMagicButton v-else type="primary" size="small" :disabled="disabled" :loading="saveFetch" @click="save">{{
|
|
50
52
|
confirmText
|
|
51
53
|
}}</TMagicButton>
|
|
52
54
|
</slot>
|
|
@@ -78,6 +80,8 @@ const props = withDefaults(
|
|
|
78
80
|
fullscreen?: boolean;
|
|
79
81
|
disabled?: boolean;
|
|
80
82
|
title?: string;
|
|
83
|
+
inline?: boolean;
|
|
84
|
+
labelPosition?: string;
|
|
81
85
|
zIndex?: number;
|
|
82
86
|
size?: 'small' | 'default' | 'large';
|
|
83
87
|
confirmText?: string;
|
|
@@ -118,10 +122,6 @@ const hasStep = computed(() => {
|
|
|
118
122
|
return false;
|
|
119
123
|
});
|
|
120
124
|
|
|
121
|
-
const cancel = () => {
|
|
122
|
-
dialogVisible.value = false;
|
|
123
|
-
};
|
|
124
|
-
|
|
125
125
|
const closeHandler = () => {
|
|
126
126
|
stepActive.value = 1;
|
|
127
127
|
emit('close');
|
|
@@ -148,6 +148,18 @@ const changeHandler = (value: any) => {
|
|
|
148
148
|
emit('change', value);
|
|
149
149
|
};
|
|
150
150
|
|
|
151
|
+
const show = () => {
|
|
152
|
+
dialogVisible.value = true;
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const hide = () => {
|
|
156
|
+
dialogVisible.value = false;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
const cancel = () => {
|
|
160
|
+
hide();
|
|
161
|
+
};
|
|
162
|
+
|
|
151
163
|
defineExpose({
|
|
152
164
|
form,
|
|
153
165
|
saveFetch,
|
|
@@ -155,5 +167,7 @@ defineExpose({
|
|
|
155
167
|
|
|
156
168
|
cancel,
|
|
157
169
|
save,
|
|
170
|
+
show,
|
|
171
|
+
hide,
|
|
158
172
|
});
|
|
159
173
|
</script>
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<TMagicDrawer
|
|
3
|
+
class="m-form-drawer"
|
|
4
|
+
ref="drawer"
|
|
5
|
+
v-model="visible"
|
|
6
|
+
:title="title"
|
|
7
|
+
:close-on-press-escape="closeOnPressEscape"
|
|
8
|
+
:append-to-body="true"
|
|
9
|
+
:show-close="true"
|
|
10
|
+
:close-on-click-modal="true"
|
|
11
|
+
:size="width"
|
|
12
|
+
:zIndex="zIndex"
|
|
13
|
+
:before-close="beforeClose"
|
|
14
|
+
@open="openHandler"
|
|
15
|
+
@opened="openedHandler"
|
|
16
|
+
@close="closeHandler"
|
|
17
|
+
@closed="closedHandler"
|
|
18
|
+
>
|
|
19
|
+
<div v-if="visible" ref="drawerBody" class="m-drawer-body">
|
|
20
|
+
<Form
|
|
21
|
+
ref="form"
|
|
22
|
+
:size="size"
|
|
23
|
+
:disabled="disabled"
|
|
24
|
+
:config="config"
|
|
25
|
+
:init-values="values"
|
|
26
|
+
:parent-values="parentValues"
|
|
27
|
+
:label-width="labelWidth"
|
|
28
|
+
:label-position="labelPosition"
|
|
29
|
+
:inline="inline"
|
|
30
|
+
@change="changeHandler"
|
|
31
|
+
></Form>
|
|
32
|
+
<slot></slot>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<template #footer>
|
|
36
|
+
<TMagicRow class="dialog-footer">
|
|
37
|
+
<TMagicCol :span="12" style="text-align: left">
|
|
38
|
+
<div style="min-height: 1px">
|
|
39
|
+
<slot name="left"></slot>
|
|
40
|
+
</div>
|
|
41
|
+
</TMagicCol>
|
|
42
|
+
<TMagicCol :span="12">
|
|
43
|
+
<slot name="footer">
|
|
44
|
+
<TMagicButton @click="handleClose">关闭</TMagicButton>
|
|
45
|
+
<TMagicButton type="primary" :disabled="disabled" :loading="saveFetch" @click="submitHandler">{{
|
|
46
|
+
confirmText
|
|
47
|
+
}}</TMagicButton>
|
|
48
|
+
</slot>
|
|
49
|
+
</TMagicCol>
|
|
50
|
+
</TMagicRow>
|
|
51
|
+
</template>
|
|
52
|
+
</TMagicDrawer>
|
|
53
|
+
</template>
|
|
54
|
+
|
|
55
|
+
<script setup lang="ts">
|
|
56
|
+
import { ref, watchEffect } from 'vue';
|
|
57
|
+
|
|
58
|
+
import { TMagicButton, TMagicCol, TMagicDrawer, TMagicRow } from '@tmagic/design';
|
|
59
|
+
|
|
60
|
+
import Form from './Form.vue';
|
|
61
|
+
import type { FormConfig } from './schema';
|
|
62
|
+
|
|
63
|
+
defineOptions({
|
|
64
|
+
name: 'MFormDialog',
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
withDefaults(
|
|
68
|
+
defineProps<{
|
|
69
|
+
config?: FormConfig;
|
|
70
|
+
values?: Object;
|
|
71
|
+
parentValues?: Object;
|
|
72
|
+
width?: string | number;
|
|
73
|
+
labelWidth?: string;
|
|
74
|
+
disabled?: boolean;
|
|
75
|
+
closeOnPressEscape?: boolean;
|
|
76
|
+
title?: string;
|
|
77
|
+
zIndex?: number;
|
|
78
|
+
size?: 'small' | 'default' | 'large';
|
|
79
|
+
confirmText?: string;
|
|
80
|
+
inline?: boolean;
|
|
81
|
+
labelPosition?: string;
|
|
82
|
+
/** 关闭前的回调,会暂停 Drawer 的关闭; done 是个 function type 接受一个 boolean 参数, 执行 done 使用 true 参数或不提供参数将会终止关闭 */
|
|
83
|
+
beforeClose?: (done: (cancel?: boolean) => void) => void;
|
|
84
|
+
}>(),
|
|
85
|
+
{
|
|
86
|
+
closeOnPressEscape: true,
|
|
87
|
+
config: () => [],
|
|
88
|
+
values: () => ({}),
|
|
89
|
+
confirmText: '确定',
|
|
90
|
+
},
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const emit = defineEmits(['close', 'closed', 'submit', 'error', 'change', 'open', 'opened']);
|
|
94
|
+
|
|
95
|
+
const drawer = ref<InstanceType<typeof TMagicDrawer>>();
|
|
96
|
+
const form = ref<InstanceType<typeof Form>>();
|
|
97
|
+
const drawerBody = ref<HTMLDivElement>();
|
|
98
|
+
const visible = ref(false);
|
|
99
|
+
const saveFetch = ref(false);
|
|
100
|
+
const bodyHeight = ref(0);
|
|
101
|
+
|
|
102
|
+
watchEffect(() => {
|
|
103
|
+
if (drawerBody.value) {
|
|
104
|
+
bodyHeight.value = drawerBody.value.clientHeight;
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
const submitHandler = async () => {
|
|
109
|
+
try {
|
|
110
|
+
const values = await form.value?.submitForm();
|
|
111
|
+
emit('submit', values);
|
|
112
|
+
} catch (e) {
|
|
113
|
+
emit('error', e);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const changeHandler = (value: any) => {
|
|
118
|
+
emit('change', value);
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const openHandler = () => {
|
|
122
|
+
emit('open');
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const openedHandler = () => {
|
|
126
|
+
emit('opened');
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const closeHandler = () => {
|
|
130
|
+
emit('close');
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const closedHandler = () => {
|
|
134
|
+
emit('closed');
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const show = () => {
|
|
138
|
+
visible.value = true;
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const hide = () => {
|
|
142
|
+
visible.value = false;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
/** 用于关闭 Drawer, 该方法会调用传入的 before-close 方法 */
|
|
146
|
+
const handleClose = () => {
|
|
147
|
+
drawer.value?.handleClose();
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
defineExpose({
|
|
151
|
+
form,
|
|
152
|
+
saveFetch,
|
|
153
|
+
bodyHeight,
|
|
154
|
+
|
|
155
|
+
show,
|
|
156
|
+
hide,
|
|
157
|
+
handleClose,
|
|
158
|
+
});
|
|
159
|
+
</script>
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
<div
|
|
3
3
|
v-if="config"
|
|
4
4
|
:style="config.tip ? 'display: flex;align-items: baseline;' : ''"
|
|
5
|
-
:class="config.className"
|
|
6
|
-
class="m-form-container"
|
|
5
|
+
:class="`m-form-container m-container-${type || ''} ${config.className || ''}`"
|
|
7
6
|
>
|
|
8
7
|
<m-fields-hidden
|
|
9
8
|
v-if="type === 'hidden'"
|
|
@@ -15,7 +14,7 @@
|
|
|
15
14
|
></m-fields-hidden>
|
|
16
15
|
|
|
17
16
|
<component
|
|
18
|
-
v-else-if="items && !
|
|
17
|
+
v-else-if="items && !text && type && display"
|
|
19
18
|
:key="key(config)"
|
|
20
19
|
:size="size"
|
|
21
20
|
:is="tagName"
|
|
@@ -36,12 +35,12 @@
|
|
|
36
35
|
<template v-else-if="type && display && !showDiff">
|
|
37
36
|
<TMagicFormItem
|
|
38
37
|
:style="config.tip ? 'flex: 1' : ''"
|
|
39
|
-
:class="{ hidden: `${itemLabelWidth}` === '0' || !
|
|
38
|
+
:class="{ hidden: `${itemLabelWidth}` === '0' || !text }"
|
|
40
39
|
:prop="itemProp"
|
|
41
40
|
:label-width="itemLabelWidth"
|
|
42
41
|
:rules="rule"
|
|
43
42
|
>
|
|
44
|
-
<template #label><span v-html="type === 'checkbox' ? '' :
|
|
43
|
+
<template #label><span v-html="type === 'checkbox' ? '' : text"></span></template>
|
|
45
44
|
<TMagicTooltip v-if="tooltip">
|
|
46
45
|
<component
|
|
47
46
|
:key="key(config)"
|
|
@@ -92,13 +91,13 @@
|
|
|
92
91
|
<!-- 上次内容 -->
|
|
93
92
|
<TMagicFormItem
|
|
94
93
|
:style="config.tip ? 'flex: 1' : ''"
|
|
95
|
-
:class="{ hidden: `${itemLabelWidth}` === '0' || !
|
|
94
|
+
:class="{ hidden: `${itemLabelWidth}` === '0' || !text }"
|
|
96
95
|
:prop="itemProp"
|
|
97
96
|
:label-width="itemLabelWidth"
|
|
98
97
|
:rules="rule"
|
|
99
98
|
style="background: #f7dadd"
|
|
100
99
|
>
|
|
101
|
-
<template #label><span v-html="type === 'checkbox' ? '' :
|
|
100
|
+
<template #label><span v-html="type === 'checkbox' ? '' : text"></span></template>
|
|
102
101
|
<TMagicTooltip v-if="tooltip">
|
|
103
102
|
<component
|
|
104
103
|
:key="key(config)"
|
|
@@ -141,13 +140,13 @@
|
|
|
141
140
|
<!-- 当前内容 -->
|
|
142
141
|
<TMagicFormItem
|
|
143
142
|
:style="config.tip ? 'flex: 1' : ''"
|
|
144
|
-
:class="{ hidden: `${itemLabelWidth}` === '0' || !
|
|
143
|
+
:class="{ hidden: `${itemLabelWidth}` === '0' || !text }"
|
|
145
144
|
:prop="itemProp"
|
|
146
145
|
:label-width="itemLabelWidth"
|
|
147
146
|
:rules="rule"
|
|
148
147
|
style="background: #def7da"
|
|
149
148
|
>
|
|
150
|
-
<template #label><span v-html="type === 'checkbox' ? '' :
|
|
149
|
+
<template #label><span v-html="type === 'checkbox' ? '' : text"></span></template>
|
|
151
150
|
<TMagicTooltip v-if="tooltip">
|
|
152
151
|
<component
|
|
153
152
|
:key="key(config)"
|
|
@@ -295,6 +294,8 @@ const tagName = computed(() => {
|
|
|
295
294
|
|
|
296
295
|
const disabled = computed(() => props.disabled || filterFunction(mForm, props.config.disabled, props));
|
|
297
296
|
|
|
297
|
+
const text = computed(() => filterFunction(mForm, props.config.text, props));
|
|
298
|
+
|
|
298
299
|
const tooltip = computed(() => filterFunction(mForm, props.config.tooltip, props));
|
|
299
300
|
|
|
300
301
|
const extra = computed(() => filterFunction(mForm, props.config.extra, props));
|
|
@@ -332,7 +333,7 @@ watch(
|
|
|
332
333
|
showDiff,
|
|
333
334
|
(showDiff) => {
|
|
334
335
|
if (type.value === 'hidden') return;
|
|
335
|
-
if (items.value && !
|
|
336
|
+
if (items.value && !text.value && type.value && display.value) return;
|
|
336
337
|
if (display.value && showDiff && type.value) {
|
|
337
338
|
emit('addDiffCount');
|
|
338
339
|
}
|
|
@@ -88,7 +88,13 @@ const title = computed(() => {
|
|
|
88
88
|
return props.model[props.config.titleKey];
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
if (props.config.title) {
|
|
92
|
+
return filterFunction(mForm, props.config.title, props);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const titlePrefix = props.config.titlePrefix || '组';
|
|
96
|
+
|
|
97
|
+
return `${titlePrefix} ${String(props.index + 1)}`;
|
|
92
98
|
});
|
|
93
99
|
|
|
94
100
|
const length = computed(() => props.groupModel?.length || 0);
|
|
@@ -113,7 +119,7 @@ const showDelete = (index: number) => {
|
|
|
113
119
|
};
|
|
114
120
|
|
|
115
121
|
// 调换顺序
|
|
116
|
-
const changeOrder = (offset = 0) => emit('swap-item', props.index,
|
|
122
|
+
const changeOrder = (offset = 0) => emit('swap-item', props.index, props.index + offset);
|
|
117
123
|
|
|
118
124
|
const movable = () => {
|
|
119
125
|
const { movable } = props.config;
|