|
@@ -2,28 +2,46 @@
|
|
|
import WdButton from 'wot-design-uni/components/wd-button/wd-button.vue'
|
|
|
import WdInput from 'wot-design-uni/components/wd-input/wd-input.vue'
|
|
|
import WdPicker from 'wot-design-uni/components/wd-picker/wd-picker.vue'
|
|
|
+import { ConfigProviderThemeVars } from 'wot-design-uni'
|
|
|
|
|
|
const modelValue = defineModel({
|
|
|
type: Object,
|
|
|
default: () => ({}),
|
|
|
})
|
|
|
-defineProps({
|
|
|
- schema: {
|
|
|
- type: Object as PropType<{
|
|
|
- [key: string | symbol]: { type: 'TextField' | 'Submit' | string; label?: string; props?: any }
|
|
|
- }>,
|
|
|
- required: true,
|
|
|
- default: () => ({}),
|
|
|
- },
|
|
|
- direction: {
|
|
|
- type: String as PropType<'horizontal' | 'vertical'>,
|
|
|
- default: 'vertical',
|
|
|
- },
|
|
|
-})
|
|
|
+// defineProps({
|
|
|
+// schema: {
|
|
|
+// type: Object as PropType<{
|
|
|
+// [key: string | symbol]: { type: 'TextField' | 'Submit' | string; label?: string; props?: any }
|
|
|
+// }>,
|
|
|
+// required: true,
|
|
|
+// default: () => ({}),
|
|
|
+// },
|
|
|
+// direction: {
|
|
|
+// type: String as PropType<'horizontal' | 'vertical'>,
|
|
|
+// default: 'vertical',
|
|
|
+// },
|
|
|
+// })
|
|
|
+withDefaults(
|
|
|
+ defineProps<{
|
|
|
+ schema: {
|
|
|
+ [key: symbol]: {
|
|
|
+ type: 'TextField' | 'Select' | 'Radio' | 'Submit'
|
|
|
+ label?: string
|
|
|
+ existing?: boolean
|
|
|
+ props?: any
|
|
|
+ }
|
|
|
+ }
|
|
|
+ direction?: 'horizontal' | 'vertical'
|
|
|
+ }>(),
|
|
|
+ { direction: 'vertical' },
|
|
|
+)
|
|
|
+const emits = defineEmits(['submit'])
|
|
|
+const form = ref()
|
|
|
const types = {
|
|
|
TextField: WdInput,
|
|
|
Submit: WdButton,
|
|
|
Select: WdPicker,
|
|
|
+ // Radio: WdRadioGroup,
|
|
|
}
|
|
|
const defaultProps = {
|
|
|
TextField: {
|
|
@@ -37,42 +55,119 @@ const defaultProps = {
|
|
|
block: true,
|
|
|
},
|
|
|
}
|
|
|
-// const
|
|
|
+const verticalDefaultProps = {
|
|
|
+ TextField: {
|
|
|
+ noBorder: true,
|
|
|
+ style: {},
|
|
|
+ customClass: 'rounded border border-[#e1e1e1] border-solid p-1',
|
|
|
+ placeholder: ' ',
|
|
|
+ },
|
|
|
+ Submit: {
|
|
|
+ customClass: 'w-full! rounded-lg! my-4!',
|
|
|
+ block: true,
|
|
|
+ },
|
|
|
+}
|
|
|
+const horizontalDefaultProps = {
|
|
|
+ TextField: {
|
|
|
+ customClass: 'text-red!',
|
|
|
+ placeholderClass: 'text-black/30',
|
|
|
+ },
|
|
|
+ Select: {
|
|
|
+ customClass: 'text-black/30! border-b-1 border-b-[#e1e1e1] border-b-solid',
|
|
|
+ },
|
|
|
+ Radio: {
|
|
|
+ customClass: 'my--4!',
|
|
|
+ },
|
|
|
+}
|
|
|
+const themeVars: ConfigProviderThemeVars = {
|
|
|
+ cellPadding: '0',
|
|
|
+ cellWrapperPadding: '10rpx',
|
|
|
+ radioButtonRadius: '8rpx',
|
|
|
+ radioButtonBg: 'transparent',
|
|
|
+}
|
|
|
+const submit = () => {
|
|
|
+ emits('submit', modelValue)
|
|
|
+}
|
|
|
+const validate = (): Promise<{ valid: boolean; errors: any[] }> => form.value?.validate()
|
|
|
+defineExpose({
|
|
|
+ validate,
|
|
|
+})
|
|
|
</script>
|
|
|
<template>
|
|
|
- <wd-form ref="form" :model="modelValue">
|
|
|
- <wd-cell-group border>
|
|
|
+ <wd-config-provider :theme-vars="themeVars">
|
|
|
+ <wd-form ref="form" :model="modelValue" >
|
|
|
<template
|
|
|
- v-for="([prop, { type, label, props }], index) in Object.entries(schema)"
|
|
|
+ v-for="([prop, { type, label, existing, props }], index) in Object.entries(schema)"
|
|
|
:key="index"
|
|
|
>
|
|
|
- <div class="grid mb-4">
|
|
|
+ <div
|
|
|
+ v-if="existing ?? true"
|
|
|
+ class="grid mb-4"
|
|
|
+ :class="[direction === 'horizontal' ? 'items-center' : '']"
|
|
|
+ :style="
|
|
|
+ direction === 'horizontal'
|
|
|
+ ? { 'grid-template-columns': `${props?.labelWidth} auto` }
|
|
|
+ : {}
|
|
|
+ "
|
|
|
+ >
|
|
|
<label
|
|
|
- v-if="type !== 'Submit' && direction === 'vertical'"
|
|
|
- class="text-black/40 text-sm font-normal font-['PingFang_SC'] leading-relaxed mb-1"
|
|
|
+ v-if="type !== 'Submit'"
|
|
|
+ class="text-sm font-normal leading-relaxed"
|
|
|
+ :class="[direction === 'horizontal' ? 'text-black/60' : 'mb-1 text-black/40']"
|
|
|
:for="prop"
|
|
|
>
|
|
|
{{ label || prop }}
|
|
|
</label>
|
|
|
- <!-- #ifdef H5 -->
|
|
|
- <component :is="types[type]" :name="prop" v-bind="defaultProps[type]">
|
|
|
- <span v-if="type === 'Submit'">提交</span>
|
|
|
- </component>
|
|
|
- <!-- #endif -->
|
|
|
- <!-- #ifdef MP-WEIXIN -->
|
|
|
<wd-input
|
|
|
v-if="type === 'TextField'"
|
|
|
- v-bind="{ label, ...props }"
|
|
|
+ v-bind="{
|
|
|
+ ...(direction === 'vertical'
|
|
|
+ ? verticalDefaultProps[type]
|
|
|
+ : horizontalDefaultProps[type]),
|
|
|
+ ...props,
|
|
|
+ }"
|
|
|
v-model="modelValue[prop]"
|
|
|
></wd-input>
|
|
|
<wd-picker
|
|
|
v-if="type === 'Select'"
|
|
|
- v-bind="{ label, ...props }"
|
|
|
+ v-bind="{
|
|
|
+ ...(direction === 'vertical'
|
|
|
+ ? verticalDefaultProps[type]
|
|
|
+ : horizontalDefaultProps[type]),
|
|
|
+ cell: false,
|
|
|
+ ...props,
|
|
|
+ }"
|
|
|
v-model="modelValue[prop]"
|
|
|
></wd-picker>
|
|
|
- <!-- #endif -->
|
|
|
+ <wd-radio-group
|
|
|
+ v-if="type === 'Radio'"
|
|
|
+ v-bind="{
|
|
|
+ ...(direction === 'vertical'
|
|
|
+ ? verticalDefaultProps[type]
|
|
|
+ : horizontalDefaultProps[type]),
|
|
|
+ ...props,
|
|
|
+ cell: true,
|
|
|
+ shape: 'button',
|
|
|
+ }"
|
|
|
+ v-model="modelValue[prop]"
|
|
|
+ >
|
|
|
+ <template v-for="{ label, value } of props.columns" :key="value">
|
|
|
+ <wd-radio :value="value">{{ label }}</wd-radio>
|
|
|
+ </template>
|
|
|
+ </wd-radio-group>
|
|
|
+ <wd-button
|
|
|
+ v-if="type === 'Submit'"
|
|
|
+ v-bind="{
|
|
|
+ ...(direction === 'vertical' ? verticalDefaultProps[type] : {}),
|
|
|
+ ...props,
|
|
|
+ formType: 'submit',
|
|
|
+ }"
|
|
|
+ @click="submit"
|
|
|
+ >
|
|
|
+ <span v-if="type === 'Submit'">提交</span>
|
|
|
+ </wd-button>
|
|
|
</div>
|
|
|
</template>
|
|
|
- </wd-cell-group>
|
|
|
- </wd-form>
|
|
|
+ </wd-form>
|
|
|
+ </wd-config-provider>
|
|
|
</template>
|