UNPKG

@ant-design/pro-utils

Version:
552 lines (550 loc) 22.9 kB
import type { ColorPickerProps, InputProps, SpaceProps } from 'antd'; import type { FormInstance, FormItemProps } from 'antd/lib/form'; import type { LabelTooltipType } from 'antd/lib/form/FormItemLabel'; import type { NamePath } from 'antd/lib/form/interface'; import type { ReactNode } from 'react'; import type { UseEditableUtilType } from './useEditableArray'; import type { SketchPickerProps } from '@chenshuai2144/sketch-color'; import type { ProSchemaValueEnumType } from '@ant-design/pro-provider'; import type { AvatarProps, CascaderProps, CheckboxProps, DatePickerProps, DividerProps, ImageProps, InputNumberProps, PopoverProps, ProgressProps, RadioProps, RateProps, SegmentedProps, SelectProps, SliderSingleProps, SwitchProps, TimeRangePickerProps, TreeSelectProps } from 'antd'; import type { RangePickerProps } from 'antd/lib/date-picker'; import type { PasswordProps, TextAreaProps } from 'antd/lib/input'; import type { SliderRangeProps } from 'antd/lib/slider'; export type ProFormBaseGroupProps = { /** * @name 分组的标题 */ title?: React.ReactNode; /** * @name 分组的标题 * @deprecated 尽量用 title */ label?: React.ReactNode; /** * @name 标题旁边的?号提示展示的信息 * * @example 自定义提示信息 * <ProForm.Group title="标题" tooltip="自定义提示信息"> * @example 自定义Icon * <ProForm.Group title="标题" tooltip={{icon:<Info/>,title:自定义提示信息}}> */ tooltip?: LabelTooltipType | string; /** * @name 额外的内容配置,在标题的另外一边 * * @example 额外的内容配置 * <ProForm.Group title="标题" extra={<ProFormSwitch name="open"/>} /> */ extra?: React.ReactNode; /** * @name 组件之前的间隔 */ size?: SpaceProps['size']; /** * @name 自定义样式 */ style?: React.CSSProperties; /** * @name 自定义 title 样式 * @example 增加背景颜色 * <ProForm.Group titleStyle={{ backgroundColor: '#f0f0f0' }} /> */ titleStyle?: React.CSSProperties; /** * @name 自定义title * @example 自定义标题 * <ProForm.Group title={(_,props)=><span>自定义标题</span>}> */ titleRender?: (title: React.ReactNode, props: ProFormBaseGroupProps) => React.ReactNode; /** 子项的对齐方式 */ align?: SpaceProps['align']; spaceProps?: SpaceProps; /** * @name 子项的排列方式 */ direction?: SpaceProps['direction']; /** * @name 布局方式,键值对模式和两行模式 * @default inline */ labelLayout?: 'inline' | 'twoLine'; /** * @name 是否折叠 */ collapsed?: boolean; /** * @name 是否可折叠 */ collapsible?: boolean; /** * @name 默认的折叠状态 * */ defaultCollapsed?: boolean; /** * @name 折叠修改的事件 * */ onCollapse?: (collapsed: boolean) => void; /** * @name 自定选中一个input,只能有一个生效 */ autoFocus?: boolean; children?: React.ReactNode; }; /** * ProFieldValueTypeWithFieldProps * 字段值类型与 ProFieldProps 的映射关系 */ export type ProFieldValueTypeWithFieldProps = { /** 文本输入框 */ text: InputProps; /** 密码输入框 */ password: PasswordProps; /** 金额 */ money: Record<string, any>; /** 索引 */ index: Record<string, any>; /** 索引带边框 */ indexBorder: Record<string, any>; /** 下拉选择 */ option: Record<string, any>; /** 多行文本 */ textarea: TextAreaProps; /** 日期选择器 */ date: DatePickerProps; /** 周选择器 */ dateWeek: DatePickerProps; /** 月选择器 */ dateMonth: DatePickerProps; /** 季度选择器 */ dateQuarter: DatePickerProps; /** 年选择器 */ dateYear: DatePickerProps; /** 日期时间选择器 */ dateTime: DatePickerProps; /** 相对时间 */ fromNow: DatePickerProps; /** 日期范围选择器 */ dateRange: RangePickerProps; /** 日期时间范围选择器 */ dateTimeRange: RangePickerProps; /** 周范围选择器 */ dateWeekRange: RangePickerProps; /** 月范围选择器 */ dateMonthRange: RangePickerProps; /** 季范围选择器 */ dateQuarterRange: RangePickerProps; /** 年范围选择器 */ dateYearRange: RangePickerProps; /** 时间选择器 */ time: TimeRangePickerProps; /** 时间范围选择器 */ timeRange: TimeRangePickerProps; /** 下拉选择器 */ select: SelectProps; /** 复选框 */ checkbox: CheckboxProps; /** 评分 */ rate: RateProps; /** 滑动条 */ slider: SliderSingleProps | SliderRangeProps; /** 单选框 */ radio: RadioProps; /** 单选框按钮 */ radioButton: RadioProps; /** 进度条 */ progress: ProgressProps; /** 百分比输入框 */ percent: InputNumberProps; /** 数字输入框 */ digit: InputNumberProps; /** 数字范围输入框 */ digitRange: InputNumberProps; /** 秒数输入框 */ second: InputNumberProps; /** 代码输入框 */ code: InputProps | TextAreaProps; /** JSON 代码输入框 */ jsonCode: InputProps | TextAreaProps; /** 头像 */ avatar: AvatarProps; /** 开关 */ switch: SwitchProps; /** 图片 */ image: ImageProps | InputProps; /** 级联选择 */ cascader: CascaderProps<any>; /** 树形选择 */ treeSelect: TreeSelectProps; /** 颜色选择器 */ color: SketchPickerProps & ColorPickerProps & { value?: string; popoverProps?: PopoverProps; mode?: 'read' | 'edit'; onChange?: (color: string) => void; colors?: string[]; /** 是否使用旧版本 */ old?: boolean; }; /** 分段器 */ segmented: SegmentedProps; /** 分组 */ group: ProFormBaseGroupProps; /** 表单列表 */ formList: Record<string, any>; /** 表单集合 */ formSet: Record<string, any>; /** 分割线 */ divider: DividerProps; /** 显示/隐藏 */ dependency: FormItemProps; }; /** * @param textarea 文本框 * @param password 密码框 * @param money 金额 option 操作 需要返回一个数组 * @param date 日期 YYYY-MM-DD * @param dateWeek 周选择器 * @param dateMonth 月选择器 * @param dateQuarter 季度选择器 * @param dateYear 年选择器 * @param dateRange 日期范围 YYYY-MM-DD[] * @param dateTime 日期和时间 YYYY-MM-DD HH:mm:ss * @param dateTimeRange 范围日期和时间 YYYY-MM-DD HH:mm:ss[] * @param time: 时间 HH:mm:ss * @param timeRange: 时间区间 HH:mm:ss[] * @param index:序列 * @param indexBorder:序列 * @param progress: 进度条 * @param percent: 百分比 * @param digit 数值 * @param second 秒速 * @param fromNow 相对于当前时间 * @param avatar 头像 * @param code 代码块 * @param image 图片设置 * @param jsonCode Json 的代码块,格式化了一下 * @param color 颜色选择器 */ export type ProFieldValueType = Extract<keyof ProFieldValueTypeWithFieldProps, any>; /** * 这是一个泛型类型定义,用于定义 FieldPropsTypeBase 类型。该类型包含了以下类型参数: * Entity:表示表单项的数据实体类型,默认为 Record<string, any>。 * ComponentsType:表示表单项对应的组件类型,默认为 'text'。 * ExtraProps:表示表单项组件的额外属性类型,默认为 Record<string, any>。 * FieldPropsType:表示表单项组件的属性类型,默认为 Record<string, any>。 * * 该类型定义了一种联合类型,可以是一个函数类型,也可以是一个对象类型。具体来说: * 如果是一个函数类型,它接收两个参数 form 和 config,并返回一个对象类型,该对象类型可以是 FieldPropsType 或 Record<string, any>。 * 其中,form 是 antd 的 FormInstance 类型,config 是 ProSchema 和其它额外属性的联合类型,并包含了一些表单项相关的信息。 * 如果不是一个函数类型,它可以是 FieldPropsType 或 Record<string, any> 中的任意一个。 * 该类型的作用是定义一个通用的表单项属性类型,使得在不同的表单项组件中,可以共用这个属性类型,提高了代码的重用性。 */ type FieldPropsTypeBase<Entity = Record<string, any>, ComponentsType = 'text', ExtraProps = Record<string, any>, FieldPropsType = ProFieldValueTypeWithFieldProps['text']> = ((form: FormInstance<any>, config: ProSchema<Entity, ExtraProps> & { type: ComponentsType; isEditable?: boolean; rowKey?: string; rowIndex: number; entity: Entity; }) => FieldPropsType | Record<string, any>) | FieldPropsType | Record<string, any>; /** * 这段代码定义了一个泛型类型 ProFieldValueObject<Type>,它的泛型参数 Type 必须是 'progress'、'money'、'percent'、'image' 中的一个。 * 当 Type 为 'progress'、'money'、'percent'、'image' 中的一种时,这个类型将被定义为一个对象,包含以下属性: * * - type: Type 类型值,即 'progress'、'money'、'percent'、'image' 中的一种; * - status: 字符串类型,表示状态,可选值为 'normal'、'active'、'success'、'exception' 或 undefined; * - locale: 字符串类型,表示地区; * - showSymbol: 布尔类型或函数类型,表示是否显示符号; * - showColor: 布尔类型,表示是否显示颜色; * - precision: 数字类型,表示精度; * - moneySymbol: 布尔类型,表示是否显示货币符号; * - request: ProFieldRequestData 类型,表示请求数据; * - width: 数字类型,表示宽度。 * * 如果 Type 不是 'progress'、'money'、'percent'、'image' 中的一种,那么 ProFieldValueObject<Type> 的类型为 never。 */ export type ProFieldValueObject<Type> = Type extends 'progress' | 'money' | 'percent' | 'image' ? { type: Type; status?: 'normal' | 'active' | 'success' | 'exception' | undefined; locale?: string; /** Percent */ showSymbol?: ((value: any) => boolean) | boolean; showColor?: boolean; precision?: number; moneySymbol?: boolean; request?: ProFieldRequestData; /** Image */ width?: number; } : never; /** * 这段代码定义了一个泛型类型 ValueTypeWithFieldPropsBase,它包含了以下属性: * - Entity:泛型类型,表示数据实体对象的类型; * - ComponentsType:泛型类型,表示组件的类型; * - ExtraProps:泛型类型,表示额外的属性; * - ValueType:泛型类型,表示字段的值类型,默认为字符串类型。 * * 该类型的主要作用是用于定义 ProTable 组件的列属性 ProColumns 中的字段属性,包括字段的类型(valueType)和自定义属性(fieldProps)。其中: * - valueType 属性可以是字符串类型,也可以是 ProFieldValueType 枚举类型,也可以是一个对象类型 ProFieldValueObject,或者是一个返回值为这些类型之一的函数。它表示字段的类型,如文本、数字、日期等; * - fieldProps 属性是一个泛型类型 FieldPropsTypeBase,它表示该字段对应的组件的属性,用于定制组件的展示形式、校验规则、事件等等。根据字段类型的不同,其属性值也会有所不同。 */ type ValueTypeWithFieldPropsBase<Entity = Record<string, any>, ComponentsType = 'form', ExtraProps = Record<string, any>, ValueType = 'text'> = { valueType?: ValueType | ProFieldValueType | ProFieldValueObject<ValueType | ProFieldValueType> | ((entity: Entity, type: ComponentsType) => ValueType | ProFieldValueType | ProFieldValueObject<ValueType | ProFieldValueType>); fieldProps?: FieldPropsTypeBase<Entity, ComponentsType, ExtraProps, ValueType extends ProFieldValueType ? ProFieldValueTypeWithFieldProps[ValueType] : ProFieldValueTypeWithFieldProps['text']>; }; /** * 这段代码定义了一个泛型类型 ValueTypeWithFieldProps,它有四个类型参数。 * 这个类型的作用是用来描述在一个数据表格中某个字段的值(value)以及可能需要传递给这个字段的其他属性(fieldProps),以便在 UI 上正确地展示这个字段。 * 具体来说,这个类型有一个属性 valueType,表示字段的值的类型,可以是 'text'、'money'、'percent'、'image'、ProFieldValueType 中的一个,也可以是一个函数。 * * 它的参数是该行数据和组件类型(例如 'table' 或 'form'),返回值为上述值中的一种。 * * 此外,这个类型还有一个属性 fieldProps,表示需要传递给该字段的其他属性,它的类型是一个泛型 FieldPropsTypeBase。这个泛型有四个类型参数, * 分别是: * - Entity 表示该字段所在行的数据类型; * - ComponentsType 表示该字段所在的组件类型; * - ExtraProps 表示传递给该字段的其他属性的类型; * - ValueType 表示该字段的值的类型,可以是 'text'、'money'、'percent'、'image'、ProFieldValueType 中的一种。 * 最终,fieldProps 属性的类型会根据 valueType 的不同,来选择特定的类型进行限制,以确保传递给该字段的其他属性符合它的值的类型。 */ export type ValueTypeWithFieldProps<Entity, ComponentsType, ExtraProps, ValueType = 'text'> = ValueTypeWithFieldPropsBase<Entity, ComponentsType, ExtraProps, ValueType>; export type PageInfo = { pageSize: number; total: number; current: number; }; export type RequestOptionsType = { /** * 选项的文本内容,可以是一个 React 组件。 */ label?: React.ReactNode; /** * 选项的值,可以是一个字符串或数字类型。 */ value?: string | number | boolean; /** 渲染的节点类型 */ optionType?: 'optGroup' | 'option'; /** * 当节点类型为 optGroup 时,可以使用该属性来定义其包含的子选项,每个子选项也可以使用 RequestOptionsType 类型来定义。 */ options?: Omit<RequestOptionsType, 'children' | 'optionType'>[]; /** 其他自定义属性。 */ [key: string]: any; }; export type ProFieldRequestData<U = any> = (params: U, props: any) => Promise<RequestOptionsType[]>; export type ProFieldValueEnumType = ProSchemaValueEnumMap | ProSchemaValueEnumObj; /** * ProFieldValueObjectType 对象,用于描述值为 'progress' | 'money' | 'percent' | 'image' 类型的 ProField 的属性。 * @typedef {Object} ProFieldValueObjectType * @property {('progress' | 'money' | 'percent' | 'image')} type - 值的类型。 * @property {('normal' | 'active' | 'success' | 'exception' | undefined)} [status] - 状态。 * @property {string} [locale] - 本地化语言。 * @property {((value: any) => boolean) | boolean} [showSymbol] - 是否显示符号。 * @property {boolean} [showColor] - 是否显示颜色。 * @property {number} [precision] - 精度。 * @property {boolean} [moneySymbol] - 是否显示货币符号。 * @property {ProFieldRequestData} [request] - 远程请求数据。 * @property {number} [width] - 图片的宽度。 */ export type ProFieldValueObjectType = { /** * 类型 * - 'progress': 进度条 * - 'money': 金钱格式 * - 'percent': 百分比 * - 'image': 图片 */ type: 'progress' | 'money' | 'percent' | 'image'; /** * 状态 * - 'normal': 正常 * - 'active': 活动中 * - 'success': 成功 * - 'exception': 异常 */ status?: 'normal' | 'active' | 'success' | 'exception' | undefined; /** 本地化信息 */ locale?: string; /** * 百分比相关 * - showSymbol?: 是否显示百分号,默认为 true * - showColor?: 是否显示颜色条,默认为 false * - precision?: 保留几位小数,默认为 2 */ showSymbol?: ((value: any) => boolean) | boolean; showColor?: boolean; precision?: number; /** * 金钱相关 * - moneySymbol?: 是否显示货币符号,默认为 true */ moneySymbol?: boolean; /** 数据请求 */ request?: ProFieldRequestData; /** * width?: 图片宽度,默认为 80 */ width?: number; }; /** * 支持 Map 和 Record<string,any> * * @name ValueEnum 的类型 */ export type ProSchemaValueEnumMap = Map<string | number | boolean, ProSchemaValueEnumType | ReactNode>; export type ProSchemaValueEnumObj = Record<string, ProSchemaValueEnumType | ReactNode>; export type ProFieldTextType = React.ReactNode | React.ReactNode[] | Record<string, any> | Record<string, any>[]; export type SearchTransformKeyFn = (value: any, namePath: string, allValues: any) => any; export type SearchConvertKeyFn = (value: any, field: NamePath) => string | boolean | Record<string, any>; export type ProTableEditableFnType<T> = (value: any, record: T, index: number) => boolean; /** 支持的变形,还未完全支持完毕 */ export type ProSchemaComponentTypes = 'form' | 'list' | 'descriptions' | 'table' | 'cardList' | undefined; /** 操作类型 */ export type ProCoreActionType<T = {}> = { /** @name 刷新 */ reload: (resetPageIndex?: boolean) => Promise<void>; /** @name 刷新并清空,只清空页面,不包括表单 */ reloadAndRest?: () => Promise<void>; /** @name 重置任何输入项,包括表单 */ reset?: () => void; /** @name 清空选择 */ clearSelected?: () => void; /** @name p页面的信息都在里面 */ pageInfo?: PageInfo; } & Omit<UseEditableUtilType, 'newLineRecord' | 'editableKeys' | 'actionRender' | 'setEditableRowKeys'> & T; export type ProSchemaFieldProps<T> = Record<string, any> | T | Partial<InputProps>; /** 各个组件公共支持的 render */ export type ProSchema<Entity = Record<string, any>, ExtraProps = unknown, ComponentsType extends ProSchemaComponentTypes = 'form', ValueType = 'text', ExtraFormItemProps = unknown> = { /** @name 确定这个列的唯一值,一般用于 dataIndex 重复的情况 */ key?: React.Key; /** * 支持一个数字,[a,b] 会转化为 obj.a.b * * @name 与实体映射的key */ dataIndex?: unknown; /** * 支持 ReactNode 和 方法 * * @name 标题 */ title?: ((schema: ProSchema<Entity, ExtraProps, ComponentsType, ValueType, ExtraFormItemProps>, type: ComponentsType, dom: React.ReactNode) => React.ReactNode) | React.ReactNode; tip?: string; /** @name 展示一个 icon,hover 是展示一些提示信息 */ tooltip?: LabelTooltipType | string; /** * 支持 object 和Map,Map 是支持其他基础类型作为 key * * @name 映射值的类型 */ valueEnum?: ((row: Entity) => ProSchemaValueEnumObj | ProSchemaValueEnumMap) | ProSchemaValueEnumObj | ProSchemaValueEnumMap; /** * @name 自定义的 formItemProps */ formItemProps?: (FormItemProps & ExtraFormItemProps) | ((form: FormInstance<any>, config: ProSchema<Entity, ExtraProps, ComponentsType, ValueType, ExtraFormItemProps> & { type: ComponentsType; isEditable?: boolean; rowKey?: string; rowIndex: number; entity: Entity; }) => FormItemProps & ExtraFormItemProps); /** * 修改的数据是会被 valueType 消费 * * @name 自定义 render 内容 */ renderText?: (text: any, record: Entity, index: number, action: ProCoreActionType) => any; /** * Render 方法只管理的只读模式,编辑模式需要使用 renderFormItem * * @name 自定义只读模式的dom */ render?: (dom: React.ReactNode, entity: Entity, index: number, action: ProCoreActionType | undefined, schema: ProSchema<Entity, ExtraProps, ComponentsType, ValueType, ExtraFormItemProps> & { isEditable?: boolean; type: ComponentsType; }) => React.ReactNode | { children: React.ReactNode; props: any; }; /** * 返回一个 ReactNode,会自动包裹 value 和 onChange * * @name 自定义编辑模式 */ renderFormItem?: (schema: ProSchema<Entity, ExtraProps, ComponentsType, ValueType, ExtraFormItemProps> & { isEditable?: boolean; index?: number; type: ComponentsType; originProps?: any; }, config: { onSelect?: (value: any) => void; onChange?: <T = any>(value: T) => void; value?: any; type: ComponentsType; recordKey?: React.Key | React.Key[]; record?: Entity; isEditable?: boolean; defaultRender: (newItem: ProSchema<Entity, ExtraProps, ComponentsType, ValueType>) => JSX.Element | null; }, form: FormInstance, action?: Omit<UseEditableUtilType, 'newLineRecord' | 'editableKeys' | 'actionRender' | 'setEditableRowKeys'>) => React.ReactNode; /** * @name 可编辑表格是否可编辑 * * @example 不允许编辑 * editable=false * * @example 如果id=1不允许编辑 * editable={(value,row,index)=> row.id !==1 } */ editable?: false | ProTableEditableFnType<Entity>; /** @name 从服务器请求枚举 */ request?: ProFieldRequestData; /** @name request防抖动时间 默认10 单位ms */ debounceTime?: number; /** @name 从服务器请求的参数,改变了会触发 reload */ params?: ((record: Entity, column: ProSchema<Entity, ExtraProps>) => Record<string, any>) | Record<string, any>; /** @name 依赖字段的name,暂时只在拥有 request 的项目中生效,会自动注入到 params 中 */ dependencies?: NamePath[]; /** * @name 忽略 FormItem,必须要和 renderFormItem 组件一起使用 */ ignoreFormItem?: boolean; /** @name 在 descriptions 隐藏 */ hideInDescriptions?: boolean; /** @name 在 Form 中隐藏 */ hideInForm?: boolean; /** @name 在 table 中隐藏 */ hideInTable?: boolean; /** @name 在 table的查询表单 中隐藏 */ hideInSearch?: boolean; /** 设置到 ProField 上面的 Props,内部属性 */ proFieldProps?: ProFieldProps & Record<string, any>; } & ExtraProps & ValueTypeWithFieldProps<Entity, ComponentsType, ExtraProps, ValueType>; export interface ProFieldProps { /** * 是否启用轻量模式 */ light?: boolean; /** * 空文本占位符 */ emptyText?: ReactNode; /** * 标签名称 */ label?: React.ReactNode; /** * 渲染模式 */ mode?: 'read' | 'edit'; /** * 设置 useSwr 的 key */ proFieldKey?: string; /** * 自定义渲染函数 */ render?: any; /** * 是否只读 */ readonly?: boolean; } export {};