fix: form item overflow fixed and layout improved (#5572)
* fix: form item overflow fixed and layout improved * fix: basic form demo update * feat: form label support render * fix: form docs updatepull/62/head
							parent
							
								
									ccd99eb24d
								
							
						
					
					
						commit
						a221d2b491
					
				|  | @ -445,9 +445,9 @@ export interface FormSchema< | ||||||
|   /** 字段名,也作为自定义插槽的名称 */ |   /** 字段名,也作为自定义插槽的名称 */ | ||||||
|   fieldName: string; |   fieldName: string; | ||||||
|   /** 帮助信息 */ |   /** 帮助信息 */ | ||||||
|   help?: string; |   help?: CustomRenderType; | ||||||
|   /** 表单项 */ |   /** 表单的标签(如果是一个string,会用于默认必选规则的消息提示) */ | ||||||
|   label?: string; |   label?: CustomRenderType; | ||||||
|   /** 自定义组件内部渲染  */ |   /** 自定义组件内部渲染  */ | ||||||
|   renderComponentContent?: RenderComponentContentType; |   renderComponentContent?: RenderComponentContentType; | ||||||
|   /** 字段规则 */ |   /** 字段规则 */ | ||||||
|  |  | ||||||
|  | @ -538,4 +538,6 @@ interface Preferences { | ||||||
| 
 | 
 | ||||||
| - `overridesPreferences`方法只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置。 | - `overridesPreferences`方法只需要覆盖项目中的一部分配置,不需要的配置不用覆盖,会自动使用默认配置。 | ||||||
| - 任何配置项都可以覆盖,只需要在`overridesPreferences`方法内覆盖即可,不要修改默认配置文件。 | - 任何配置项都可以覆盖,只需要在`overridesPreferences`方法内覆盖即可,不要修改默认配置文件。 | ||||||
| - 更改配置后请清空缓存,否则可能不生效。::: | - 更改配置后请清空缓存,否则可能不生效。 | ||||||
|  | 
 | ||||||
|  | ::: | ||||||
|  |  | ||||||
|  | @ -193,7 +193,7 @@ const fieldProps = computed(() => { | ||||||
|   const rules = fieldRules.value; |   const rules = fieldRules.value; | ||||||
|   return { |   return { | ||||||
|     keepValue: true, |     keepValue: true, | ||||||
|     label, |     label: isString(label) ? label : '', | ||||||
|     ...(rules ? { rules } : {}), |     ...(rules ? { rules } : {}), | ||||||
|     ...(formFieldProps as Record<string, any>), |     ...(formFieldProps as Record<string, any>), | ||||||
|   }; |   }; | ||||||
|  | @ -285,7 +285,7 @@ function autofocus() { | ||||||
|         'pb-6': !compact, |         'pb-6': !compact, | ||||||
|         'pb-2': compact, |         'pb-2': compact, | ||||||
|       }" |       }" | ||||||
|       class="flex" |       class="relative flex" | ||||||
|       v-bind="$attrs" |       v-bind="$attrs" | ||||||
|     > |     > | ||||||
|       <FormLabel |       <FormLabel | ||||||
|  | @ -305,11 +305,13 @@ function autofocus() { | ||||||
|         :style="labelStyle" |         :style="labelStyle" | ||||||
|       > |       > | ||||||
|         <template v-if="label"> |         <template v-if="label"> | ||||||
|           <span>{{ label }}</span> |           <VbenRenderContent :content="label" /> | ||||||
|           <span v-if="colon" class="ml-[2px]">:</span> |           <span v-if="colon" class="ml-[2px]">:</span> | ||||||
|         </template> |         </template> | ||||||
|       </FormLabel> |       </FormLabel> | ||||||
|  |       <div class="w-full overflow-hidden"> | ||||||
|         <div :class="cn('relative flex w-full items-center', wrapperClass)"> |         <div :class="cn('relative flex w-full items-center', wrapperClass)"> | ||||||
|  |           <div class="flex-auto overflow-hidden"> | ||||||
|             <FormControl :class="cn(controlClass)"> |             <FormControl :class="cn(controlClass)"> | ||||||
|               <slot |               <slot | ||||||
|                 v-bind="{ |                 v-bind="{ | ||||||
|  | @ -343,17 +345,19 @@ function autofocus() { | ||||||
|                 </component> |                 </component> | ||||||
|               </slot> |               </slot> | ||||||
|             </FormControl> |             </FormControl> | ||||||
|  |           </div> | ||||||
|  | 
 | ||||||
|           <!-- 自定义后缀 --> |           <!-- 自定义后缀 --> | ||||||
|           <div v-if="suffix" class="ml-1"> |           <div v-if="suffix" class="ml-1"> | ||||||
|             <VbenRenderContent :content="suffix" /> |             <VbenRenderContent :content="suffix" /> | ||||||
|           </div> |           </div> | ||||||
| 
 |           <FormDescription v-if="description" class="ml-1"> | ||||||
|         <FormDescription v-if="description"> |  | ||||||
|             <VbenRenderContent :content="description" /> |             <VbenRenderContent :content="description" /> | ||||||
|           </FormDescription> |           </FormDescription> | ||||||
|  |         </div> | ||||||
| 
 | 
 | ||||||
|         <Transition name="slide-up"> |         <Transition name="slide-up"> | ||||||
|           <FormMessage class="absolute -bottom-[22px]" /> |           <FormMessage class="absolute bottom-1" /> | ||||||
|         </Transition> |         </Transition> | ||||||
|       </div> |       </div> | ||||||
|     </FormItem> |     </FormItem> | ||||||
|  |  | ||||||
|  | @ -1,10 +1,16 @@ | ||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
| import { FormLabel, VbenHelpTooltip } from '@vben-core/shadcn-ui'; | import type { CustomRenderType } from '../types'; | ||||||
|  | 
 | ||||||
|  | import { | ||||||
|  |   FormLabel, | ||||||
|  |   VbenHelpTooltip, | ||||||
|  |   VbenRenderContent, | ||||||
|  | } from '@vben-core/shadcn-ui'; | ||||||
| import { cn } from '@vben-core/shared/utils'; | import { cn } from '@vben-core/shared/utils'; | ||||||
| 
 | 
 | ||||||
| interface Props { | interface Props { | ||||||
|   class?: string; |   class?: string; | ||||||
|   help?: string; |   help?: CustomRenderType; | ||||||
|   required?: boolean; |   required?: boolean; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -16,7 +22,7 @@ const props = defineProps<Props>(); | ||||||
|     <span v-if="required" class="text-destructive mr-[2px]">*</span> |     <span v-if="required" class="text-destructive mr-[2px]">*</span> | ||||||
|     <slot></slot> |     <slot></slot> | ||||||
|     <VbenHelpTooltip v-if="help" trigger-class="size-3.5 ml-1"> |     <VbenHelpTooltip v-if="help" trigger-class="size-3.5 ml-1"> | ||||||
|       {{ help }} |       <VbenRenderContent :content="help" /> | ||||||
|     </VbenHelpTooltip> |     </VbenHelpTooltip> | ||||||
|   </FormLabel> |   </FormLabel> | ||||||
| </template> | </template> | ||||||
|  |  | ||||||
|  | @ -244,13 +244,13 @@ export interface FormSchema< | ||||||
|   /** 依赖 */ |   /** 依赖 */ | ||||||
|   dependencies?: FormItemDependencies; |   dependencies?: FormItemDependencies; | ||||||
|   /** 描述 */ |   /** 描述 */ | ||||||
|   description?: string; |   description?: CustomRenderType; | ||||||
|   /** 字段名 */ |   /** 字段名 */ | ||||||
|   fieldName: string; |   fieldName: string; | ||||||
|   /** 帮助信息 */ |   /** 帮助信息 */ | ||||||
|   help?: string; |   help?: CustomRenderType; | ||||||
|   /** 表单项 */ |   /** 表单项 */ | ||||||
|   label?: string; |   label?: CustomRenderType; | ||||||
|   // 自定义组件内部渲染
 |   // 自定义组件内部渲染
 | ||||||
|   renderComponentContent?: RenderComponentContentType; |   renderComponentContent?: RenderComponentContentType; | ||||||
|   /** 字段规则 */ |   /** 字段规则 */ | ||||||
|  |  | ||||||
|  | @ -4,10 +4,18 @@ import { h, ref } from 'vue'; | ||||||
| import { Page } from '@vben/common-ui'; | import { Page } from '@vben/common-ui'; | ||||||
| 
 | 
 | ||||||
| import { useDebounceFn } from '@vueuse/core'; | import { useDebounceFn } from '@vueuse/core'; | ||||||
| import { Button, Card, message, Spin, TabPane, Tabs } from 'ant-design-vue'; | import { | ||||||
|  |   Button, | ||||||
|  |   Card, | ||||||
|  |   message, | ||||||
|  |   Spin, | ||||||
|  |   TabPane, | ||||||
|  |   Tabs, | ||||||
|  |   Tag, | ||||||
|  | } from 'ant-design-vue'; | ||||||
| import dayjs from 'dayjs'; | import dayjs from 'dayjs'; | ||||||
| 
 | 
 | ||||||
| import { useVbenForm } from '#/adapter/form'; | import { useVbenForm, z } from '#/adapter/form'; | ||||||
| import { getAllMenusApi } from '#/api'; | import { getAllMenusApi } from '#/api'; | ||||||
| 
 | 
 | ||||||
| import DocButton from '../doc-button.vue'; | import DocButton from '../doc-button.vue'; | ||||||
|  | @ -111,6 +119,7 @@ const [BaseForm, baseFormApi] = useVbenForm({ | ||||||
|           notFoundContent: fetching.value ? h(Spin) : undefined, |           notFoundContent: fetching.value ? h(Spin) : undefined, | ||||||
|         }; |         }; | ||||||
|       }, |       }, | ||||||
|  |       rules: 'selectRequired', | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       component: 'ApiTreeSelect', |       component: 'ApiTreeSelect', | ||||||
|  | @ -151,6 +160,7 @@ const [BaseForm, baseFormApi] = useVbenForm({ | ||||||
|       label: '图标', |       label: '图标', | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|  |       colon: false, | ||||||
|       component: 'Select', |       component: 'Select', | ||||||
|       componentProps: { |       componentProps: { | ||||||
|         allowClear: true, |         allowClear: true, | ||||||
|  | @ -169,7 +179,7 @@ const [BaseForm, baseFormApi] = useVbenForm({ | ||||||
|         showSearch: true, |         showSearch: true, | ||||||
|       }, |       }, | ||||||
|       fieldName: 'options', |       fieldName: 'options', | ||||||
|       label: '下拉选', |       label: () => h(Tag, { color: 'warning' }, () => '😎自定义:'), | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       component: 'RadioGroup', |       component: 'RadioGroup', | ||||||
|  | @ -225,6 +235,7 @@ const [BaseForm, baseFormApi] = useVbenForm({ | ||||||
|           default: () => ['我已阅读并同意'], |           default: () => ['我已阅读并同意'], | ||||||
|         }; |         }; | ||||||
|       }, |       }, | ||||||
|  |       rules: z.any().refine((v) => v, { message: '为什么不同意?勾上它!' }), | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|       component: 'Mentions', |       component: 'Mentions', | ||||||
|  | @ -255,6 +266,7 @@ const [BaseForm, baseFormApi] = useVbenForm({ | ||||||
|         class: 'w-auto', |         class: 'w-auto', | ||||||
|       }, |       }, | ||||||
|       fieldName: 'switch', |       fieldName: 'switch', | ||||||
|  |       help: () => ['这是一个帮助信息', '第二行'].map((v) => h('p', () => v)), | ||||||
|       label: '开关', |       label: '开关', | ||||||
|     }, |     }, | ||||||
|     { |     { | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Netfan
						Netfan