@schema-render/core-react
Version:
Through a set of simple JSON Schema, efficiently build a set of forms.
286 lines (263 loc) • 7.55 kB
TypeScript
import type React from 'react'
import type { ReactNode } from 'react'
import type { ILayout, IValidationStatus } from '../constants'
import type localeStruct from '../locale/zh_CN'
import type {
IApiPath,
IDeepReadonly,
IDictionary,
IMaybePromise,
IObjectAny,
IPath,
IWindow,
} from './common'
import type { IChangeEvent, IRendererInstance, IRootContext } from './rootContext'
import type { IRootSchema, IRuleItem, ISchema } from './schema'
export interface IItemChangeEvent extends IChangeEvent {
/**
* 字符串化路径
*/
sPath: string
}
export interface ICore {
/* 核心参数 */
/**
* 表单默认值
*/
defaultValue?: IObjectAny
/**
* 表单数据
*/
value?: IObjectAny
/**
* 表单描述协议
*/
schema: IRootSchema
/**
* 数据变化监听,用于数据联动处理
*/
watch?: IDictionary<(value: IObjectAny, e: IItemChangeEvent) => void>
/**
* 数据变化事件
* @param value 全量表单数据
* @param e 事件对象
*/
onChange?: (value: IObjectAny, e: IItemChangeEvent) => void
/**
* 表单项数据变化事件
* @param e 事件对象
*/
onItemChange?: (e: IItemChangeEvent) => void
/* UI 型参数 */
/**
* 样式类名前缀,默认为 schema-render
*/
prefixCls?: string
/**
* 根节点类名
*/
className?: string
/**
* 根节点样式
*/
style?: React.CSSProperties
/**
* 整体表单布局结构
*/
layout?: ILayout
/**
* 布局内每个表单项列间距,对应 grid-column-gap
*/
layoutColumnGap?: number
/**
* 布局内每个表单项行间距,对应 grid-row-gap
*/
layoutRowGap?: number
/**
* 当 layout 为 autoFill、autoFit 时生效,定义表单项最小宽度与最大宽度
*/
layoutMinMax?: [string | number, string | number]
/**
* 表单项布局结构
*/
itemLayout: React.ComponentType<IOpenItemLayoutParams>
/* 国际化 */
locale?: typeof localeStruct
/* 功能型参数 */
/**
* 禁用态,是否禁用,权重大于 schema 的 disabled 属性
*/
disabled?: boolean
/**
* 只读态,是否只读
*/
readonly?: boolean
/**
* 渲染器列表
*/
renderers: IRenderers
/**
* 全局校验器
*/
validators?: IValidators
/**
* 全局上下文信息
*/
userCtx?: IObjectAny
/**
* 捕获错误的提示信息,默认标红提示错误
* - 传入函数则自定义错误信息
* - 传入 silent 则不提示错误
*/
catchErrorTips?: 'silent' | ((e: Error) => ReactNode)
}
// 开放表单项布局结构参数
export interface IOpenItemLayoutParams
extends Pick<
IOpenComponentParams,
'schema' | 'required' | 'disabled' | 'readonly' | 'validator' | 'locale' | 'userCtx'
> {
/* 渲染器组件 */
body: React.ReactNode
/* 类名工具函数:对 classnames 包的封装,带有 prefixCls 类名前缀 */
prefixClassNames: IRootContext['prefixClassNames']
}
export interface IValidators<V extends any = any, S extends ISchema = ISchema> {
[name: string]: IRenderer<V, S>['validator']
}
export interface IOpenValidateError extends IOpenFunctionValidatorResult {
path: IPath
value: any
}
export interface IOpenValidateResult {
// 是否存在错误
hasError: boolean
// 是否存在警告
hasWarning: boolean
// 错误列表
errorList: IOpenValidateError[]
// 警告列表
warningList: IOpenValidateError[]
}
export interface IScrollToOptions {
/**
* 滚动过渡行为 'smooth' | 'instant' | 'auto'
* https://developer.mozilla.org/zh-CN/docs/Web/API/Element/scrollTo#behavior
*/
behavior?: ScrollBehavior
/** 是否触发 x 轴移动,默认 true */
xAxis?: boolean
/** 是否触发 y 轴移动,默认 true */
yAxis?: boolean
/** 移动到指定位置的间隙,可以是正负值,默认为 0 */
gap?: number
/** 指定 “定位元素”,适用于外部滚动 */
positionedElement?: HTMLElement | IWindow | null
}
export interface ICoreRef {
/**
* 校验数据
*/
validate: () => Promise<IOpenValidateResult>
/**
* 重置错误信息(含警告信息),当数据回填时,可以用此方法重置错误信息
*/
resetError: (paths?: IApiPath) => void
/**
* 获取表单数据
*/
getValue: () => IObjectAny
/**
* 设置表单数据
*/
setValue: (value: IObjectAny) => void
/**
* 重置数据
*/
resetValue: () => void
/**
* 获取根节点元素
*/
getRootElement: () => HTMLDivElement | null
/**
* 查找指定表单项,返回表单项实例的开放 API
*/
findItem: (paths?: IApiPath) => IRendererInstance | undefined
/**
* 滚动到指定表单项
* @param paths 表单项路径
* @param options 滚动参数
*/
scrollTo: (paths?: IApiPath, options?: IScrollToOptions) => void
}
export interface IRenderers<V extends any = any, S extends ISchema = ISchema> {
[type: string]: IRenderer<V, S>
}
// 开放渲染器
export interface IRenderer<V extends any = any, S extends ISchema = ISchema> {
/** 渲染器组件 component 模式 */
component?: React.ComponentType<IOpenComponentParams<V, S>>
/** 只读态 component */
readonlyComponent?: React.ComponentType<IOpenComponentParams<V, S>>
/** 禁用态 component */
disabledComponent?: React.ComponentType<IOpenComponentParams<V, S>>
/** 渲染器组件 formItem 模式:自定义渲染内容,覆盖 itemLayout 布局 */
formItem?: React.ComponentType<IOpenFormItemParams<V, S>>
/** 只读态 formItem */
readonlyFormItem?: React.ComponentType<IOpenFormItemParams<V, S>>
/** 禁用态 formItem */
disabledFormItem?: React.ComponentType<IOpenFormItemParams<V, S>>
/** 校验器 */
validator?: IRuleItem[] | IOpenFunctionValidator<V, S>
}
// 开放校验器
export type IOpenFunctionValidator<V extends any = any, S extends ISchema = ISchema> = (
IParams: IOpenValidatorParams<V, S>
) => IMaybePromise<IRuleItem[] | IOpenFunctionValidatorResult | void>
// 函数校验器返回结果
export interface IOpenFunctionValidatorResult {
status: IValidationStatus
message?: string
extra?: IObjectAny
}
// 开放渲染器参数 formItem 模式
export type IOpenFormItemParams<
V extends any = any,
S extends ISchema = ISchema
> = IOpenComponentParams<V, S>
export interface IOpenChangeOptions {
// 是否触发校验器
triggerValidator?: boolean
// 额外信息
extra?: any
}
// 开放渲染器参数 component 模式
export interface IOpenComponentParams<V extends any = any, S extends ISchema = ISchema>
extends IOpenValidatorParams<V, S> {
// 对象类型样式
objectStyle: IObjectAny
// 校验器信息,包含校验状态、提示消息与附加数据
validator: IDeepReadonly<IOpenFunctionValidatorResult>
// 值回调事件
onChange: (value: V | undefined, options?: IOpenChangeOptions) => void
}
// 开放校验器参数
export interface IOpenValidatorParams<V extends any = any, S extends ISchema = ISchema>
extends Pick<IRootContext, 'rootValue' | 'userCtx'> {
// 渲染器 schema
schema: S
// 渲染器 value
value: V | undefined
// 渲染器路径
path: IPath
// 渲染器路径字符串化表示
sPath: string
// 是否必填,表达式执行的结果
required: boolean
// 是否禁用,表达式执行与全局状态控制的结果
disabled: boolean
// 是否只读,表达式执行与全局状态控制的结果
readonly: boolean
// 国际化 - 当前语言
locale: ICore['locale'] & IObjectAny
}