import type { VbenButtonProps } from '@vben-core/shadcn-ui';
|
import type { ClassType } from '@vben-core/typings';
|
import type { FieldOptions, FormContext, GenericObject } from 'vee-validate';
|
import type { ZodTypeAny } from 'zod';
|
|
import type { FormApi } from './form-api';
|
|
import type { Component, HtmlHTMLAttributes, Ref } from 'vue';
|
|
export type FormLayout = 'horizontal' | 'vertical';
|
|
export type BaseFormComponentType =
|
| 'DefaultButton'
|
| 'PrimaryButton'
|
| 'VbenCheckbox'
|
| 'VbenInput'
|
| 'VbenInputPassword'
|
| 'VbenPinInput'
|
| 'VbenSelect'
|
| (Record<never, never> & string);
|
|
type Breakpoints = '' | '2xl:' | '3xl:' | 'lg:' | 'md:' | 'sm:' | 'xl:';
|
|
type GridCols = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13;
|
|
export type WrapperClassType =
|
| `${Breakpoints}grid-cols-${GridCols}`
|
| (Record<never, never> & string);
|
|
export type FormItemClassType =
|
| `${Breakpoints}cols-end-${'auto' | GridCols}`
|
| `${Breakpoints}cols-span-${'auto' | 'full' | GridCols}`
|
| `${Breakpoints}cols-start-${'auto' | GridCols}`
|
| (Record<never, never> & string)
|
| WrapperClassType;
|
|
export type FormFieldOptions = Partial<
|
{
|
validateOnBlur?: boolean;
|
validateOnChange?: boolean;
|
validateOnInput?: boolean;
|
validateOnModelUpdate?: boolean;
|
} & FieldOptions
|
>;
|
|
export interface FormShape {
|
/** 默认值 */
|
default?: any;
|
/** 字段名 */
|
fieldName: string;
|
/** 是否必填 */
|
required?: boolean;
|
rules?: ZodTypeAny;
|
}
|
|
export type MaybeComponentPropKey =
|
| 'options'
|
| 'placeholder'
|
| 'title'
|
| keyof HtmlHTMLAttributes
|
| (Record<never, never> & string);
|
|
export type MaybeComponentProps = { [K in MaybeComponentPropKey]?: any };
|
|
export type FormActions = FormContext<GenericObject>;
|
|
export type CustomRenderType = (() => Component | string) | string;
|
|
export type FormSchemaRuleType =
|
| 'required'
|
| 'selectRequired'
|
| null
|
| (Record<never, never> & string)
|
| ZodTypeAny;
|
|
type FormItemDependenciesCondition<T = boolean | PromiseLike<boolean>> = (
|
value: Partial<Record<string, any>>,
|
actions: FormActions,
|
) => T;
|
|
type FormItemDependenciesConditionWithRules = (
|
value: Partial<Record<string, any>>,
|
actions: FormActions,
|
) => FormSchemaRuleType | PromiseLike<FormSchemaRuleType>;
|
|
type FormItemDependenciesConditionWithProps = (
|
value: Partial<Record<string, any>>,
|
actions: FormActions,
|
) => MaybeComponentProps | PromiseLike<MaybeComponentProps>;
|
|
export interface FormItemDependencies {
|
/**
|
* 组件参数
|
* @returns 组件参数
|
*/
|
componentProps?: FormItemDependenciesConditionWithProps;
|
/**
|
* 是否禁用
|
* @returns 是否禁用
|
*/
|
disabled?: boolean | FormItemDependenciesCondition;
|
/**
|
* 是否渲染(删除dom)
|
* @returns 是否渲染
|
*/
|
if?: boolean | FormItemDependenciesCondition;
|
/**
|
* 是否必填
|
* @returns 是否必填
|
*/
|
required?: FormItemDependenciesCondition;
|
/**
|
* 字段规则
|
*/
|
rules?: FormItemDependenciesConditionWithRules;
|
/**
|
* 是否隐藏(Css)
|
* @returns 是否隐藏
|
*/
|
show?: boolean | FormItemDependenciesCondition;
|
/**
|
* 任意触发都会执行
|
*/
|
trigger?: FormItemDependenciesCondition<void>;
|
/**
|
* 触发字段
|
*/
|
triggerFields: string[];
|
}
|
|
type ComponentProps =
|
| ((
|
value: Partial<Record<string, any>>,
|
actions: FormActions,
|
) => MaybeComponentProps)
|
| MaybeComponentProps;
|
|
export interface FormCommonConfig {
|
/**
|
* 所有表单项的props
|
*/
|
componentProps?: ComponentProps;
|
/**
|
* 所有表单项的控件样式
|
*/
|
controlClass?: string;
|
/**
|
* 所有表单项的禁用状态
|
* @default false
|
*/
|
disabled?: boolean;
|
/**
|
* 是否禁用所有表单项的change事件监听
|
* @default false
|
*/
|
disabledOnChangeListener?: boolean;
|
/**
|
* 所有表单项的空状态值,默认都是undefined,naive-ui的空状态值是null
|
*/
|
emptyStateValue?: null | undefined;
|
/**
|
* 所有表单项的控件样式
|
* @default {}
|
*/
|
formFieldProps?: FormFieldOptions;
|
/**
|
* 所有表单项的栅格布局
|
* @default ""
|
*/
|
formItemClass?: string;
|
/**
|
* 隐藏所有表单项label
|
* @default false
|
*/
|
hideLabel?: boolean;
|
/**
|
* 是否隐藏必填标记
|
* @default false
|
*/
|
hideRequiredMark?: boolean;
|
/**
|
* 所有表单项的label样式
|
* @default ""
|
*/
|
labelClass?: string;
|
/**
|
* 所有表单项的label宽度
|
*/
|
labelWidth?: number;
|
/**
|
* 所有表单项的wrapper样式
|
*/
|
wrapperClass?: string;
|
}
|
|
type RenderComponentContentType = (
|
value: Partial<Record<string, any>>,
|
api: FormActions,
|
) => Record<string, any>;
|
|
export type HandleSubmitFn = (
|
values: Record<string, any>,
|
) => Promise<void> | void;
|
|
export type HandleResetFn = (
|
values: Record<string, any>,
|
) => Promise<void> | void;
|
|
export type FieldMappingTime = [
|
string,
|
[string, string],
|
([string, string] | string)?,
|
][];
|
|
export interface FormSchema<
|
T extends BaseFormComponentType = BaseFormComponentType,
|
> extends FormCommonConfig {
|
/** 组件 */
|
component: Component | T;
|
/** 组件参数 */
|
componentProps?: ComponentProps;
|
/** 默认值 */
|
defaultValue?: any;
|
/** 依赖 */
|
dependencies?: FormItemDependencies;
|
/** 描述 */
|
description?: string;
|
/** 字段名 */
|
fieldName: string;
|
/** 帮助信息 */
|
help?: string;
|
/** 表单项 */
|
label?: string;
|
// 自定义组件内部渲染
|
renderComponentContent?: RenderComponentContentType;
|
/** 字段规则 */
|
rules?: FormSchemaRuleType;
|
/** 后缀 */
|
suffix?: CustomRenderType;
|
}
|
|
export interface FormFieldProps extends FormSchema {
|
required?: boolean;
|
}
|
|
export interface FormRenderProps<
|
T extends BaseFormComponentType = BaseFormComponentType,
|
> {
|
/**
|
* 是否展开,在showCollapseButton=true下生效
|
*/
|
collapsed?: boolean;
|
/**
|
* 折叠时保持行数
|
* @default 1
|
*/
|
collapsedRows?: number;
|
/**
|
* 是否触发resize事件
|
* @default false
|
*/
|
collapseTriggerResize?: boolean;
|
/**
|
* 表单项通用后备配置,当子项目没配置时使用这里的配置,子项目配置优先级高于此配置
|
*/
|
commonConfig?: FormCommonConfig;
|
/**
|
* 组件v-model事件绑定
|
*/
|
componentBindEventMap?: Partial<Record<BaseFormComponentType, string>>;
|
/**
|
* 组件集合
|
*/
|
componentMap: Record<BaseFormComponentType, Component>;
|
/**
|
* 表单实例
|
*/
|
form?: FormContext<GenericObject>;
|
/**
|
* 表单项布局
|
*/
|
layout?: FormLayout;
|
/**
|
* 表单定义
|
*/
|
schema?: FormSchema<T>[];
|
/**
|
* 是否显示展开/折叠
|
*/
|
showCollapseButton?: boolean;
|
/**
|
* 表单栅格布局
|
* @default "grid-cols-1"
|
*/
|
wrapperClass?: WrapperClassType;
|
}
|
|
export interface ActionButtonOptions extends VbenButtonProps {
|
[key: string]: any;
|
content?: string;
|
show?: boolean;
|
}
|
|
export interface VbenFormProps<
|
T extends BaseFormComponentType = BaseFormComponentType,
|
> extends Omit<
|
FormRenderProps<T>,
|
'componentBindEventMap' | 'componentMap' | 'form'
|
> {
|
/**
|
* 操作按钮是否反转(提交按钮前置)
|
*/
|
actionButtonsReverse?: boolean;
|
/**
|
* 表单操作区域class
|
*/
|
actionWrapperClass?: ClassType;
|
/**
|
* 表单字段映射成时间格式
|
*/
|
fieldMappingTime?: FieldMappingTime;
|
/**
|
* 表单重置回调
|
*/
|
handleReset?: HandleResetFn;
|
/**
|
* 表单提交回调
|
*/
|
handleSubmit?: HandleSubmitFn;
|
/**
|
* 表单值变化回调
|
*/
|
handleValuesChange?: (values: Record<string, any>) => void;
|
/**
|
* 重置按钮参数
|
*/
|
resetButtonOptions?: ActionButtonOptions;
|
/**
|
* 是否显示默认操作按钮
|
* @default true
|
*/
|
showDefaultActions?: boolean;
|
|
/**
|
* 提交按钮参数
|
*/
|
submitButtonOptions?: ActionButtonOptions;
|
|
/**
|
* 是否在字段值改变时提交表单
|
* @default false
|
*/
|
submitOnChange?: boolean;
|
|
/**
|
* 是否在回车时提交表单
|
* @default false
|
*/
|
submitOnEnter?: boolean;
|
}
|
|
export type ExtendedFormApi = {
|
useStore: <T = NoInfer<VbenFormProps>>(
|
selector?: (state: NoInfer<VbenFormProps>) => T,
|
) => Readonly<Ref<T>>;
|
} & FormApi;
|
|
export interface VbenFormAdapterOptions<
|
T extends BaseFormComponentType = BaseFormComponentType,
|
> {
|
config?: {
|
baseModelPropName?: string;
|
disabledOnChangeListener?: boolean;
|
emptyStateValue?: null | undefined;
|
modelPropNameMap?: Partial<Record<T, string>>;
|
};
|
defineRules?: {
|
required?: (
|
value: any,
|
params: any,
|
ctx: Record<string, any>,
|
) => boolean | string;
|
selectRequired?: (
|
value: any,
|
params: any,
|
ctx: Record<string, any>,
|
) => boolean | string;
|
};
|
}
|