npm package: @hbtv/pro-form
Description: ant-design 4.x 自定义Form套件
Latest version: 1.4.24

# @hbtv/pro-form 组件

ant-design 4.x 自定义Form套件

- 支持数据分组
- 支持图形化生成表单
- 支持根据数据生成表单

## 安装方法

`npm install @hbtv/pro-form --save`

## 更新记录

[查看更新记录](./CHANGELOG.md)

## 使用方法

ProForm 共有 5 个组件

- `ProForm`, 根据配置的`json`, 生成表单
- `ProFormEditor` 编辑器，图形化生成表单对应的`json`数据
- `ProFormRender` 渲染器, 根据表单配置`json`和表单数据`data`，渲染表单数据
- `TemplateRender` 渲染器, 根据表单配置`json`，表单数据`data`及模板来渲染页面
- `ProFormCodeView` 查看表单配置`json`代码

### ProForm

#### `ProForm`使用方法

```tsx
import React from 'react';
import { ProForm } from '@hbtv/pro-form';
import { Button } from 'antd';

const ProFromTest = () => {
  const [form] = ProForm.useForm();
  const fields = [
      { dataIndex: 'userName', title: '用户名', componentType: 'text' },
      { dataIndex: 'user.trueName', title: '真实姓名', componentType: 'text' },
      { dataIndex: 'user.nickname', title: '昵称', componentType: 'text' },
      { dataIndex: 'startTime', title: '时间', componentType: 'time', displayRule: 'date(HH:mm)' },
  ];
  const handleFinish = (values:any) => {
    console.log('values',values)
  };

  return (
    <>
      <ProForm form={form} fields={fields} onFinish={handleFinish} />
      <Button onClick={()=>form.submit()}>提交表单</Button>
    </>
  );
}
```

```ts
export interface ProFormProps {
  uploadServices?: ServicesType; // MediaUploadProps 的 services
  form: FormInstance; // 通过 ProForm.useForm() 创建, 等同 antd Form.useForm()
  labelCol?: any; // 等同 antd labelCol
  wrapperCol?: any; // 等同 antd wrapperCol
  menuWidth?: number; // 如果是分组表单，分类菜单的宽度
  fields: ProFormFieldType[];  // 详见下方的 字段声明
  activeGroup?: string; // 当前分组的dataIndex
  initialValue?:any; // 1.1.23 新增 表单初始值
  onGroupChange?: (
    newGroupName: string,
    oldGroupName: string,
    oldValues?: any,
    isValidate?: boolean | any,
  ) => void; // 1.1.22 修改了参数
  onFinish?: (values: any, groupName?: string) => void; // form.submit() 后校验成功后触发
  valueEnum?: {  // 可供select作为枚举值使用的枚举
    [k: string]: ProFormEnumType[];
  };
}
```

#### 字段配置文件的声明

```ts
import { ListColumnType, ValueEnumType, TreeDataType } from '@hbtv/list-input';

export interface ProFormFieldType extends ListColumnType {
  dependOn?: DependOnType[];
}
```

### ProFormEditor

辅助工具，可以生成`ProFormFieldType`对应的字段，详见`src/ProFormTest.tsx`

#### `ProFormEditor`使用方法

```tsx
import React,{ useState } from 'react';
import { ProFormFieldType } from '@hbtv/pro-form';
import { ProFormEditor } from '@hbtv/pro-form/dist/ProFormEditor';

const ProFormEditorTest = () => {
  const [fields , setFields] = useState<ProFormFieldType[]>([]);

  return <ProFormEditor value={fields} onChange={setFields} />
}
```

```ts
export interface ProFormEditorProps {
  value?: ProFormFieldType[];
  onChange?: (values: ProFormFieldType[]) => void;
  createGroupBtn?: boolean;
  previewBtn?: boolean;
  actions?: React.ReactNode[];
}
```

### ProFormRender

```tsx
import React,{ useState } from 'react';
import { ProFormFieldType } from '@hbtv/pro-form';
import { ProFormRender } from '@hbtv/pro-form/dist/ProFormRender';

const ProFormRenderTest = () => {
  const fields = [
      { dataIndex: 'userName', title: '用户名', componentType: 'text' },
      { dataIndex: 'detail.trueName', title: '真实姓名', componentType: 'text' },
      { dataIndex: 'detail.nickname', title: '昵称', componentType: 'text' },
      { dataIndex: 'startTime', title: '时间', componentType: 'time', displayRule: 'date(HH:mm)' },
  ];

  const data = {
    userName:'your name',
    detail:{
      trueName:'your trueName',
      nickname:'your nickname',
    },
    startTime:'2020-06-20 09:10:30',  // ProForm中所有的时间都保存为完整时间字符串，仅通过显示规则来显示不同
  }

  return <ProFormRender fields={fields} data={data} />
}
```

```ts
export interface ProFormRenderProps {
  fields: ProFormFieldType[];
  data?: any;
  valueEnum?: {
    [k: string]: ValueEnumType[] | TreeDataType[];
  };
}
```

### TemplateRender

```tsx
import React,{ useState } from 'react';
import { ProFormFieldType } from '@hbtv/pro-form';
import { TemplateRender } from '@hbtv/pro-form/dist/TemplateRender';

const TemplateRenderTest = () => {
  const fields = [
      { dataIndex: 'userName', title: '用户名', componentType: 'text' },
      { dataIndex: 'detail.trueName', title: '真实姓名', componentType: 'text' },
      { dataIndex: 'detail.nickname', title: '昵称', componentType: 'text' },
      { dataIndex: 'startTime', title: '时间', componentType: 'time', displayRule: 'date(HH:mm)' },
  ];

  const data = {
    userName:'your name',
    detail:{
      trueName:'your trueName',
      nickname:'your nickname',
    },
    startTime:'2020-06-20 09:10:30',  // ProForm中所有的时间都保存为完整时间字符串，仅通过显示规则来显示不同
  }

  const template = `<p>{{userName}}</p>
  <p>{{user.trueName}}</p>
  <p>{{user.nickname}}</p>
  <p>{{allowLogin}}</p>
  `;

  return <TemplateRender fields={fields} data={data} template={template} />
}
```

```ts
export interface TemplateRenderProps {
  fields: ProFormFieldType[];
  data: { [k: string]: any };
  template: string;
  valueEnum?: {
    [k: string]: ValueEnumType[] | TreeDataType[];
  };
}
```

## 显示规则配置`displayRule`

- date  显示时间及日期，例如 `date(YYYY-MM)` `date(HH:mm)`, 通`moment.format`使用的字符串
- image 显示图片，image(宽,高), 缺省为`auto`,例如 `image(128,128)`图片尺寸为 128*128,  `image(,64)`指定宽度`auto`,高度为`64`
- video 显示视频，参数同`image`
- audio 显示音频，无参数
- bool  显示布尔值
- url   显示为链接，url(显示的文本), 默认为当前值