@tmagic/form 1.4.8 → 1.4.10
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 +4 -0
- package/dist/tmagic-form.js +13 -12
- package/dist/tmagic-form.umd.cjs +13 -12
- package/package.json +5 -5
- package/src/Form.vue +201 -0
- package/src/FormBox.vue +120 -0
- package/src/FormDialog.vue +173 -0
- package/src/FormDrawer.vue +159 -0
- package/src/containers/Col.vue +52 -0
- package/src/containers/Container.vue +408 -0
- package/src/containers/Fieldset.vue +124 -0
- package/src/containers/GroupList.vue +139 -0
- package/src/containers/GroupListItem.vue +135 -0
- package/src/containers/Panel.vue +99 -0
- package/src/containers/Row.vue +54 -0
- package/src/containers/Step.vue +82 -0
- package/src/containers/Table.vue +648 -0
- package/src/containers/Tabs.vue +226 -0
- package/src/fields/Cascader.vue +131 -0
- package/src/fields/Checkbox.vue +58 -0
- package/src/fields/CheckboxGroup.vue +44 -0
- package/src/fields/ColorPicker.vue +30 -0
- package/src/fields/Date.vue +38 -0
- package/src/fields/DateTime.vue +47 -0
- package/src/fields/Daterange.vue +99 -0
- package/src/fields/Display.vue +21 -0
- package/src/fields/DynamicField.vue +90 -0
- package/src/fields/Hidden.vue +16 -0
- package/src/fields/Link.vue +86 -0
- package/src/fields/Number.vue +49 -0
- package/src/fields/NumberRange.vue +50 -0
- package/src/fields/RadioGroup.vue +28 -0
- package/src/fields/Select.vue +449 -0
- package/src/fields/Switch.vue +59 -0
- package/src/fields/Text.vue +170 -0
- package/src/fields/Textarea.vue +46 -0
- package/src/fields/Time.vue +34 -0
- package/src/fields/Timerange.vue +76 -0
- package/src/index.ts +139 -0
- package/src/schema.ts +758 -0
- package/src/shims-vue.d.ts +6 -0
- package/src/theme/container.scss +5 -0
- package/src/theme/date-time.scss +7 -0
- package/src/theme/fieldset.scss +28 -0
- package/src/theme/form-box.scss +13 -0
- package/src/theme/form-dialog.scss +13 -0
- package/src/theme/form-drawer.scss +11 -0
- package/src/theme/form.scss +43 -0
- package/src/theme/group-list.scss +23 -0
- package/src/theme/index.scss +15 -0
- package/src/theme/link.scss +3 -0
- package/src/theme/number-range.scss +8 -0
- package/src/theme/panel.scss +24 -0
- package/src/theme/select.scss +3 -0
- package/src/theme/table.scss +70 -0
- package/src/theme/tabs.scss +27 -0
- package/src/theme/text.scss +6 -0
- package/src/utils/config.ts +27 -0
- package/src/utils/containerProps.ts +50 -0
- package/src/utils/form.ts +273 -0
- package/src/utils/useAddField.ts +40 -0
- package/types/schema.d.ts +7 -5
- package/types/utils/form.d.ts +2 -2
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="m-fields-dynamic-field">
|
|
3
|
+
<TMagicForm size="small">
|
|
4
|
+
<TMagicFormItem v-for="key in Object.keys(fieldMap.value)" :key="key" :label="fieldLabelMap.value[key]">
|
|
5
|
+
<TMagicInput
|
|
6
|
+
v-model="fieldMap.value[key]"
|
|
7
|
+
:placeholder="fieldLabelMap.value[key]"
|
|
8
|
+
@change="inputChangeHandler(key)"
|
|
9
|
+
></TMagicInput>
|
|
10
|
+
</TMagicFormItem>
|
|
11
|
+
</TMagicForm>
|
|
12
|
+
</div>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script lang="ts" setup>
|
|
16
|
+
/**
|
|
17
|
+
* 动态表单,目前只支持input类型字段
|
|
18
|
+
* inputType: 'dynamic-field',
|
|
19
|
+
* text: '动态表单',
|
|
20
|
+
* dynamicKey: 'keyname', 如果model[dynamicKey]变化,表单字段变化
|
|
21
|
+
* returnFields(config,model,request): 函数,返回字段列表[{name:'',label:'',defaultValue:''}]
|
|
22
|
+
*
|
|
23
|
+
* 特别注意!!!field的上一级必须extensible: true,才能保存未声明的字段
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import { onBeforeUnmount, reactive, watch } from 'vue';
|
|
27
|
+
|
|
28
|
+
import { TMagicForm, TMagicFormItem, TMagicInput } from '@tmagic/design';
|
|
29
|
+
|
|
30
|
+
import type { DynamicFieldConfig, FieldProps } from '../schema';
|
|
31
|
+
import { getConfig } from '../utils/config';
|
|
32
|
+
import { useAddField } from '../utils/useAddField';
|
|
33
|
+
|
|
34
|
+
defineOptions({
|
|
35
|
+
name: 'MFormDynamicField',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const props = defineProps<FieldProps<DynamicFieldConfig>>();
|
|
39
|
+
|
|
40
|
+
const emit = defineEmits(['change']);
|
|
41
|
+
|
|
42
|
+
useAddField(props.prop);
|
|
43
|
+
|
|
44
|
+
const request = getConfig<Function>('request');
|
|
45
|
+
const fieldMap = reactive<{ [key: string]: any }>({
|
|
46
|
+
value: {},
|
|
47
|
+
});
|
|
48
|
+
const fieldLabelMap = reactive<{ [key: string]: any }>({
|
|
49
|
+
value: {},
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
const changeFieldMap = async () => {
|
|
53
|
+
if (typeof props.config.returnFields !== 'function' || !props.model) return;
|
|
54
|
+
const fields = await props.config.returnFields(props.config, props.model, request);
|
|
55
|
+
fieldMap.value = {};
|
|
56
|
+
fieldLabelMap.value = {};
|
|
57
|
+
fields.forEach((v) => {
|
|
58
|
+
if (typeof v !== 'object' || v.name === undefined) return;
|
|
59
|
+
let oldVal = props.model?.[v.name] || '';
|
|
60
|
+
if (!oldVal && v.defaultValue !== undefined) {
|
|
61
|
+
oldVal = v.defaultValue;
|
|
62
|
+
emit('change', oldVal, v.name);
|
|
63
|
+
}
|
|
64
|
+
fieldMap.value[v.name] = oldVal;
|
|
65
|
+
fieldLabelMap.value[v.name] = v.label || '';
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const unwatch = watch(
|
|
70
|
+
() => props.model?.[props.config.dynamicKey],
|
|
71
|
+
(val) => {
|
|
72
|
+
if (val !== '') {
|
|
73
|
+
changeFieldMap();
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
immediate: true,
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
onBeforeUnmount(() => {
|
|
82
|
+
if (typeof unwatch === 'function') {
|
|
83
|
+
unwatch();
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const inputChangeHandler = (key: string) => {
|
|
88
|
+
emit('change', fieldMap.value[key], key);
|
|
89
|
+
};
|
|
90
|
+
</script>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<input v-if="model" v-model="model[name]" type="hidden" />
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import type { FieldProps, HiddenConfig } from '../schema';
|
|
7
|
+
import { useAddField } from '../utils/useAddField';
|
|
8
|
+
|
|
9
|
+
defineOptions({
|
|
10
|
+
name: 'MFormHidden',
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const props = defineProps<FieldProps<HiddenConfig>>();
|
|
14
|
+
|
|
15
|
+
useAddField(props.prop);
|
|
16
|
+
</script>
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<a v-if="config.href && !disabled" target="_blank" :href="href" :style="config.css || {}">{{ displayText }}</a>
|
|
3
|
+
<span v-else-if="config.href && disabled" :style="config.disabledCss || {}">{{ displayText }}</span>
|
|
4
|
+
<div v-else class="m-fields-link">
|
|
5
|
+
<TMagicButton link type="primary" @click="editHandler">点击编辑</TMagicButton>
|
|
6
|
+
<FormDialog
|
|
7
|
+
ref="editor"
|
|
8
|
+
:title="config.formTitle || '编辑扩展配置'"
|
|
9
|
+
:width="config.formWidth"
|
|
10
|
+
:values="formValue"
|
|
11
|
+
:config="formConfig"
|
|
12
|
+
:parentValues="values"
|
|
13
|
+
:fullscreen="config.fullscreen"
|
|
14
|
+
@submit="action"
|
|
15
|
+
></FormDialog>
|
|
16
|
+
</div>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<script lang="ts" setup>
|
|
20
|
+
import { computed, inject, ref } from 'vue';
|
|
21
|
+
|
|
22
|
+
import { TMagicButton } from '@tmagic/design';
|
|
23
|
+
|
|
24
|
+
import FormDialog from '../FormDialog.vue';
|
|
25
|
+
import type { FieldProps, FormState, LinkConfig } from '../schema';
|
|
26
|
+
import { useAddField } from '../utils/useAddField';
|
|
27
|
+
|
|
28
|
+
defineOptions({
|
|
29
|
+
name: 'MFormLink',
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const props = defineProps<FieldProps<LinkConfig>>();
|
|
33
|
+
|
|
34
|
+
const emit = defineEmits(['change']);
|
|
35
|
+
|
|
36
|
+
useAddField(props.prop);
|
|
37
|
+
|
|
38
|
+
const formValue = ref({});
|
|
39
|
+
const editor = ref<InstanceType<typeof FormDialog>>();
|
|
40
|
+
const mForm = inject<FormState | undefined>('mForm');
|
|
41
|
+
|
|
42
|
+
const href = computed(() => {
|
|
43
|
+
if (typeof props.config.href === 'function' && props.model) {
|
|
44
|
+
return props.config.href(props.model);
|
|
45
|
+
}
|
|
46
|
+
return props.config.href || props.model?.[props.name];
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const init = () => {
|
|
50
|
+
formValue.value = props.model?.[props.name] || {};
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const formConfig = computed(() => {
|
|
54
|
+
if (typeof props.config.form === 'function') {
|
|
55
|
+
return props.config.form(mForm, {
|
|
56
|
+
model: props.model || {},
|
|
57
|
+
values: props.values || {},
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return props.config.form;
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const displayText = computed(() => {
|
|
64
|
+
if (typeof props.config.displayText === 'function') {
|
|
65
|
+
return props.config.displayText(mForm, { model: props.model || {} });
|
|
66
|
+
}
|
|
67
|
+
if (props.config.displayText) {
|
|
68
|
+
return props.config.displayText;
|
|
69
|
+
}
|
|
70
|
+
return '跳转';
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
const editHandler = () => {
|
|
74
|
+
init();
|
|
75
|
+
editor.value && (editor.value.dialogVisible = true);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const action = (data: any) => {
|
|
79
|
+
if (props.model) {
|
|
80
|
+
props.model[props.name] = data;
|
|
81
|
+
formValue.value = data;
|
|
82
|
+
emit('change', props.model[props.name]);
|
|
83
|
+
}
|
|
84
|
+
editor.value && (editor.value.dialogVisible = false);
|
|
85
|
+
};
|
|
86
|
+
</script>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<TMagicInputNumber
|
|
3
|
+
v-if="model"
|
|
4
|
+
v-model="model[name]"
|
|
5
|
+
clearable
|
|
6
|
+
controls-position="right"
|
|
7
|
+
:size="size"
|
|
8
|
+
:max="config.max"
|
|
9
|
+
:min="config.min"
|
|
10
|
+
:step="config.step"
|
|
11
|
+
:placeholder="config.placeholder"
|
|
12
|
+
:disabled="disabled"
|
|
13
|
+
@change="changeHandler"
|
|
14
|
+
@input="inputHandler"
|
|
15
|
+
></TMagicInputNumber>
|
|
16
|
+
</template>
|
|
17
|
+
|
|
18
|
+
<script lang="ts" setup>
|
|
19
|
+
import { inject } from 'vue';
|
|
20
|
+
|
|
21
|
+
import { TMagicInputNumber } from '@tmagic/design';
|
|
22
|
+
|
|
23
|
+
import type { FieldProps, FormState, NumberConfig } from '../schema';
|
|
24
|
+
import { useAddField } from '../utils/useAddField';
|
|
25
|
+
|
|
26
|
+
defineOptions({
|
|
27
|
+
name: 'MFormNumber',
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const props = defineProps<FieldProps<NumberConfig>>();
|
|
31
|
+
|
|
32
|
+
const emit = defineEmits<{
|
|
33
|
+
change: [values: number];
|
|
34
|
+
input: [values: number];
|
|
35
|
+
}>();
|
|
36
|
+
|
|
37
|
+
useAddField(props.prop);
|
|
38
|
+
|
|
39
|
+
const mForm = inject<FormState | null>('mForm');
|
|
40
|
+
|
|
41
|
+
const changeHandler = (value: number) => {
|
|
42
|
+
emit('change', value);
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const inputHandler = (v: number) => {
|
|
46
|
+
emit('input', v);
|
|
47
|
+
mForm?.$emit('field-input', props.prop, v);
|
|
48
|
+
};
|
|
49
|
+
</script>
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="m-fields-number-range">
|
|
3
|
+
<TMagicInput
|
|
4
|
+
v-model="model[name][0]"
|
|
5
|
+
clearable
|
|
6
|
+
:size="size"
|
|
7
|
+
:disabled="disabled"
|
|
8
|
+
@change="minChangeHandler"
|
|
9
|
+
></TMagicInput>
|
|
10
|
+
<span class="split-tag">-</span>
|
|
11
|
+
<TMagicInput
|
|
12
|
+
v-model="model[name][1]"
|
|
13
|
+
clearable
|
|
14
|
+
:size="size"
|
|
15
|
+
:disabled="disabled"
|
|
16
|
+
@change="maxChangeHandler"
|
|
17
|
+
></TMagicInput>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script lang="ts" setup>
|
|
22
|
+
import { TMagicInput } from '@tmagic/design';
|
|
23
|
+
|
|
24
|
+
import type { FieldProps, NumberRangeConfig } from '../schema';
|
|
25
|
+
import { useAddField } from '../utils/useAddField';
|
|
26
|
+
|
|
27
|
+
defineOptions({
|
|
28
|
+
name: 'MFormNumberRange',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const props = defineProps<FieldProps<NumberRangeConfig>>();
|
|
32
|
+
|
|
33
|
+
const emit = defineEmits<{
|
|
34
|
+
change: [values: [number, number]];
|
|
35
|
+
}>();
|
|
36
|
+
|
|
37
|
+
useAddField(props.prop);
|
|
38
|
+
|
|
39
|
+
if (!Array.isArray(props.model[props.name])) {
|
|
40
|
+
props.model[props.name] = [];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const minChangeHandler = (v: string) => {
|
|
44
|
+
emit('change', [Number(v), props.model[props.name][1]]);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const maxChangeHandler = (v: string) => {
|
|
48
|
+
emit('change', [props.model[props.name][0], Number(v)]);
|
|
49
|
+
};
|
|
50
|
+
</script>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<TMagicRadioGroup v-if="model" v-model="model[name]" :size="size" :disabled="disabled" @change="changeHandler">
|
|
3
|
+
<TMagicRadio v-for="option in config.options" :value="option.value" :key="`${option.value}`">{{
|
|
4
|
+
option.text
|
|
5
|
+
}}</TMagicRadio>
|
|
6
|
+
</TMagicRadioGroup>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script lang="ts" setup>
|
|
10
|
+
import { TMagicRadio, TMagicRadioGroup } from '@tmagic/design';
|
|
11
|
+
|
|
12
|
+
import type { FieldProps, RadioGroupConfig } from '../schema';
|
|
13
|
+
import { useAddField } from '../utils/useAddField';
|
|
14
|
+
|
|
15
|
+
defineOptions({
|
|
16
|
+
name: 'MFormRadioGroup',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
const props = defineProps<FieldProps<RadioGroupConfig>>();
|
|
20
|
+
|
|
21
|
+
const emit = defineEmits(['change']);
|
|
22
|
+
|
|
23
|
+
const changeHandler = (value: number) => {
|
|
24
|
+
emit('change', value);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
useAddField(props.prop);
|
|
28
|
+
</script>
|