@simpleform/render 2.0.7 → 3.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/README.md +197 -219
- package/README_CN.md +201 -222
- package/lib/components/grid.d.ts +2 -2
- package/lib/hooks.d.ts +2 -2
- package/lib/index.js +1 -1
- package/lib/store.d.ts +15 -25
- package/lib/types.d.ts +21 -31
- package/lib/utils/object.d.ts +0 -1
- package/lib/utils/utils.d.ts +13 -26
- package/package.json +2 -2
package/README_CN.md
CHANGED
|
@@ -2,15 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
[English](./README.md) | 中文说明
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/@simpleform/render)
|
|
6
6
|
|
|
7
7
|
> 轻量级动态表单引擎,实现动态渲染表单很简单.
|
|
8
8
|
|
|
9
|
+
* Break Change: 建议使用3.x以上版本,提供了更好的语义化`JSON`结构。
|
|
10
|
+
- 废弃 ~`properties`~ : 由`widgetList`代替.
|
|
11
|
+
- 废弃 ~`onPropertiesChange`~ : 由`onRenderChange`代替.
|
|
12
|
+
- `useSimpleFormRender()`的方法全部变更使用方式.
|
|
13
|
+
|
|
9
14
|
## 介绍
|
|
10
|
-
- 组件注册: 在`@simpleform/render`中使用的表单控件必须是具有`value`和`onChange
|
|
11
|
-
- 组件描述:`
|
|
15
|
+
- 组件注册: 在`@simpleform/render`中使用的表单控件必须是具有`value`和`onChange`两个`props`的受控组件.
|
|
16
|
+
- 组件描述:`widgetList`数组列表描述当前的表单结构.
|
|
12
17
|
- 组件渲染:`Form`组件处理表单的值, `FormChildren`组件处理表单的渲染, 一个`Form`组件可以支持多个`FormChildren`组件在内部渲染.
|
|
13
|
-
- 组件联动:表单属性均可以支持字符串表达式描述联动条件(`
|
|
18
|
+
- 组件联动:表单属性均可以支持字符串表达式描述联动条件(`widgetList`属性除外).
|
|
14
19
|
|
|
15
20
|
## 安装
|
|
16
21
|
- [Node.js](https://nodejs.org/en/) Version >= 14.0.0
|
|
@@ -26,7 +31,7 @@ yarn add @simpleform/render
|
|
|
26
31
|
### 1.首先注册基本组件(以antd@5.x组件库为例)
|
|
27
32
|
```javascript
|
|
28
33
|
// register
|
|
29
|
-
import
|
|
34
|
+
import DefaultFormRender, { FormChildren as DefaultFormChildren, FormRenderProps, FormChildrenProps } from '@simpleform/render';
|
|
30
35
|
import '@simpleform/render/lib/css/main.css';
|
|
31
36
|
import React from 'react';
|
|
32
37
|
import dayjs from 'dayjs';
|
|
@@ -76,7 +81,7 @@ export type CustomFormChildrenProps = FormChildrenProps<any>;
|
|
|
76
81
|
export function FormChildren(props: CustomFormChildrenProps) {
|
|
77
82
|
const { components, plugins, ...rest } = props;
|
|
78
83
|
return (
|
|
79
|
-
<
|
|
84
|
+
<DefaultFormChildren
|
|
80
85
|
options={{ props: { autoComplete: 'off' } }}
|
|
81
86
|
components={{ ...widgets, ...components }}
|
|
82
87
|
plugins={{ ...plugins, dayjs }}
|
|
@@ -88,7 +93,7 @@ export type CustomFormRenderProps = FormRenderProps<any>;
|
|
|
88
93
|
export default function FormRender(props: CustomFormRenderProps) {
|
|
89
94
|
const { components, plugins, ...rest } = props;
|
|
90
95
|
return (
|
|
91
|
-
<
|
|
96
|
+
<DefaultFormRender
|
|
92
97
|
options={{ props: { autoComplete: 'off' } }}
|
|
93
98
|
components={{ ...widgets, ...components }}
|
|
94
99
|
plugins={{ ...plugins, dayjs }}
|
|
@@ -116,105 +121,104 @@ export default function Demo5(props) {
|
|
|
116
121
|
}
|
|
117
122
|
}
|
|
118
123
|
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
children:
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
124
|
+
const widgetList = [
|
|
125
|
+
{
|
|
126
|
+
label: "readonly",
|
|
127
|
+
name: 'name1',
|
|
128
|
+
readOnly: true,
|
|
129
|
+
readOnlyRender: "readonly component",
|
|
130
|
+
initialValue: 1111,
|
|
131
|
+
hidden: '{{formvalues && formvalues.name6 == true}}',
|
|
132
|
+
type: 'Input',
|
|
133
|
+
props: {}
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
label: "input",
|
|
137
|
+
name: 'name2',
|
|
138
|
+
rules: [{ required: true, message: 'input empty' }],
|
|
139
|
+
initialValue: 1,
|
|
140
|
+
hidden: '{{formvalues && formvalues.name6 == true}}',
|
|
141
|
+
type: 'Input',
|
|
142
|
+
props: {}
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
label: 'list[0]',
|
|
146
|
+
name: 'list[0]',
|
|
147
|
+
rules: [{ required: true, message: 'list[0] empty' }],
|
|
148
|
+
initialValue: { label: 'option1', value: '1', key: '1' },
|
|
149
|
+
type: 'Select',
|
|
150
|
+
props: {
|
|
151
|
+
labelInValue: true,
|
|
152
|
+
style: { width: '100%' },
|
|
153
|
+
children: [
|
|
154
|
+
{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } },
|
|
155
|
+
{ type: 'Select.Option', props: { key: 2, value: '2', children: 'option2' } }
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
label: 'list[1]',
|
|
161
|
+
name: 'list[1]',
|
|
162
|
+
rules: [{ required: true, message: 'list[1] empty' }],
|
|
163
|
+
type: 'Select',
|
|
164
|
+
props: {
|
|
165
|
+
labelInValue: true,
|
|
166
|
+
style: { width: '100%' },
|
|
167
|
+
children: [
|
|
168
|
+
{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } },
|
|
169
|
+
{ type: 'Select.Option', props: { key: 2, value: '2', children: 'option2' } }
|
|
170
|
+
]
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
label: 'first',
|
|
175
|
+
name: 'name4.first',
|
|
176
|
+
rules: [{ required: true, message: 'first empty' }],
|
|
177
|
+
type: 'Select',
|
|
178
|
+
props: {
|
|
179
|
+
style: { width: '100%' },
|
|
180
|
+
children: [{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } }]
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
label: 'second',
|
|
185
|
+
name: 'name4.second',
|
|
186
|
+
rules: [{ required: true, message: 'second empty' }],
|
|
187
|
+
type: 'Select',
|
|
188
|
+
props: {
|
|
189
|
+
style: { width: '100%' },
|
|
190
|
+
children: [{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } }]
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
label: 'name5',
|
|
195
|
+
name: 'name5',
|
|
196
|
+
initialValue: { span: 12 },
|
|
197
|
+
valueSetter: "{{(value)=> (value && value['span'])}}",
|
|
198
|
+
valueGetter: "{{(value) => ({span: value})}}",
|
|
199
|
+
type: 'Select',
|
|
200
|
+
props: {
|
|
201
|
+
style: { width: '100%' },
|
|
202
|
+
children: [
|
|
203
|
+
{ type: 'Select.Option', props: { key: 1, value: 12, children: 'option1' } },
|
|
204
|
+
{ type: 'Select.Option', props: { key: 2, value: 6, children: 'option2' } },
|
|
205
|
+
{ type: 'Select.Option', props: { key: 3, value: 4, children: 'option3' } }
|
|
206
|
+
]
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
{
|
|
210
|
+
label: 'checkbox',
|
|
211
|
+
name: 'name6',
|
|
212
|
+
valueProp: 'checked',
|
|
213
|
+
initialValue: true,
|
|
214
|
+
rules: [{ required: true, message: 'checkbox empty' }],
|
|
215
|
+
type: 'Checkbox',
|
|
216
|
+
props: {
|
|
217
|
+
style: { width: '100%' },
|
|
218
|
+
children: 'option'
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
]
|
|
218
222
|
|
|
219
223
|
const form = useSimpleForm();
|
|
220
224
|
// const formrender = useSimpleFormRender();
|
|
@@ -230,7 +234,7 @@ export default function Demo5(props) {
|
|
|
230
234
|
<FormRender
|
|
231
235
|
form={form}
|
|
232
236
|
// formrender={formrender}
|
|
233
|
-
|
|
237
|
+
widgetList={widgetList}
|
|
234
238
|
watch={watch} />
|
|
235
239
|
<div style={{ marginLeft: '120px' }}>
|
|
236
240
|
<Button onClick={onSubmit}>submit</Button>
|
|
@@ -250,25 +254,23 @@ import { FormChildren, Form, useSimpleForm } from './form-render';
|
|
|
250
254
|
import { Button } from 'antd';
|
|
251
255
|
export default function Demo(props) {
|
|
252
256
|
|
|
253
|
-
const
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
},
|
|
271
|
-
}
|
|
257
|
+
const widgetList1 = [{
|
|
258
|
+
label: "part1input",
|
|
259
|
+
name: 'part1',
|
|
260
|
+
rules: [{ required: true, message: 'part1 empty' }],
|
|
261
|
+
initialValue: 1,
|
|
262
|
+
type: 'Input',
|
|
263
|
+
props: {}
|
|
264
|
+
}]
|
|
265
|
+
|
|
266
|
+
const widgetList2 = [{
|
|
267
|
+
label: "part2input",
|
|
268
|
+
name: 'part2',
|
|
269
|
+
rules: [{ required: true, message: 'part2 empty' }],
|
|
270
|
+
initialValue: 1,
|
|
271
|
+
type: 'Input',
|
|
272
|
+
props: {}
|
|
273
|
+
}]
|
|
272
274
|
|
|
273
275
|
const form = useSimpleForm();
|
|
274
276
|
// const formrender1 = useSimpleFormRender()
|
|
@@ -287,14 +289,14 @@ export default function Demo(props) {
|
|
|
287
289
|
<p>part1</p>
|
|
288
290
|
<FormChildren
|
|
289
291
|
// formrender={formrender1}
|
|
290
|
-
|
|
292
|
+
widgetList={widgetList1}
|
|
291
293
|
/>
|
|
292
294
|
</div>
|
|
293
295
|
<div>
|
|
294
296
|
<p>part2</p>
|
|
295
297
|
<FormChildren
|
|
296
298
|
// formrender={formrender2}
|
|
297
|
-
|
|
299
|
+
widgetList={widgetList2}
|
|
298
300
|
/>
|
|
299
301
|
</div>
|
|
300
302
|
</Form>
|
|
@@ -313,32 +315,36 @@ import FormRender, { useSimpleForm } from './form-render';
|
|
|
313
315
|
import { Button } from 'antd';
|
|
314
316
|
export default function Demo(props) {
|
|
315
317
|
const form = useSimpleForm();
|
|
316
|
-
const
|
|
318
|
+
const widgetList =
|
|
317
319
|
[
|
|
318
320
|
{
|
|
319
321
|
label: "list-0",
|
|
320
|
-
|
|
322
|
+
name: 'list[0]',
|
|
323
|
+
rules: [{ required: true, message: 'list[0] empty' }],
|
|
321
324
|
initialValue: 1,
|
|
322
325
|
type: 'Input',
|
|
323
326
|
props: {}
|
|
324
327
|
},
|
|
325
328
|
{
|
|
326
329
|
label: "list-1",
|
|
327
|
-
|
|
330
|
+
name: 'list[1]',
|
|
331
|
+
rules: [{ required: true, message: 'list[1] empty' }],
|
|
328
332
|
initialValue: 2,
|
|
329
333
|
type: 'Input',
|
|
330
334
|
props: {}
|
|
331
335
|
},
|
|
332
336
|
{
|
|
333
337
|
label: "list-2",
|
|
334
|
-
|
|
338
|
+
name: 'list[2]',
|
|
339
|
+
rules: [{ required: true, message: 'list[2] empty' }],
|
|
335
340
|
initialValue: 3,
|
|
336
341
|
type: 'Input',
|
|
337
342
|
props: {}
|
|
338
343
|
},
|
|
339
344
|
{
|
|
340
345
|
label: "list-3",
|
|
341
|
-
|
|
346
|
+
name: 'list[3]',
|
|
347
|
+
rules: [{ required: true, message: 'list[3] empty' }],
|
|
342
348
|
initialValue: 4,
|
|
343
349
|
type: 'Input',
|
|
344
350
|
props: {}
|
|
@@ -355,7 +361,7 @@ export default function Demo(props) {
|
|
|
355
361
|
<div style={{ padding: '0 8px' }}>
|
|
356
362
|
<FormRender
|
|
357
363
|
form={form}
|
|
358
|
-
|
|
364
|
+
widgetList={widgetList}
|
|
359
365
|
/>
|
|
360
366
|
<div style={{ marginLeft: '120px' }}>
|
|
361
367
|
<Button onClick={onSubmit}>submit</Button>
|
|
@@ -371,26 +377,25 @@ export default function Demo(props) {
|
|
|
371
377
|
来源于[@simpleform/form](../form);
|
|
372
378
|
|
|
373
379
|
### FormChildren's props
|
|
374
|
-
- `
|
|
380
|
+
- `widgetList`: `WidgetItem[]` 渲染表单的DSL形式的json数据
|
|
375
381
|
- `components`:注册表单中的所有组件;
|
|
376
382
|
- `plugins`:表单中需要引入的外来库;
|
|
377
383
|
- `options`: `GenerateFormNodeProps | ((field: GenerateFormNodeProps) => any)` 传递给表单节点组件的参数信息. 优先级比表单节点自身的参数要低
|
|
378
384
|
- `renderList`:提供自定义渲染列表的函数.
|
|
379
385
|
- `renderItem`:提供自定义渲染节点的函数.
|
|
380
|
-
- `
|
|
386
|
+
- `onRenderChange`: `(newValue: WidgetList) => void;` `widgetList`更改时回调函数
|
|
381
387
|
- `formrender`: 负责渲染的表单类。通过`useSimpleFormRender()`创建,选填.
|
|
382
388
|
- `form`: 负责表单的值的类。通过`useSimpleForm()`创建,选填.
|
|
383
389
|
- `uneval`: 不执行表单中的字符串表达式.
|
|
384
390
|
|
|
385
391
|
### SimpleFormRender's Methods
|
|
386
|
-
- `updateItemByPath`: `(data?: any, path?: string
|
|
387
|
-
- `setItemByPath`: `(data?: any, path?: string
|
|
388
|
-
- `
|
|
389
|
-
- `
|
|
390
|
-
- `
|
|
391
|
-
- `getItemByPath`: `(path?: string, attributeName?: string) => void` 获取路径`path`对应的节点,如果是节点中的具体属性则需要`attributeName`参数
|
|
392
|
+
- `updateItemByPath`: `(data?: any, path?: string) => void` 根据`path`获取对应的节点
|
|
393
|
+
- `setItemByPath`: `(data?: any, path?: string) => void` 根据`path`设置对应的节点
|
|
394
|
+
- `delItemByPath`: `(path?: string) => void` 删除路径`path`对应的节点
|
|
395
|
+
- `insertItemByIndex`: `(data: WidgetItem | WidgetItem[], index?: number, parent?: string) => void` 根据序号和父节点路径添加节点
|
|
396
|
+
- `getItemByPath`: `(path?: string) => void` 获取路径`path`对应的节点
|
|
392
397
|
- `moveItemByPath`: `(from: { parent?: string, index: number }, to: { parent?: string, index?: number })` 把树中的选项从一个位置调换到另外一个位置
|
|
393
|
-
- `
|
|
398
|
+
- `setWidgetList`: `(data?: WidgetList) => void` 设置表单的`widgetList`属性;
|
|
394
399
|
|
|
395
400
|
### Hooks
|
|
396
401
|
- `useSimpleFormRender()`: 创建 `new SimpleFormRender()`.
|
|
@@ -398,66 +403,40 @@ export default function Demo(props) {
|
|
|
398
403
|
|
|
399
404
|
## 其他
|
|
400
405
|
|
|
401
|
-
###
|
|
402
|
-
`
|
|
403
|
-
-
|
|
404
|
-
|
|
405
|
-
- 控件节点:
|
|
406
|
-
无`properties`属性的节点,默认携带表单域组件(`Form.Item`)。
|
|
406
|
+
### widgetList结构说明
|
|
407
|
+
`widgetList`列表中每一项均为一个渲染节点, 分为表单控件节点和非控件节点
|
|
408
|
+
- 表单控件节点:
|
|
409
|
+
具有`name`属性的节点为表单控件节点,默认携带表单域组件(`Form.Item`),举例:
|
|
407
410
|
```javascript
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
label: 'first',
|
|
417
|
-
rules: [{ required: true, message: 'first empty' }],
|
|
418
|
-
type: 'Select',
|
|
419
|
-
props: {
|
|
420
|
-
style: { width: '100%' },
|
|
421
|
-
children: [{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } }]
|
|
422
|
-
}
|
|
423
|
-
},
|
|
424
|
-
}
|
|
425
|
-
},
|
|
426
|
-
}
|
|
411
|
+
const widgetList = [{
|
|
412
|
+
label: "part2input",
|
|
413
|
+
name: 'part2',
|
|
414
|
+
rules: [{ required: true, message: 'part2 empty' }],
|
|
415
|
+
initialValue: 1,
|
|
416
|
+
type: 'Input',
|
|
417
|
+
props: {}
|
|
418
|
+
}]
|
|
427
419
|
```
|
|
428
|
-
-
|
|
420
|
+
- 普通组件节点:
|
|
421
|
+
无`name`属性的节点。举例:
|
|
429
422
|
```javascript
|
|
430
|
-
|
|
431
|
-
type
|
|
432
|
-
props
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
// 表单上的组件联合类型
|
|
442
|
-
export type CustomUnionType = FormComponent | Array<FormComponent> | UnionComponent<any> | Function | ReactNode
|
|
443
|
-
// 表单对象
|
|
444
|
-
export type PropertiesData = { [name: string]: FormNodeProps } | FormNodeProps[]
|
|
445
|
-
// 表单域(字符串表达式编译后)
|
|
446
|
-
export type GenerateFormNodeProps<T = {}> = FormComponent & FormItemProps & T & {
|
|
447
|
-
ignore?: boolean; // 标记当前节点为非表单节点
|
|
448
|
-
inside?: CustomUnionType; // 节点内层嵌套组件
|
|
449
|
-
outside?: CustomUnionType; // 节点外层嵌套组件
|
|
423
|
+
const widgetList = [{
|
|
424
|
+
type: 'CustomCard',
|
|
425
|
+
props: {}
|
|
426
|
+
}]
|
|
427
|
+
```
|
|
428
|
+
- 节点的属性
|
|
429
|
+
```javascript
|
|
430
|
+
export type GenerateWidgetItem<T extends Record<string, any> = {}> = FormItemProps & T & {
|
|
431
|
+
inside?: CustomUnionType; // 节点的内层
|
|
432
|
+
outside?: CustomUnionType; // 节点的外层
|
|
450
433
|
readOnly?: boolean; // 只读模式
|
|
451
|
-
readOnlyRender?: CustomUnionType; //
|
|
452
|
-
typeRender?: CustomUnionType; //
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
}
|
|
456
|
-
//
|
|
457
|
-
export type FormNodeProps = {
|
|
458
|
-
[key in keyof GenerateFormNodeProps]: key extends 'rules' ?
|
|
459
|
-
(string | Array<{ [key in keyof FormRule]: FormRule[key] | string }> | GenerateFormNodeProps[key])
|
|
460
|
-
: (key extends 'properties' ? GenerateFormNodeProps[key] : (string | GenerateFormNodeProps[key]))
|
|
434
|
+
readOnlyRender?: CustomUnionType; // 只读模式下的组件
|
|
435
|
+
typeRender?: CustomUnionType; // 自定义渲染实例
|
|
436
|
+
hidden?: boolean; // 隐藏节点
|
|
437
|
+
type?: string; // 注册组件
|
|
438
|
+
props?: Record<string, any> & { children?: any | Array<CustomWidget> }; // 注册组件的props
|
|
439
|
+
widgetList?: WidgetList; // 嵌套的子节点(会覆盖props.children)
|
|
461
440
|
}
|
|
462
441
|
```
|
|
463
442
|
|
|
@@ -480,10 +459,8 @@ export type FormNodeProps = {
|
|
|
480
459
|
表单中的注册组件会接收到上下文参数
|
|
481
460
|
```javascript
|
|
482
461
|
export interface GenerateParams<T = {}> {
|
|
483
|
-
name?: string;
|
|
484
462
|
path?: string;
|
|
485
|
-
|
|
486
|
-
parent?: { name?: string; path?: string, field?: GenerateFormNodeProps<T>; };
|
|
463
|
+
widgetItem?: GenerateWidgetItem<T>;
|
|
487
464
|
formrender?: SimpleFormRender;
|
|
488
465
|
form?: SimpleForm;
|
|
489
466
|
};
|
|
@@ -497,14 +474,15 @@ export interface GenerateParams<T = {}> {
|
|
|
497
474
|
- `a[0].b`表示数组a下面的第一个选项的b属性
|
|
498
475
|
|
|
499
476
|
### 字符串表达式用法
|
|
500
|
-
表单节点中属性字段除`
|
|
477
|
+
表单节点中属性字段除`widgetList`外均可以支持字符串表达式来进行联动
|
|
501
478
|
1. 快速使用:用`{{`和`}}`包裹目标属性值的计算表达式
|
|
502
479
|
```javascript
|
|
503
480
|
...
|
|
504
481
|
|
|
505
|
-
const
|
|
506
|
-
|
|
482
|
+
const widgetList = [
|
|
483
|
+
{
|
|
507
484
|
label: 'name1',
|
|
485
|
+
name: 'name1',
|
|
508
486
|
valueProp: 'checked',
|
|
509
487
|
initialValue: true,
|
|
510
488
|
type: 'Checkbox',
|
|
@@ -512,20 +490,22 @@ export interface GenerateParams<T = {}> {
|
|
|
512
490
|
children: 'option'
|
|
513
491
|
}
|
|
514
492
|
},
|
|
515
|
-
|
|
493
|
+
{
|
|
516
494
|
label: "name2",
|
|
495
|
+
name: 'name2',
|
|
517
496
|
rules: '{{[{ required: formvalues && formvalues.name1 === true, message: "name2 empty" }]}}',
|
|
518
497
|
initialValue: 1,
|
|
519
498
|
type: 'Input',
|
|
520
499
|
props: {}
|
|
521
|
-
}
|
|
522
|
-
|
|
500
|
+
}
|
|
501
|
+
]
|
|
523
502
|
|
|
524
503
|
// OR
|
|
525
504
|
|
|
526
|
-
const
|
|
527
|
-
|
|
505
|
+
const widgetList = [
|
|
506
|
+
{
|
|
528
507
|
label: 'name1',
|
|
508
|
+
name: 'name1',
|
|
529
509
|
valueProp: 'checked',
|
|
530
510
|
initialValue: true,
|
|
531
511
|
type: 'Checkbox',
|
|
@@ -533,14 +513,15 @@ export interface GenerateParams<T = {}> {
|
|
|
533
513
|
children: 'option'
|
|
534
514
|
}
|
|
535
515
|
},
|
|
536
|
-
|
|
516
|
+
{
|
|
537
517
|
label: "name2",
|
|
518
|
+
name: 'name2',
|
|
538
519
|
hidden: '{{formvalues && formvalues.name1 === true}}',
|
|
539
520
|
initialValue: 1,
|
|
540
521
|
type: 'Input',
|
|
541
522
|
props: {}
|
|
542
523
|
},
|
|
543
|
-
|
|
524
|
+
]
|
|
544
525
|
```
|
|
545
526
|
2. 字符串表达式的使用规则
|
|
546
527
|
- 一个字符串有且只能有一对`{{`和`}}`.
|
|
@@ -549,14 +530,12 @@ export interface GenerateParams<T = {}> {
|
|
|
549
530
|
import dayjs from 'dayjs';
|
|
550
531
|
import FormRender from "./form-render";
|
|
551
532
|
|
|
552
|
-
const
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
},
|
|
559
|
-
}
|
|
533
|
+
const widgetList = [{
|
|
534
|
+
label: "name3",
|
|
535
|
+
initialValue: "{{dayjs().format('YYYY-MM-DD')}}",
|
|
536
|
+
type: 'Input',
|
|
537
|
+
props: {}
|
|
538
|
+
}]
|
|
560
539
|
|
|
561
|
-
<FormRender
|
|
562
|
-
```
|
|
540
|
+
<FormRender widgetList={widgetList} plugins={{ dayjs }} />
|
|
541
|
+
```
|
package/lib/components/grid.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { ColProps, RowProps } from "antd";
|
|
|
3
3
|
import { GenerateParams } from '../types';
|
|
4
4
|
import './grid.less';
|
|
5
5
|
export declare const getColProps: (props: ColProps, inline?: boolean) => {
|
|
6
|
-
flex?: (number | import("antd/es/_util/type").LiteralUnion<"
|
|
6
|
+
flex?: (number | import("antd/es/_util/type").LiteralUnion<"auto" | "none">) | undefined;
|
|
7
7
|
order?: (string | number) | undefined;
|
|
8
8
|
offset?: (string | number) | undefined;
|
|
9
9
|
push?: (string | number) | undefined;
|
|
@@ -18,7 +18,7 @@ export declare const getColProps: (props: ColProps, inline?: boolean) => {
|
|
|
18
18
|
accessKey?: string | undefined;
|
|
19
19
|
autoFocus?: boolean | undefined;
|
|
20
20
|
className?: string | undefined;
|
|
21
|
-
contentEditable?: (boolean | "true" | "false") | "
|
|
21
|
+
contentEditable?: "inherit" | (boolean | "true" | "false") | "plaintext-only" | undefined;
|
|
22
22
|
contextMenu?: string | undefined;
|
|
23
23
|
dir?: string | undefined;
|
|
24
24
|
draggable?: (boolean | "true" | "false") | undefined;
|
package/lib/hooks.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { SimpleFormRender } from './store';
|
|
3
|
-
import {
|
|
3
|
+
import { WidgetList } from './types';
|
|
4
4
|
export declare function useSimpleFormRender(): SimpleFormRender;
|
|
5
|
-
export declare function
|
|
5
|
+
export declare function useWidgetList(formrender: SimpleFormRender): (WidgetList | import("react").Dispatch<import("react").SetStateAction<WidgetList | undefined>> | undefined)[];
|