yy-forms 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.fatherrc.js +37 -0
- package/CHANGELOG.md +254 -0
- package/LICENSE +21 -0
- package/README.md +99 -0
- package/dist/index.d.ts +145 -0
- package/dist/index.esm.js +4006 -0
- package/dist/index.js +4041 -0
- package/es/Provider.js +248 -0
- package/es/index.d.ts +145 -0
- package/es/index.js +44 -0
- package/es/settings/index.js +975 -0
- package/es/styles/atom.less +1134 -0
- package/es/styles/index.less +358 -0
- package/es/transformer/form-render.js +75 -0
- package/es/utils/context.js +3 -0
- package/es/utils/hooks.js +48 -0
- package/es/utils/index.js +706 -0
- package/es/utils/mapping.js +31 -0
- package/es/utils/serialize.js +276 -0
- package/es/widgets/htmlInput.js +20 -0
- package/es/widgets/idInput.js +23 -0
- package/es/widgets/index.js +5 -0
- package/es/widgets/jsonInput.js +24 -0
- package/es/widgets/list.js +24 -0
- package/es/widgets/percentSlider.js +89 -0
- package/package.json +53 -0
- package/src/Provider.jsx +239 -0
- package/src/components/Canvas/core/RenderChildren.jsx +18 -0
- package/src/components/Canvas/core/RenderField.jsx +129 -0
- package/src/components/Canvas/core/Wrapper.jsx +298 -0
- package/src/components/Canvas/core/Wrapper.less +57 -0
- package/src/components/Canvas/core/index.jsx +171 -0
- package/src/components/Canvas/index.jsx +178 -0
- package/src/components/Settings/GlobalSettings.jsx +48 -0
- package/src/components/Settings/ItemSettings.jsx +143 -0
- package/src/components/Settings/index.jsx +75 -0
- package/src/components/Settings/index.less +25 -0
- package/src/components/Sidebar/Element.jsx +80 -0
- package/src/components/Sidebar/Element.less +18 -0
- package/src/components/Sidebar/index.jsx +47 -0
- package/src/components/Sidebar/index.less +23 -0
- package/src/i18next/index.ts +14 -0
- package/src/i18next/locales/enUS.json +60 -0
- package/src/i18next/locales/resources.ts +7 -0
- package/src/i18next/locales/zhCN.json +3 -0
- package/src/index.d.ts +145 -0
- package/src/index.js +45 -0
- package/src/settings/index.js +1058 -0
- package/src/styles/atom.less +1134 -0
- package/src/styles/index.less +358 -0
- package/src/transformer/form-render.js +65 -0
- package/src/utils/context.js +4 -0
- package/src/utils/hooks.js +35 -0
- package/src/utils/index.js +678 -0
- package/src/utils/mapping.js +29 -0
- package/src/utils/serialize.js +368 -0
- package/src/widgets/htmlInput.jsx +24 -0
- package/src/widgets/idInput.jsx +27 -0
- package/src/widgets/index.js +6 -0
- package/src/widgets/jsonInput.jsx +29 -0
- package/src/widgets/list.jsx +28 -0
- package/src/widgets/percentSlider.jsx +74 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useDrag } from 'react-dnd';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import { addItem } from '../../utils';
|
|
5
|
+
import { useGlobal, useStore } from '../../utils/hooks';
|
|
6
|
+
import './Element.less';
|
|
7
|
+
|
|
8
|
+
const Element = ({ text, name, schema, icon, fixedName }) => {
|
|
9
|
+
const setGlobal = useGlobal();
|
|
10
|
+
const {
|
|
11
|
+
selected,
|
|
12
|
+
flatten,
|
|
13
|
+
errorFields,
|
|
14
|
+
userProps,
|
|
15
|
+
onFlattenChange,
|
|
16
|
+
elementRender,
|
|
17
|
+
} = useStore();
|
|
18
|
+
const { getId } = userProps;
|
|
19
|
+
const [{ isDragging }, dragRef] = useDrag({
|
|
20
|
+
type: 'box',
|
|
21
|
+
item: {
|
|
22
|
+
dragItem: {
|
|
23
|
+
parent: '#',
|
|
24
|
+
schema,
|
|
25
|
+
children: [],
|
|
26
|
+
},
|
|
27
|
+
$id: fixedName ? `#/${name}` : `#/${getId(name)}`,
|
|
28
|
+
},
|
|
29
|
+
collect: monitor => ({
|
|
30
|
+
isDragging: monitor.isDragging(),
|
|
31
|
+
}),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const handleElementClick = async () => {
|
|
35
|
+
if (errorFields?.length) return;
|
|
36
|
+
if (selected && !flatten[selected]) {
|
|
37
|
+
setGlobal({ selected: '#' });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const { newId, newFlatten } = addItem({
|
|
41
|
+
selected,
|
|
42
|
+
name,
|
|
43
|
+
schema,
|
|
44
|
+
flatten,
|
|
45
|
+
fixedName,
|
|
46
|
+
getId,
|
|
47
|
+
});
|
|
48
|
+
onFlattenChange(newFlatten);
|
|
49
|
+
setGlobal({ selected: newId });
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const widgetProps = {
|
|
53
|
+
text,
|
|
54
|
+
icon,
|
|
55
|
+
onClick: handleElementClick,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const originNode = <WidgetUI {...widgetProps} />;
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<div ref={dragRef}>
|
|
62
|
+
{elementRender
|
|
63
|
+
? elementRender(schema, widgetProps, originNode)
|
|
64
|
+
: originNode}
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
export default Element;
|
|
70
|
+
|
|
71
|
+
// 目前没有用icon,但是可以补上
|
|
72
|
+
const WidgetUI = ({ onClick, text, icon }) => {
|
|
73
|
+
const { t } = useTranslation(["components"]);
|
|
74
|
+
return (
|
|
75
|
+
<li className="left-item" onClick={onClick}>
|
|
76
|
+
{icon}
|
|
77
|
+
{t(text)}
|
|
78
|
+
</li>
|
|
79
|
+
);
|
|
80
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.left-item {
|
|
2
|
+
width: 7.0rem;
|
|
3
|
+
height: 2.2rem;
|
|
4
|
+
display: flex;
|
|
5
|
+
margin: 4px;
|
|
6
|
+
cursor: pointer;
|
|
7
|
+
display: flex;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
align-items: center;
|
|
10
|
+
color: #333;
|
|
11
|
+
background-color: #f5f7fa;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.left-item:hover {
|
|
15
|
+
border: 1px dashed #ddd;
|
|
16
|
+
color: #409eff;
|
|
17
|
+
border: 1px dashed #409eff;
|
|
18
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { defaultSettings } from '../../settings';
|
|
4
|
+
import { useStore } from '../../utils/hooks';
|
|
5
|
+
import Element from './Element';
|
|
6
|
+
import './index.less';
|
|
7
|
+
|
|
8
|
+
const Sidebar = props => {
|
|
9
|
+
const { t } = useTranslation();
|
|
10
|
+
const { userProps = {} } = useStore();
|
|
11
|
+
const { settings } = userProps;
|
|
12
|
+
const _settings = Array.isArray(settings) ? settings : defaultSettings;
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div className="left-layout w5-l w4">
|
|
16
|
+
{Array.isArray(_settings) ? (
|
|
17
|
+
_settings.map((item, idx) => {
|
|
18
|
+
if (item && item.show === false) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return (
|
|
22
|
+
<div key={idx}>
|
|
23
|
+
<p className="f6 b">{t(item.title, {ns: 'components'})}</p>
|
|
24
|
+
<ul className="pl0">
|
|
25
|
+
{Array.isArray(item.widgets) ? (
|
|
26
|
+
item.widgets
|
|
27
|
+
.filter(item => item.show !== false)
|
|
28
|
+
.map((widget, idx) => {
|
|
29
|
+
return (
|
|
30
|
+
<Element key={idx.toString()} {...props} {...widget} />
|
|
31
|
+
);
|
|
32
|
+
})
|
|
33
|
+
) : (
|
|
34
|
+
<div>{t('此处配置有误')}</div>
|
|
35
|
+
)}
|
|
36
|
+
</ul>
|
|
37
|
+
</div>
|
|
38
|
+
);
|
|
39
|
+
})
|
|
40
|
+
) : (
|
|
41
|
+
<div>{t('配置错误:Setting不是数组')}</div>
|
|
42
|
+
)}
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export default Sidebar;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
.left-layout {
|
|
2
|
+
flex-shrink: 0;
|
|
3
|
+
padding: 16px 0 0 8px;
|
|
4
|
+
overflow-y: auto;
|
|
5
|
+
height: 100%;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// 修复 Windows 滚动条太宽导致两列布局变成一列
|
|
9
|
+
.left-layout::-webkit-scrollbar {
|
|
10
|
+
width: 5px;
|
|
11
|
+
background-color: #0002;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.left-layout::-webkit-scrollbar-thumb {
|
|
15
|
+
background: #0004;
|
|
16
|
+
border-radius: 5px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.left-layout ul {
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-wrap: wrap;
|
|
22
|
+
align-content: flex-start;
|
|
23
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import i18n from 'i18next';
|
|
2
|
+
import { initReactI18next } from 'react-i18next';
|
|
3
|
+
import resources from './locales/resources';
|
|
4
|
+
|
|
5
|
+
i18n.use(initReactI18next).init({
|
|
6
|
+
debug: false,
|
|
7
|
+
resources: resources,
|
|
8
|
+
lng: 'cn',
|
|
9
|
+
interpolation: {
|
|
10
|
+
escapeValue: false, // react already safes from xss
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export default i18n;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"translation": {
|
|
3
|
+
"导入": "Import",
|
|
4
|
+
"清除": "Clear",
|
|
5
|
+
"清空": "Clear",
|
|
6
|
+
"导出schema": "Export Schema",
|
|
7
|
+
"最终展示": "Preview",
|
|
8
|
+
"开始编辑": "Edit",
|
|
9
|
+
"复制": "Copy",
|
|
10
|
+
"取消": "Cancel",
|
|
11
|
+
"复制成功": "Copy Success",
|
|
12
|
+
"贴入需要导入的schema,模样可点击导出schema参考": "Paste the schema. Click export schema reference",
|
|
13
|
+
"格式不对哦,请重新尝试": "Wrong format, please try again",
|
|
14
|
+
"点击/拖拽左侧栏的组件进行添加": "Click / Drag the component in the left column to add",
|
|
15
|
+
"组件配置": "Component Setting",
|
|
16
|
+
"表单配置": "Form Setting",
|
|
17
|
+
"此处配置有误": "Incorrect configuration here",
|
|
18
|
+
"配置错误:Setting不是数组": "Configuration error: setting is not an array"
|
|
19
|
+
},
|
|
20
|
+
"components": {
|
|
21
|
+
"基础组件": "Basic",
|
|
22
|
+
"高级组件": "Advanced",
|
|
23
|
+
"布局组件": "Layout",
|
|
24
|
+
"模板": "Template",
|
|
25
|
+
|
|
26
|
+
"输入框": "Input",
|
|
27
|
+
"大输入框": "Textarea",
|
|
28
|
+
"日期选择": "Date Picker",
|
|
29
|
+
"数字输入框": "NumberInput",
|
|
30
|
+
"是否选择": "Checkbox",
|
|
31
|
+
"是否switch": "Switch",
|
|
32
|
+
"下拉单选": "SelectSingle",
|
|
33
|
+
"点击单选": "Radio",
|
|
34
|
+
"下拉多选": "SelectMultiple",
|
|
35
|
+
"点击多选": "CheckboxGroup",
|
|
36
|
+
"HTML": "HTML",
|
|
37
|
+
|
|
38
|
+
"日期范围": "DateRange",
|
|
39
|
+
"数字(slider)": "Slider",
|
|
40
|
+
"图片展示": "Image",
|
|
41
|
+
"颜色选择": "ColorPicker",
|
|
42
|
+
|
|
43
|
+
"对象": "Section",
|
|
44
|
+
"常规列表": "List",
|
|
45
|
+
"简单列表": "SimpleList",
|
|
46
|
+
"表格列表": "TableList",
|
|
47
|
+
"复杂表格列表": "DrawerList",
|
|
48
|
+
"整体布局":"Grid Columns",
|
|
49
|
+
"一行一列": "Single Column",
|
|
50
|
+
"一行二列": "Two Columns",
|
|
51
|
+
"一行三列": "Three Columns",
|
|
52
|
+
"默认一行一列":"Single Column by default",
|
|
53
|
+
"标签宽度":"Form Label Width",
|
|
54
|
+
"标签展示模式": "Label Alignment",
|
|
55
|
+
"同行": "Horizontal",
|
|
56
|
+
"单独一行": "Vertical",
|
|
57
|
+
|
|
58
|
+
"复杂结构样例": "Example"
|
|
59
|
+
}
|
|
60
|
+
}
|
package/src/index.d.ts
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { FC, ForwardRefExoticComponent, ReactNode, RefAttributes } from 'react';
|
|
2
|
+
|
|
3
|
+
export interface Transformer {
|
|
4
|
+
/** 正向的转换函数 */
|
|
5
|
+
from?: (schema: any) => any;
|
|
6
|
+
/** 反向的转换函数 */
|
|
7
|
+
to?: (schema: any) => any;
|
|
8
|
+
/** 反向的转换函数 */
|
|
9
|
+
fromSetting?: (schema: any) => any;
|
|
10
|
+
/** 反向的转换函数 */
|
|
11
|
+
toSetting?: (schema: any) => any;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface ExtraButton {
|
|
15
|
+
/** 按钮文案 */
|
|
16
|
+
text: string;
|
|
17
|
+
/** 点击回调 */
|
|
18
|
+
onClick?: (event: any) => void;
|
|
19
|
+
[key: string]: any;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ControlButton {
|
|
23
|
+
/** 按钮文案 */
|
|
24
|
+
text?: string;
|
|
25
|
+
/** 点击回调 */
|
|
26
|
+
onClick?: (event: any, schema: any) => void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface SettingWidget {
|
|
30
|
+
/** 按钮生成的 schema 的 key 值 */
|
|
31
|
+
name: string;
|
|
32
|
+
/** 在左侧栏按钮展示文案 */
|
|
33
|
+
text: string;
|
|
34
|
+
/** 在左侧栏按钮展示图标 */
|
|
35
|
+
icon?: string | ReactNode;
|
|
36
|
+
/** 如果是基本组件,这个字段注明它对应的 widgets */
|
|
37
|
+
widget?: string;
|
|
38
|
+
/** 组件对应的 schema 片段 */
|
|
39
|
+
schema?: any;
|
|
40
|
+
/** 组件的配置信息,使用 form-render 的 schema 来描述 */
|
|
41
|
+
setting?: any;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface Setting {
|
|
45
|
+
/** 最外层的分组名称 */
|
|
46
|
+
title: string;
|
|
47
|
+
/** 每个组件的配置,在左侧栏是一个按钮 */
|
|
48
|
+
widgets: SettingWidget[];
|
|
49
|
+
show?: boolean;
|
|
50
|
+
useCommon?: boolean;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface FRGeneratorProps {
|
|
54
|
+
getId?: (name: string) => string;
|
|
55
|
+
/** 国际化配置 */
|
|
56
|
+
locale?: 'cn' | 'en';
|
|
57
|
+
/** 隐藏组件 ID */
|
|
58
|
+
hideId?: boolean;
|
|
59
|
+
/** 固定 id */
|
|
60
|
+
fixedName?: boolean;
|
|
61
|
+
/** 组件删除控制 */
|
|
62
|
+
canDelete?: boolean | Function;
|
|
63
|
+
/** 默认一进入编辑器展示的表单对应的 schema */
|
|
64
|
+
defaultValue?: any;
|
|
65
|
+
/** 自定义 schema 到 form-render 的 schema 的双向转换函数 */
|
|
66
|
+
transformer?: Transformer;
|
|
67
|
+
/** 编辑区顶部的自定义按钮 */
|
|
68
|
+
extraButtons?: (ExtraButton | boolean | string)[];
|
|
69
|
+
/** 选中项操作按钮 */
|
|
70
|
+
controlButtons?: (ControlButton | boolean | Function)[];
|
|
71
|
+
/** 预览态控制 */
|
|
72
|
+
preview?: boolean;
|
|
73
|
+
/** 左右侧栏配置 */
|
|
74
|
+
settings?: Setting[];
|
|
75
|
+
/** 通用配置 */
|
|
76
|
+
commonSettings?: any;
|
|
77
|
+
/** 全局配置 */
|
|
78
|
+
globalSettings?: any;
|
|
79
|
+
/** 自定义组件 */
|
|
80
|
+
widgets?: any;
|
|
81
|
+
/** 配置栏自定义组件 */
|
|
82
|
+
settingsWidgets?: any;
|
|
83
|
+
/** 组件和 schema 的映射规则 */
|
|
84
|
+
mapping?: any;
|
|
85
|
+
/** 配置表单校验 */
|
|
86
|
+
validation?: boolean;
|
|
87
|
+
fieldRender?: (
|
|
88
|
+
schema?: any,
|
|
89
|
+
widgetProps?: any,
|
|
90
|
+
children?: ReactNode,
|
|
91
|
+
originNode?: ReactNode
|
|
92
|
+
) => ReactNode;
|
|
93
|
+
fieldWrapperRender?: (
|
|
94
|
+
schema?: any,
|
|
95
|
+
isSelected?: boolean,
|
|
96
|
+
children?: ReactNode,
|
|
97
|
+
originNode?: ReactNode
|
|
98
|
+
) => ReactNode;
|
|
99
|
+
elementRender?: (
|
|
100
|
+
schema?: any,
|
|
101
|
+
widgetProps?: SettingWidget,
|
|
102
|
+
originNode?: ReactNode
|
|
103
|
+
) => ReactNode;
|
|
104
|
+
/** 表单 data 变化回调 */
|
|
105
|
+
onChange?: (data: any) => void;
|
|
106
|
+
/** 表单 schema 变化回调 */
|
|
107
|
+
onSchemaChange?: (schema: any) => void;
|
|
108
|
+
/** 画布组件选择回调 */
|
|
109
|
+
onCanvasSelect?: (schema: any) => void;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface SettingsProps {
|
|
113
|
+
/** 自定义组件 */
|
|
114
|
+
widgets?: any;
|
|
115
|
+
}
|
|
116
|
+
export interface CanvasProps {
|
|
117
|
+
/** 画布组件选择回调 */
|
|
118
|
+
onCanvasSelect?: (schema: any) => void;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface SidebarProps {
|
|
122
|
+
/** 固定 id */
|
|
123
|
+
fixedName?: boolean;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export interface Generator
|
|
127
|
+
extends ForwardRefExoticComponent<
|
|
128
|
+
FRGeneratorProps & RefAttributes<HTMLElement>
|
|
129
|
+
> {
|
|
130
|
+
Provider: FC<FRGeneratorProps>;
|
|
131
|
+
Settings: FC<SettingsProps>;
|
|
132
|
+
Canvas: FC<CanvasProps>;
|
|
133
|
+
Sidebar: FC<SidebarProps>;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
declare const FRGenerator: Generator;
|
|
137
|
+
declare const defaultSettings: Setting[];
|
|
138
|
+
declare const defaultCommonSettings: any;
|
|
139
|
+
declare const defaultGlobalSettings: any;
|
|
140
|
+
declare const fromSetting: (schema: any) => any;
|
|
141
|
+
declare const toSetting: (schema: any) => any;
|
|
142
|
+
|
|
143
|
+
export { defaultSettings, defaultCommonSettings, defaultGlobalSettings };
|
|
144
|
+
export { fromSetting, toSetting };
|
|
145
|
+
export default FRGenerator;
|
package/src/index.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React, { useEffect, forwardRef } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import Canvas from './components/Canvas';
|
|
4
|
+
import Settings from './components/Settings';
|
|
5
|
+
import Sidebar from './components/Sidebar';
|
|
6
|
+
import Provider from './Provider';
|
|
7
|
+
import './i18next';
|
|
8
|
+
import './styles/index.less';
|
|
9
|
+
|
|
10
|
+
const Generator = forwardRef(
|
|
11
|
+
(
|
|
12
|
+
{ fixedName, settingsWidgets, onCanvasSelect, locale = 'cn', ...props },
|
|
13
|
+
ref
|
|
14
|
+
) => {
|
|
15
|
+
const { i18n } = useTranslation();
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
i18n.changeLanguage(locale);
|
|
18
|
+
}, [locale]);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<Provider ref={ref} {...props}>
|
|
22
|
+
<div className="fr-generator-container">
|
|
23
|
+
<Sidebar fixedName={fixedName} />
|
|
24
|
+
<Canvas onSelect={onCanvasSelect} />
|
|
25
|
+
<Settings widgets={settingsWidgets} />
|
|
26
|
+
</div>
|
|
27
|
+
</Provider>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
Generator.Provider = Provider;
|
|
33
|
+
Generator.Sidebar = Sidebar;
|
|
34
|
+
Generator.Canvas = Canvas;
|
|
35
|
+
Generator.Settings = Settings;
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
defaultCommonSettings,
|
|
39
|
+
defaultGlobalSettings,
|
|
40
|
+
defaultSettings,
|
|
41
|
+
} from './settings';
|
|
42
|
+
export { fromSetting, toSetting } from './transformer/form-render';
|
|
43
|
+
export default Generator;
|
|
44
|
+
|
|
45
|
+
export * from './utils/serialize';
|