@form-eng/core 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/README.md +499 -0
- package/dist/index.d.mts +1457 -0
- package/dist/index.d.ts +1457 -0
- package/dist/index.js +4361 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +4218 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +69 -0
- package/schemas/field-config.schema.json +310 -0
- package/schemas/wizard-config.schema.json +91 -0
package/package.json
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@form-eng/core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Core business rules engine and form orchestration for dynamic React forms",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/bghcore/form-engine.git",
|
|
8
|
+
"directory": "packages/core"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/bghcore/form-engine#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/bghcore/form-engine/issues"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"react",
|
|
16
|
+
"forms",
|
|
17
|
+
"dynamic-forms",
|
|
18
|
+
"business-rules",
|
|
19
|
+
"form-builder",
|
|
20
|
+
"react-hook-form",
|
|
21
|
+
"configuration-driven",
|
|
22
|
+
"declarative-forms",
|
|
23
|
+
"json-forms",
|
|
24
|
+
"schema-forms",
|
|
25
|
+
"form-engine",
|
|
26
|
+
"conditional-logic",
|
|
27
|
+
"field-dependencies",
|
|
28
|
+
"form-validation",
|
|
29
|
+
"async-validation",
|
|
30
|
+
"wizard-form",
|
|
31
|
+
"multi-step-form",
|
|
32
|
+
"field-array",
|
|
33
|
+
"i18n-forms",
|
|
34
|
+
"zod",
|
|
35
|
+
"json-schema"
|
|
36
|
+
],
|
|
37
|
+
"main": "dist/index.js",
|
|
38
|
+
"module": "dist/index.mjs",
|
|
39
|
+
"types": "dist/index.d.ts",
|
|
40
|
+
"exports": {
|
|
41
|
+
".": {
|
|
42
|
+
"types": "./dist/index.d.ts",
|
|
43
|
+
"import": "./dist/index.mjs",
|
|
44
|
+
"require": "./dist/index.js"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"dist",
|
|
49
|
+
"schemas",
|
|
50
|
+
"README.md"
|
|
51
|
+
],
|
|
52
|
+
"license": "MIT",
|
|
53
|
+
"sideEffects": false,
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsup",
|
|
56
|
+
"clean": "rimraf dist"
|
|
57
|
+
},
|
|
58
|
+
"peerDependencies": {
|
|
59
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
60
|
+
"react-hook-form": "^7.0.0"
|
|
61
|
+
},
|
|
62
|
+
"devDependencies": {
|
|
63
|
+
"react": "^19.2.4",
|
|
64
|
+
"react-hook-form": "^7.71.2",
|
|
65
|
+
"tsup": "^8.5.1",
|
|
66
|
+
"typescript": "^5.9.3",
|
|
67
|
+
"@types/react": "^19.2.14"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://github.com/bghcore/form-engine/field-config.schema.json",
|
|
4
|
+
"title": "Dynamic Forms Field Configuration",
|
|
5
|
+
"description": "Schema for defining configuration-driven form fields used by @form-eng/core. Each top-level property key is a field name and its value is a FieldConfig object.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": {
|
|
8
|
+
"$ref": "#/definitions/FieldConfig"
|
|
9
|
+
},
|
|
10
|
+
"definitions": {
|
|
11
|
+
"ComponentType": {
|
|
12
|
+
"type": "string",
|
|
13
|
+
"description": "UI component type key. Must match a registered component in InjectedFieldProvider.",
|
|
14
|
+
"enum": [
|
|
15
|
+
"Textbox",
|
|
16
|
+
"Dropdown",
|
|
17
|
+
"Toggle",
|
|
18
|
+
"Number",
|
|
19
|
+
"Multiselect",
|
|
20
|
+
"DateControl",
|
|
21
|
+
"Slider",
|
|
22
|
+
"DynamicFragment",
|
|
23
|
+
"SimpleDropdown",
|
|
24
|
+
"MultiSelectSearch",
|
|
25
|
+
"PopOutEditor",
|
|
26
|
+
"DocumentLinks",
|
|
27
|
+
"StatusDropdown",
|
|
28
|
+
"ReadOnly",
|
|
29
|
+
"ReadOnlyArray",
|
|
30
|
+
"ReadOnlyDateTime",
|
|
31
|
+
"ReadOnlyCumulativeNumber",
|
|
32
|
+
"ReadOnlyRichText",
|
|
33
|
+
"ReadOnlyWithButton",
|
|
34
|
+
"FieldArray",
|
|
35
|
+
"ChoiceSet",
|
|
36
|
+
"RichText",
|
|
37
|
+
"Textarea"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
"Option": {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"description": "A single option for Dropdown, StatusDropdown, Multiselect, or SimpleDropdown components.",
|
|
43
|
+
"properties": {
|
|
44
|
+
"value": {
|
|
45
|
+
"oneOf": [
|
|
46
|
+
{ "type": "string" },
|
|
47
|
+
{ "type": "number" }
|
|
48
|
+
],
|
|
49
|
+
"description": "Unique identifier for the option. Used as the stored value when this option is selected."
|
|
50
|
+
},
|
|
51
|
+
"label": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"description": "Display text shown to the user for this option."
|
|
54
|
+
},
|
|
55
|
+
"disabled": {
|
|
56
|
+
"type": "boolean",
|
|
57
|
+
"description": "If true, the option is rendered but not selectable.",
|
|
58
|
+
"default": false
|
|
59
|
+
},
|
|
60
|
+
"hidden": {
|
|
61
|
+
"type": "boolean",
|
|
62
|
+
"description": "If true, the option is not rendered in the dropdown list. Used by dropdown dependency filtering.",
|
|
63
|
+
"default": false
|
|
64
|
+
},
|
|
65
|
+
"selected": {
|
|
66
|
+
"type": "boolean",
|
|
67
|
+
"description": "If true, the option is pre-selected when the dropdown renders.",
|
|
68
|
+
"default": false
|
|
69
|
+
},
|
|
70
|
+
"title": {
|
|
71
|
+
"type": "string",
|
|
72
|
+
"description": "Tooltip text shown on hover over this option."
|
|
73
|
+
},
|
|
74
|
+
"data": {
|
|
75
|
+
"description": "Arbitrary data payload attached to this option, passed through to the field component."
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"required": ["value", "label"],
|
|
79
|
+
"additionalProperties": false
|
|
80
|
+
},
|
|
81
|
+
"DeprecatedOption": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"description": "Represents a deprecated dropdown option mapping for backward compatibility. If a field's current value matches oldVal, the deprecated option is shown as disabled with an info indicator.",
|
|
84
|
+
"properties": {
|
|
85
|
+
"oldVal": {
|
|
86
|
+
"type": "string",
|
|
87
|
+
"description": "The old/deprecated option value that should be recognized for backward compatibility."
|
|
88
|
+
},
|
|
89
|
+
"newVal": {
|
|
90
|
+
"type": "string",
|
|
91
|
+
"description": "The new replacement option value. If set, indicates the old value was renamed rather than deleted."
|
|
92
|
+
},
|
|
93
|
+
"isDeleted": {
|
|
94
|
+
"type": "boolean",
|
|
95
|
+
"description": "If true, indicates the option has been completely removed rather than renamed.",
|
|
96
|
+
"default": false
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
"required": ["oldVal"],
|
|
100
|
+
"additionalProperties": false
|
|
101
|
+
},
|
|
102
|
+
"ICondition": {
|
|
103
|
+
"type": "object",
|
|
104
|
+
"description": "A condition that matches when a field has a specific value or one of a set of values.",
|
|
105
|
+
"properties": {
|
|
106
|
+
"field": {
|
|
107
|
+
"type": "string",
|
|
108
|
+
"description": "The name of the form field to check."
|
|
109
|
+
},
|
|
110
|
+
"is": {
|
|
111
|
+
"oneOf": [
|
|
112
|
+
{ "type": "string" },
|
|
113
|
+
{
|
|
114
|
+
"type": "array",
|
|
115
|
+
"items": { "type": "string" }
|
|
116
|
+
}
|
|
117
|
+
],
|
|
118
|
+
"description": "The value or array of acceptable values. The condition is met when the field's value matches any value in this set."
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
"required": ["field", "is"],
|
|
122
|
+
"additionalProperties": false
|
|
123
|
+
},
|
|
124
|
+
"ValidationRule": {
|
|
125
|
+
"type": "object",
|
|
126
|
+
"description": "A validation rule referencing a registered validator by name, with optional flags for async and cross-field behavior.",
|
|
127
|
+
"properties": {
|
|
128
|
+
"validator": {
|
|
129
|
+
"type": "string",
|
|
130
|
+
"description": "The name of the registered validator function."
|
|
131
|
+
},
|
|
132
|
+
"async": {
|
|
133
|
+
"type": "boolean",
|
|
134
|
+
"description": "If true, this validator is asynchronous and returns a Promise.",
|
|
135
|
+
"default": false
|
|
136
|
+
},
|
|
137
|
+
"crossField": {
|
|
138
|
+
"type": "boolean",
|
|
139
|
+
"description": "If true, this validator receives all form values, not just this field's value.",
|
|
140
|
+
"default": false
|
|
141
|
+
},
|
|
142
|
+
"debounceMs": {
|
|
143
|
+
"type": "number",
|
|
144
|
+
"description": "Debounce delay in milliseconds for async validators. Prevents excessive calls during rapid input.",
|
|
145
|
+
"minimum": 0
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
"required": ["validator"],
|
|
149
|
+
"additionalProperties": false
|
|
150
|
+
},
|
|
151
|
+
"Rule": {
|
|
152
|
+
"type": "object",
|
|
153
|
+
"description": "A declarative business rule that applies config changes to fields when conditions are met.",
|
|
154
|
+
"properties": {
|
|
155
|
+
"when": {
|
|
156
|
+
"oneOf": [
|
|
157
|
+
{ "$ref": "#/definitions/ICondition" },
|
|
158
|
+
{
|
|
159
|
+
"type": "array",
|
|
160
|
+
"items": { "$ref": "#/definitions/ICondition" },
|
|
161
|
+
"description": "Array of conditions. ALL must be met (AND logic) for the rule to apply."
|
|
162
|
+
}
|
|
163
|
+
],
|
|
164
|
+
"description": "Condition(s) that must be met for this rule to apply."
|
|
165
|
+
},
|
|
166
|
+
"then": {
|
|
167
|
+
"type": "object",
|
|
168
|
+
"description": "Config overrides to apply to dependent fields when conditions are met. Keys are field names, values are partial FieldConfig objects.",
|
|
169
|
+
"additionalProperties": {
|
|
170
|
+
"$ref": "#/definitions/FieldConfig"
|
|
171
|
+
}
|
|
172
|
+
},
|
|
173
|
+
"order": {
|
|
174
|
+
"type": "array",
|
|
175
|
+
"items": { "type": "string" },
|
|
176
|
+
"description": "Field order to apply when the condition is met. Array of field names in desired order."
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"additionalProperties": false
|
|
180
|
+
},
|
|
181
|
+
"FieldConfig": {
|
|
182
|
+
"type": "object",
|
|
183
|
+
"description": "Static configuration for a single form field. This is the primary consumer-facing type used to define forms as JSON configuration. It controls the field's rendering, validation, dependencies, and business rule behavior. At runtime, field configs are processed into IRuntimeFieldState objects by the business rules engine.",
|
|
184
|
+
"properties": {
|
|
185
|
+
"type": {
|
|
186
|
+
"$ref": "#/definitions/ComponentType",
|
|
187
|
+
"description": "UI component type key (e.g., 'Textbox', 'Dropdown', 'Toggle'). Must match a registered component in InjectedFieldProvider. Can be overridden by rules to swap a field's component type at runtime."
|
|
188
|
+
},
|
|
189
|
+
"required": {
|
|
190
|
+
"type": "boolean",
|
|
191
|
+
"description": "Whether the field is required for form submission. When true, the field displays a required indicator and validation prevents saving with an empty value. Can be toggled dynamically by rules.",
|
|
192
|
+
"default": false
|
|
193
|
+
},
|
|
194
|
+
"hidden": {
|
|
195
|
+
"type": "boolean",
|
|
196
|
+
"description": "Whether the field is hidden from the form. Hidden fields are not rendered and their values are excluded from validation. Can be toggled dynamically by rules.",
|
|
197
|
+
"default": false
|
|
198
|
+
},
|
|
199
|
+
"readOnly": {
|
|
200
|
+
"type": "boolean",
|
|
201
|
+
"description": "Whether the field is read-only (rendered but not editable). The field displays its value using the read-only variant of its component.",
|
|
202
|
+
"default": false
|
|
203
|
+
},
|
|
204
|
+
"disabled": {
|
|
205
|
+
"type": "boolean",
|
|
206
|
+
"description": "Whether the field is disabled at the layout level. When the form's layout-level readOnly is set, this flag is used to compute the final read-only state. Differs from readOnly in that it interacts with skipLayoutReadOnly.",
|
|
207
|
+
"default": false
|
|
208
|
+
},
|
|
209
|
+
"label": {
|
|
210
|
+
"type": "string",
|
|
211
|
+
"description": "Display label for the field. Rendered by FieldWrapper above the field component. Also used for filter matching when the form supports field search."
|
|
212
|
+
},
|
|
213
|
+
"validate": {
|
|
214
|
+
"type": "array",
|
|
215
|
+
"items": {
|
|
216
|
+
"$ref": "#/definitions/ValidationRule"
|
|
217
|
+
},
|
|
218
|
+
"description": "Array of validation rules. Each rule references a registered validator by name and can be flagged as async or cross-field."
|
|
219
|
+
},
|
|
220
|
+
"computedValue": {
|
|
221
|
+
"type": "string",
|
|
222
|
+
"description": "Computed value expression or value function reference. Use '$values.fieldName' syntax for reactive expressions (e.g., '$values.qty * $values.price'). Use '$fn.functionName()' syntax for value functions from the ValueFunctionRegistry."
|
|
223
|
+
},
|
|
224
|
+
"computeOnCreateOnly": {
|
|
225
|
+
"type": "boolean",
|
|
226
|
+
"description": "If true, the computed value runs only during form creation (not when editing an existing entity). Used for fields like 'createdBy' or 'createdDate' that should only be set once.",
|
|
227
|
+
"default": false
|
|
228
|
+
},
|
|
229
|
+
"rules": {
|
|
230
|
+
"type": "array",
|
|
231
|
+
"items": {
|
|
232
|
+
"$ref": "#/definitions/Rule"
|
|
233
|
+
},
|
|
234
|
+
"description": "Declarative business rules. Each rule specifies conditions (when) and field config overrides (then) or field ordering (order) to apply when conditions are met."
|
|
235
|
+
},
|
|
236
|
+
"options": {
|
|
237
|
+
"type": "array",
|
|
238
|
+
"items": {
|
|
239
|
+
"$ref": "#/definitions/Option"
|
|
240
|
+
},
|
|
241
|
+
"description": "Static dropdown options for Dropdown, StatusDropdown, SimpleDropdown, and Multiselect components. Each option has a value (stored value) and label (display value). Options can be filtered at runtime by rules."
|
|
242
|
+
},
|
|
243
|
+
"defaultValue": {
|
|
244
|
+
"oneOf": [
|
|
245
|
+
{ "type": "string" },
|
|
246
|
+
{ "type": "number" },
|
|
247
|
+
{ "type": "boolean" }
|
|
248
|
+
],
|
|
249
|
+
"description": "Default value applied when the field becomes visible and its current value is null or undefined. Useful for pre-populating fields that are conditionally shown by rules."
|
|
250
|
+
},
|
|
251
|
+
"confirmInput": {
|
|
252
|
+
"type": "boolean",
|
|
253
|
+
"description": "If true, changing fields that depend on this one triggers a confirmation modal before applying the change. Used for high-impact fields where accidental changes could have cascading effects.",
|
|
254
|
+
"default": false
|
|
255
|
+
},
|
|
256
|
+
"hideOnCreate": {
|
|
257
|
+
"type": "boolean",
|
|
258
|
+
"description": "If true, the field is not rendered when the form is in create mode (i.e., no existing entity data). Useful for fields like 'lastModified' that only make sense for existing records.",
|
|
259
|
+
"default": false
|
|
260
|
+
},
|
|
261
|
+
"skipLayoutReadOnly": {
|
|
262
|
+
"type": "boolean",
|
|
263
|
+
"description": "If true, the field ignores the layout-level disabled/readOnly override. This allows specific fields to remain editable even when the form is globally set to read-only (e.g., a status field on a locked record).",
|
|
264
|
+
"default": false
|
|
265
|
+
},
|
|
266
|
+
"config": {
|
|
267
|
+
"type": "object",
|
|
268
|
+
"description": "Arbitrary configuration passed through to the field component. Can contain any key-value pairs needed by custom field implementations (e.g., icons, sort settings, placeholder text, custom styling flags). The core engine does not interpret these values.",
|
|
269
|
+
"additionalProperties": {
|
|
270
|
+
"oneOf": [
|
|
271
|
+
{ "type": "string" },
|
|
272
|
+
{ "type": "boolean" },
|
|
273
|
+
{ "type": "number" },
|
|
274
|
+
{
|
|
275
|
+
"type": "array",
|
|
276
|
+
"items": { "type": "string" }
|
|
277
|
+
},
|
|
278
|
+
{ "type": "object" }
|
|
279
|
+
]
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
"deprecatedDropdownOptions": {
|
|
283
|
+
"type": "array",
|
|
284
|
+
"items": {
|
|
285
|
+
"$ref": "#/definitions/DeprecatedOption"
|
|
286
|
+
},
|
|
287
|
+
"description": "Deprecated dropdown option mappings for backward compatibility. When a field's current value matches an oldVal entry, the deprecated option is displayed as disabled with an info indicator, allowing users to see the old value and optionally migrate to the new one."
|
|
288
|
+
},
|
|
289
|
+
"items": {
|
|
290
|
+
"type": "object",
|
|
291
|
+
"description": "Field configurations for each item in a repeating field array. Keys are sub-field names within a single item row. Only applicable when type is 'FieldArray'.",
|
|
292
|
+
"additionalProperties": {
|
|
293
|
+
"$ref": "#/definitions/FieldConfig"
|
|
294
|
+
}
|
|
295
|
+
},
|
|
296
|
+
"minItems": {
|
|
297
|
+
"type": "number",
|
|
298
|
+
"description": "Minimum number of items required in a field array. Validation will fail if fewer items exist.",
|
|
299
|
+
"minimum": 0
|
|
300
|
+
},
|
|
301
|
+
"maxItems": {
|
|
302
|
+
"type": "number",
|
|
303
|
+
"description": "Maximum number of items allowed in a field array. The 'add' button is hidden when this limit is reached.",
|
|
304
|
+
"minimum": 1
|
|
305
|
+
}
|
|
306
|
+
},
|
|
307
|
+
"additionalProperties": false
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://github.com/bghcore/form-engine/wizard-config.schema.json",
|
|
4
|
+
"title": "Dynamic Forms Wizard Configuration",
|
|
5
|
+
"description": "Schema for defining multi-step wizard configurations used by @form-eng/core. A wizard organizes form fields into sequential steps with optional conditional visibility and navigation controls.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"definitions": {
|
|
8
|
+
"ICondition": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"description": "Condition that determines whether a wizard step is visible. The step is shown only when the specified field's current value matches one of the provided values.",
|
|
11
|
+
"properties": {
|
|
12
|
+
"field": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"description": "The name of the form field whose value determines this step's visibility."
|
|
15
|
+
},
|
|
16
|
+
"is": {
|
|
17
|
+
"oneOf": [
|
|
18
|
+
{ "type": "string" },
|
|
19
|
+
{
|
|
20
|
+
"type": "array",
|
|
21
|
+
"items": {
|
|
22
|
+
"type": "string"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
],
|
|
26
|
+
"description": "The value or array of acceptable values. The step is visible when the field's current value matches any value in this set."
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"required": ["field", "is"],
|
|
30
|
+
"additionalProperties": false
|
|
31
|
+
},
|
|
32
|
+
"WizardStep": {
|
|
33
|
+
"type": "object",
|
|
34
|
+
"description": "Configuration for a single step in the wizard. Each step groups a subset of form fields and is displayed as a distinct page or section in the wizard UI.",
|
|
35
|
+
"properties": {
|
|
36
|
+
"id": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "Unique identifier for this step. Used internally for navigation state tracking and as a key for step-level operations."
|
|
39
|
+
},
|
|
40
|
+
"title": {
|
|
41
|
+
"type": "string",
|
|
42
|
+
"description": "Display title shown in the wizard step header and navigation breadcrumb/sidebar."
|
|
43
|
+
},
|
|
44
|
+
"description": {
|
|
45
|
+
"type": "string",
|
|
46
|
+
"description": "Optional descriptive text displayed below the step title. Provides additional context or instructions for the user about what this step covers."
|
|
47
|
+
},
|
|
48
|
+
"fields": {
|
|
49
|
+
"type": "array",
|
|
50
|
+
"items": {
|
|
51
|
+
"type": "string"
|
|
52
|
+
},
|
|
53
|
+
"description": "Array of field names to display in this step. Field names must match keys in the form's field configuration object. Fields are rendered in the order listed."
|
|
54
|
+
},
|
|
55
|
+
"visibleWhen": {
|
|
56
|
+
"$ref": "#/definitions/ICondition",
|
|
57
|
+
"description": "Optional condition that controls whether this step appears in the wizard. When omitted, the step is always visible. When specified, the step is only shown if the condition is met."
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"required": ["id", "title", "fields"],
|
|
61
|
+
"additionalProperties": false
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
"properties": {
|
|
65
|
+
"steps": {
|
|
66
|
+
"type": "array",
|
|
67
|
+
"items": {
|
|
68
|
+
"$ref": "#/definitions/WizardStep"
|
|
69
|
+
},
|
|
70
|
+
"description": "Ordered array of wizard steps. Steps are displayed in the order defined here, subject to visibleWhen conditions. At least one step is required.",
|
|
71
|
+
"minItems": 1
|
|
72
|
+
},
|
|
73
|
+
"linearNavigation": {
|
|
74
|
+
"type": "boolean",
|
|
75
|
+
"description": "If true, the user must complete steps in order and cannot skip ahead. The 'next' button is the only way to advance. If false, users can freely navigate to any visible step via the step navigation UI.",
|
|
76
|
+
"default": false
|
|
77
|
+
},
|
|
78
|
+
"validateOnStepChange": {
|
|
79
|
+
"type": "boolean",
|
|
80
|
+
"description": "If true, all fields in the current step are validated before allowing navigation to the next step. Validation errors prevent the step transition and are displayed to the user.",
|
|
81
|
+
"default": false
|
|
82
|
+
},
|
|
83
|
+
"saveOnStepChange": {
|
|
84
|
+
"type": "boolean",
|
|
85
|
+
"description": "If true, the form auto-saves when the user navigates to a different step. This triggers the same save mechanism as the form's auto-save feature, persisting the current step's data before moving on.",
|
|
86
|
+
"default": false
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"required": ["steps"],
|
|
90
|
+
"additionalProperties": false
|
|
91
|
+
}
|