@bolttech/form-engine-core 1.0.0-beta.14 → 1.0.0-beta.16

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/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Subject, Subscription, groupBy, mergeMap, debounceTime, filter, combineLatest, startWith, map, distinctUntilKeyChanged, distinctUntilChanged, skip } from 'rxjs';
1
+ import { Subject, Subscription, groupBy, mergeMap, debounceTime, filter, combineLatest, startWith, map, distinctUntilKeyChanged } from 'rxjs';
2
2
  import creditCardType from 'credit-card-type';
3
3
  import { isNumber as isNumber$1, isFunction, cloneDeep, merge, isEqual, get, isNil, set } from 'lodash';
4
4
  import { getCurrencySymbol } from '@gaignoux/currency';
@@ -48,8 +48,8 @@ const DEFAULT_API_DEBOUNCE_TIME = 1000;
48
48
  const DEFAULT_STATE_REFRESH_TIME = 100;
49
49
  const TEMPLATE_REGEX_STRING_CONCATENATION_DETECTOR = /^\$\{(?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*\}$/;
50
50
  const TEMPLATE_REGEX_DELIMITATOR = /\$\{((?:[^{}]|\{(?:[^{}]|\{[^{}]*\})*\})*)\}/g;
51
- const TEMPLATE_REGEX_OPERATOR_SPLITTER = /\s*(\|\||&&|!)\s*/g;
52
- const TEMPLATE_REGEX_OPERATOR_MATCHER = /^\|\||&&|!$/;
51
+ const TEMPLATE_REGEX_OPERATOR_SPLITTER = /\s*(\|\||&&|!+)\s*/g;
52
+ const TEMPLATE_REGEX_OPERATOR_MATCHER = /^\|\||&&|!+$/;
53
53
  const TEMPLATE_AVALIABLE_SCOPES = ['fields', 'iVars', 'form'];
54
54
  const ALLOWED_RESET_PROPS_MUTATIONS = ['api', 'apiSchema', 'props', 'validations', 'visibilityConditions', 'resetValues'];
55
55
  const DEFAULT_LOG_VERBOSE = false;
@@ -578,7 +578,7 @@ const formatters = {
578
578
  * console.log(maskedValue); // Output: 'ab***gh###'
579
579
  * ```
580
580
  */
581
- var generic = ((value, masks) => {
581
+ var generic = (value, masks) => {
582
582
  if (!(masks === null || masks === void 0 ? void 0 : masks.generic)) return value;
583
583
  let masked = value;
584
584
  masks.generic.forEach(item => {
@@ -597,7 +597,7 @@ var generic = ((value, masks) => {
597
597
  masked = masked.slice(0, from - 1) + maskedPortion + masked.slice(to);
598
598
  });
599
599
  return masked;
600
- });
600
+ };
601
601
 
602
602
  /**
603
603
  * Replaces all characters in a string with a specified replacement string or character.
@@ -882,7 +882,7 @@ const masks = {
882
882
  * console.log(isValid); // Output: true or false based on validation
883
883
  * ```
884
884
  */
885
- var length = ((value, validations) => {
885
+ var length = (value, validations) => {
886
886
  if (!validations.length || !value) return false;
887
887
  let targetValue = value;
888
888
  // We want length even if it is a numeric
@@ -898,7 +898,7 @@ var length = ((value, validations) => {
898
898
  greaterOrEqual: targetValue.length < validations.length.target
899
899
  };
900
900
  return condition[validations.length.rule];
901
- });
901
+ };
902
902
 
903
903
  /**
904
904
  * Validates a Spanish NIF (Número de Identificación Fiscal).
@@ -1136,7 +1136,7 @@ const CIF = value => {
1136
1136
  * console.log(isValid); // Output: true or false based on validation
1137
1137
  * ```
1138
1138
  */
1139
- var document = ((value, validations) => {
1139
+ var document = (value, validations) => {
1140
1140
  if (!value || !validations.document) return true;
1141
1141
  const validation = {
1142
1142
  NIF: (value, locale) => NIF(value, locale),
@@ -1145,7 +1145,7 @@ var document = ((value, validations) => {
1145
1145
  IBAN: value => IBAN(value)
1146
1146
  };
1147
1147
  return validation[validations.document.type](value, validations.document.locale);
1148
- });
1148
+ };
1149
1149
 
1150
1150
  /**
1151
1151
  * Validates if a value exceeds the maximum allowed value.
@@ -2263,10 +2263,10 @@ function run$1(value, handlers, validations) {
2263
2263
  * const isValid = validateValue(value, methods);
2264
2264
  * console.log(isValid); // Output: true
2265
2265
  */
2266
- var namedRule = ((value, methods, validations) => {
2266
+ var namedRule = (value, methods, validations) => {
2267
2267
  if (!methods) return false;
2268
2268
  return run$1(value, methods, validations).some(validation => validation);
2269
- });
2269
+ };
2270
2270
 
2271
2271
  /**
2272
2272
  * @internal
@@ -2486,6 +2486,7 @@ class FormField {
2486
2486
  * @param {() => TFormValues<unknown>} options.getFormValues, - form instance function that builds onData parameter payload from fields
2487
2487
  */
2488
2488
  constructor({
2489
+ formIndex,
2489
2490
  schemaComponent,
2490
2491
  config,
2491
2492
  path,
@@ -2506,6 +2507,7 @@ class FormField {
2506
2507
  var _a, _b, _c, _d, _e, _f, _g;
2507
2508
  this.valueSubscription$ = new Subscription();
2508
2509
  this.fieldStateSubscription$ = new Subscription();
2510
+ this.formIndex = formIndex;
2509
2511
  this.originalSchema = cloneDeep(schemaComponent);
2510
2512
  this.config = {
2511
2513
  defaultAPIdebounceTimeMS: Number(config === null || config === void 0 ? void 0 : config.defaultAPIdebounceTimeMS) ? Number(config === null || config === void 0 ? void 0 : config.defaultAPIdebounceTimeMS) : DEFAULT_API_DEBOUNCE_TIME,
@@ -2881,11 +2883,12 @@ class FormField {
2881
2883
  emitValue(prop) {
2882
2884
  if (!this.visibility || !this.mounted) return;
2883
2885
  this.value = prop.value;
2884
- this.emitEvents({
2885
- event: prop.event
2886
- });
2887
2886
  this.dataSubject$.next({
2888
- key: this.name,
2887
+ event: prop.event,
2888
+ fieldIndex: this.name,
2889
+ formIndex: this.formIndex
2890
+ });
2891
+ this.emitEvents({
2889
2892
  event: prop.event
2890
2893
  });
2891
2894
  }
@@ -3125,6 +3128,16 @@ class FormField {
3125
3128
  this.errorSubject$.unsubscribe();
3126
3129
  this.apiEventQueueSubject$.unsubscribe();
3127
3130
  this.triggerFieldValidNotification();
3131
+ this.dataSubject$.next({
3132
+ event: 'ON_FIELD_UNMOUNT',
3133
+ fieldIndex: this.name,
3134
+ formIndex: this.formIndex
3135
+ });
3136
+ !this.fieldEventSubject$.closed && this.fieldEventSubject$.next({
3137
+ event: 'ON_FIELD_UNMOUNT',
3138
+ fieldName: this.name,
3139
+ fieldInstance: this
3140
+ });
3128
3141
  }
3129
3142
  /**
3130
3143
  * Subscribes to changes in the field state and executes the provided callback function.
@@ -3194,14 +3207,15 @@ class FormCore {
3194
3207
  (_h = entry.mappers) === null || _h === void 0 ? void 0 : _h.map(mapper => {
3195
3208
  this.mappers.set(mapper.componentName, mapper);
3196
3209
  });
3210
+ if ((!entry.submitSubject$ || !entry.dataSubject$ || !entry.formValidSubject$) && this.config.defaultLogVerbose) console.warn(`some formGroup events are not properly instanciated, any onData, onValid, onSubmit events managed by formGroup won't trigger on form: ${this.index}`);
3197
3211
  this.schema && FormCore.checkIndexes(this.schema.components);
3198
3212
  this.templateSubject$ = new Subject();
3199
- this.submitSubject$ = new Subject();
3200
3213
  this.fieldEventSubject$ = new Subject();
3201
- this.dataSubject$ = new Subject();
3202
3214
  this.mountSubject$ = new Subject();
3203
3215
  this.fieldValidNotification$ = new Subject();
3204
- this.formValidNotification$ = new Subject();
3216
+ this.submitSubject$ = entry.submitSubject$ ? entry.submitSubject$ : new Subject();
3217
+ this.dataSubject$ = entry.dataSubject$ ? entry.dataSubject$ : new Subject();
3218
+ this.formValidSubject$ = entry.formValidSubject$ ? entry.formValidSubject$ : new Subject();
3205
3219
  this.subscribedTemplates = [];
3206
3220
  this.templateSubscription$ = this.templateSubject$.subscribe(this.refreshTemplates.bind(this));
3207
3221
  this.fieldValidNotification$.subscribe(() => {
@@ -3242,7 +3256,7 @@ class FormCore {
3242
3256
  @TODO check a better way to handle nested fields unmounted by visiblity conditions from a parent
3243
3257
  since they are dependent on adapter field recycling runtimes
3244
3258
  */
3245
- this.config.defaultLogVerbose && console.log(`field ${key} was mounted but since it's parent has some visibility condition the field was already removed`);
3259
+ this.config.defaultLogVerbose && console.warn(`field ${key} was mounted but since it's parent has some visibility condition the field was already removed`);
3246
3260
  return;
3247
3261
  }
3248
3262
  this.subscribeTemplates();
@@ -3254,7 +3268,10 @@ class FormCore {
3254
3268
  scope: 'iVars',
3255
3269
  event: 'ON_IVARS'
3256
3270
  });
3257
- if (!this.queuedInitialValues.has(key)) field.emitEvents({
3271
+ if (!this.queuedInitialValues.has(key)) field.valuePropName && !field.value ? field.emitValue({
3272
+ event: 'ON_FIELD_MOUNT',
3273
+ value: ''
3274
+ }) : field.emitEvents({
3258
3275
  event: 'ON_FIELD_MOUNT'
3259
3276
  });
3260
3277
  this.checkFieldEventQueues(key);
@@ -3321,7 +3338,7 @@ class FormCore {
3321
3338
  event: 'ON_FORM',
3322
3339
  scope: 'form'
3323
3340
  });
3324
- this.formValidNotification$.next({
3341
+ this.formValidSubject$.next({
3325
3342
  formIndex: this.index,
3326
3343
  valid: this.valid
3327
3344
  });
@@ -3666,11 +3683,17 @@ class FormCore {
3666
3683
  * and trigger the validation when it's visible
3667
3684
  */
3668
3685
  if (fieldInstance.visibility) {
3669
- fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitValue({
3670
- value: this.queuedInitialValues.get(field) || '',
3671
- event: 'ON_FIELD_MOUNT'
3672
- });
3673
- this.queuedInitialValues.delete(field);
3686
+ if (this.queuedInitialValues.has(field)) {
3687
+ fieldInstance === null || fieldInstance === void 0 ? void 0 : fieldInstance.emitValue({
3688
+ value: this.queuedInitialValues.get(field) || '',
3689
+ event: 'ON_FIELD_MOUNT'
3690
+ });
3691
+ this.queuedInitialValues.delete(field);
3692
+ } else {
3693
+ fieldInstance.emitEvents({
3694
+ event: 'ON_FIELD_MOUNT'
3695
+ });
3696
+ }
3674
3697
  } else {
3675
3698
  fieldInstance.value = '';
3676
3699
  fieldInstance.valid = true;
@@ -3799,7 +3822,7 @@ class FormCore {
3799
3822
  value
3800
3823
  }) {
3801
3824
  const field = this.fields.get(key);
3802
- if (!field || field.mounted) {
3825
+ if (!field) {
3803
3826
  this.queuedFieldResetPropertyEvents.set(key, {
3804
3827
  property,
3805
3828
  path,
@@ -3876,6 +3899,7 @@ class FormCore {
3876
3899
  }
3877
3900
  }
3878
3901
  this.fields.set(fieldSchema.name, new FormField({
3902
+ formIndex: this.index,
3879
3903
  schemaComponent: fieldSchema,
3880
3904
  mapper,
3881
3905
  children: fieldSchema.children ? fieldSchema.children.map(el => el.name) : [],
@@ -3931,6 +3955,7 @@ class FormCore {
3931
3955
  }
3932
3956
  if (!mapper) throw new Error(`mapper not found for ${structElement.component}, add it to the mappers configuration`);
3933
3957
  this.fields.set(structElement.name, new FormField({
3958
+ formIndex: this.index,
3934
3959
  schemaComponent: structElement,
3935
3960
  mapper,
3936
3961
  path,
@@ -4075,10 +4100,12 @@ class FormCore {
4075
4100
  * @param {(payload: { field: string; data: TFormValues }) => void} callback callback function to call onData
4076
4101
  */
4077
4102
  subscribeData(callback) {
4078
- const sub = this.dataSubject$.pipe(groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
4079
- key
4103
+ const sub = this.dataSubject$.pipe(filter(({
4104
+ formIndex
4105
+ }) => this.index === formIndex), groupBy(payload => payload.event), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
4106
+ fieldIndex
4080
4107
  }) => ({
4081
- field: key,
4108
+ field: fieldIndex,
4082
4109
  data: this.getFormValues()
4083
4110
  }))).subscribe({
4084
4111
  next: callback
@@ -4091,7 +4118,11 @@ class FormCore {
4091
4118
  * @param {(payload: TFormValues<T>) => void} callback callback function to call when the submit action occurs
4092
4119
  */
4093
4120
  subscribeOnSubmit(callback) {
4094
- const sub = this.submitSubject$.subscribe({
4121
+ const sub = this.submitSubject$.pipe(filter(({
4122
+ formIndex
4123
+ }) => formIndex === this.index), map(({
4124
+ values
4125
+ }) => values)).subscribe({
4095
4126
  next: callback
4096
4127
  });
4097
4128
  return sub;
@@ -4102,7 +4133,9 @@ class FormCore {
4102
4133
  * @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
4103
4134
  */
4104
4135
  subscribeFormValidation(callback) {
4105
- const sub = this.formValidNotification$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS), map(() => ({
4136
+ const sub = this.formValidSubject$.pipe(filter(({
4137
+ formIndex
4138
+ }) => this.index === formIndex), debounceTime(this.config.defaultStateRefreshTimeMS), map(() => ({
4106
4139
  formIndex: this.index,
4107
4140
  valid: this.valid
4108
4141
  })), distinctUntilKeyChanged('valid')).subscribe({
@@ -4121,17 +4154,17 @@ class FormCore {
4121
4154
  });
4122
4155
  if (!this.valid) return;
4123
4156
  const values = this.getFormValues();
4124
- this.submitSubject$.next(values);
4157
+ this.submitSubject$.next({
4158
+ formIndex: this.index,
4159
+ values
4160
+ });
4125
4161
  }
4126
4162
  /**
4127
4163
  * recycles all the Suscriptions, to be called from the adapter when the form leaves the page
4128
4164
  */
4129
4165
  destroy() {
4130
- this.submitSubject$.unsubscribe();
4131
4166
  this.templateSubscription$.unsubscribe();
4132
4167
  this.fieldEventSubject$.unsubscribe();
4133
- this.dataSubject$.unsubscribe();
4134
- this.formValidNotification$.unsubscribe();
4135
4168
  this.fieldValidNotification$.unsubscribe();
4136
4169
  this.fields.forEach(field => field.destroyField());
4137
4170
  }
@@ -4175,6 +4208,9 @@ class FormGroup {
4175
4208
  var _a, _b, _c, _d, _e;
4176
4209
  this.destroy = () => {
4177
4210
  this.forms.forEach(form => form.destroy());
4211
+ this.dataSubject$.unsubscribe();
4212
+ this.formValidSubject$.unsubscribe();
4213
+ this.submitSubject$.unsubscribe();
4178
4214
  };
4179
4215
  this.forms = new Map();
4180
4216
  this.config = {
@@ -4182,6 +4218,9 @@ class FormGroup {
4182
4218
  defaultStateRefreshTimeMS: Number((_c = entry === null || entry === void 0 ? void 0 : entry.config) === null || _c === void 0 ? void 0 : _c.defaultStateRefreshTimeMS) ? Number((_d = entry === null || entry === void 0 ? void 0 : entry.config) === null || _d === void 0 ? void 0 : _d.defaultStateRefreshTimeMS) : DEFAULT_STATE_REFRESH_TIME,
4183
4219
  defaultLogVerbose: ((_e = entry === null || entry === void 0 ? void 0 : entry.config) === null || _e === void 0 ? void 0 : _e.defaultLogVerbose) ? entry.config.defaultLogVerbose : DEFAULT_LOG_VERBOSE
4184
4220
  };
4221
+ this.dataSubject$ = new Subject();
4222
+ this.formValidSubject$ = new Subject();
4223
+ this.submitSubject$ = new Subject();
4185
4224
  }
4186
4225
  /**
4187
4226
  * Creates an empty form with given index
@@ -4193,14 +4232,13 @@ class FormGroup {
4193
4232
  index,
4194
4233
  mappers
4195
4234
  }) {
4196
- const formInstance = new FormCore({
4197
- index,
4198
- mappers,
4199
- config: this.config
4200
- });
4201
4235
  this.addForm({
4202
4236
  key: index,
4203
- formInstance
4237
+ params: {
4238
+ index,
4239
+ mappers,
4240
+ config: this.config
4241
+ }
4204
4242
  });
4205
4243
  }
4206
4244
  /**
@@ -4212,11 +4250,16 @@ class FormGroup {
4212
4250
  */
4213
4251
  addForm({
4214
4252
  key,
4215
- formInstance
4253
+ params
4216
4254
  }) {
4217
4255
  this.checkIndexes({
4218
- key
4256
+ key: key
4219
4257
  });
4258
+ const formInstance = new FormCore(Object.assign(Object.assign({}, params), {
4259
+ dataSubject$: this.dataSubject$,
4260
+ formValidSubject$: this.formValidSubject$,
4261
+ submitSubject$: this.submitSubject$
4262
+ }));
4220
4263
  if (!formInstance.config) {
4221
4264
  formInstance.config = this.config;
4222
4265
  }
@@ -4319,52 +4362,42 @@ class FormGroup {
4319
4362
  ids,
4320
4363
  callback
4321
4364
  }) {
4322
- const subs = ids.reduce((acc, formId) => {
4323
- var _a, _b;
4324
- const sub = (_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.dataSubject$.pipe(groupBy(payload => `${formId}.${payload.event}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(({
4325
- key
4326
- }) => {
4327
- var _a;
4328
- return {
4329
- formField: key,
4330
- values: (_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.getFormValues()
4365
+ const sub = this.dataSubject$.pipe(filter(({
4366
+ formIndex
4367
+ }) => ids.includes(formIndex)), groupBy(({
4368
+ event,
4369
+ formIndex
4370
+ }) => `${event}.${formIndex}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(() => ids.reduce((acc, curr) => {
4371
+ const formInstance = this.forms.get(curr);
4372
+ if (formInstance) {
4373
+ acc[curr] = {
4374
+ values: formInstance.getFormValues()
4331
4375
  };
4332
- }), startWith({
4333
- formField: null,
4334
- values: (_b = this.forms.get(formId)) === null || _b === void 0 ? void 0 : _b.getFormValues()
4335
- }));
4336
- if (sub) {
4337
- acc[formId] = sub;
4338
- } else {
4339
- this.config.defaultLogVerbose && console.warn(`failed to register form id ${formId}`);
4340
4376
  }
4341
4377
  return acc;
4342
- }, {});
4343
- const sub = combineLatest(subs).subscribe(callback);
4378
+ }, {}))).subscribe(callback);
4344
4379
  return sub;
4345
4380
  }
4346
4381
  onValidSubscription({
4347
4382
  ids,
4348
4383
  callback
4349
4384
  }) {
4350
- const subs = ids.reduce((acc, formId) => {
4351
- var _a;
4352
- const sub = (_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.formValidNotification$.pipe(groupBy(payload => `${formId}.${payload.formIndex}`), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), startWith({
4353
- fieldTrigger: null
4354
- }), map(() => {
4385
+ const sub = this.formValidSubject$.pipe(filter(({
4386
+ formIndex
4387
+ }) => ids.includes(formIndex)), groupBy(({
4388
+ formIndex
4389
+ }) => formIndex), mergeMap(group$ => group$.pipe(debounceTime(this.config.defaultStateRefreshTimeMS))), map(() => ({
4390
+ groupValid: ids.every(id => {
4355
4391
  var _a;
4356
- return ((_a = this.forms.get(formId)) === null || _a === void 0 ? void 0 : _a.valid) === false ? false : true;
4357
- }), distinctUntilChanged());
4358
- if (sub) {
4359
- acc[formId] = sub;
4360
- } else {
4361
- this.config.defaultLogVerbose && console.warn(`failed to register validation subscription form id ${formId}`);
4362
- }
4363
- return acc;
4364
- }, {});
4365
- const sub = combineLatest(subs).pipe(map(forms => ({
4366
- groupValid: Object.keys(forms).every(formId => forms[formId]),
4367
- forms
4392
+ return (_a = this.forms.get(id)) === null || _a === void 0 ? void 0 : _a.valid;
4393
+ }),
4394
+ forms: ids.reduce((acc, curr) => {
4395
+ const formInstance = this.forms.get(curr);
4396
+ if (formInstance) {
4397
+ acc[curr] = formInstance.valid;
4398
+ }
4399
+ return acc;
4400
+ }, {})
4368
4401
  }))).subscribe(callback);
4369
4402
  return sub;
4370
4403
  }
@@ -4372,17 +4405,15 @@ class FormGroup {
4372
4405
  ids,
4373
4406
  callback
4374
4407
  }) {
4375
- const subs = ids.reduce((acc, formId) => {
4376
- const form = this.forms.get(formId);
4377
- const sub = form === null || form === void 0 ? void 0 : form.submitSubject$.pipe(map(() => form === null || form === void 0 ? void 0 : form.getFormValues()), startWith(undefined));
4378
- if (sub) {
4379
- acc[formId] = sub;
4380
- } else {
4381
- this.config.defaultLogVerbose && console.warn(`failed to register form id ${formId}`);
4408
+ const sub = this.submitSubject$.pipe(filter(({
4409
+ formIndex
4410
+ }) => ids.includes(formIndex)), map(() => ids.reduce((acc, curr) => {
4411
+ const formInstance = this.forms.get(curr);
4412
+ if (formInstance) {
4413
+ acc[curr] = formInstance.getFormValues();
4382
4414
  }
4383
4415
  return acc;
4384
- }, {});
4385
- const sub = combineLatest(subs).pipe(skip(1)).subscribe(callback);
4416
+ }, {}))).subscribe(callback);
4386
4417
  return sub;
4387
4418
  }
4388
4419
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bolttech/form-engine-core",
3
- "version": "1.0.0-beta.14",
3
+ "version": "1.0.0-beta.16",
4
4
  "module": "./index.esm.js",
5
5
  "type": "module",
6
6
  "main": "./index.esm.js",
@@ -2,7 +2,7 @@ import { Subject, Subscription } from 'rxjs';
2
2
  import { TApiConfig, TApiEvent, TApiResponse, TErrorMessages, TFormatters, TMasks, TResetPathMethods, TResetValueMethods, TSchemaFormConfig, TValidations, TVisibility } from '../types/schema';
3
3
  import { IComponentSchema, IComponentSchemaAsFormField } from '../interfaces/schema';
4
4
  import { IState } from '../interfaces/state';
5
- import { TEvents, TFieldEvent, TFieldValidationPayload, TValueChangeEvent } from '../types/event';
5
+ import { TEvents, TFieldEvent, TFieldValidationPayload, TFormDataPayload, TValueChangeEvent } from '../types/event';
6
6
  import { TMapper } from '../types/mapper';
7
7
  import { SafeSubject } from '../helpers/SafeSubject';
8
8
  import { TTemplateEvent } from '../types/template';
@@ -11,6 +11,7 @@ import { TFormValues } from '../types/form';
11
11
  * Represents a form field with observables for managing form state, validations, and API requests.
12
12
  */
13
13
  declare class FormField {
14
+ formIndex: string;
14
15
  name: string;
15
16
  nameToSubmit?: string;
16
17
  component: string;
@@ -50,10 +51,7 @@ declare class FormField {
50
51
  }>;
51
52
  fieldStateSubscription$: Subscription;
52
53
  templateSubject$: Subject<TTemplateEvent>;
53
- dataSubject$: Subject<{
54
- key: string;
55
- event: TEvents;
56
- }>;
54
+ dataSubject$: Subject<TFormDataPayload>;
57
55
  fieldValidNotification$: Subject<TFieldValidationPayload>;
58
56
  mountSubject$: Subject<{
59
57
  key: string;
@@ -92,7 +90,8 @@ declare class FormField {
92
90
  * @param {TMapper<unknown>} options.mapper, - component generic mapper containing render parameters for adapters
93
91
  * @param {() => TFormValues<unknown>} options.getFormValues, - form instance function that builds onData parameter payload from fields
94
92
  */
95
- constructor({ schemaComponent, config, path, children, validateVisibility, resetValue, resetProperty, templateSubject$, fieldEventSubject$, dataSubject$, fieldValidNotification$, mountSubject$, mapper, getFormValues, submitEvent, visibility, }: {
93
+ constructor({ formIndex, schemaComponent, config, path, children, validateVisibility, resetValue, resetProperty, templateSubject$, fieldEventSubject$, dataSubject$, fieldValidNotification$, mountSubject$, mapper, getFormValues, submitEvent, visibility, }: {
94
+ formIndex: string;
96
95
  schemaComponent: IComponentSchema;
97
96
  config?: TSchemaFormConfig;
98
97
  path?: string;
@@ -112,10 +111,7 @@ declare class FormField {
112
111
  submitEvent: () => void;
113
112
  templateSubject$: Subject<TTemplateEvent>;
114
113
  fieldEventSubject$: Subject<TFieldEvent>;
115
- dataSubject$: Subject<{
116
- key: string;
117
- event: TEvents;
118
- }>;
114
+ dataSubject$: Subject<TFormDataPayload>;
119
115
  fieldValidNotification$: Subject<TFieldValidationPayload>;
120
116
  mountSubject$: Subject<{
121
117
  key: string;
@@ -3,7 +3,7 @@ import { Subject, Subscription } from 'rxjs';
3
3
  import { IComponentSchema, IComponentSchemaAsFormField, IFormSchema } from '../interfaces/schema';
4
4
  import { TSchemaFormConfig } from '../types/schema';
5
5
  import { TSubscribedTemplates, TTemplateEvent } from '../types/template';
6
- import { TEvents, TFieldEvent, TFieldValidationPayload, TFormValidationPayload, TMutationEvents } from '../types/event';
6
+ import { TEvents, TFieldEvent, TFieldValidationPayload, TFormDataPayload, TFormSubmitPayload, TFormValidationPayload, TMutationEvents } from '../types/event';
7
7
  import { TFormEntry, TFormValues } from '../types/form';
8
8
  import { TMapper } from '../types/mapper';
9
9
  import { TEMPLATE_AVALIABLE_SCOPES } from '../constants/constants';
@@ -17,17 +17,14 @@ declare class FormCore {
17
17
  private _iVars;
18
18
  templateSubject$: Subject<TTemplateEvent>;
19
19
  templateSubscription$: Subscription;
20
- submitSubject$: Subject<TFormValues<any>>;
20
+ submitSubject$: Subject<TFormSubmitPayload<unknown>>;
21
21
  mountSubject$: Subject<{
22
22
  key: string;
23
23
  status: boolean;
24
24
  }>;
25
25
  fieldEventSubject$: Subject<TFieldEvent>;
26
- dataSubject$: Subject<{
27
- key: string;
28
- event: TEvents;
29
- }>;
30
- formValidNotification$: Subject<TFormValidationPayload>;
26
+ dataSubject$: Subject<TFormDataPayload>;
27
+ formValidSubject$: Subject<TFormValidationPayload>;
31
28
  fieldValidNotification$: Subject<TFieldValidationPayload>;
32
29
  subscribedTemplates: TSubscribedTemplates[];
33
30
  action?: string;
@@ -334,10 +331,7 @@ declare class FormCore {
334
331
  *
335
332
  * @param {(payload: TFormValidationPayload) => void} callback callback function to call onValid
336
333
  */
337
- subscribeFormValidation(callback: (payload: {
338
- formIndex: string;
339
- valid: boolean;
340
- }) => void): Subscription;
334
+ subscribeFormValidation(callback: (payload: TFormValidationPayload) => void): Subscription;
341
335
  /**
342
336
  * Submits the form by triggering form field events and invoking the onSubmit callback.
343
337
  */
@@ -1,14 +1,18 @@
1
- import { TFormValues } from '../types/form';
1
+ import { Subject } from 'rxjs';
2
+ import { TFormEntry, TFormValues } from '../types/form';
2
3
  import { TMapper } from '../types/mapper';
3
4
  import { TFormCore } from './form';
4
5
  import { TSchemaFormConfig } from '../types/schema';
5
- import { TFormGroupOnDataEventPayload, TFormGroupOnSubmitEventPayload, TFormGroupOnValidEventPayload } from '../types/event';
6
+ import { TFormDataPayload, TFormGroupOnDataEventPayload, TFormGroupOnSubmitEventPayload, TFormGroupOnValidEventPayload, TFormSubmitPayload, TFormValidationPayload } from '../types/event';
6
7
  /**
7
8
  * Represents a group that manages multiple forms.
8
9
  */
9
10
  declare class FormGroup {
10
11
  forms: Map<string, TFormCore>;
11
12
  config: Required<TSchemaFormConfig>;
13
+ dataSubject$: Subject<TFormDataPayload>;
14
+ formValidSubject$: Subject<TFormValidationPayload>;
15
+ submitSubject$: Subject<TFormSubmitPayload<unknown>>;
12
16
  /**
13
17
  * Creates an instance of FormGroup.
14
18
  */
@@ -32,9 +36,9 @@ declare class FormGroup {
32
36
  * @param {string} options.key - The key associated with the form instance.
33
37
  * @param {TFormCore} options.formInstance - The instance of the form to add.
34
38
  */
35
- addForm({ key, formInstance }: {
39
+ addForm({ key, params }: {
36
40
  key: string;
37
- formInstance: TFormCore;
41
+ params: TFormEntry;
38
42
  }): void;
39
43
  /**
40
44
  * Retrieves a form instance from the form group.
@@ -9,7 +9,7 @@ import { TFormValues } from './form';
9
9
  * const event: TEvents = 'ON_FIELD_CHANGE';
10
10
  * ```
11
11
  */
12
- type TEvents = 'ON_FIELD_MOUNT' | 'ON_FIELD_CHANGE' | 'ON_FIELD_BLUR' | 'ON_FIELD_FOCUS' | 'ON_FIELD_CLICK' | 'ON_FIELD_KEYUP' | 'ON_FIELD_KEYDOWN' | 'ON_FIELD_CLEARED' | 'ON_FORM_SUBMIT' | 'ON_FIELD_VALIDATION' | 'ON_FORM_MOUNT' | 'ON_API_FIELD_REQUEST' | 'ON_API_FIELD_RESPONSE';
12
+ type TEvents = 'ON_FIELD_MOUNT' | 'ON_FIELD_UNMOUNT' | 'ON_FIELD_CHANGE' | 'ON_FIELD_BLUR' | 'ON_FIELD_FOCUS' | 'ON_FIELD_CLICK' | 'ON_FIELD_KEYUP' | 'ON_FIELD_KEYDOWN' | 'ON_FIELD_CLEARED' | 'ON_FORM_SUBMIT' | 'ON_FIELD_VALIDATION' | 'ON_FORM_MOUNT' | 'ON_API_FIELD_REQUEST' | 'ON_API_FIELD_RESPONSE';
13
13
  /**
14
14
  * @type TMutationEvents
15
15
  * Represents the different types of events that can occur internally that triggers templating.
@@ -51,6 +51,23 @@ type TFieldEvent = {
51
51
  fieldName: string;
52
52
  fieldInstance?: IFormField;
53
53
  };
54
+ /**
55
+ * @type TFormDataPayload
56
+ * Event emitted to formGroup instance to capture onData form events
57
+ */
58
+ type TFormDataPayload = {
59
+ formIndex: string;
60
+ fieldIndex: string;
61
+ event: TEvents;
62
+ };
63
+ /**
64
+ * @type TFormSubmitPayload
65
+ * Event emitted to formGroup instance to capture onSubmit form events
66
+ */
67
+ type TFormSubmitPayload<T> = {
68
+ formIndex: string;
69
+ values: TFormValues<T>;
70
+ };
54
71
  /**
55
72
  * @type TFormValidationPayload
56
73
  * Form onValid event emmited payload on callback function parameter
@@ -71,8 +88,6 @@ type TFieldValidationPayload = {
71
88
  * Form Group onData event emitted payload on callback function parameter
72
89
  */
73
90
  type TFormGroupOnDataEventPayload<T> = Record<string, {
74
- formId: string;
75
- formField: string;
76
91
  values?: TFormValues<T>;
77
92
  }>;
78
93
  /**
@@ -88,4 +103,4 @@ type TFormGroupOnValidEventPayload = {
88
103
  * Form Group onSubmit event emitted payload on callback function parameter
89
104
  */
90
105
  type TFormGroupOnSubmitEventPayload<T> = Record<string, TFormValues<T> | undefined>;
91
- export { TEvents, TMutationEvents, TMutationEnum, TValueChangeEvent, TFieldEvent, TFormGroupOnDataEventPayload, TFormGroupOnValidEventPayload, TFormGroupOnSubmitEventPayload, TFormValidationPayload, TFieldValidationPayload, };
106
+ export { TEvents, TMutationEvents, TMutationEnum, TValueChangeEvent, TFieldEvent, TFormDataPayload, TFormSubmitPayload, TFormGroupOnDataEventPayload, TFormGroupOnValidEventPayload, TFormGroupOnSubmitEventPayload, TFormValidationPayload, TFieldValidationPayload, };
@@ -1,5 +1,7 @@
1
+ import { Subject } from 'rxjs';
1
2
  import { IFormSchema } from '../interfaces/schema';
2
3
  import { TMapper } from './mapper';
4
+ import { TFormDataPayload, TFormSubmitPayload, TFormValidationPayload } from './event';
3
5
  /**
4
6
  * @type TFormValues<T>
5
7
  * Represents the values and state of a form. It has a generic type that allows the importer to determine which type values key will return.
@@ -30,6 +32,9 @@ type TFormValues<T> = {
30
32
  * @property {IFormSchema} [schema] - The schema defining the structure and behavior of the form.
31
33
  * @property {Record<string, unknown>} [initialValues] - The initial values for the form fields.
32
34
  * @property {(data: TFormValues) => void} [onSubmit] - Callback function to handle form submission.
35
+ * @property {Subject<TFormDataPayload>} [dataSubject$] - data subject passed from formGroup instance
36
+ * @property {Subject<TFormValidationPayload>} [formValidSubject$] - formValid subject passed from formGroup instance
37
+ * @property {Subject<TFormSubmitPayload<unknown>>} [submitSubject$] - submit subject passed from formGroup instance
33
38
  *
34
39
  * @example
35
40
  * ```typescript
@@ -43,5 +48,8 @@ type TFormValues<T> = {
43
48
  type TFormEntry = Omit<IFormSchema, 'components'> & {
44
49
  schema?: IFormSchema;
45
50
  mappers?: TMapper<unknown>[];
51
+ dataSubject$?: Subject<TFormDataPayload>;
52
+ formValidSubject$?: Subject<TFormValidationPayload>;
53
+ submitSubject$?: Subject<TFormSubmitPayload<unknown>>;
46
54
  };
47
55
  export { TFormValues, TFormEntry };