jamis
Version:
一种支持通过JSON配置方式生成页面的组件库
320 lines (319 loc) • 9.57 kB
TypeScript
import type { Api, BaseSchemaScoped, GridSizeUnit, GridSizeUnitStr, OnEventProps, RendererEvent, RendererProps, SchemaBoolean, SchemaClassName, SchemaExpression, SchemaMessage } from 'jamis-core';
import type { CSSProperties } from 'react';
import type { ActionSchema, SchemaCollection } from '../types';
import type { IFormStore, LabelAlign } from './types';
export interface FormHorizontal {
left?: GridSizeUnit | SchemaClassName;
right?: GridSizeUnit | SchemaClassName;
leftFixed?: boolean | 'xs' | 'sm' | 'normal' | 'md' | 'lg' | 'auto';
justify?: boolean;
labelAlign?: 'left' | 'right';
/** label自定义宽度,默认单位为px */
labelWidth?: number | string;
}
export interface FormSchemaBase {
/**
* 表单标题
*/
title?: string | false;
titleClassName?: SchemaClassName;
desc?: SchemaCollection;
descClassName?: SchemaClassName;
/**
* 按钮集合,会固定在底部显示。
*/
actions?: Array<any>;
/**
* 表单项集合
*/
body?: any;
/**
* 内容体的样式
*/
bodyStyle?: CSSProperties;
/**
* @deprecated 请用类型 tabs
*/
tabs?: any;
/**
* @deprecated 请用类型 fieldSet
*/
fieldSet?: any;
/**
* 用来初始化表单数据
*/
initApi?: Api;
/**
* Form 用来获取初始数据的 api,与initApi不同的是,会一直轮询请求该接口,直到返回 finished 属性为 true 才 结束。
*/
initAsyncApi?: Api;
/**
* 设置了initAsyncApi后,默认会从返回数据的data.finished来判断是否完成,也可以设置成其他的xxx,就会从data.xxx中获取
*/
initFinishedField?: string;
/**
* 设置了initAsyncApi以后,默认拉取的时间间隔
*/
initCheckInterval?: number;
/**
* 是否初始加载
*/
initFetch?: boolean;
/**
* 建议改成 api 的 sendOn 属性。
*/
initFetchOn?: string;
/**
* 设置后将轮询调用 initApi
*/
interval?: number;
/**
* 是否静默拉取
*/
silentPolling?: boolean;
/**
* 配置停止轮询的条件
*/
stopAutoRefreshWhen?: string;
/**
* 是否开启本地缓存
*/
persistData?: string;
/**
* 开启本地缓存后限制保存哪些 key
*/
persistDataKeys?: string[];
/**
* 提交成功后清空本地缓存
*/
clearPersistDataAfterSubmit?: boolean;
/**
* Form 用来保存数据的 api。
*
* 详情:https://baidu.gitee.io/amis/docs/components/form/index#%E8%A1%A8%E5%8D%95%E6%8F%90%E4%BA%A4
*/
api?: Api;
/**
* 延迟提交的毫秒数
*/
submitDelay?: number;
/**
* Form 也可以配置 feedback。
*/
feedback?: any;
/**
* 设置此属性后,表单提交发送保存接口后,还会继续轮询请求该接口,直到返回 finished 属性为 true 才 结束。
*/
asyncApi?: Api;
/**
* 轮询请求的时间间隔,默认为 3秒。设置 asyncApi 才有效
*/
checkInterval?: number;
/**
* 如果决定结束的字段名不是 `finished` 请设置此属性,比如 `is_success`
*/
finishedField?: string;
/**
* 提交完后重置表单
*/
resetAfterSubmit?: boolean;
/**
* 提交后清空表单
*/
clearAfterSubmit?: boolean;
/**
* 配置表单项默认的展示方式。
*/
mode?: FormMode;
modeExpr?: SchemaExpression;
/**
* 表单项显示为几列
*/
columnCount?: GridSizeUnit | SchemaExpression | Record<GridSizeUnitStr, boolean | SchemaBoolean>;
/**
* 如果是水平排版,这个属性可以细化水平排版的左右宽度占比。
*/
horizontal?: FormHorizontal;
/**
* 是否自动将第一个表单元素聚焦。
*/
autoFocus?: boolean;
/**
* 消息文案配置,记住这个优先级是最低的,如果你的接口返回了 msg,接口返回的优先。
*/
messages?: SchemaMessage & {
/**
* 表单验证失败时的提示
*/
validateFailed?: string;
};
name?: string;
bodyClassName?: SchemaClassName;
/**
* 配置容器 panel className
*/
panelClassName?: SchemaClassName;
itemClassName?: SchemaClassName;
/**
* 给所有的formitem的label设置label样式类
*/
labelClassName?: SchemaClassName;
/**
* 容器 panel的等级
*/
panelLevel?: 'default' | 'info' | 'success' | 'warning' | 'danger' | 'primary';
actionsClassName?: SchemaClassName;
/**
* 设置主键 id, 当设置后,检测表单是否完成时(asyncApi),只会携带此数据。
* @default id
*/
primaryField?: string;
redirect?: string;
reload?: string;
/**
* 修改的时候是否直接提交表单。
*/
submitOnChange?: boolean;
/**
* 表单初始先提交一次,联动的时候有用
*/
submitOnInit?: boolean;
/**
* 默认的提交按钮名称,如果设置成空,则可以把默认按钮去掉。
*/
submitText?: string | null;
/**
* 默认表单提交自己会通过发送 api 保存数据,但是也可以设定另外一个 form 的 name 值,或者另外一个 `CRUD` 模型的 name 值。 如果 target 目标是一个 `Form` ,则目标 `Form` 会重新触发 `initApi` 和 `schemaApi`,api 可以拿到当前 form 数据。如果目标是一个 `CRUD` 模型,则目标模型会重新触发搜索,参数为当前 Form 数据。
*/
target?: string;
/**
* 是否用 panel 包裹起来
*/
wrapWithPanel?: boolean | {
id?: string;
/**
* 配置容器 panel是否可以展开
*/
collapsable?: boolean;
collapsableOn?: SchemaBoolean;
collapsed?: boolean;
collapsedOn?: SchemaBoolean;
onEvent?: OnEventProps['onEvent'];
};
/**
* 是否固定底下的按钮在底部。
*/
affixFooter?: boolean;
/**
* 页面离开提示,为了防止页面不小心跳转而导致表单没有保存。
*/
promptPageLeave?: boolean;
/**
* 具体的提示信息,选填。
*/
promptPageLeaveMessage?: string;
/**
* 组合校验规则,选填
*/
rules?: Array<{
/** 校验规则 */
rule: SchemaExpression;
/** 校验失败时消息 */
message: string;
name?: string | Array<string>;
}>;
/**
* 禁用回车提交
*/
preventEnterSubmit?: boolean;
/**
* 表单label的对齐方式
*/
labelAlign?: LabelAlign;
/**
* label自定义宽度,默认单位为px
*/
labelWidth?: number | string;
/**是否可以访问父数据域, 默认是true */
canAccessSuperData?: boolean;
formLazyChange?: boolean;
/** 包装form的元素 */
wrapperComponent?: React.ElementType;
/** 提交表单的键盘快捷键 */
hotKey?: string;
showLoading?: boolean;
showLoadingOn?: SchemaBoolean;
onSubmit?: (values: any, action: any) => any;
onChange?: (values: any, diff: any, props: FormProps) => any;
onInit?: (values: any, props: FormProps) => any;
onValidate?: (values: object, form: any) => any;
/**
* submit完成回调
*/
onFinished?: (values: object, action: any) => any;
}
/**
* Form 表单渲染器。
*/
export interface FormSchema extends FormSchemaBase, BaseSchemaScoped, OnEventProps {
/**
* 指定为表单渲染器。
*/
type: 'form';
/**
* 按钮集合,会固定在底部显示。
*/
actions?: Array<ActionSchema>;
/**
* 表单项集合
*/
body?: SchemaCollection;
/**
* @deprecated 请使用body
*/
controls?: SchemaCollection;
/**
* @deprecated 请通过监听onEvent.submit来替代
*/
onSubmit?: (values: object, action: any) => any;
}
export type FormGroup = FormSchemaBase & {
title?: string;
className?: string;
};
export type FormGroupNode = FormGroup | FormGroupArray;
export interface FormGroupArray extends Array<FormGroupNode> {
}
export type FormMode = 'normal' | 'inline' | 'horizontal' | 'row';
export interface FormProps extends RendererProps, Omit<FormSchemaBase, 'mode' | 'className' | 'columnCount'> {
data: any;
store: IFormStore;
mode: FormMode;
wrapperComponent: React.ElementType;
trimValues?: boolean;
lazyLoad?: boolean;
simpleMode?: boolean;
columnCount?: GridSizeUnit;
messages: SchemaMessage & {
/**
* 表单验证失败时的提示
*/
validateFailed?: string;
};
rules: Array<{
rule: string;
message: string;
name?: string | Array<string>;
}>;
lazyChange?: boolean;
formLazyChange?: boolean;
dispatchEvent: (event: IFormEvent, data?: any) => Promise<RendererEvent>;
onInit?: (values: object, props: any) => any;
onReset?: (values: object, action?: any) => void;
onSubmit?: (values: object, action: any) => any;
onChange?: (values: object, diff: object, props: any) => any;
onFailed?: (reason: string, errors: any) => any;
onFinished: (values: object, action: any) => any;
onValidate: (values: object, form: any) => any;
}
export type IFormEvent = 'inited' | 'validateSucc' | 'validateError' | 'change' | 'submitSucc' | 'submitFail';