@bolttech/form-engine 3.0.0-beta.16 → 3.0.0-beta.17

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
@@ -1,56 +1,128 @@
1
1
  # Form Engine React Adapter
2
2
 
3
- This is a react adapter to be used with form engine.
3
+ This is an adapter to be used with the bolttech form engine. Compatible with Next.js 13 and 14 and react 18.
4
4
 
5
- ## React `<FormProvider />`
5
+ ## React `<FormGroupContextProvider />`
6
6
 
7
- React context that lets you provide configuration information to your application forms
7
+ Provider of the context surrounding the child components, providing the state and functions to manage the group of forms.
8
8
 
9
9
  ### Props
10
10
 
11
- | Prop | Type | Description |
12
- | ------------ | ------------- | ------------------------------------------------------------- |
13
- | mapper | TMapper | Allow you to map your own components to be used with the form |
14
- | propsMapping | TPropsMapping | Map your component props names with the form functionalities |
11
+ | Prop | Type | Description |
12
+ | --------- | ---------------------- | ------------------------------------------------------------------------------------------------------ |
13
+ | mappers | TMapper<ElementType>[] | Array of mappers for form element types. Allow you to map your own components to be used with the form |
14
+ | debugMode | boolean | Optional flag to enable debug mode (default: `false`). |
15
+
16
+ ### Implementation
17
+
18
+ - Creates a reference to the form group instance.
19
+ - Defines functions for adding, getting, and removing forms from the group.
20
+ - Defines a function to print the form group instance.
21
+ - Defines a function to submit multiple forms via the index.
22
+ - Defines the value of the context with the created functions and states.
23
+ - Returns the context provider involving the child components.
15
24
 
16
25
  ### Example
17
26
 
18
27
  The following example shows a provider that will provide forms with input and Dropdown component
19
28
 
20
- ```javascript
21
- import Input from 'Components/Input';
22
- import Dropdown from 'Components/Dropdown';
29
+ #### With lazy import
23
30
 
24
- const Mappings = {
25
- inputForm: { component: Input },
26
- dropdownForm: { component: Dropdown },
31
+ ```typescript
32
+ import { ElementType, SyntheticEvent } from 'react';
33
+ import { TValueChangeEvent, TMapper } from '@bolttech/form-engine-core';
34
+
35
+ const defaultChangeEvent: TValueChangeEvent = (event: unknown) => {
36
+ return (event as SyntheticEvent<HTMLInputElement>).currentTarget.value;
27
37
  };
28
38
 
