@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 CHANGED
@@ -2,15 +2,19 @@
2
2
 
3
3
  English | [中文说明](./README_CN.md)
4
4
 
5
- [![](https://img.shields.io/badge/version-2.0.5-green)](https://www.npmjs.com/package/@simpleform/render)
5
+ [![](https://img.shields.io/badge/version-3.0.0-green)](https://www.npmjs.com/package/@simpleform/render)
6
6
 
7
7
  > A lightweight dynamic forms engine that makes it easy to dynamically render forms.
8
8
 
9
+ * Break Change: Version >= 3.x is recommended, providing a better semanticized `JSON` structure.
10
+ - Deprecated ~`properties`~ : Replaced by `widgetList`.
11
+ - Deprecated ~`onPropertiesChange`~ : replaced by `onRenderChange`.
12
+ - All methods of `useSimpleFormRender()` are changed.
9
13
  ## Introduction
10
- - Component Registration: Form controls used in `@simpleform/render` must be controlled components with `value` and `onChange` props.
11
- - Component Description: `properties` supports rendering of object or array types, and adding nested object fields via the `properties` property.
12
- - Component Rendering: `Form` component handles form values, `FormChildren` component handles form rendering, a `Form` component can support multiple `FormChildren` components rendering inside.
13
- - Component linkage: All form properties can support string expressions to describe linkage conditions (except `properties`).
14
+ - Component Registration: The form control used in `@simpleform/render` must be a controlled component with `value` and `onChange` `props`.
15
+ - Component Description: `widgetList` array list describing the current form structure.
16
+ - Component Rendering: `Form` component handles the values of the form, `FormChildren` component handles the rendering of the form, a `Form` component can support multiple `FormChildren` components for internal rendering.
17
+ - Component linkage: All form properties can support string expressions to describe linkage conditions (except `widgetList` property).
14
18
 
15
19
  ## install
16
20
  - [Node.js](https://nodejs.org/en/) Version >= 14.0.0
@@ -25,7 +29,7 @@ yarn add @simpleform/render
25
29
  ### 1. First register the basic components (Take antd@5.x as an example)
26
30
  ```javascript
27
31
  // register
28
- import FormRenderCore, { FormChildren as FormChildrenCore, FormRenderProps, FormChildrenProps } from '@simpleform/render';
32
+ import DefaultFormRender, { FormChildren as DefaultFormChildren, FormRenderProps, FormChildrenProps } from '@simpleform/render';
29
33
  import '@simpleform/render/lib/css/main.css';
30
34
  import React from 'react';
31
35
  import dayjs from 'dayjs';
@@ -75,7 +79,7 @@ export type CustomFormChildrenProps = FormChildrenProps<any>;
75
79
  export function FormChildren(props: CustomFormChildrenProps) {
76
80
  const { components, plugins, ...rest } = props;
77
81
  return (
78
- <FormChildrenCore
82
+ <DefaultFormChildren
79
83
  options={{ props: { autoComplete: 'off' } }}
80
84
  components={{ ...widgets, ...components }}
81
85
  plugins={{ ...plugins, dayjs }}
@@ -87,7 +91,7 @@ export type CustomFormRenderProps = FormRenderProps<any>;
87
91
  export default function FormRender(props: CustomFormRenderProps) {
88
92
  const { components, plugins, ...rest } = props;
89
93
  return (
90
- <FormRenderCore
94
+ <DefaultFormRender
91
95
  options={{ props: { autoComplete: 'off' } }}
92
96
  components={{ ...widgets, ...components }}
93
97
  plugins={{ ...plugins, dayjs }}
@@ -115,105 +119,104 @@ export default function Demo5(props) {
115
119
  }
116
120
  }
117
121
 
118
- const properties = {
119
- name1: {
120
- label: "readonly",
121
- readOnly: true,
122
- readOnlyRender: "readonly component",
123
- initialValue: 1111,
124
- hidden: '{{formvalues && formvalues.name6 == true}}',
125
- type: 'Input',
126
- props: {}
127
- },
128
- name2: {
129
- label: "input",
130
- rules: [{ required: true, message: 'input empty' }],
131
- initialValue: 1,
132
- hidden: '{{formvalues && formvalues.name6 == true}}',
133
- type: 'Input',
134
- props: {}
135
- },
136
- name3: {
137
- // type: '',
138
- // props: {},
139
- properties: [{
140
- label: 'list[0]',
141
- rules: [{ required: true, message: 'list[0] empty' }],
142
- initialValue: { label: 'option1', value: '1', key: '1' },
143
- type: 'Select',
144
- props: {
145
- labelInValue: true,
146
- style: { width: '100%' },
147
- children: [
148
- { type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } },
149
- { type: 'Select.Option', props: { key: 2, value: '2', children: 'option2' } }
150
- ]
151
- }
152
- }, {
153
- label: 'list[1]',
154
- rules: [{ required: true, message: 'list[1] empty' }],
155
- type: 'Select',
156
- props: {
157
- labelInValue: true,
158
- style: { width: '100%' },
159
- children: [
160
- { type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } },
161
- { type: 'Select.Option', props: { key: 2, value: '2', children: 'option2' } }
162
- ]
163
- }
164
- }]
165
- },
166
- name4: {
167
- // type: '',
168
- // props: {},
169
- properties: {
170
- first: {
171
- label: 'first',
172
- rules: [{ required: true, message: 'first empty' }],
173
- type: 'Select',
174
- props: {
175
- style: { width: '100%' },
176
- children: [{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } }]
177
- }
178
- },
179
- second: {
180
- label: 'second',
181
- rules: [{ required: true, message: 'second empty' }],
182
- type: 'Select',
183
- props: {
184
- style: { width: '100%' },
185
- children: [{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } }]
186
- }
187
- }
188
- }
189
- },
190
- name5: {
191
- label: 'name5',
192
- initialValue: { span: 12 },
193
- valueSetter: "{{(value)=> (value && value['span'])}}",
194
- valueGetter: "{{(value) => ({span: value})}}",
195
- type: 'Select',
196
- props: {
197
- style: { width: '100%' },
198
- children: [
199
- { type: 'Select.Option', props: { key: 1, value: 12, children: 'option1' } },
200
- { type: 'Select.Option', props: { key: 2, value: 6, children: 'option2' } },
201
- { type: 'Select.Option', props: { key: 3, value: 4, children: 'option3' } }
202
- ]
203
- }
204
- },
205
- name6: {
206
- label: 'checkbox',
207
- valueProp: 'checked',
208
- initialValue: true,
209
- rules: [{ required: true, message: 'checkbox empty' }],
210
- type: 'Checkbox',
211
- props: {
212
- style: { width: '100%' },
213
- children: 'option'
214
- }
215
- },
216
- }
122
+ const widgetList = [
123
+ {
124
+ label: "readonly",
125
+ name: 'name1',
126
+ readOnly: true,
127
+ readOnlyRender: "readonly component",
128
+ initialValue: 1111,
129
+ hidden: '{{formvalues && formvalues.name6 == true}}',
130
+ type: 'Input',
131
+ props: {}
132
+ },
133
+ {
134
+ label: "input",
135
+ name: 'name2',
136
+ rules: [{ required: true, message: 'input empty' }],
137
+ initialValue: 1,
138
+ hidden: '{{formvalues && formvalues.name6 == true}}',
139
+ type: 'Input',
140
+ props: {}
141
+ },
142
+ {
143
+ label: 'list[0]',
144
+ name: 'list[0]',
145
+ rules: [{ required: true, message: 'list[0] empty' }],
146
+ initialValue: { label: 'option1', value: '1', key: '1' },
147
+ type: 'Select',
148
+ props: {
149
+ labelInValue: true,
150
+ style: { width: '100%' },
151
+ children: [
152
+ { type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } },
153
+ { type: 'Select.Option', props: { key: 2, value: '2', children: 'option2' } }
154
+ ]
155
+ }
156
+ },
157
+ {
158
+ label: 'list[1]',
159
+ name: 'list[1]',
160
+ rules: [{ required: true, message: 'list[1] empty' }],
161
+ type: 'Select',
162
+ props: {
163
+ labelInValue: true,
164
+ style: { width: '100%' },
165
+ children: [
166
+ { type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } },
167
+ { type: 'Select.Option', props: { key: 2, value: '2', children: 'option2' } }
168
+ ]
169
+ }
170
+ },
171
+ {
172
+ label: 'first',
173
+ name: 'name4.first',
174
+ rules: [{ required: true, message: 'first empty' }],
175
+ type: 'Select',
176
+ props: {
177
+ style: { width: '100%' },
178
+ children: [{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } }]
179
+ }
180
+ },
181
+ {
182
+ label: 'second',
183
+ name: 'name4.second',
184
+ rules: [{ required: true, message: 'second empty' }],
185
+ type: 'Select',
186
+ props: {
187
+ style: { width: '100%' },
188
+ children: [{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } }]
189
+ }
190
+ },
191
+ {
192
+ label: 'name5',
193
+ name: 'name5',
194
+ initialValue: { span: 12 },
195
+ valueSetter: "{{(value)=> (value && value['span'])}}",
196
+ valueGetter: "{{(value) => ({span: value})}}",
197
+ type: 'Select',
198
+ props: {
199
+ style: { width: '100%' },
200
+ children: [
201
+ { type: 'Select.Option', props: { key: 1, value: 12, children: 'option1' } },
202
+ { type: 'Select.Option', props: { key: 2, value: 6, children: 'option2' } },
203
+ { type: 'Select.Option', props: { key: 3, value: 4, children: 'option3' } }
204
+ ]
205
+ }
206
+ },
207
+ {
208
+ label: 'checkbox',
209
+ name: 'name6',
210
+ valueProp: 'checked',
211
+ initialValue: true,
212
+ rules: [{ required: true, message: 'checkbox empty' }],
213
+ type: 'Checkbox',
214
+ props: {
215
+ style: { width: '100%' },
216
+ children: 'option'
217
+ }
218
+ },
219
+ ]
217
220
 
218
221
  const form = useSimpleForm();
219
222
  // const formrender = useSimpleFormRender();
@@ -229,7 +232,7 @@ export default function Demo5(props) {
229
232
  <FormRender
230
233
  form={form}
231
234
  // formrender={formrender}
232
- properties={properties}
235
+ widgetList={widgetList}
233
236
  watch={watch} />
234
237
  <div style={{ marginLeft: '120px' }}>
235
238
  <Button onClick={onSubmit}>submit</Button>
@@ -248,25 +251,23 @@ import { FormChildren, Form, useSimpleForm } from './form-render';
248
251
  import { Button } from 'antd';
249
252
  export default function Demo(props) {
250
253
 
251
- const properties1 = {
252
- part1: {
253
- label: "part1input",
254
- rules: [{ required: true, message: 'name1 empty' }],
255
- initialValue: 1,
256
- type: 'Input',
257
- props: {}
258
- },
259
- }
260
-
261
- const properties2 = {
262
- part2: {
263
- label: "part2input",
264
- rules: [{ required: true, message: 'name1 empty' }],
265
- initialValue: 1,
266
- type: 'Input',
267
- props: {}
268
- },
269
- }
254
+ const widgetList1 = [{
255
+ label: "part1input",
256
+ name: 'part1',
257
+ rules: [{ required: true, message: 'part1 empty' }],
258
+ initialValue: 1,
259
+ type: 'Input',
260
+ props: {}
261
+ }]
262
+
263
+ const widgetList2 = [{
264
+ label: "part2input",
265
+ name: 'part2',
266
+ rules: [{ required: true, message: 'part2 empty' }],
267
+ initialValue: 1,
268
+ type: 'Input',
269
+ props: {}
270
+ }]
270
271
 
271
272
  const form = useSimpleForm();
272
273
  // const formrender1 = useSimpleFormRender()
@@ -285,14 +286,14 @@ export default function Demo(props) {
285
286
  <p>part1</p>
286
287
  <FormChildren
287
288
  // formrender={formrender1}
288
- properties={properties1}
289
+ widgetList={widgetList1}
289
290
  />
290
291
  </div>
291
292
  <div>
292
293
  <p>part2</p>
293
294
  <FormChildren
294
295
  // formrender={formrender2}
295
- properties={properties2}
296
+ widgetList={widgetList2}
296
297
  />
297
298
  </div>
298
299
  </Form>
@@ -311,32 +312,36 @@ import FormRender, { useSimpleForm } from './form-render';
311
312
  import { Button } from 'antd';
312
313
  export default function Demo(props) {
313
314
  const form = useSimpleForm();
314
- const properties =
315
+ const widgetList =
315
316
  [
316
317
  {
317
318
  label: "list-0",
318
- rules: [{ required: true, message: 'name1 empty' }],
319
+ name: 'list[0]',
320
+ rules: [{ required: true, message: 'list[0] empty' }],
319
321
  initialValue: 1,
320
322
  type: 'Input',
321
323
  props: {}
322
324
  },
323
325
  {
324
326
  label: "list-1",
325
- rules: [{ required: true, message: 'name1 empty' }],
327
+ name: 'list[1]',
328
+ rules: [{ required: true, message: 'list[1] empty' }],
326
329
  initialValue: 2,
327
330
  type: 'Input',
328
331
  props: {}
329
332
  },
330
333
  {
331
334
  label: "list-2",
332
- rules: [{ required: true, message: 'name1 empty' }],
335
+ name: 'list[2]',
336
+ rules: [{ required: true, message: 'list[2] empty' }],
333
337
  initialValue: 3,
334
338
  type: 'Input',
335
339
  props: {}
336
340
  },
337
341
  {
338
342
  label: "list-3",
339
- rules: [{ required: true, message: 'name1 empty' }],
343
+ name: 'list[3]',
344
+ rules: [{ required: true, message: 'list[3] empty' }],
340
345
  initialValue: 4,
341
346
  type: 'Input',
342
347
  props: {}
@@ -353,7 +358,7 @@ export default function Demo(props) {
353
358
  <div style={{ padding: '0 8px' }}>
354
359
  <FormRender
355
360
  form={form}
356
- properties={properties}
361
+ widgetList={widgetList}
357
362
  />
358
363
  <div style={{ marginLeft: '120px' }}>
359
364
  <Button onClick={onSubmit}>submit</Button>
@@ -368,26 +373,25 @@ export default function Demo(props) {
368
373
  Sourced from [@simpleform/form](../form);
369
374
 
370
375
  ### FormChildren's props
371
- - `properties`: `{ [name: string]: FormNodeProps } | FormNodeProps[]` Renders the form's DSL form json data
376
+ - `widgetList`: `WidgetItem[]` Renders the form's DSL form json data
372
377
  - `components`: registers all components in the form.
373
378
  - `plugins`: foreign libraries to be introduced in the form.
374
379
  - `options`: `GenerateFormNodeProps | ((field: GenerateFormNodeProps) => any)` Parameter information passed to the form node components. The priority is lower than the form node's own parameters
375
380
  - `renderList`: Provides a function to customize the rendered list.
376
381
  - `renderItem`: provides a function to customize the rendering of the node.
377
- - `onPropertiesChange`: `(newValue: PropertiesData) => void;` `Properties` change callback function.
382
+ - `onRenderChange`: `(newValue: WidgetList) => void;` `onRenderChange` change callback function.
378
383
  - `formrender`: The form class responsible for rendering. Created by `useSimpleFormRender()`, optional.
379
384
  - `form`: Class responsible for the value of the form. Created via `useSimpleForm()`, optional.
380
385
  - `uneval`: does not execute string expressions in the form.
381
386
 
382
387
  ### SimpleFormRender's Methods
383
- - `updateItemByPath`: `(data?: any, path?: string, attributeName?: string) => void` Updates the node corresponding to the path `path`, if updating a specific attribute in the node then the `attributeName` parameter is required.
384
- - `setItemByPath`: `(data?: any, path?: string, attributeName?: string) => void` Sets the node corresponding to the path `path`, the `attributeName` parameter is required if you are updating a specific attribute in the node.
385
- - `updateNameByPath`: `(newName?: string, path: string) => void` Updates the name key of the specified path.
386
- - `delItemByPath`: `(path?: string, attributeName?: string) => void` Deletes the node corresponding to the path `path`, if deleting a specific attribute in the node then the `attributeName` parameter is required.
387
- - `insertItemByIndex`: `(data: InsertItemType, index?: number, parent?: { path?: string, attributeName?: string }) => void` Adds an option based on the serial number and the path of the parent node.
388
- - `getItemByPath`: `(path?: string, attributeName?: string) => void` Get the node that corresponds to the path `path`, or the `attributeName` parameter if it is a specific attribute in the node.
389
- - `moveItemByPath`: `(from: { parent?: string, index: number }, to: { parent?: string, index?: number })` Swap options in the tree from one location to another.
390
- - `setProperties`: `(data?: Partial<FormNodeProps>) => void` sets `properties`.
388
+ - `updateItemByPath`: `(data?: any, path?: string) => void` Get the corresponding node based on `path`.
389
+ - `setItemByPath`: `(data?: any, path?: string) => void` Sets the corresponding node according to `path`.
390
+ - `delItemByPath`: `(path?: string) => void` Removes the node corresponding to the path `path`.
391
+ - `insertItemByIndex`: `(data: WidgetItem | WidgetItem[], index?: number, parent?: string) => void` Adds a node based on the serial number and the path of the parent node.
392
+ - `getItemByPath`: `(path?: string) => void` Get the node corresponding to the path `path`.
393
+ - `moveItemByPath`: `(from: { parent?: string, index: number }, to: { parent?: string, index?: number })` Swap options in the tree from one position to another
394
+ - `setWidgetList`: `(data?: WidgetList) => void` Sets the `widgetList` attribute of the form.
391
395
 
392
396
  ### Hooks
393
397
  - `useSimpleFormRender()`: create `new SimpleFormRender()`.
@@ -395,66 +399,40 @@ Sourced from [@simpleform/form](../form);
395
399
 
396
400
  ## Other
397
401
 
398
- ### Properties structure description
399
- Each item in the `properties` property is a form node, and the nodes are categorized into nested nodes and control nodes.
400
- - Nested nodes.
401
- Nodes that have a `properties` property that describes which component the node is, via the `type` and `props` fields, and do not carry a form field component (`Form.Item`).
402
- - Form control Node.
403
- A node with no `properties` attribute that carries the form field component (`Form.Item`) by default.
402
+ ### widgetList structure description
403
+ Each item in the `widgetList` list is a rendering node, divided into a form control node and nonform node.
404
+ - Form control nodes.
405
+ Nodes with the `name` attribute are form control nodes and carry the form field component (`Form.Item`) by default, for example:
404
406
  ```javascript
405
- const properties = {
406
- name3: {
407
- // Nested nodes
408
- // type: '',
409
- // props: {},
410
- properties: {
411
- // Control node
412
- first: {
413
- label: 'first',
414
- rules: [{ required: true, message: 'first empty' }],
415
- type: 'Select',
416
- props: {
417
- style: { width: '100%' },
418
- children: [{ type: 'Select.Option', props: { key: 1, value: '1', children: 'option1' } }]
419
- }
420
- }
421
- }
422
- },
423
- }
407
+ const widgetList = [{
408
+ label: "part2input",
409
+ name: 'part2',
410
+ rules: [{ required: true, message: 'part2 empty' }],
411
+ initialValue: 1,
412
+ type: 'Input',
413
+ props: {}
414
+ }]
415
+ ```
416
+ - nonform node.
417
+ Nodes without the `name` attribute. Example:
418
+ ```javascript
419
+ const widgetList = [{
420
+ type: 'CustomCard',
421
+ props: {}
422
+ }]
424
423
  ```
425
424
  - Form Node's types
426
425
  ```javascript
427
- export interface FormComponent {
428
- type?: string;
429
- props?: any & { children?: any | Array<FormComponent> };
430
- }
431
-
432
- export type UnionComponent<P> =
433
- | React.ComponentType<P>
434
- | React.ForwardRefExoticComponent<P>
435
- | React.FC<P>
436
- | keyof React.ReactHTML;
437
-
438
- // Component
439
- export type CustomUnionType = FormComponent | Array<FormComponent> | UnionComponent<any> | Function | ReactNode
440
- // FormRender's properties
441
- export type PropertiesData = { [name: string]: FormNodeProps } | FormNodeProps[]
442
- // field's props(String expressions after compilation)
443
- export type GenerateFormNodeProps<T = {}> = FormComponent & FormItemProps & T & {
444
- ignore?: boolean; // Mark the current node as a non-form node
445
- inside?: CustomUnionType; // Nested components within nodes
446
- outside?: CustomUnionType; // Nested components in the outer layer of the node
426
+ export type GenerateWidgetItem<T extends Record<string, any> = {}> = FormItemProps & T & {
427
+ inside?: CustomUnionType; // The inner layer of the node
428
+ outside?: CustomUnionType; // The outside layer of the node
447
429
  readOnly?: boolean; // read-only mode
448
430
  readOnlyRender?: CustomUnionType; // Read-only mode rendering
449
431
  typeRender?: CustomUnionType; // Registering components for custom rendering
450
- properties?: PropertiesData;
451
432
  hidden?: boolean;
452
- }
453
- // field's props(String expressions before compilation)
454
- export type FormNodeProps = {
455
- [key in keyof GenerateFormNodeProps]: key extends 'rules' ?
456
- (string | Array<{ [key in keyof FormRule]: FormRule[key] | string }> | GenerateFormNodeProps[key])
457
- : (key extends 'properties' ? GenerateFormNodeProps[key] : (string | GenerateFormNodeProps[key]))
433
+ type?: string; // Register the component
434
+ props?: Record<string, any> & { children?: any | Array<CustomWidget> }; // Register the component's props
435
+ widgetList?: WidgetList; // children of the component(will override props.children)
458
436
  }
459
437
  ```
460
438
  ### parameter injection
@@ -476,10 +454,8 @@ Set the global properties of the form node via 'options'
476
454
  The registration component in the form receives a context parameter
477
455
  ```javascript
478
456
  export interface GenerateParams<T = {}> {
479
- name?: string;
480
457
  path?: string;
481
- field?: GenerateFormNodeProps<T>;
482
- parent?: { name?: string; path?: string, field?: GenerateFormNodeProps<T>; };
458
+ widgetItem?: GenerateWidgetItem<T>;
483
459
  formrender?: SimpleFormRender;
484
460
  form?: SimpleForm;
485
461
  };
@@ -492,15 +468,16 @@ Example:
492
468
  - `a[0].b` represents the `b` attribute of the first option below the array `a`
493
469
 
494
470
  ### String Expression Usage
495
- Property fields in a form node can support string expressions for linkage, except for `properties`.
471
+ Property fields in a form node can support string expressions for linkage, except for `widgetList`.
496
472
  1. Quick use: computational expressions wrapping target attribute values in `{{` and `}}`
497
473
  ```javascript
498
474
 
499
475
  ...
500
476
 
501
- const properties = {
502
- name1: {
477
+ const widgetList = [
478
+ {
503
479
  label: 'name1',
480
+ name: 'name1',
504
481
  valueProp: 'checked',
505
482
  initialValue: true,
506
483
  type: 'Checkbox',
@@ -508,20 +485,22 @@ Property fields in a form node can support string expressions for linkage, excep
508
485
  children: 'option'
509
486
  }
510
487
  },
511
- name2: {
488
+ {
512
489
  label: "name2",
490
+ name: 'name2',
513
491
  rules: '{{[{ required: formvalues && formvalues.name1 === true, message: "name2 empty" }]}}',
514
492
  initialValue: 1,
515
493
  type: 'Input',
516
494
  props: {}
517
- },
518
- }
495
+ }
496
+ ]
519
497
 
520
498
  // OR
521
499
 
522
- const properties = {
523
- name1: {
500
+ const widgetList = [
501
+ {
524
502
  label: 'name1',
503
+ name: 'name1',
525
504
  valueProp: 'checked',
526
505
  initialValue: true,
527
506
  type: 'Checkbox',
@@ -529,14 +508,15 @@ Property fields in a form node can support string expressions for linkage, excep
529
508
  children: 'option'
530
509
  }
531
510
  },
532
- name2: {
511
+ {
533
512
  label: "name2",
513
+ name: 'name2',
534
514
  hidden: '{{formvalues && formvalues.name1 === true}}',
535
515
  initialValue: 1,
536
516
  type: 'Input',
537
517
  props: {}
538
518
  },
539
- }
519
+ ]
540
520
  ```
541
521
  2. Rules for the use of string expressions
542
522
  - A string has and can have only one pair of `{{` and `}}`.
@@ -545,14 +525,12 @@ Property fields in a form node can support string expressions for linkage, excep
545
525
  import dayjs from 'dayjs';
546
526
  import FormRender from "./form-render";
547
527
 
548
- const properties = {
549
- name3: {
550
- label: "name3",
551
- initialValue: "{{dayjs().format('YYYY-MM-DD')}}",
552
- type: 'Input',
553
- props: {}
554
- },
555
- }
528
+ const widgetList = [{
529
+ label: "name3",
530
+ initialValue: "{{dayjs().format('YYYY-MM-DD')}}",
531
+ type: 'Input',
532
+ props: {}
533
+ }]
556
534
 
557
- <FormRender properties={properties} plugins={{ dayjs }} />
535
+ <FormRender widgetList={widgetList} plugins={{ dayjs }} />
558
536
  ```