@tmagic/form 1.4.8 → 1.4.9
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/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 +43 -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 +757 -0
- package/src/shims-vue.d.ts +6 -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 +14 -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 +268 -0
- package/src/utils/useAddField.ts +40 -0
|
@@ -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>
|