@jdfed/drip-form
Version:
drip-form表单渲染core
189 lines (188 loc) • 6.86 kB
TypeScript
/// <reference types="react" />
import React from "react";
import { ElementType, Dispatch, NamedExoticComponent } from "react";
import { Dispatch as DispatchR } from "react";
import { UnitedSchema, Action, Map, Get, Theme, ContainerStyle, UiSchema, DataSchema, Description, TitleUi } from "@jdfed/utils";
import { Set, Merge, DeleteField, GetKey, AddField, ErrorsMap } from "@jdfed/hooks";
import { Plugin, Options } from "ajv/dist/2019";
type ContainerType = {
object: ElementType;
array: ElementType;
default: ElementType;
};
type ContainerHoc = (FormItem: JSX.Element, formItemProps: {
fieldKey: string;
error: string;
containerStyle: ContainerStyle;
type: string;
parentMode: string;
parentType: string;
// 是否是第一个表单
isFirst: boolean;
uiProp: Record<string, any>;
theme: string;
}) => JSX.Element;
type RenderFnProps = {
// ajv是否已经设置了默认值
hasDefault: boolean;
dataSchema: DataSchema;
uiSchema: UiSchema;
// 错误信息
errors: ErrorsMap;
formData: Map;
onQuery?: FuncType;
onValidate?: OnValidate;
// 当前表单父级表单的fieldKey
parentFormDataKey?: string;
// uiSchema父级表单的key
parentUiSchemaKey?: Array<string>;
// dataSchema父级表单的key
parentDataSchemaKey?: Array<string>;
// 不同type类型对应渲染的容器 ArrayContainer 和objectContainer特有
containerMap?: ContainerType;
// 允许入参高阶组件,在Container进行包裹
containerHoc?: ContainerHoc;
get: Get;
dispatch: Dispatch<Action>;
uiComponents: UiComponents;
getKey?: Map;
customComponents?: CustomComponents;
// Array类型表单当前渲染的数据是数组中第几个
currentArrayKey?: number;
// 是否是第一层级
isRoot?: boolean;
// 数组容器对应的react key映射
arrayKey: Record<string, Array<string>>;
};
type Dispatch$0 = DispatchR<Action>;
type UiComponentType = {
[propName: string]: any;
} & {
theme: string;
};
// 支持混合模式
type UiComponents = Partial<Record<Theme, UiComponentType>>;
type FieldData = string | Record<string, unknown> | boolean | number | Array<unknown>;
type AsyncValidate = {
type: "change" | "click" | "submit";
fn: (fieldData: FieldData) => any;
};
type OnValidate = Record<string, AsyncValidate>;
type FuncType = {
[propName: string]: () => any;
};
type ControlFuc = ({ formData, uiSchema, dataSchema, dispatch, changeKey, checking, get, set, deleteField }: {
uiSchema: Map;
dataSchema: Map;
formData: Map;
dispatch: Dispatch$0;
changeKey: string;
checking: boolean;
get: Get;
set: Set;
merge: Merge;
deleteField: DeleteField;
}) => void;
type CustomFunc = (val: any, dispatch: Dispatch$0, fieldKey: string, prevFieldData?: any) => void;
type ParseFunc = (formData: Map | undefined) => Map;
type TransformFunc = (formData: Map | undefined) => void | Map;
type CustomComponents = Record<string, ElementType>;
type FooterBtnFuncType = ({ formData, errors, checking }: {
formData: Map;
errors: Map;
checking: boolean;
}) => void;
/**
* 供DripFormContainer和DripForm使用的通用Props
*/
type DripFormProps = {
// 自定义Ajv插件
plugins?: Array<Plugin<Options>> | Plugin<Options>;
unitedSchema: UnitedSchema;
// 表单数据
formData?: Map;
uiComponents: UiComponents;
customComponents?: CustomComponents;
customFunc?: Record<string, CustomFunc | JSX.Element>;
control?: ControlFuc;
onQuery?: FuncType;
// v2 默认状态 formData、unitedSchema变化会触发reducer的reload(一般情况无需设置)
reload?: boolean;
onValidate?: OnValidate;
// 首轮外渲染时都会触发对formData的解析
parse?: ParseFunc;
// 每次渲染完成时都会触发对formData的转化,转化在校验后执行
transform?: TransformFunc;
// 允许入参高阶组件,针对renderCoreFn中的Container进行包裹,便于执行拖拽等操作
containerHoc?: ContainerHoc;
onSubmit?: FooterBtnFuncType;
onCancel?: FooterBtnFuncType;
ajvOptions?: Options;
};
type SubmitReturn = {
formData: Record<string, any>;
errors: Map;
checking: boolean;
};
/**
* DripForm对外的ref的类型
*/
type DripFormRefType = {
reset: () => void;
submit: () => Promise<SubmitReturn>;
// 获取任意FieldKey对应的schema,根路径key为''
get: Get;
// 设置任意FieldKey对应的schema,根路径key为''
set: Set;
// 合并任意FieldKey对应的schema,根路径key为''
merge: Merge;
// 获取fieldKey相对uiSchema、dataSchema、typeMap路径
getKey: GetKey;
// 错误信息
errors: Map;
// 是否在校验态
checking: boolean;
// 【已废弃,请使用set】修改函数
dispatch: Dispatch$0;
// 表单数据
formData: Map;
// 仅适用于生成器的对象
__generator__: {
// 删除表单项并清除对应的schema
deleteField: DeleteField;
// 添加表单项
addField: AddField;
};
};
declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<DripFormProps & React.RefAttributes<unknown>>>;
declare const DripForm: typeof _default;
type CommonContainer = {
titleUi: TitleUi;
showTitle: boolean;
description: Description;
showError: boolean;
error: string;
requiredFields: Array<string>;
fieldKey: string;
uiComponents: UiComponents;
theme: Theme;
title: string;
dispatch: Dispatch<Action>;
formMode: "edit" | "generator" | "view";
containerStyle: ContainerStyle;
// 表单UI生成控制项
uiProp: Record<string, unknown>;
};
declare const _default: React.NamedExoticComponent<CommonContainer>;
declare const _default: React.NamedExoticComponent<CommonContainer>;
declare const _default: React.NamedExoticComponent<CommonContainer>;
declare const containerMap: {
object: import("react").NamedExoticComponent<CommonContainer>;
array: import("react").NamedExoticComponent<CommonContainer>;
default: import("react").NamedExoticComponent<CommonContainer>;
};
/*TODO 优化renderprops和container编写 区分component prop和container prop*/
declare const Render: ({ hasDefault, uiComponents, dataSchema, uiSchema, errors, formData, onQuery, onValidate, dispatch, customComponents, parentUiSchemaKey, parentDataSchemaKey, parentFormDataKey, currentArrayKey, containerMap, containerHoc, get, getKey, isRoot, arrayKey }: RenderFnProps) => Array<JSX.Element | null>;
declare const renderFunc: typeof Render;
export { DripForm as default, containerMap, renderFunc };
export type { DripFormProps, DripFormRefType, Dispatch$0 as Dispatch, RenderFnProps, ContainerStyle, UiComponents, ContainerHoc, ControlFuc };