Files
ff-dist/grid-layout-form.d.ts
T

378 lines
20 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { CSSProperties } from 'react';
import { GridLayoutProps, LayoutField, GridLayoutItem, GridLayoutGroup, FormInstance } from './grid-layout';
export { FormInstance } from './grid-layout';
import { Rule } from 'rc-field-form/es/interface';
export { Rule } from 'rc-field-form/es/interface';
export { useFnRun } from './grid-layout';
/** useStructure 返回的表单结构数据,请求完成前为 `{ items: [], hides: [] }` */
interface GridLayoutFormStructure extends GridLayoutProps {
/** 记录主键 */
pk?: unknown
/** 表单唯一标识 */
uuid?: string
/** 表单编码 */
code?: string
/** 关联资源标识 */
resource?: string
/** 字段对齐方式 */
align?: unknown
/** 字段联动监听字段列表(字段 code 数组) */
listenChangeFields?: string[]
/** 字段联动处理函数/表达式,经 func.exec 执行 */
listenChangeFieldsFunc?: GridLayoutFormWidgetDecorator
/** 可见字段列表(field.hidden 为 false) */
items?: GridLayoutFormItem[]
/** 隐藏字段列表(field.hidden 为 true) */
hides?: GridLayoutFormField[]
}
/** 表单字段定义(对应后端返回的 field 对象,继承布局通用字段) */
interface GridLayoutFormField extends LayoutField {
/** 是否必填 */
required?: boolean
/** 是否隐藏 */
hidden?: boolean
/** 输入占位文字 */
placeholder?: string
/** 是否隐藏 FormItem 样式 */
noStyle?: boolean
/** FormItem 根节点行内样式 */
style?: CSSProperties
/** 字段提示文字 */
help?: string
/** 校验规则配置 */
validators?: GridLayoutFormFieldValidators
/** 控件切换表达式/函数 */
widgetDecorator?: GridLayoutFormWidgetDecorator
/** 可切换的候选子控件列表 */
subWidgets?: GridLayoutFormSubWidget[]
}
/** 表单项(网格布局单元,包含字段定义与布局信息) */
interface GridLayoutFormItem extends GridLayoutItem {
/** 表单字段定义(收窄自 GridLayoutItem.field) */
field?: GridLayoutFormField
}
/** 字段分组配置,用于主题多分组渲染(结构等同于 GridLayoutGroup) */
type GridLayoutFormGroup = GridLayoutGroup
/** itemWidgetRender 生成的渲染函数接收的字段 props(即 GridLayoutFormField 字段在运行时的合并结果) */
type GridLayoutFormItemWidgetProps = GridLayoutFormField & Record<string, unknown>
/**
* itemWidgetRender 中实际渲染的部件组件约定接收的 props
* (由 itemWidgetRender 注入,开发者在实现自定义控件时参考此约定)
*/
interface GridLayoutFormItemWidgetComponentProps {
/** 字段值类型 */
type?: string
/** rc-field-form 表单实例 */
rcform?: unknown
/** 外层表单实例,用于字段联动/表达式求值 */
basicForm?: unknown
/** 传给 antd FormItem 的属性(label/noStyle/style/required/validateStatus/help 等) */
itemProps?: Record<string, unknown>
/** 传给实际输入控件的属性(placeholder/value/onChange 等) */
fieldProps?: Record<string, unknown>
/** 扩展配置,由 defaultProps.extras 的 key 从 props 中拆分而来 */
$setting?: Record<string, unknown>
}
/**
* 增强后的表单实例,在 rc-field-form FormInstance 基础上补全 antd 兼容接口
* (__INTERNAL__ / scrollToField / focusField / getFieldInstance)
*/
type EnhancedFormInstance = FormInstance & Record<string, unknown>
/** useFormData / useFormSubmit / useFormAction 的表单配置参数 */
interface GridLayoutFormSetting {
/** 初始化数据的请求地址,默认 `/api/{code}` */
initDataUri?: string
/** 初始化数据的请求方法,默认 `'GET'` */
initDataMethod?: string
/** 提交数据的请求地址,默认 `/api/{code}` */
submitDataUri?: string
/** 提交数据的请求方法,默认 `'POST'` */
submitDataMethod?: string
}
/** useFormSubmit / useFormAction 的提交选项 */
interface SubmitOptions {
/** 提交前对表单数据做转换,默认原样返回 */
serialize?: (data: Record<string, unknown>) => unknown
/** 提交成功回调 */
onSuccess?: (res: unknown) => void
/** 提交失败回调,默认校验错误时弹出提示 */
onFail?: (error: unknown) => void
}
/** widgetDecorator 命中时可切换的候选子控件 */
interface GridLayoutFormSubWidget {
/** 控件标识,规则同 GridLayoutFormWidget.widget */
widget: string
/** 控件前缀,默认同外层 widgetPrefix */
widgetPrefix?: string
/** 合并到实际控件的额外 props */
props?: Record<string, unknown>
}
/** 决定控件切换的表达式或函数,经 useFnRun 执行,返回值作为 subWidgets 下标 */
type GridLayoutFormWidgetDecorator = string | ((...args: unknown[]) => number | undefined)
/**
* listenChangeFieldsFunc / validator 动态表达式可调用的表单字段 API;
* 由 GridLayoutForm 和 useRules 通过 func.exec 第三参数注入
*/
type GridLayoutFormAPI = Pick<
FormInstance,
'getFieldValue' | 'setFieldValue' | 'setFieldsValue' | 'isFieldTouched' | 'isFieldsTouched'
>
/** useFieldArray 的返回值 */
interface UseFieldArrayReturn {
/** 当前受控数组(始终是干净的原始数组,不含注入字段) */
items: unknown[]
/** 返回第 i 项的稳定 React key,供 map 时使用 */
keyAt: (i: number) => string
/** 追加一个或多个项到末尾 */
append: (...values: unknown[]) => void
/** 插入一个或多个项到开头 */
prepend: (...values: unknown[]) => void
/** 在指定下标处插入一个或多个项 */
insert: (index: number, ...values: unknown[]) => void
/** 按下标删除一个或多个项 */
remove: (...indexes: number[]) => void
/** 清空所有项 */
clear: () => void
/** 替换指定下标的项 */
update: (index: number, value: unknown) => void
/** 整体替换数组内容 */
reset: (value: unknown) => void
/** 交换两个下标的项 */
swap: (indexA: number, indexB: number) => void
/** 将 from 处的项移动到 to 位置 */
move: (from: number, to: number) => void
}
/**
* GridLayoutFormWidget 字段校验规则配置
* 对应 useRules 的入参,由 validators prop 传入
*/
interface GridLayoutFormFieldValidators {
/** 校验类型:string 长度校验 / pattern 正则校验 / validator 自定义 */
type?: 'string' | 'pattern' | 'validator' | ''
/** 是否必填 */
required?: boolean
/** 最大长度/值(type='string' 时生效) */
max?: number
/** 最小长度/值(type='string' 时生效) */
min?: number
/** 正则表达式(type='pattern' 时生效) */
pattern?: string | RegExp
/** 校验失败提示文字 */
message?: string
/** 自定义校验表达式/函数(type='validator' 时经 func.exec 执行) */
validator?: unknown
}
/**
* 按表单编码(code)拉取表单结构定义,并把字段列表拆分为可见项(items)与隐藏项(hides)
* @param {string} code 表单编码,为空时不发起请求
* @returns {GridLayoutFormStructure} 表单结构数据,请求完成前为 `{ items: [], hides: [] }`
*/
declare function useStructure(code: string): GridLayoutFormStructure;
/**
* 根据字段的校验配置生成 rc-field-form 的 rules 数组;支持必填、长度限制、正则、自定义校验函数
* @param {GridLayoutFormFieldValidators} config
* @param {string} fieldName 字段名,传给自定义 validator 表达式
* @param {string} fieldType 字段类型('number'|'string'|'array'|'bool'|'json' 等),决定必填校验的 type 及 bool/json 的映射
* @returns {Rule[]} rc-field-form 规则数组
*/
declare function useRules({ max, min, type, message, pattern, required, validator, }: GridLayoutFormFieldValidators, fieldName: string, fieldType: string): Rule[];
/**
* 按主键(primaryKey)拉取表单初始数据;primaryKey 为空时不请求
* @param {string} code 表单编码,用于拼接默认的请求地址 `/api/{code}`
* @param {string|number} primaryKey 记录主键,为空时不发起请求
* @param {GridLayoutFormSetting} [formSetting] 表单配置
* @returns {Record<string, unknown>|null} 拉取到的表单数据,请求完成前为 `null`
*/
declare function useFormData(code: string, primaryKey: string | number, formSetting?: GridLayoutFormSetting): Record<string, unknown> | null;
/**
* 生成提交表单的回调函数;校验通过后按 `__RESOURCE__` 字段值裁剪数据(若存在),经 opt.serialize 序列化后提交
* @param {string} code 表单编码,用于拼接默认的请求地址 `/api/{code}`
* @param {string|number} primaryKey 记录主键,存在时拼到请求地址后面
* @param {GridLayoutFormSetting} [formSetting] 表单配置
* @returns {(form: FormInstance, opt?: SubmitOptions) => Promise<*>} 提交函数
*/
declare function useFormSubmit(code: string, primaryKey: string | number, formSetting?: GridLayoutFormSetting): (form: FormInstance, opt?: SubmitOptions) => Promise<any>;
/**
* 组合 useFormData 与 useFormSubmit:数据拉取到后自动回填表单(否则重置),并返回已绑定 form 的提交函数
* @param {FormInstance} form rc-field-form 的表单实例
* @param {string} code 表单编码
* @param {string|number} primaryKey 记录主键
* @param {GridLayoutFormSetting} [formSetting] 表单配置(透传给 useFormData/useFormSubmit)
* @returns {(opt?: SubmitOptions) => Promise<*>} 已绑定当前 form 的提交函数
*/
declare function useFormAction(form: FormInstance, code: string, primaryKey: string | number, formSetting?: GridLayoutFormSetting): (opt?: SubmitOptions) => Promise<any>;
/**
* 根据 widgetDecorator 表达式动态决定字段实际渲染的控件;
* widgetDecorator 执行结果为 subWidgets 的下标时,切换为对应子控件(合并其 props),
* 同时暴露 setDisabled/setRequired/getDisabled/getRequired 供 widgetDecorator 内部调用来动态调整禁用/必填状态
* @param {string} itemWidget 默认使用的控件(已归一化的 widget 路径)
* @param {GridLayoutFormWidgetDecorator} widgetDecorator 决定控件切换的表达式/函数,经 useFnRun 执行,返回值作为 subWidgets 下标
* @param {GridLayoutFormSubWidget[]} [subWidgets=[]] 可切换的候选子控件列表
* @param {FormInstance|null} [basicForm={}] 传给 widgetDecorator 执行上下文的表单实例
* @returns {[string, Object]} `[实际渲染的控件路径, 当前生效的控件 props]`
*/
declare function useWidgetDecorator(itemWidget: string, widgetDecorator: GridLayoutFormWidgetDecorator, subWidgets?: GridLayoutFormSubWidget[], basicForm?: FormInstance | null): [string, any];
/**
* 把受控的 value/onChange 与 rc-field-form 表单实例双向桥接:外部 value 变化时同步进表单
* (仅当与内部最近一次变更不同,避免循环),表单内部变化时回调 onChange;
* 同时补全一份兼容 antd Form 的 `__INTERNAL__`/getFieldInstance 等接口(scrollToField/focusField 未实现,仅打印警告)
* @param {Object} config
* @param {Record<string, unknown>} [config.value] 外部受控值,变化时会同步到表单
* @param {(allValues: Record<string, unknown>) => void} [config.onChange] 表单值变化时的回调
* @param {FormInstance|null} [form=null] 复用的 rc-field-form 表单实例,不传则内部创建
* @returns {[EnhancedFormInstance, (changedValues: Record<string, unknown>, allValues: Record<string, unknown>) => void]} `[增强后的表单实例(补全 antd __INTERNAL__/scrollToField 等接口), 供 Form onValuesChange 使用的处理函数]`
*/
declare function useMergedFormValuesChange({ value, onChange }: {
value?: Record<string, unknown>;
onChange?: (allValues: Record<string, unknown>) => void;
}, form?: FormInstance | null): [EnhancedFormInstance, (changedValues: Record<string, unknown>, allValues: Record<string, unknown>) => void];
/**
* 受控的数组字段管理 hook,提供 append/prepend/insert/remove/update/set/clear/swap/move
* 等操作方法,调用方无需手写 immutability-helper 语句。
*
* 数据不归 hook 自己管,由外部通过 value/onChange 控制(对应 antd Form.Item 受控字段契约)。
*
* **稳定 key 设计**:不向 items 数据注入额外字段,改为单独提供 `keyAt(i)` 按下标查询——
* items 始终是干净的原始数组。key 由内部自增 id 生成(用下标当 key 时,删除中间项会导致
* React 按位置复用组件实例,表现为"删第 1 条,视觉上最后一条消失"),外部整体替换 value
* 时自动按长度兜底同步。
*
* @param {*} value 受控数组值(antd Form.Item 注入的 value),任意类型经 toPrimitive 强转为数组
* @param {(value: Array) => void} onChange 数组变化回调(antd Form.Item 注入的 onChange)
* @returns {UseFieldArrayReturn} 当前数组及全部操作方法
*/
declare function useFieldArray(value: any, onChange: (value: any[]) => void): UseFieldArrayReturn;
/**
* 按 widget 标识异步加载并渲染对应的表单部件,加载完成前不渲染任何内容;
* 加载出错时渲染错误信息文本;支持通过 widgetDecorator/subWidgets 在运行时动态切换实际渲染的子控件(见 useWidgetDecorator)
* @param {Object} props
* @param {string} [props.widget='Input'] 部件标识;以 `@` 或 `blob:` 开头时按原样使用,否则拼接 widgetPrefix 前缀
* @param {string} [props.widgetPrefix='@pkg/ff/grid-layout-forms'] widget 非绝对标识时使用的前缀
* @param {GridLayoutFormWidgetDecorator} [props.widgetDecorator] 决定控件切换的表达式/函数,详见 useWidgetDecorator
* @param {GridLayoutFormSubWidget[]} [props.subWidgets=[]] widgetDecorator 命中时可切换的候选子控件列表
* @param {FormInstance|null} [props.basicForm] 表达式求值/字段联动用的外层表单实例
* @param {string} [props.code] 字段 name,对应 rc-field-form Field.name
* @param {string} [props.type] 字段值类型(string/number/boolean 等),用于取值归一化
* @param {string} [props.label] 字段标签
* @param {boolean} [props.required] 是否必填
* @param {string} [props.placeholder] 输入占位文字,透传给实际控件
* @param {boolean} [props.noStyle] 是否隐藏 FormItem 的 label/border 等样式
* @param {CSSProperties} [props.style] FormItem 根节点行内样式
* @param {string} [props.help] 字段提示文字(tooltip)
* @param {GridLayoutFormFieldValidators} [props.validators] 校验规则配置,合并到 rc-field-form rules
* @param {Record<string, unknown>} [props.extras] 透传给 ItemWidget.$setting 的扩展配置(key 由 defaultProps.extras 定义)
* @param {*} [props.initialValue] 字段初始值
* @param {string} [props.initialValueLanguage] 初始值语言(用于特定类型的取值转换)
* @param {boolean} [props.isVirtual] 虚拟字段,不参与表单提交
* 其余未识别的 props 经 itemWidgetRender 透传到实际控件的 fieldProps 中
* @returns {React.JSX.Element | null}
*/
declare function GridLayoutFormWidget({ widget, widgetPrefix, widgetDecorator, subWidgets, basicForm, ...props }: {
widget?: string;
widgetPrefix?: string;
widgetDecorator?: GridLayoutFormWidgetDecorator;
subWidgets?: GridLayoutFormSubWidget[];
basicForm?: FormInstance | null;
code?: string;
type?: string;
label?: string;
required?: boolean;
placeholder?: string;
noStyle?: boolean;
style?: React.CSSProperties;
help?: string;
validators?: GridLayoutFormFieldValidators;
extras?: Record<string, unknown>;
initialValue?: any;
initialValueLanguage?: string;
isVirtual?: boolean;
}): React.JSX.Element | null;
/**
* 弹窗表单容器:包裹 GridLayoutForm 并附带保存/取消操作按钮,保存时校验并提交表单,
* 成功后调用 $close 关闭弹窗;常配合 Popup.modal 或 useButton 的 'grid-layout-form' widgetType 使用
* @param {Object} props
* @param {Object} [props.$setting] 表单配置(透传给 useFormAction 作为 formSetting),okText/cancelText 可自定义按钮文案
* @param {(result?: *) => void} [props.$close] 关闭弹窗的函数,保存成功或点击取消时调用
* @param {*} [props.extras] 传给 FFContainer 的额外内容(如头部区域)
* @param {string} [props.code] 表单编码,透传给 useFormAction/GridLayoutForm
* @param {string|number} [props.primaryKey] 记录主键,透传给 useFormAction/GridLayoutForm
*/
declare function GridLayoutFormHelper({ $setting, $close, extras, code, primaryKey, ...props }: {
$setting?: any;
$close?: (result?: any) => void;
extras?: any;
code?: string;
primaryKey?: string | number;
}): React.JSX.Element;
/**
* 表单容器组件,按 fields 渲染栅格布局字段并托管一个 rc-field-form 表单;
* 支持字段联动(listenChangeFields/listenChangeFieldsFunc)、隐藏字段(hides,内部用 HideField 渲染)、
* 以及指定 theme 时委托 GridLayoutFramework 渲染主题外壳
* @param {Object} props
* @param {string} [props.name] 表单字段容器名
* @param {FormInstance|null} [props.form] 外部传入的 rc-field-form 表单实例,不传时内部自建
* @param {FormInstance|null} [props.basicForm] 表达式求值/字段联动用的外层表单实例
* @param {CSSProperties} [props.style] 容器行内样式
* @param {string} [props.className] 容器额外 class 名
* @param {number} [props.cols=24] 栅格列数
* @param {number} [props.rowHeight=16] 栅格行高(px)
* @param {[number, number]} [props.itemMargin=[8, 16]] 字段项间距 [横向, 纵向](px)
* @param {[number, number]} [props.containerPadding=[0, 0]] 容器内边距 [纵向, 横向](px)
* @param {GridLayoutFormItem[]} [props.fields=[]] 可见字段配置列表(位置、尺寸、部件类型等)
* @param {GridLayoutFormField[]} [props.hides=[]] 隐藏字段配置列表,按 initialValueLanguage 求值后写入对应字段
* @param {string|number} [props.primaryKey=0] 记录主键,注入为 `__PRIMARY_KEY__` 字段值
* @param {Record<string, unknown>} [props.formProps={}] 注入为 `__PROPS__` 字段值的表单级参数
* @param {GridLayoutFormItem[]} [props.formFields=[]] 额外注入的表单字段(与 formProps/primaryKey 一并作为初始 fields)
* @param {string[]} [props.listenChangeFields] 触发联动表达式重新求值的字段列表
* @param {GridLayoutFormWidgetDecorator} [props.listenChangeFieldsFunc] 字段值变化时执行的联动表达式(经 func.exec 执行)
* @param {(changedValues: Object, allValues: Object) => void} [props.onValuesChange] 表单值变化回调,先于联动表达式执行
* @param {string} [props.theme] 主题组件标识,指定时通过 GridLayoutFramework 渲染主题外壳
* @param {Record<string, unknown>} [props.themeProps={}] 传给主题组件的额外参数
* @param {GridLayoutFormGroup[]} [props.groups=[{key:'default',label:'默认'}]] 字段分组配置,用于主题多分组渲染
* @param {ReactNode} [props.children] 附加渲染在字段项之后的内容
*/
declare function GridLayoutForm({ name, form: initForm, basicForm, style, className, cols, rowHeight, itemMargin, containerPadding, fields, hides, primaryKey, formProps, formFields, listenChangeFields, listenChangeFieldsFunc, onValuesChange, theme, themeProps, groups, children, ...props }: {
name?: string;
form?: FormInstance | null;
basicForm?: FormInstance | null;
style?: React.CSSProperties;
className?: string;
cols?: number;
rowHeight?: number;
itemMargin?: [number, number];
containerPadding?: [number, number];
fields?: GridLayoutFormItem[];
hides?: GridLayoutFormField[];
primaryKey?: string | number;
formProps?: Record<string, unknown>;
formFields?: GridLayoutFormItem[];
listenChangeFields?: string[];
listenChangeFieldsFunc?: GridLayoutFormWidgetDecorator;
onValuesChange?: (changedValues: any, allValues: any) => void;
theme?: string;
themeProps?: Record<string, unknown>;
groups?: GridLayoutFormGroup[];
children?: React.ReactNode;
}): React.JSX.Element;
export { GridLayoutForm, GridLayoutFormHelper, GridLayoutFormWidget, useFieldArray, useFormAction, useFormData, useFormSubmit, useMergedFormValuesChange, useRules, useStructure, useWidgetDecorator };
export type { EnhancedFormInstance, GridLayoutFormAPI, GridLayoutFormField, GridLayoutFormFieldValidators, GridLayoutFormGroup, GridLayoutFormItem, GridLayoutFormItemWidgetComponentProps, GridLayoutFormItemWidgetProps, GridLayoutFormSetting, GridLayoutFormStructure, GridLayoutFormSubWidget, GridLayoutFormWidgetDecorator, SubmitOptions, UseFieldArrayReturn };