29
- const propsMapping = {
30
- inputForm: {
31
- getValue: 'onChange',
32
- setValue: 'value',
39
+ const pathImports = {
40
+ input: lazy(() =>
41
+ import('@bolttech/atoms-input').then((module) => ({
42
+ default: module.Input,
43
+ }))
44
+ ),
45
+ };
46
+
47
+ const mappers: TMapper<ElementType>[] = [
48
+ {
49
+ asynccomponent: pathImports.input,
50
+ componentName: 'input',
51
+ events: {
52
+ getValue: 'onChange',
53
+ setValue: 'value',
54
+ setErrorMessage: 'errorMessage',
55
+ onBlur: 'onBlur',
56
+ onFocus: 'onFocus',
57
+ onKeyUp: 'onKeyUp',
58
+ onKeyDown: 'onKeyUpCapture',
59
+ },
60
+ valueChangeEvent: defaultChangeEvent,
33
61
  },
34
- dropdownForm: {
35
- getValue: 'onChangeCallback',
36
- setValue: 'data',
37
- setErrorMessage: 'errorMessageArray',
38
- setErrorState: 'isErrored',
39
- onBlur: 'onBlurCallback',
40
- onFocus: 'onFocusCallback',
41
- onKeyUp: 'onKeyUpCallback',
42
- onKeyDown: 'onKeyDownCallback',
62
+ ];
63
+ ```
64
+
65
+ #### Without lazy import
66
+
67
+ ```typescript
68
+ import { ElementType, SyntheticEvent } from 'react';
69
+ import { TValueChangeEvent, TMapper } from '@bolttech/form-engine-core';
70
+ import { OptionType } from '@bolttech/atoms-select';
71
+ import { Dropdown } from '@bolttech/molecules-dropdown';
72
+
73
+ const mappers: TMapper<ElementType>[] = [
74
+ {
75
+ component: Dropdown,
76
+ componentName: 'dropdown',
77
+ events: {
78
+ getValue: 'onChange',
79
+ setValue: 'value',
80
+ setErrorMessage: 'errorMessage',
81
+ },
82
+ valueChangeEvent: (event: unknown, opts) => {
83
+ if (typeof event === 'object' && event !== null && 'value' in event && 'id' in event) {
84
+ return {
85
+ _value: event?.id,
86
+ _metadata: event,
87
+ };
88
+ } else if (typeof event === 'string' && typeof opts === 'object' && 'props' in opts && typeof opts.props === 'object' && 'optionList' in opts.props && Array.isArray(opts.props.optionList)) {
89
+ const option = (opts.props.optionList as OptionType[]).find((el) => el?.value === event);
90
+ if (option) return { _value: option.id, _metadata: option };
91
+ } else return { _value: event, _metadata: event };
92
+ },
43
93
  },
94
+ ];
95
+ ```
96
+
97
+ The codes above are created using the `valueChangeEvent` method, which is a new way of controlling how the field value will be manipulated when setValue happens. In other words: Optional function to handle value changes.
98
+
99
+ #### Calling provider
100
+
101
+ ```typescript
102
+ import React from 'react';
103
+ import { FormGroupContextProvider } from '@bolttech/form-engine'; // Import the previously created provider
104
+
105
+ type Props = {
106
+ children: React.ReactNode;
44
107
  };
45
108
 
46
- const App = () => {
47
- return <FormProvider mapper={Mappings} propsMapping={propsMapping} />;
109
+ const App = ({ children }: Props): React.ReactElement => {
110
+ const mappers = []; // Define your type mappers here
111
+ const debugMode = true; // Enable debug mode
112
+
113
+ return (
114
+ <FormGroupContextProvider mappers={mappers} debugMode={debugMode}>
115
+ {children}
116
+ </FormGroupContextProvider>
117
+ );
48
118
  };
119
+
120
+ export default App;
49
121
  ```
50
122
 
51
- You now can use in your [form](#react-form-) the mapped components with names `inputForm` and `dropdownForm`.
123
+ You now can use in your [form](#react-form-) the mapped components with names `input` and `dropdown`.
52
124
 
53
- Also note the data in `propsMapping`. There you can map up to five form functionalities per component
125
+ Also note the data in `TMapper.events`. There you can map up to five form functionalities per component
54
126
 
55
127
  | Key | Functionality |
56
128
  | --------------- | -------------------------------------------------------------------------------------------------------------------- |
@@ -63,7 +135,7 @@ Also note the data in `propsMapping`. There you can map up to five form function
63
135
  | onKeyUp | Prop name that is called when user releases a key on field |
64
136
  | onKeyDown | Prop name that is called when user presses a key on field |
65
137
 
66
- You can also use default prop names for functionalities like:
138
+ [DEPRECIATED] You can also use default prop names for functionalities like:
67
139
 
68
140
  ```javascript
69
141
  import Input from 'Components/Input';
@@ -91,180 +163,131 @@ const App = () => {
91
163
  };
92
164
  ```
93
165
 
94
- This will make form search for those names in all your components that do not have split mapping.
166
+ [DEPRECIATED] This will make form search for those names in all your components that do not have split mapping.
95
167
 
96
- ## React `<Form />`
168
+ ## React `useFormGroupContext()` hook
97
169
 
98
- After configuring the provider, `<Form />` components lets you render a form
170
+ Hook that facilitates the use of the FormGroupContext context in functional components.
99
171
 
100
- ### Props
172
+ - Checks if the context is set and throws an error if not.
173
+ - Returns the context.
101
174
 
102
- | Prop | Type | Description |
103
- | --------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
104
- | disable | boolean | Disable all form inputs. It will use the default htm disable attribute |
105
- | group | string | Form group identifier. Used be able to group several forms and then get data with useGroupForm. One will be generated as default if omitted |
106
- | id | string | Form identified. One will be generated as default if omitted |
107
- | hooks | THooks | Provide functions to run on certain life-cycle events |
108
- | iVars | Object | One object with internal variables to be used in form with data binding |
109
- | initialValues | Object | Object with form initial values that will map to a field. |
110
- | Schema | TSchema | Form Schema |
111
- | autoComplete | string | HTML autocomplete |
112
- | className | string | Allow to style form |
113
- | onSubmit | callback(HTMLFormElement,TFormValues) | Will be called when there is a submit action in the form |
114
- | onData | callback(TFormValues,TComponent, TField) | Will be called when any field data change. The arguments will let you know which field changed and the field configuration |
115
- | onBlur | callback(TFormValues,TComponent, TField) | Will be called when any field blured. The arguments will let you know which field blured and the field configuration |
116
- | onFocus | callback(TFormValues,TComponent, TField) | Will be called when any field focused change. The arguments will let you know which field focused and the field configuration |
117
- | onFieldMount | callback(TFormValues,TComponent, TField) | Will be called when some field mounted. Its called with the field that information that mounted. |
118
- | onStep | callback(TFormValues) | Called when a form step changed |
119
- | onLog | callback(TLoggingEvent) | Called on each log, if the logging is enabled |
120
- | onScopeChange | onScopeChange?(scope: TScope, namespace: string, key: string): void; | Called everything scope change with the changing information (namespace and key) and the changed scope |
121
- | onClick | onClick(TFormValues, TField) | Callback function that runs on each component click |
122
- | afterApiCall | afterApiCall(values: TFormValues, component?: TComponent, field?: TField) | Callback function that runs on each component after api call. |
123
- | onFieldRehydrate | onFieldRehydrate?(values: TFormValues, component: TComponent, field: TField): void | This callback is called whenever some form field was rehydrated |
124
- | renderLoading | renderLoading?(): ReactElement; | Component to render while the schema has not rendered |
125
- | onFormMount | onFormMount?(values: TFormValues): void; | Called when the form finished mounted |
126
- | formattedDataDefaults | Object | Some default data to fields when they are undefined |
127
- | submitOnValidOnly | boolean | Boolean indicating if form can be submitted even if it is invalid |
128
- | renderFieldWrapper | renderFieldWrapper(component: TComponent, children: ReactElement[]) | Function that allows to insert a wrapper in place of a component or wrapping the component |
175
+ ### What comes from
129
176
 
130
- ### Example
177
+ - `addForm`: Function to add a form to the group.
178
+ - `getForm`: Function to obtain a specific form from the group.
179
+ - `removeForm`: Function to remove a form from the group.
180
+ - `formGroupInstance`: Instance of the form group.
181
+ - `printFormGroupInstance`: Function to print the form group instance.
182
+ - `submitMultipleFormsByIndex`: Function to submit multiple forms by index.
131
183
 
132
- A simple example of rendering a basic form
133
-
134
- ```javascript
135
- <Form schema={schema} />
184
+ ```typescript
185
+ type TFormContext = {
186
+ addForm: (payload: { key: string; formInstance: TFormCore }) => void;
187
+ getForm: (payload: { key: string }) => FormCore | undefined;
188
+ removeForm: (payload: { key: string }) => void;
189
+ formGroupInstance: TFormGroup;
190
+ printFormGroupInstance: () => void;
191
+ submitMultipleFormsByIndex: (indexes: string[]) => TFormValues;
192
+ };
136
193
  ```
137
194
 
138
- ## React `useForm()`
139
-
140
- Exposed hook that allows you to connect to any form by the formId in any part of the application, as long as you are inside the form context.
195
+ ### Example
141
196
 
142
- ### Props
197
+ ```typescript
198
+ import React from 'react';
199
+ import { useFormGroupContext } from '@bolttech/form-engine'; // Import the previously created hook
143
200
 
144
- You can use the following arguments to tho hook
201
+ const FormComponent = (): React.ReactElement => {
202
+ const { addForm, removeForm, getForm, printFormGroupInstance, submitMultipleFormsByIndex, debugMode } = useFormGroupContext();
145
203
 
146
- | Prop | Type | Description |
147
- | -------- | --------------- | ------------------------------------------------------ |
148
- | id | string | The id of the form you want to connect to |
149
- | ids | array of string | A range of ids of the each form you want to connect to |
150
- | onValid | callback | Called whenever form validation changes |
151
- | onClick | callback | Called whenever field has clicked |
152
- | onData | callback | Called whenever data changes |
153
- | onSubmit | callback | Called whenever form is submitted |
204
+ const handleAddForm = () => {
205
+ const key = 'form1';
206
+ const formInstance = new FormCore(); // Assuming FormCore is an existing class
207
+ addForm({ key, formInstance });
208
+ };
154
209
 
155
- And it will provide you the following
210
+ const handleRemoveForm = () => {
211
+ const key = 'form1';
212
+ removeForm({ key });
213
+ };
156
214
 
157
- | Prop | Type | Description |
158
- | ---------- | -------- | ----------------------------------------------------------------------------------------------- |
159
- | submitForm | function | Function that lets you call the submit on the form. After, the onSubmit callback will be called |
160
- | formData | function | Lets you get the most up-to-date form date |
215
+ const handleGetForm = () => {
216
+ const key = 'form1';
217
+ const form = getForm({ key });
218
+ console.log(form);
219
+ };
161
220
 
162
- ### Example
221
+ const handleSubmitForms = () => {
222
+ const indexes = ['form1', 'form2'];
223
+ const formValues = submitMultipleFormsByIndex(indexes);
224
+ console.log(formValues);
225
+ };
163
226
 
164
- In the following example `useForm` hooks are used to connect to multiple forms that are inside other components.
227
+ return (
228
+ <div>
229
+ <button onClick={handleAddForm}>Add Form</button>
230
+ <button onClick={handleRemoveForm}>Remove Form</button>
231
+ <button onClick={handleGetForm}>Get Form</button>
232
+ <button onClick={handleSubmitForms}>Submit Forms</button>
233
+ <button onClick={printFormGroupInstance}>Print Form Group Instance</button>
234
+ {debugMode && <p>Debug mode is enabled</p>}
235
+ </div>
236
+ );
237
+ };
165
238
 
166
- ```javascript
167
- const Comp = () => {
168
- const { submitForm: submitOne } = useForm({
169
- id: 'id1',
170
- onData: (data) => {},
171
- onSubmit: () => {},
172
- });
173
- const { submitForm: submitTwo } = useForm({
174
- id: 'id2',
175
- onData: (data) => {},
176
- onSubmit: () => {},
177
- });
178
-
179
- return (
180
- <>
181
- <button onClick={(() => submitOne())}>
182
- <button onClick={(() => submitTwo())}>
183
- </>
184
- );
185
- }
186
-
187
- const CompOne = () => {
188
- return (
189
- <Form id="id1" {...}/>
190
- );
191
- }
192
-
193
- const CompTwo = () => {
194
- return (
195
- <Form id="id2" {...} />
196
- );
197
- }
239
+ export default FormComponent;
198
240
  ```
199
241
 
200
- ## React `useFormGroup()`
242
+ ## React `<Form />`
201
243
 
202
- Similar to `useForm`
244
+ After configuring the provider, `<Form />` components lets you render a form
203
245
 
204
246
  ### Props
205
247
 
206
- You can use the following arguments to tho hook
207
-
208
- | Prop | Type | Description |
209
- | -------- | --------------- | --------------------------------------------------------- |
210
- | ids | array of string | The ids we want to listen to |
211
- | group | string | A string to identify the form group we want to connect to |
212
- | onValid | callback | Called whenever form validation changes |
213
- | onClick | callback | Called whenever field has clicked |
214
- | onData | callback | Called whenever data changes |
215
- | onSubmit | callback | Called whenever form is submitted |
216
-
217
- And it will provide you the following
218
-
219
- | Prop | Type | Description |
220
- | ---------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
221
- | submitForm | function | Function that lets you call the submit on the form. After, the onSubmit callback will be called |
222
- | formData | function({aggregate}) | Lets you get the most up-to-date form date in two ways. Aggregate the forms data in a single object or split by the several forms in the group or identified by the id |
248
+ | Prop | Type | Description |
249
+ | ----------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
250
+ | [DEPRECIATED] disable | boolean | Disable all form inputs. It will use the default htm disable attribute |
251
+ | [DEPRECIATED] group | string | Form group identifier. Used be able to group several forms and then get data with useGroupForm. One will be generated as default if omitted |
252
+ | index | string | Form identified. One will be generated as default if omitted |
253
+ | [DEPRECIATED] hooks | THooks | Provide functions to run on certain life-cycle events |
254
+ | iVars | Object | One object with internal variables to be used in form with data binding |
255
+ | initialValues | Object | Object with form initial values that will map to a field. |
256
+ | Schema | TSchema | Form Schema |
257
+ | [DEPRECIATED] autoComplete | string | HTML autocomplete |
258
+ | className | string | Allow to style form |
259
+ | onSubmit | callback(HTMLFormElement,TFormValues) | Will be called when there is a submit action in the form |
260
+ | onData | callback(TFormValues,TComponent, TField) | Will be called when any field data change. The arguments will let you know which field changed and the field configuration |
261
+ | onBlur | callback(TFormValues,TComponent, TField) | Will be called when any field blured. The arguments will let you know which field blured and the field configuration |
262
+ | onFocus | callback(TFormValues,TComponent, TField) | Will be called when any field focused change. The arguments will let you know which field focused and the field configuration |
263
+ | onMount | callback(TFormValues,TComponent, TField) | Will be called when some field mounted. Its called with the field that information that mounted. |
264
+ | [DEPRECIATED] onStep | callback(TFormValues) | Called when a form step changed |
265
+ | [DEPRECIATED] onLog | callback(TLoggingEvent) | Called on each log, if the logging is enabled |
266
+ | [DEPRECIATED] onScopeChange | onScopeChange?(scope: TScope, namespace: string, key: string): void; | Called everything scope change with the changing information (namespace and key) and the changed scope |
267
+ | onClick | onClick(TFormValues, TField) | Callback function that runs on each component click |
268
+ | onApiResponse | onApiResponse(values: TFormValues, component?: TComponent, field?: TField) | Callback function that runs on each component after api call. |
269
+ | [DEPRECIATED] onFieldRehydrate | onFieldRehydrate?(values: TFormValues, component: TComponent, field: TField): void | This callback is called whenever some form field was rehydrated |
270
+ | [DEPRECIATED] renderLoading | renderLoading?(): ReactElement; | Component to render while the schema has not rendered |
271
+ | [DEPRECIATED] onFormMount | onFormMount?(values: TFormValues): void; | Called when the form finished mounted |
272
+ | [DEPRECIATED] formattedDataDefaults | Object | Some default data to fields when they are undefined |
273
+ | [DEPRECIATED] submitOnValidOnly | boolean | Boolean indicating if form can be submitted even if it is invalid |
274
+ | [DEPRECIATED] renderFieldWrapper | renderFieldWrapper(component: TComponent, children: ReactElement[]) | Function that allows to insert a wrapper in place of a component or wrapping the component |
223
275
 
224
276
  ### Example
225
277
 
226
- In the following example `useForm` hooks are used to connect to multiple forms that are inside other components.
278
+ A simple example of rendering a basic form
227
279
 
228
280
  ```javascript
229
- useForm({
230
- onSubmit: () => {
231
- dispatch(
232
- formData({
233
- aggregate: true,
234
- }),
235
- );
236
- },
237
- id: 'main-form',
238
- });
239
- const { formData } = useFormGroup({
240
- onSubmit: (data) => {
241
- console.log('SUBMIT', data);
242
- },
243
- onData: (data) => {
244
- console.log('-> ', data);
245
- },
246
- group: 'logical',
247
- });
248
-
249
- return (
250
- <Form
251
- id="1"
252
- group="logical"
253
- schema={...}
254
- />
255
- <Form
256
- id="2"
257
- group="logical"
258
- schema={...}
259
- />
260
- <Form
261
- id="main-form"
262
- schema={...}
263
- />
264
- )
281
+ <Form schema={schema} />
265
282
  ```
266
283
 
267
- The above example will connect to main-form with `useForm` and to a form group (logical) with `useFormGroup`
284
+ ## React `useForm()`
285
+
286
+ Exposed hook that allows you to connect to any form by the formId in any part of the application, as long as you are inside the form context.
287
+
288
+ ## React `useFormGroup()` [DEPRECIATED]
289
+
290
+ Similar to `useForm`
268
291
 
269
292
  ## React `asFormField()`
270
293
 
@@ -314,54 +337,83 @@ In the following example `asFormField` hooks are used to create `Component` fiel
314
337
  propsMapping: propsMapping.component,
315
338
  };
316
339
 
317
- <FormProvider mapper={Mappings} propsMapping={formBuilderPropsMapping}>
340
+ <FormGroupContextProvider mapper={Mappings}>
318
341
  <FormComponent
319
342
  formId="test"
320
343
  label="Field example"
321
344
  name="ss"
322
- filter={{ maxLength: 10 }}
323
- masks={{
324
- ON_FIELD_FOCUS: { cleanMask: true },
325
- ON_FIELD_BLUR: {
326
- generic: [
327
- {
328
- from: 1,
329
- to: 2,
330
- mask: 'X',
331
- },
332
- {
333
- from: 4,
334
- to: 5,
335
- mask: 'X',
336
- },
337
- ],
338
- },
339
- }}
340
- formatters={{
341
- ON_FIELD_CHANGE: {
342
- splitter: [
343
- {
344
- position: 2,
345
- value: '/',
346
- },
347
- {
348
- position: 5,
349
- value: '/',
350
- },
351
- ],
352
- },
353
- }}
345
+ formatters={
346
+ splitter: [
347
+ {
348
+ position: 2,
349
+ value: '/',
350
+ },
351
+ {
352
+ position: 5,
353
+ value: '/',
354
+ },
355
+ ]
356
+ }
354
357
  validations={{
355
- ON_FIELD_BLUR: {
358
+ config: {
356
359
  callback: (data) => {
357
360
  return {
358
361
  fail: data === '10/10/1000',
359
362
  };
360
363
  },
361
364
  },
365
+ events: ['ON_FIELD_BLUR']
362
366
  }}
363
- errorMessages={{ default: 'ERRRO' }}
367
+ errorMessages={{ callback: 'ERRRO' }}
364
368
  />
365
- </FormProvider>;
369
+ </FormGroupContextProvider>;
366
370
  }
367
371
  ```
372
+
373
+ ## React `AsFormFieldBuilder()`
374
+
375
+ Extends the asFormField implementation with the addition of the prop formId and mapper and doesn't required the Form component to render a form field
376
+
377
+ | Prop | Type | Description |
378
+ |formIndex | string | index of the form to identity the form |
379
+ |mapper | TMapper<ElementType> | same mapper used on the mapper context |
380
+
381
+ ```javascript
382
+ <FormGroupContextProvider mapper={Mappings}>
383
+ <AsFormFieldBuilder
384
+ mapper={{
385
+ component: Input,
386
+ componentName: 'input',
387
+ events: {
388
+ getValue: 'onChange',
389
+ setValue: 'value',
390
+ setErrorMessage: 'errorMessage',
391
+ onBlur: 'onBlur',
392
+ onFocus: 'onFocus',
393
+ onKeyUp: 'onKeyUp',
394
+ onKeyDown: 'onKeyUpCapture',
395
+ },
396
+ valueChangeEvent: (event: unknown) => {
397
+ return (event as SyntheticEvent<HTMLInputElement>).currentTarget
398
+ .value;
399
+ },
400
+ }}
401
+ formIndex="form1"
402
+ name={`input1`}
403
+ props={{
404
+ label: '${"insert something"||${input1.value}}',
405
+ helperMessage: `\${input1.api.default.response}`,
406
+ }}
407
+ api={{
408
+ defaultConfig: {
409
+ config: {
410
+ method: 'GET',
411
+ url: 'https://api.chucknorris.io/jokes/random',
412
+ resultPath: 'value',
413
+ },
414
+ events: ['ON_FIELD_MOUNT'],
415
+ },
416
+ }}
417
+ />
418
+ </FormGroupContextProvider>
419
+ ```
package/index.esm.js CHANGED
@@ -1616,8 +1616,13 @@ $$1({ target: 'Object', stat: true, arity: 2, forced: Object.assign !== assign }
1616
1616
  assign: assign
1617
1617
  });
1618
1618
 
1619
- let context;
1620
1619
  const FormGroupContext = /*#__PURE__*/createContext({});
1620
+ /**
1621
+ * context interface to be used isolated or with the context provider
1622
+ *
1623
+ * @param {TFormContextProvider} param context parameters
1624
+ * @returns {TFormContext}
1625
+ */
1621
1626
  const IsolatedContext = ({
1622
1627
  debugMode: _debugMode = false,
1623
1628
  mappers
@@ -1670,6 +1675,12 @@ const IsolatedContext = ({
1670
1675
  };
1671
1676
  return contextValue;
1672
1677
  };
1678
+ /**
1679
+ * context provider to wrap form-engine adapter elements
1680
+ *
1681
+ * @param {PropsWithChildren<TFormContextProvider>} param context parameters
1682
+ * @returns {ReactElement}
1683
+ */
1673
1684
  const FormGroupContextProvider = ({
1674
1685
  children,
1675
1686
  mappers,
@@ -1691,9 +1702,15 @@ const FormGroupContextProvider = ({
1691
1702
  }), children]
1692
1703
  });
1693
1704
  };
1705
+ /**
1706
+ * FormGroup context hook to handle context or isolated context implementations
1707
+ *
1708
+ * @param {TFormContextProvider} props form group context parameters
1709
+ * @returns {TFormContext}
1710
+ */
1694
1711
  const useFormGroupContext = props => {
1695
- context = useContext(FormGroupContext);
1696
- if (Object.keys(context).length === 0) {
1712
+ const context = useContext(FormGroupContext);
1713
+ if (Object.keys(context).length === 0 && props) {
1697
1714
  return IsolatedContext({
1698
1715
  debugMode: props.debugMode,
1699
1716
  mappers: props.mappers
@@ -1702,6 +1719,12 @@ const useFormGroupContext = props => {
1702
1719
  return context;
1703
1720
  };
1704
1721
 
1722
+ /**
1723
+ * Renders the React element defined on the mappers configuration
1724
+ *
1725
+ * @param param component props, field instance and children to render
1726
+ * @returns
1727
+ */
1705
1728
  const FieldWrapperComponentRender = ({
1706
1729
  props,
1707
1730
  fieldInstance,
@@ -1722,6 +1745,13 @@ const FieldWrapperComponentRender = ({
1722
1745
  children: `failed to render field ${fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.name} with componentName:${(_c = fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.mapper) === null || _c === void 0 ? void 0 : _c.componentName}, please check mappers`
1723
1746
  });
1724
1747
  };
1748
+ /**
1749
+ * Base field Wrapper to render the component with the necessary configurations from the schema
1750
+ * and mapper configuration
1751
+ *
1752
+ * @param {TFieldWrapperProps} param FieldWrapper params
1753
+ * @returns {ReactElement}
1754
+ */
1725
1755
  const FieldWrapper = ({
1726
1756
  name,
1727
1757
  formIndex,
@@ -1731,37 +1761,40 @@ const FieldWrapper = ({
1731
1761
  }) => {
1732
1762
  var _a;
1733
1763
  const localContext = useFormGroupContext({});
1764
+ /**
1765
+ * picks the right context prioritizing the context passed as prop
1766
+ */
1734
1767
  const {
1735
1768
  formGroupInstance,
1736
1769
  debugMode
1737
1770
  } = useMemo(() => context ? context : localContext, [context, localContext]);
1738
- const fieldInstance = (_a = formGroupInstance.getForm({
1771
+ const fieldInstance = useRef((_a = formGroupInstance.getForm({
1739
1772
  key: formIndex
1740
1773
  })) === null || _a === void 0 ? void 0 : _a.getField({
1741
1774
  key: name
1742
- });
1743
- const [valueState, setValueState] = useState(fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.stateValue);
1775
+ })).current;
1776
+ const [valueState, setValueState] = useState((fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.stateValue) || {});
1744
1777
  const [state, setState] = useState({
1745
1778
  visibility: (fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.visibility) || true,
1746
- props: (fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.props) || props,
1747
- apiResponse: fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.api
1779
+ props: (fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.props) || props
1748
1780
  });
1781
+ /**
1782
+ * handles the mounting and unmounting logic onto the field instance
1783
+ */
1749
1784
  useEffect(() => {
1750
1785
  fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.mountField({
1751
1786
  valueSubscription: value => {
1752
1787
  setValueState(value);
1753
1788
  },
1754
1789
  propsSubscription: ({
1755
- errors,
1756
1790
  visibility,
1757
- apiResponse,
1758
- props
1791
+ props,
1792
+ errors
1759
1793
  }) => {
1760
1794
  setState(prev => Object.assign(Object.assign({}, prev), {
1761
- errors,
1762
1795
  visibility,
1763
- apiResponse,
1764
- props
1796
+ props,
1797
+ errors
1765
1798
  }));
1766
1799
  }
1767
1800
  });
@@ -1769,17 +1802,27 @@ const FieldWrapper = ({
1769
1802
  fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.destroyField();
1770
1803
  };
1771
1804
  }, []);
1805
+ /**
1806
+ * handles the value change onto the field instance
1807
+ */
1772
1808
  const handleChange = useCallback(event => {
1773
1809
  fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitValue({
1774
1810
  value: event,
1775
1811
  event: 'ON_FIELD_CHANGE'
1776
1812
  });
1777
1813
  }, []);
1814
+ /**
1815
+ * handles the event emission onto the field instance
1816
+ */
1778
1817
  const handleEvent = useCallback(event => {
1779
1818
  fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitEvents({
1780
1819
  event
1781
1820
  });
1782
1821
  }, []);
1822
+ /**
1823
+ * handles the mappers configuration to bind the event submission callback
1824
+ * to the corresponding prop defined on the mappers
1825
+ */
1783
1826
  const mapProps = useMemo(() => {
1784
1827
  var _a;
1785
1828
  const events = (_a = fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.mapper) === null || _a === void 0 ? void 0 : _a.events;
@@ -1792,13 +1835,6 @@ const FieldWrapper = ({
1792
1835
  if (events === null || events === void 0 ? void 0 : events.onKeyDown) props[events.onKeyDown] = () => handleEvent('ON_FIELD_KEYDOWN');
1793
1836
  return props;
1794
1837
  }, []);
1795
- const mapValue = useMemo(() => {
1796
- var _a;
1797
- const events = (_a = fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.mapper) === null || _a === void 0 ? void 0 : _a.events;
1798
- return (events === null || events === void 0 ? void 0 : events.setValue) ? {
1799
- [events.setValue]: valueState
1800
- } : {};
1801
- }, [valueState]);
1802
1838
  return (state === null || state === void 0 ? void 0 : state.visibility) ? jsxs(Fragment, {
1803
1839
  children: [debugMode && jsxs(Fragment, {
1804
1840
  children: [jsx("b", {
@@ -1809,13 +1845,22 @@ const FieldWrapper = ({
1809
1845
  children: name
1810
1846
  }), jsx("br", {}), jsx("hr", {})]
1811
1847
  }), jsx(FieldWrapperComponentRender, {
1812
- props: Object.assign(Object.assign(Object.assign({}, mapProps), state.props), mapValue),
1848
+ props: Object.assign(Object.assign(Object.assign(Object.assign({}, mapProps), state.props), state.errors), valueState),
1813
1849
  fieldInstance: fieldInstance,
1814
1850
  children: children && children
1815
1851
  })]
1816
1852
  }) : jsx(Fragment, {});
1817
1853
  };
1818
1854
 
1855
+ /**
1856
+ * recursive function to transform form fields from a form instance into
1857
+ * a react component tree
1858
+ *
1859
+ * @param {Map<string,IFormField>} param.fields form instance field Map
1860
+ * @param {string} param.prevPath previous field path to track the tree branch creation
1861
+ * @param {string} param.formIndex form index to aid field identification onto the FieldWrapper
1862
+ * @returns {ReactNode}
1863
+ */
1819
1864
  const BuildTree = ({
1820
1865
  fields,
1821
1866
  prevPath,
@@ -1838,6 +1883,12 @@ const BuildTree = ({
1838
1883
  }, fieldName);
1839
1884
  });
1840
1885
  };
1886
+ /**
1887
+ * function to transform AsFormField elements onto a JSON schema
1888
+ *
1889
+ * @param param.children ReactNode children elements
1890
+ * @returns {IComponentSchema[] | null | undefined}
1891
+ */
1841
1892
  const BuildAsFormFieldTree = ({
1842
1893
  children
1843
1894
  }) => {
@@ -1890,6 +1941,9 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
1890
1941
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
1891
1942
  };
1892
1943
 
1944
+ /**
1945
+ * events mapping to aid function callback binding
1946
+ */
1893
1947
  const eventsMapping = {
1894
1948
  ON_FIELD_CHANGE: 'onChange',
1895
1949
  ON_FIELD_BLUR: 'onBlur',
@@ -1901,6 +1955,9 @@ const eventsMapping = {
1901
1955
  ON_FIELD_CLICK: 'onClick'
1902
1956
  };
1903
1957
 
1958
+ /**
1959
+ * Hook to register events callback functions
1960
+ */
1904
1961
  const useForm = _a => {
1905
1962
  var {
1906
1963
  id
@@ -1909,10 +1966,18 @@ const useForm = _a => {
1909
1966
  const {
1910
1967
  formGroupInstance
1911
1968
  } = useFormGroupContext({});
1969
+ /**
1970
+ * reference to store all updated callback functions rerendered by props change
1971
+ */
1912
1972
  const callbackRefs = useRef(rest);
1913
1973
  useEffect(() => {
1914
1974
  callbackRefs.current = rest;
1915
1975
  }, [rest]);
1976
+ /**
1977
+ * handle function call after the debounce occurs on the form instance field event
1978
+ * subject in order to call the most updated function with the updated function
1979
+ * reference to avoid events get outdated values
1980
+ */
1916
1981
  useEffect(() => {
1917
1982
  var _a;
1918
1983
  const callback = payload => {
@@ -1932,6 +1997,11 @@ const useForm = _a => {
1932
1997
  return;
1933
1998
  };
1934
1999
 
2000
+ /**
2001
+ *
2002
+ * @param {TFormProps} param form properties initializor
2003
+ * @returns {ReactElement}
2004
+ */
1935
2005
  const Form = ({
1936
2006
  schema,
1937
2007
  index,
@@ -1960,6 +2030,9 @@ const Form = ({
1960
2030
  } = useFormGroupContext({});
1961
2031
  const [tree, setTree] = useState();
1962
2032
  const schemaIndex = useMemo(() => index || (schema === null || schema === void 0 ? void 0 : schema.index) || 'defaultChange', [index, schema]);
2033
+ /**
2034
+ * logic to initialize the form instance and it's removal
2035
+ */
1963
2036
  useEffect(() => {
1964
2037
  if (schemaIndex === 'defaultChange') {
1965
2038
  console.warn('please, add an unique id to the form, otherwise multiple forms will break');
@@ -1988,6 +2061,11 @@ const Form = ({
1988
2061
  });
1989
2062
  };
1990
2063
  }, []);
2064
+ /**
2065
+ * logic to transform AsFormFields onto JSON schema
2066
+ * and JSON schema onto FieldWrappers, refreshes when
2067
+ * the react tree changes it's children
2068
+ */
1991
2069
  useEffect(() => {
1992
2070
  var _a;
1993
2071
  const schema = BuildAsFormFieldTree({
@@ -2007,11 +2085,17 @@ const Form = ({
2007
2085
  setTree(buildTree);
2008
2086
  }
2009
2087
  }, [children]);
2088
+ /**
2089
+ * iVars change tracker to update iVars onto form instance
2090
+ */
2010
2091
  useEffect(() => {
2011
2092
  if (iVars) getForm({
2012
2093
  key: index
2013
2094
  }).iVars = iVars;
2014
2095
  }, [iVars]);
2096
+ /**
2097
+ * hook usage to keep event bindings updated on callback functions passed as props
2098
+ */
2015
2099
  useForm({
2016
2100
  id: schemaIndex,
2017
2101
  onApiResponse,
@@ -2066,10 +2150,17 @@ const Form = ({
2066
2150
  });
2067
2151
  };
2068
2152
 
2153
+ /**
2154
+ * Component wrapper to aid building schemas with react without writting a JSON schema
2155
+ * along with BuildAsFormFieldTree inside a Form component, FieldWrapper gets this props
2156
+ * to build the component as it does with a JSON schema, this component only works inside
2157
+ * the Form component
2158
+ *
2159
+ * @param {TAsFormFieldProps} props JSON schema props
2160
+ * @returns {ReactNode}
2161
+ */
2069
2162
  const AsFormField = props => {
2070
- return jsx(Fragment, {
2071
- children: props.children
2072
- });
2163
+ return props.children;
2073
2164
  };
2074
2165
 
2075
2166
  var wellKnownSymbol$1 = wellKnownSymbol$8;
@@ -2318,9 +2409,24 @@ $({ target: 'RegExp', proto: true, forced: /./.exec !== exec }, {
2318
2409
  exec: exec
2319
2410
  });
2320
2411
 
2412
+ /**
2413
+ * Component Wrapper to render form fields without the Form component, gets additional formId and mapper since
2414
+ * it won't rely on them and needs to be manually declared
2415
+ *
2416
+ * @param {TAsFormFieldBuilderProps} props JSON schema props along with FieldWrapper props and mapper props
2417
+ * @returns {ReactElement}
2418
+ */
2321
2419
  const AsFormFieldBuilder = props => {
2322
2420
  const context = useFormGroupContext({});
2421
+ /**
2422
+ * state to track the field instance creation process
2423
+ */
2323
2424
  const [mounted, setMounted] = useState(false);
2425
+ /**
2426
+ * initializer to create or add a form instance to the formGroup by it's formId
2427
+ * and add the field to the form instance
2428
+ * Also has the logic to remove it once this element is removed
2429
+ */
2324
2430
  useEffect(() => {
2325
2431
  var _a;
2326
2432
  if (!((_a = context.formGroupInstance) === null || _a === void 0 ? void 0 : _a.forms.has(props.formIndex))) {
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bolttech/form-engine",
3
- "version": "3.0.0-beta.16",
3
+ "version": "3.0.0-beta.17",
4
4
  "description": "A react adapter for bolttech form engine",
5
5
  "module": "./index.esm.js",
6
6
  "type": "module",
7
7
  "main": "./index.esm.js",
8
8
  "dependencies": {
9
- "@bolttech/form-engine-core": "0.0.1-beta.7",
9
+ "@bolttech/form-engine-core": "0.0.1-beta.8",
10
10
  "react": "18.2.0"
11
11
  },
12
12
  "peerDependencies": {}
@@ -1,4 +1,13 @@
1
- import { IComponentSchema } from '@bolttech/form-engine-core';
2
- import { PropsWithChildren, ReactElement } from 'react';
3
- declare const AsFormField: (props: PropsWithChildren<Omit<IComponentSchema, 'children'>>) => ReactElement;
1
+ import { ReactNode } from 'react';
2
+ import { TAsFormFieldProps } from './AsFormField.type';
3
+ /**
4
+ * Component wrapper to aid building schemas with react without writting a JSON schema
5
+ * along with BuildAsFormFieldTree inside a Form component, FieldWrapper gets this props
6
+ * to build the component as it does with a JSON schema, this component only works inside
7
+ * the Form component
8
+ *
9
+ * @param {TAsFormFieldProps} props JSON schema props
10
+ * @returns {ReactNode}
11
+ */
12
+ declare const AsFormField: (props: TAsFormFieldProps) => ReactNode;
4
13
  export default AsFormField;
@@ -0,0 +1,9 @@
1
+ import { IComponentSchema } from '@bolttech/form-engine-core';
2
+ import { PropsWithChildren } from 'react';
3
+ /**
4
+ * AsFormField props, inherits all schema field implementation except the children
5
+ * property, that will be a ReactNode
6
+ * @see {@link IComponentSchema}
7
+ */
8
+ type TAsFormFieldProps = PropsWithChildren<Omit<IComponentSchema, 'children'>>;
9
+ export type { TAsFormFieldProps };
@@ -1,7 +1,11 @@
1
- import { IComponentSchema, TMapper } from '@bolttech/form-engine-core';
2
- import { ElementType, PropsWithChildren, ReactElement } from 'react';
3
- import { TFieldWrapper } from '../../types';
4
- declare const AsFormFieldBuilder: (props: PropsWithChildren<Omit<IComponentSchema, 'children' | 'component'> & Required<TFieldWrapper> & {
5
- mapper: TMapper<ElementType>;
6
- }>) => ReactElement;
1
+ import { ReactElement } from 'react';
2
+ import { TAsFormFieldBuilderProps } from './AsFormFieldBuilder.type';
3
+ /**
4
+ * Component Wrapper to render form fields without the Form component, gets additional formId and mapper since
5
+ * it won't rely on them and needs to be manually declared
6
+ *
7
+ * @param {TAsFormFieldBuilderProps} props JSON schema props along with FieldWrapper props and mapper props
8
+ * @returns {ReactElement}
9
+ */
10
+ declare const AsFormFieldBuilder: (props: TAsFormFieldBuilderProps) => ReactElement;
7
11
  export default AsFormFieldBuilder;
@@ -0,0 +1,16 @@
1
+ import { IComponentSchema, TMapper } from '@bolttech/form-engine-core';
2
+ import { ElementType, PropsWithChildren } from 'react';
3
+ import { TFieldWrapper } from '../../types';
4
+ /**
5
+ * AsFormField props, inherits all schema field implementation except the children
6
+ * property, that will be a ReactNode
7
+ * also gets the formIndex for form identification and the mapper to build the component
8
+ * @property {TMapper} mapper element mapper to use
9
+ * @see {@link TMapper}
10
+ * @see {@link IComponentSchema}
11
+ * @see {@link TFieldWrapper}
12
+ */
13
+ type TAsFormFieldBuilderProps = PropsWithChildren<Omit<IComponentSchema, 'children' | 'component' | 'name'> & Required<TFieldWrapper> & {
14
+ mapper: TMapper<ElementType>;
15
+ }>;
16
+ export type { TAsFormFieldBuilderProps };
@@ -1,9 +1,11 @@
1
- import { PropsWithChildren, ReactElement } from 'react';
2
- import { TFormContext } from '../../context/FormGroupContext';
3
- import { TFieldWrapper } from '../../types';
4
- declare const FieldWrapper: ({ name, formIndex, children, props, context, }: PropsWithChildren<TFieldWrapper & {
5
- name: string;
6
- props?: Record<string, unknown> | undefined;
7
- context?: TFormContext | null | undefined;
8
- }>) => ReactElement;
1
+ import { ReactElement } from 'react';
2
+ import { TFieldWrapperProps } from './FieldWrapper.type';
3
+ /**
4
+ * Base field Wrapper to render the component with the necessary configurations from the schema
5
+ * and mapper configuration
6
+ *
7
+ * @param {TFieldWrapperProps} param FieldWrapper params
8
+ * @returns {ReactElement}
9
+ */
10
+ declare const FieldWrapper: ({ name, formIndex, children, props, context, }: TFieldWrapperProps) => ReactElement;
9
11
  export default FieldWrapper;
@@ -0,0 +1,28 @@
1
+ import { PropsWithChildren } from 'react';
2
+ import { TFieldWrapper } from '../../types';
3
+ import { TFormContext } from '../../context/FormGroupContext';
4
+ import { FormField } from '@bolttech/form-engine-core';
5
+ /**
6
+ * Represents the props for a field wrapper component, including children.
7
+ *
8
+ * @property {Record<string, unknown>} [props] - Additional properties for the field.
9
+ * @property {TFormContext | null} [context] - The context of the form, which may be null.
10
+ * @property {React.ReactNode} children - The child elements of the component.
11
+ * @see {@link TFieldWrapper}
12
+ */
13
+ type TFieldWrapperProps = PropsWithChildren<TFieldWrapper & {
14
+ props?: Record<string, unknown>;
15
+ context?: TFormContext | null;
16
+ }>;
17
+ /**
18
+ * Represents the props for rendering a field wrapper component, including children.
19
+ *
20
+ * @property {Record<string, unknown>} props - Additional properties for the field.
21
+ * @property {FormField} [fieldInstance] - The instance of the form field, which may be undefined.
22
+ * @property {React.ReactNode} children - The child elements of the component.
23
+ */
24
+ type TFieldWrapperComponentRenderProps = PropsWithChildren<{
25
+ props: Record<string, unknown>;
26
+ fieldInstance?: FormField;
27
+ }>;
28
+ export type { TFieldWrapperProps, TFieldWrapperComponentRenderProps };
@@ -1,5 +1,9 @@
1
- import { TFormEntry } from '@bolttech/form-engine-core';
2
- import { PropsWithChildren } from 'react';
3
- import { TEventsCallbackProps } from '../../types';
4
- declare const Form: ({ schema, index, initialValues, iVars, action, method, onSubmit, onData, onBlur, onChange, onApiResponse, onClick, onFocus, onKeyDown, onKeyUp, onMount, children, }: PropsWithChildren<Omit<TFormEntry, 'mappers'> & TEventsCallbackProps>) => import("react/jsx-runtime").JSX.Element;
1
+ import { ReactElement } from 'react';
2
+ import { TFormProps } from './Form.type';
3
+ /**
4
+ *
5
+ * @param {TFormProps} param form properties initializor
6
+ * @returns {ReactElement}
7
+ */
8
+ declare const Form: ({ schema, index, initialValues, iVars, action, method, onSubmit, onData, onBlur, onChange, onApiResponse, onClick, onFocus, onKeyDown, onKeyUp, onMount, children, }: TFormProps) => ReactElement;
5
9
  export default Form;
@@ -0,0 +1,11 @@
1
+ import { TFormEntry } from '@bolttech/form-engine-core';
2
+ import { PropsWithChildren } from 'react';
3
+ import { TEventsCallbackProps } from '../../types';
4
+ /**
5
+ * Form props, inherits the form instance constructor implementation except the mapper
6
+ * along with all event callback register props shared with other implementations
7
+ * @see {@link TFormEntry}
8
+ * @see {@link TEventsCallbackProps}
9
+ */
10
+ type TFormProps = PropsWithChildren<Omit<TFormEntry, 'mappers'> & TEventsCallbackProps>;
11
+ export type { TFormProps };
@@ -1,30 +1,19 @@
1
- import { FormCore, TFormCore, TFormGroup, TFormValues, TMapper } from '@bolttech/form-engine-core';
2
- import { ElementType, PropsWithChildren, ReactElement } from 'react';
3
- type TFormContext = {
4
- addFormWithIndex: (index: string) => void;
5
- addForm: (payload: {
6
- key: string;
7
- formInstance: TFormCore;
8
- }) => void;
9
- getForm: (payload: {
10
- key: string;
11
- }) => FormCore | undefined;
12
- removeForm: (payload: {
13
- key: string;
14
- }) => void;
15
- formGroupInstance: TFormGroup;
16
- mappers?: TMapper<ElementType>[];
17
- printFormGroupInstance: () => void;
18
- submitMultipleFormsByIndex: (indexes: string[]) => TFormValues;
19
- debugMode: boolean;
20
- active: boolean;
21
- };
22
- type TFormContextProvider = {
23
- mappers?: TMapper<ElementType>[];
24
- debugMode?: boolean;
25
- };
1
+ import { PropsWithChildren, ReactElement } from 'react';
2
+ import { TFormContext, TFormContextProvider } from './FormGroupContext.type';
26
3
  declare const FormGroupContext: import("react").Context<TFormContext>;
4
+ /**
5
+ * context provider to wrap form-engine adapter elements
6
+ *
7
+ * @param {PropsWithChildren<TFormContextProvider>} param context parameters
8
+ * @returns {ReactElement}
9
+ */
27
10
  declare const FormGroupContextProvider: ({ children, mappers, debugMode, }: PropsWithChildren<TFormContextProvider>) => ReactElement;
28
- declare const useFormGroupContext: (props: TFormContextProvider) => TFormContext;
11
+ /**
12
+ * FormGroup context hook to handle context or isolated context implementations
13
+ *
14
+ * @param {TFormContextProvider} props form group context parameters
15
+ * @returns {TFormContext}
16
+ */
17
+ declare const useFormGroupContext: (props?: TFormContextProvider) => TFormContext;
29
18
  export { FormGroupContext, FormGroupContextProvider, useFormGroupContext };
30
19
  export type { TFormContext };
@@ -0,0 +1,46 @@
1
+ import { FormCore, TFormCore, TFormGroup, TFormValues, TMapper } from '@bolttech/form-engine-core';
2
+ import { ElementType } from 'react';
3
+ /**
4
+ * Represents the context for managing forms within a form group.
5
+ *
6
+ * @property {function(string): void} addFormWithIndex - Adds a form to the form group by its index.
7
+ * @property {function({ key: string, formInstance: TFormCore }): void} addForm - Adds a form to the form group using a payload containing the key and form instance.
8
+ * @property {function({ key: string }): (FormCore | undefined)} getForm - Retrieves a form from the form group using a payload containing the key.
9
+ * @property {function({ key: string }): void} removeForm - Removes a form from the form group using a payload containing the key.
10
+ * @property {TFormGroup} formGroupInstance - The instance of the form group.
11
+ * @property {TMapper<ElementType>[]} [mappers] - Optional array of mappers for elements.
12
+ * @property {function(): void} printFormGroupInstance - Prints the form group instance.
13
+ * @property {function(string[]): TFormValues} submitMultipleFormsByIndex - Submits multiple forms by their indexes and returns the form values.
14
+ * @property {boolean} debugMode - Indicates if debug mode is active.
15
+ * @property {boolean} active - Indicates if the form context is active.
16
+ */
17
+ type TFormContext = {
18
+ addFormWithIndex: (index: string) => void;
19
+ addForm: (payload: {
20
+ key: string;
21
+ formInstance: TFormCore;
22
+ }) => void;
23
+ getForm: (payload: {
24
+ key: string;
25
+ }) => FormCore | undefined;
26
+ removeForm: (payload: {
27
+ key: string;
28
+ }) => void;
29
+ formGroupInstance: TFormGroup;
30
+ mappers?: TMapper<ElementType>[];
31
+ printFormGroupInstance: () => void;
32
+ submitMultipleFormsByIndex: <T>(indexes: string[]) => TFormValues<T>;
33
+ debugMode: boolean;
34
+ active: boolean;
35
+ };
36
+ /**
37
+ * Represents the props for a form context provider.
38
+ *
39
+ * @property {TMapper<ElementType>[]} [mappers] - Optional array of mappers for elements.
40
+ * @property {boolean} [debugMode] - Optional flag indicating if debug mode should be enabled.
41
+ */
42
+ type TFormContextProvider = {
43
+ mappers?: TMapper<ElementType>[];
44
+ debugMode?: boolean;
45
+ };
46
+ export type { TFormContext, TFormContextProvider };
@@ -1,10 +1,25 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { IFormField, IComponentSchema } from '@bolttech/form-engine-core';
3
+ /**
4
+ * recursive function to transform form fields from a form instance into
5
+ * a react component tree
6
+ *
7
+ * @param {Map<string,IFormField>} param.fields form instance field Map
8
+ * @param {string} param.prevPath previous field path to track the tree branch creation
9
+ * @param {string} param.formIndex form index to aid field identification onto the FieldWrapper
10
+ * @returns {ReactNode}
11
+ */
3
12
  declare const BuildTree: ({ fields, prevPath, formIndex, }: {
4
13
  fields: Map<string, IFormField>;
5
14
  prevPath?: string | undefined;
6
15
  formIndex: string;
7
16
  }) => ReactNode;
17
+ /**
18
+ * function to transform AsFormField elements onto a JSON schema
19
+ *
20
+ * @param param.children ReactNode children elements
21
+ * @returns {IComponentSchema[] | null | undefined}
22
+ */
8
23
  declare const BuildAsFormFieldTree: ({ children, }: {
9
24
  children?: ReactNode;
10
25
  }) => IComponentSchema[] | null | undefined;
@@ -1,4 +1,7 @@
1
1
  import { TEvents } from '@bolttech/form-engine-core';
2
- import { eventProps } from '../types';
3
- declare const eventsMapping: Partial<Record<TEvents, eventProps>>;
2
+ import { TEventProps } from '../types';
3
+ /**
4
+ * events mapping to aid function callback binding
5
+ */
6
+ declare const eventsMapping: Partial<Record<TEvents, TEventProps>>;
4
7
  export { eventsMapping };
@@ -1,6 +1,6 @@
1
- import { TEventsCallbackProps } from '../types';
2
- import { TFieldEvent } from '@bolttech/form-engine-core';
3
- declare const useForm: ({ id, ...rest }: {
4
- id: string;
5
- } & Partial<Record<import("../types").eventProps, ((payload: TFieldEvent) => void) | null | undefined>>) => void;
1
+ import { TUseFormProps } from './useForm.type';
2
+ /**
3
+ * Hook to register events callback functions
4
+ */
5
+ declare const useForm: ({ id, ...rest }: TUseFormProps) => void;
6
6
  export default useForm;
@@ -0,0 +1,12 @@
1
+ import { TEventsCallbackProps } from '../types';
2
+ /**
3
+ * Represents the properties for the useForm hook, including an ID and event callback properties.
4
+ *
5
+ * @property {string} id - The unique identifier for the form.
6
+ *
7
+ * @see {@link TEventsCallbackProps}
8
+ */
9
+ type TUseFormProps = {
10
+ id: string;
11
+ } & TEventsCallbackProps;
12
+ export type { TUseFormProps };
@@ -1,46 +1,20 @@
1
1
  import { TFieldEvent } from '@bolttech/form-engine-core';
2
2
  /**
3
- * @type TFieldWrapper
4
- * Represents the wrapper for a form field, including the component,
5
- * event handlers, and other properties related to form management.
3
+ * Represents a field wrapper containing the name of the field and its index in the form.
6
4
  *
7
- * @property {string} index - The index of the field in the form.
8
- * @property {ElementType} Component - The component to be rendered.
9
- * @property {(event: unknown) => unknown} [valueChangeEvent] - Function to handle value change events.
10
- * @property {string} formKey - The key of the form.
11
- * @property {string} [onBlur] - Function to handle the blur event.
12
- * @property {string} [onChange] - Function to handle the change event.
13
- * @property {string} [onFocus] - Function to handle the focus event.
14
- * @property {string} [onClick] - Function to handle the click event.
15
- * @property {string} [onKeyUp] - Function to handle the keyup event.
16
- * @property {string} [onKeyDown] - Function to handle the keydown event.
17
- * @property {unknown} [onValue] - The current value of the field.
18
- * @property {string} [onErrorMessage] - error message prop name to set message string
19
- *
20
- * @example
21
- * ```typescript
22
- * const fieldWrapper: TFieldWrapper = {
23
- * index: '1',
24
- * Component: MyComponent,
25
- * valueChangeEvent: (event) => {
26
- * const newValue = (event as React.ChangeEvent<HTMLInputElement>).target.value;
27
- * return newValue;
28
- * },
29
- * formKey: 'myForm',
30
- * onBlur: 'handleBlur',
31
- * onChange: 'handleChange',
32
- * onFocus: 'handleFocus',
33
- * onClick: 'handleClick',
34
- * onKeyUp: 'handleKeyUp',
35
- * onKeyDown: 'handleKeyDown',
36
- * onValue: 'value'
37
- * };
38
- * ```
5
+ * @property {string} name - The name of the field.
6
+ * @property {string} formIndex - The index of the field within the form.
39
7
  */
40
8
  type TFieldWrapper = {
41
9
  name: string;
42
10
  formIndex: string;
43
11
  };
44
- type eventProps = 'onChange' | 'onBlur' | 'onFocus' | 'onKeyDown' | 'onKeyUp' | 'onMount' | 'onApiResponse' | 'onClick';
45
- type TEventsCallbackProps = Partial<Record<eventProps, ((payload: TFieldEvent) => void) | null | undefined>>;
46
- export { TFieldWrapper, eventProps, TEventsCallbackProps };
12
+ /**
13
+ * Represents the possible event properties for form fields callbacks.
14
+ */
15
+ type TEventProps = 'onChange' | 'onBlur' | 'onFocus' | 'onKeyDown' | 'onKeyUp' | 'onMount' | 'onApiResponse' | 'onClick' | 'onSubmit';
16
+ /**
17
+ * Represents a mapping of event properties to their corresponding callback functions.
18
+ */
19
+ type TEventsCallbackProps = Partial<Record<TEventProps, ((payload: TFieldEvent) => void) | null | undefined>>;
20
+ export { TFieldWrapper, TEventProps, TEventsCallbackProps };