extended-dynamic-forms 0.3.5 → 0.3.6

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
@@ -145,6 +145,67 @@ const schema = {
145
145
  condition: { "==": [{ "var": "hasDriversLicense" }, true] }
146
146
  ```
147
147
 
148
+ Note on wizard detection:
149
+ - Wizard mode activates only when the root schema contains two or more properties whose keys start with `STEP_`.
150
+ - With a single `STEP_…` property, the form renders as a single-page form (no progress/navigation UI).
151
+ - To display steps UI, define at least two step objects (e.g., `STEP_PERSONAL`, `STEP_REVIEW`).
152
+
153
+ ### Step Layouts with LayoutGridField
154
+
155
+ Wizard steps can define their own grid layout using a custom object field (e.g., `LayoutGridField`). Place the layout at the step key in `uiSchema` and pass your custom field via `fields` to `WizardForm`.
156
+
157
+ ```tsx
158
+ import { WizardForm } from 'extended-dynamic-forms';
159
+
160
+ const schema = {
161
+ type: 'object',
162
+ properties: {
163
+ STEP_LAYOUT: {
164
+ type: 'object',
165
+ title: 'Personal Info',
166
+ properties: {
167
+ firstName: { type: 'string', title: 'First Name' },
168
+ lastName: { type: 'string', title: 'Last Name' },
169
+ age: { type: 'number', title: 'Age' },
170
+ gender: { type: 'string', enum: ['Male','Female','Other'] },
171
+ favoriteBook: { type: 'string' },
172
+ }
173
+ }
174
+ }
175
+ };
176
+
177
+ const uiSchema = {
178
+ STEP_LAYOUT: {
179
+ 'ui:field': 'LayoutGridField',
180
+ 'ui:layoutGrid': {
181
+ 'ui:row': [
182
+ { 'ui:row': { gutter: [16,16], children: [
183
+ { 'ui:col': { span: 12, children: ['firstName'] } },
184
+ { 'ui:col': { span: 12, children: ['lastName'] } }
185
+ ]}},
186
+ { 'ui:row': { gutter: [16,16], children: [
187
+ { 'ui:col': { span: 24, children: ['age'] } }
188
+ ]}},
189
+ { 'ui:row': { gutter: [16,16], children: [
190
+ { 'ui:col': { span: 24, children: ['gender'] } }
191
+ ]}},
192
+ { 'ui:row': { gutter: [16,16], children: [
193
+ { 'ui:col': { span: 24, children: ['favoriteBook'] } }
194
+ ]}}
195
+ ]
196
+ }
197
+ }
198
+ };
199
+
200
+ // LayoutGridField is included by default in EDF; no extra wiring needed
201
+ <WizardForm schema={schema} uiSchema={uiSchema} />
202
+ ```
203
+
204
+ Notes:
205
+ - EDF includes `LayoutGridField` out of the box. Just set `ui:field: 'LayoutGridField'` on the step object.
206
+ - EDF variant uses `'ui:layoutGrid'` with AntD gutter and 24-grid spans. The RJSF canonical layout (`'ui:layout'` with 12-grid widths) is also parsed.
207
+ - You can still override or extend via the `fields` prop if needed.
208
+
148
209
  ## Event System & Webhooks
149
210
 
150
211
  Central event orchestration for all form interactions:
@@ -191,6 +252,26 @@ export const CustomWidget: FC<WidgetProps> = ({ id, value, onChange, schema }) =
191
252
  };
192
253
  ```
193
254
 
255
+ ### Auto-registered by Default
256
+ - All EDF custom widgets are included by default; no wiring is required.
257
+ - Every widget is also exposed as a field, so you can use either `ui:widget` or `ui:field` with the same key.
258
+
259
+ Examples:
260
+
261
+ ```json
262
+ {
263
+ "schema": { "type": "string", "title": "First Name" },
264
+ "uiSchema": { "ui:widget": "text" }
265
+ }
266
+ ```
267
+
268
+ ```json
269
+ {
270
+ "schema": { "type": "string", "title": "First Name" },
271
+ "uiSchema": { "ui:field": "text" }
272
+ }
273
+ ```
274
+
194
275
  ## JsonLogic Migration Examples
195
276
 
196
277
  Common patterns for migrating from function-based conditions:
@@ -437,21 +518,14 @@ Common patterns for migrating from function-based conditions:
437
518
  }
