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