438
519
  ```
439
520
 
440
- ### Widget Registration
521
+ ### Widget Registration (optional)
441
522
 
442
- Register custom widgets with ExtendedForm:
523
+ Widgets are auto-registered. You can still override or pass a subset if needed:
443
524
 
444
525
  ```typescript
445
526
  import { ExtendedForm, customWidgets } from 'extended-dynamic-forms';
446
527
 
447
- // Use all built-in widgets
448
- <ExtendedForm
449
- widgets={customWidgets}
450
- schema={schema}
451
- uiSchema={uiSchema}
452
- />
453
-
454
- // Or register specific widgets
528
+ // Override or register specific widgets
455
529
  <ExtendedForm
456
530
  widgets={{
457
531
  text: customWidgets.text,
@@ -540,4 +614,4 @@ import {
540
614
 
541
615
  ## License
542
616
 
543
- MIT License - see LICENSE file for details.
617
+ MIT License - see LICENSE file for details.
@@ -24,5 +24,8 @@ export interface WizardFormProps {
24
24
  onWebhookStart?: (webhook: WebhookConfig, event: any) => void;
25
25
  onWebhookComplete?: (webhook: WebhookConfig, event: any, response: any) => void;
26
26
  onWebhookError?: (webhook: WebhookConfig, event: any, error: Error) => void;
27
+ widgets?: any;
28
+ fields?: any;
29
+ templates?: any;
27
30
  }
28
- export declare function WizardForm({ schema, uiSchema, webhooks, formData: initialFormData, onSubmit, onStepChange, onFieldFocus, onFieldBlur, onFieldChange, onLiveChange, showProgressBar, showStepDescription, submitButtonText, liveValidate, showErrorList, onWebhookStart, onWebhookComplete, onWebhookError, }: WizardFormProps): import("react/jsx-runtime").JSX.Element;
31
+ export declare function WizardForm({ schema, uiSchema, webhooks, formData: initialFormData, onSubmit, onStepChange, onFieldFocus, onFieldBlur, onFieldChange, onLiveChange, showProgressBar, showStepDescription, submitButtonText, liveValidate, showErrorList, onWebhookStart, onWebhookComplete, onWebhookError, widgets, fields, templates, }: WizardFormProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,4 @@
1
+ import { FieldProps, RJSFSchema, StrictRJSFSchema, FormContextType } from '@rjsf/utils';
2
+
3
+ export declare const LayoutGridField: <T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: FieldProps<T, S, F>) => import("react/jsx-runtime").JSX.Element;
4
+ export default LayoutGridField;
@@ -1,24 +1,28 @@
1
+ import { default as React } from 'react';
1
2
  import { AddressField } from './fields/AddressField';
2
3
  import { PhoneField } from './fields/PhoneField';
3
4
  import { CurrencyField } from './fields/CurrencyField';
5
+ import { LayoutGridField } from './fields/LayoutGridField';
4
6
  import { ArrayFieldTemplate, ArrayFieldItemTemplate } from './arrays';
5
7
  import { WizardObjectFieldTemplate, WizardSectionTemplate } from '../layouts/wizard';
6
8
  import { SubmitButton } from './templates/SubmitButton';
7
9
  import { FieldTemplate } from './templates/FieldTemplate';
10
+ import { FieldProps } from '@rjsf/utils';
8
11
 
9
12
  export declare const customFields: {
10
- address: import('react').FC<import('@rjsf/utils').FieldProps<any, import('@rjsf/utils').RJSFSchema, any>>;
11
- phone: import('react').FC<import('@rjsf/utils').FieldProps<any, import('@rjsf/utils').RJSFSchema, any>>;
12
- currency: import('react').FC<import('@rjsf/utils').FieldProps<any, import('@rjsf/utils').RJSFSchema, any>>;
13
+ address: React.FC<FieldProps<any, import('@rjsf/utils').RJSFSchema, any>>;
14
+ phone: React.FC<FieldProps<any, import('@rjsf/utils').RJSFSchema, any>>;
15
+ currency: React.FC<FieldProps<any, import('@rjsf/utils').RJSFSchema, any>>;
16
+ LayoutGridField: <T = any, S extends import('@rjsf/utils').StrictRJSFSchema = import('@rjsf/utils').RJSFSchema, F extends import('@rjsf/utils').FormContextType = any>(props: FieldProps<T, S, F>) => import("react/jsx-runtime").JSX.Element;
13
17
  };
14
18
  export declare const customTemplates: {
15
- FieldTemplate: import('react').FC<import('@rjsf/utils').FieldTemplateProps>;
19
+ FieldTemplate: React.FC<import('@rjsf/utils').FieldTemplateProps>;
16
20
  ArrayFieldTemplate: (props: import('@rjsf/utils').ArrayFieldTemplateProps) => import("react/jsx-runtime").JSX.Element;
17
21
  ArrayFieldItemTemplate: (props: import('@rjsf/utils').ArrayFieldItemTemplateType) => import("react/jsx-runtime").JSX.Element;
18
- WizardObjectFieldTemplate: import('react').FC<import('@rjsf/utils').ObjectFieldTemplateProps>;
19
- WizardSectionTemplate: import('react').FC<import('../layouts/wizard/WizardSectionTemplate').WizardSectionTemplateProps>;
22
+ WizardObjectFieldTemplate: React.FC<import('@rjsf/utils').ObjectFieldTemplateProps>;
23
+ WizardSectionTemplate: React.FC<import('../layouts/wizard/WizardSectionTemplate').WizardSectionTemplateProps>;
20
24
  ButtonTemplates: {
21
- SubmitButton: import('react').FC<import('@rjsf/utils').SubmitButtonProps>;
25
+ SubmitButton: React.FC<import('@rjsf/utils').SubmitButtonProps>;
22
26
  };
23
27
  };
24
- export { AddressField, PhoneField, CurrencyField, FieldTemplate, ArrayFieldTemplate, ArrayFieldItemTemplate, WizardObjectFieldTemplate, WizardSectionTemplate, SubmitButton, };
28
+ export { AddressField, PhoneField, CurrencyField, LayoutGridField, FieldTemplate, ArrayFieldTemplate, ArrayFieldItemTemplate, WizardObjectFieldTemplate, WizardSectionTemplate, SubmitButton, };
@@ -3,7 +3,7 @@ export type { Rule, EngineConfig, ConditionalEngineHook, UiEffect, SchemaEffect,
3
3
  export { useConditionalUi, type UiRule } from './hooks/useConditionalUi';
4
4
  export { useConditionalSchema, type SchemaRule, } from './hooks/useConditionalSchema';
5
5
  export { useConditionalValidation, type ValidationRule, } from './hooks/useConditionalValidation';
6
- export { createDynamicArrayItemsUiSchema, mergeItemUiSchema, arrayItemPatterns, type ArrayItemsFunction, type ArrayItemConditionalFn, } from './utils/dynamicArrayItems';
6
+ export { createDynamicArrayItemsUiSchema, mergeItemUiSchema, arrayItemPatterns, normalizeUiSchemaDynamicItems, compileDynamicItems, type ArrayItemsFunction, type ArrayItemConditionalFn, type DynamicItemsConfig, type DynamicItemsRule, } from './utils/dynamicArrayItems';
7
7
  export { uiEngineConfig } from './engines/uiEngineConfig';
8
8
  export { schemaEngineConfig } from './engines/schemaEngineConfig';
9
9
  export { validationEngineConfig, createCustomValidate, } from './engines/validationEngineConfig';
@@ -40,6 +40,31 @@ export declare function createDynamicArrayItemsUiSchema(baseItemUiSchema: UiSche
40
40
  * @returns Merged UI schema
41
41
  */
42
42
  export declare function mergeItemUiSchema(base: UiSchema, overrides: Partial<UiSchema>): UiSchema;
43
+ /**
44
+ * Declarative JSON config for dynamic array items (compiled to a function at runtime)
45
+ */
46
+ export type DynamicItemsRule = {
47
+ condition: any;
48
+ ui?: Partial<UiSchema>;
49
+ otherwise?: Partial<UiSchema>;
50
+ };
51
+ export type DynamicItemsConfig = {
52
+ base?: UiSchema;
53
+ rules: DynamicItemsRule[];
54
+ };
55
+ /**
56
+ * Compile a declarative JSON config into an ArrayItemsFunction
57
+ * - Supports single-rule shorthand and multi-rule configs
58
+ * - JsonLogic context = itemData extended with {$index, $formContext}
59
+ */
60
+ export declare function compileDynamicItems(def: {
61
+ 'ui:dynamicItems': DynamicItemsConfig;
62
+ }): ArrayItemsFunction;
63
+ /**
64
+ * Recursively scan a UiSchema and convert declarative dynamic items into functions
65
+ * - Looks for items: { ui:dynamicItems: { ... } }
66
+ */
67
+ export declare function normalizeUiSchemaDynamicItems(uiSchema: UiSchema): UiSchema;
43
68
  /**
44
69
  * Helper to create common conditional patterns
45
70
  */