gform-react 2.6.3 → 2.7.2

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.
Files changed (42) hide show
  1. package/dist/cjs/gform-react.development.js +70 -79
  2. package/dist/cjs/gform-react.development.js.map +1 -1
  3. package/dist/cjs/gform-react.production.js +1 -1
  4. package/dist/cjs/gform-react.production.js.map +1 -1
  5. package/dist/esm/GForm.development.js +14 -44
  6. package/dist/esm/GForm.development.js.map +1 -1
  7. package/dist/esm/GForm.production.js +1 -1
  8. package/dist/esm/GForm.production.js.map +1 -1
  9. package/dist/esm/GInput.development.js +6 -6
  10. package/dist/esm/GInput.development.js.map +1 -1
  11. package/dist/esm/GInput.production.js +1 -1
  12. package/dist/esm/GInput.production.js.map +1 -1
  13. package/dist/esm/GValidator.development.js +0 -6
  14. package/dist/esm/GValidator.development.js.map +1 -1
  15. package/dist/esm/GValidator.production.js +1 -1
  16. package/dist/esm/GValidator.production.js.map +1 -1
  17. package/dist/esm/shared.development.js +48 -7
  18. package/dist/esm/shared.development.js.map +1 -1
  19. package/dist/esm/shared.production.js +1 -1
  20. package/dist/esm/shared.production.js.map +1 -1
  21. package/dist/esm/useFormSelector.development.js +2 -3
  22. package/dist/esm/useFormSelector.development.js.map +1 -1
  23. package/dist/esm/useFormSelector.production.js +1 -1
  24. package/dist/index.d.ts +0 -4
  25. package/native/dist/cjs/gform-react.development.js +85 -104
  26. package/native/dist/cjs/gform-react.development.js.map +1 -1
  27. package/native/dist/cjs/gform-react.production.js +1 -1
  28. package/native/dist/cjs/gform-react.production.js.map +1 -1
  29. package/native/dist/esm/RNGForm.development.js +11 -45
  30. package/native/dist/esm/RNGForm.development.js.map +1 -1
  31. package/native/dist/esm/RNGForm.production.js +1 -1
  32. package/native/dist/esm/RNGForm.production.js.map +1 -1
  33. package/native/dist/esm/RNGInput.development.js +12 -6
  34. package/native/dist/esm/RNGInput.development.js.map +1 -1
  35. package/native/dist/esm/RNGInput.production.js +1 -1
  36. package/native/dist/esm/RNGInput.production.js.map +1 -1
  37. package/native/dist/esm/shared.development.js +45 -22
  38. package/native/dist/esm/shared.development.js.map +1 -1
  39. package/native/dist/esm/shared.production.js +1 -1
  40. package/native/dist/esm/shared.production.js.map +1 -1
  41. package/native/dist/index.d.ts +4 -5
  42. package/package.json +9 -3
@@ -1,8 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var _extends = require('@babel/runtime/helpers/extends');
4
- var React = require('react');
5
- require('@babel/runtime/helpers/defineProperty');
4
+ var React$1 = require('react');
6
5
  var reactNative = require('react-native');
7
6
 
8
7
  const isObject = o => o && typeof o === 'object' && !Array.isArray(o);
@@ -83,8 +82,8 @@ const _buildFormInitialValues = (rows = []) => {
83
82
  };
84
83
  const _findInputs = (root, total = []) => {
85
84
  if (!root) return total;
86
- React.Children.forEach(root, child => {
87
- if (!React.isValidElement(child)) return;
85
+ React$1.Children.forEach(root, child => {
86
+ if (!React$1.isValidElement(child)) return;
88
87
  if (child.props) {
89
88
  const {
90
89
  formKey,
@@ -109,8 +108,7 @@ const _findValidityKey = (validity, exclude = []) => {
109
108
  }
110
109
  };
111
110
  const _checkTypeMismatch = input => {
112
- var _input$value;
113
- const value = (_input$value = input.value) === null || _input$value === void 0 ? void 0 : _input$value.toString().trim();
111
+ const value = input.value?.toString().trim();
114
112
  if (!value) return false;
115
113
  switch (input.type) {
116
114
  case 'email':
@@ -128,6 +126,14 @@ const _checkTypeMismatch = input => {
128
126
  return false;
129
127
  }
130
128
  };
129
+ const _checkIfFormIsValid = fields => {
130
+ for (const f in fields) {
131
+ if (fields[f].error) {
132
+ return false;
133
+ }
134
+ }
135
+ return true;
136
+ };
131
137
  const _toRawData = (fields, options = {}) => {
132
138
  const data = {};
133
139
  const {
@@ -136,19 +142,15 @@ const _toRawData = (fields, options = {}) => {
136
142
  transform
137
143
  } = options;
138
144
  if (include) {
139
- include.forEach(key => {
140
- var _fields$key;
141
- return data[key] = (_fields$key = fields[key]) === null || _fields$key === void 0 ? void 0 : _fields$key.value;
142
- });
145
+ include.forEach(key => data[key] = fields[key]?.value);
143
146
  } else for (const f in fields) {
144
147
  data[f] = fields[f].value;
145
148
  }
146
- exclude === null || exclude === void 0 || exclude.forEach(key => delete data[key]);
149
+ exclude?.forEach(key => delete data[key]);
147
150
  if (transform) {
148
151
  for (const key in transform) {
149
- var _fields$key2;
150
152
  const set = transform[key];
151
- data[key] = set(((_fields$key2 = fields[key]) === null || _fields$key2 === void 0 ? void 0 : _fields$key2.value) || fields[key]);
153
+ data[key] = set(fields[key]?.value || fields[key]);
152
154
  }
153
155
  }
154
156
  return data;
@@ -163,19 +165,15 @@ function _toURLSearchParams(options) {
163
165
  } = options;
164
166
  if (include) {
165
167
  data = {};
166
- include.forEach(key => {
167
- var _this$key;
168
- return data[key] = (_this$key = this[key]) === null || _this$key === void 0 ? void 0 : _this$key.value;
169
- });
168
+ include.forEach(key => data[key] = this[key]?.value);
170
169
  } else {
171
170
  data = this.toRawData();
172
- exclude === null || exclude === void 0 || exclude.forEach(key => delete data[key]);
171
+ exclude?.forEach(key => delete data[key]);
173
172
  }
174
173
  if (transform) {
175
174
  for (const key in transform) {
176
- var _this$key2;
177
175
  const set = transform[key];
178
- data[key] = set((_this$key2 = this[key]) === null || _this$key2 === void 0 ? void 0 : _this$key2.value);
176
+ data[key] = set(this[key]?.value);
179
177
  }
180
178
  }
181
179
  } else data = this.toRawData();
@@ -183,8 +181,7 @@ function _toURLSearchParams(options) {
183
181
  }
184
182
  function __debounce(timeout, id) {
185
183
  return new Promise(resolve => {
186
- var _this$id;
187
- if ((_this$id = this[id]) !== null && _this$id !== void 0 && _this$id.timerId) clearTimeout(this[id].timerId);
184
+ if (this[id]?.timerId) clearTimeout(this[id].timerId);
188
185
  const timerId = setTimeout(() => resolve(), timeout);
189
186
  if (this[id]) {
190
187
  this[id].timerId = timerId;
@@ -195,11 +192,11 @@ function __debounce(timeout, id) {
195
192
  }
196
193
  const _debounce = __debounce.bind({});
197
194
  const _extractValue = (e, unknown) => {
198
- if (e !== null && e !== void 0 && e.target) {
195
+ if (e?.target) {
199
196
  if (Object.hasOwn(typeValueDict, e.target.type)) return e.target[typeValueDict[e.target.type]];
200
197
  return e.target.value;
201
198
  }
202
- return (e === null || e === void 0 ? void 0 : e.value) || (isObject(unknown) ? unknown.value : unknown);
199
+ return e?.value || (isObject(unknown) ? unknown.value : unknown);
203
200
  };
204
201
  const _checkResult = (handlerResult, value) => typeof handlerResult === 'boolean' ? handlerResult : typeof value === 'string' ? typeof handlerResult === 'string' ? !new RegExp(handlerResult).test(value) : !handlerResult.test(value) : false;
205
202
  const _merge = (target = {}, ...nodes) => {
@@ -215,6 +212,29 @@ const _merge = (target = {}, ...nodes) => {
215
212
  }
216
213
  return _merge(target, ...nodes);
217
214
  };
215
+ const _buildRNFormState = (fields, dispatchChanges) => {
216
+ const isFormValid = _checkIfFormIsValid(fields);
217
+ const formState = {
218
+ ...fields,
219
+ isValid: isFormValid,
220
+ isInvalid: !isFormValid,
221
+ toRawData: options => _toRawData(fields, options),
222
+ toURLSearchParams: _toURLSearchParams,
223
+ checkValidity: () => {
224
+ for (const i in fields) {
225
+ const valid = fields[i].checkValidity();
226
+ if (!valid) {
227
+ return false;
228
+ }
229
+ }
230
+ return true;
231
+ },
232
+ dispatchChanges: changes => dispatchChanges({
233
+ fields: _merge({}, fields, changes)
234
+ })
235
+ };
236
+ return formState;
237
+ };
218
238
 
219
239
  let handlersMap;
220
240
  let validityMap;
@@ -245,10 +265,9 @@ const useFormHandlers = (getState, setState, validators = {}, optimized = false)
245
265
  const _viHandler = (input, e) => {
246
266
  if (!input) return;
247
267
  const element = e && e.target;
248
- const hasInitialValue = !input.dirty && input.value && !input.touched;
249
- if (!element && !hasInitialValue) return;
250
268
  if (typeof document !== 'undefined' && (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement)) {
251
269
  if (!input.checkValidity) input.checkValidity = () => element.checkValidity();
270
+ const hasInitialValue = !input.dirty && input.value && !input.touched;
252
271
  if (hasInitialValue) {
253
272
  _checkInputManually(input);
254
273
  _dispatchChanges(input, input.formKey);
@@ -292,7 +311,7 @@ const useFormHandlers = (getState, setState, validators = {}, optimized = false)
292
311
  const _validateInput = (input, validityKey, setValidity) => {
293
312
  const inputValidator = validators[input.validatorKey || input.formKey] || validators['*'];
294
313
  {
295
- if (validityKey && !(inputValidator !== null && inputValidator !== void 0 && inputValidator.hasConstraint(validityKey))) {
314
+ if (validityKey && !inputValidator?.hasConstraint(validityKey)) {
296
315
  if (validityKey === 'typeMismatch') console.warn(`DEV ONLY - [Missing Validator] - the input '${input.formKey}' has described the constraint '${validityMap[validityKey]}' however, a correspond validator/custom validation/pattern validator is missing.\nadd '${handlersMap[validityMap[validityKey]]}' or 'withCustomValidation' or '${handlersMap[validityMap.patternMismatch]}' to the input validator.\nexample:\nconst validators: GValidators = {\n\temail: new GValidator().withPatternMismatchMessage('pattern mismatch'),\n\t...\n}\n\nor either remove the constraint '${validityMap[validityKey]}' from the input props`);else console.warn(`DEV ONLY - [Missing Validator] - the input '${input.formKey}' has described the constraint '${validityMap[validityKey]}' however, a correspond validator is missing.\nadd '${handlersMap[validityMap[validityKey]]}' to the input validator.\nexample:\nconst validators: GValidators = {\n\temail: new GValidator().withPatternMismatchMessage('pattern mismatch'),\n\t...\n}\n\nor either remove the constraint '${validityMap[validityKey]}' from the input props`);
297
316
  }
298
317
  }
@@ -367,21 +386,26 @@ const useFormHandlers = (getState, setState, validators = {}, optimized = false)
367
386
  };
368
387
  };
369
388
 
370
- const GFormContext = React.createContext({});
389
+ const GFormContext = React$1.createContext({});
371
390
  const GFormContextProvider = ({
372
391
  children,
373
392
  initialState,
374
393
  validators,
375
394
  optimized
376
395
  }) => {
377
- const stateRef = React.useRef(initialState);
378
- const listeners = React.useRef(null);
379
- const setState = React.useCallback(updater => {
380
- stateRef.current = typeof updater === 'function' ? updater(stateRef.current) : updater;
396
+ const stateRef = React$1.useRef(initialState);
397
+ const listeners = React$1.useRef(null);
398
+ const setState = React$1.useCallback(updater => {
399
+ const prevState = stateRef.current;
400
+ const nextState = typeof updater === "function" ? updater(prevState) : updater;
401
+ if (Object.is(prevState, nextState)) {
402
+ return;
403
+ }
404
+ stateRef.current = nextState;
381
405
  listeners.current.forEach(l => l());
382
406
  }, []);
383
407
  const handlers = useFormHandlers(() => stateRef.current, setState, validators, optimized);
384
- const store = React.useMemo(() => {
408
+ const store = React$1.useMemo(() => {
385
409
  if (!listeners.current) {
386
410
  listeners.current = new Set();
387
411
  } else {
@@ -402,18 +426,18 @@ const GFormContextProvider = ({
402
426
  handlers
403
427
  };
404
428
  }, [initialState]);
405
- return React.createElement(GFormContext.Provider, {
429
+ return React$1.createElement(GFormContext.Provider, {
406
430
  value: store
407
431
  }, children);
408
432
  };
409
433
  const useFormStore = () => {
410
- const store = React.useContext(GFormContext);
434
+ const store = React$1.useContext(GFormContext);
411
435
  if (!store.getState) throw new Error('useGFormStore must be used within `GForm` component');
412
436
  return store;
413
437
  };
414
438
  const useFormSelector = selector => {
415
439
  const store = useFormStore();
416
- return React.useSyncExternalStore(store.subscribe, () => selector(store.getState()), () => selector(store.getState()));
440
+ return React$1.useSyncExternalStore(store.subscribe, () => selector(store.getState()), () => selector(store.getState()));
417
441
  };
418
442
  function createSelector(selectors, combiner) {
419
443
  let lastArgs = [];
@@ -429,21 +453,7 @@ function createSelector(selectors, combiner) {
429
453
  };
430
454
  }
431
455
 
432
- const selectFields = [state => state.fields];
433
- const selectFirstInvalidField = createSelector(selectFields, fields => {
434
- for (const f in fields) {
435
- if (fields[f].error) {
436
- return true;
437
- }
438
- }
439
- return false;
440
- });
441
- const makeSelectFields = (keys = []) => createSelector(selectFields, fields => {
442
- const selected = keys.map(key => fields[key]).filter(Boolean);
443
- return selected.length ? selected : null;
444
- });
445
-
446
- const FormRenderer = React.forwardRef(({
456
+ const FormRenderer = React$1.forwardRef(({
447
457
  stateRef,
448
458
  children,
449
459
  onInit,
@@ -451,43 +461,21 @@ const FormRenderer = React.forwardRef(({
451
461
  ...rest
452
462
  }, ref) => {
453
463
  const {
454
- getState,
455
- handlers
464
+ handlers,
465
+ getState
456
466
  } = useFormStore();
457
- const isFormInvalid = useFormSelector(selectFirstInvalidField);
458
- const getFormState = React.useCallback(() => {
459
- const fields = getState().fields;
460
- const formState = {
461
- ...fields,
462
- isValid: !isFormInvalid,
463
- isInvalid: isFormInvalid,
464
- toRawData: options => _toRawData(fields, options),
465
- toURLSearchParams: _toURLSearchParams,
466
- checkValidity: () => {
467
- for (const i in fields) {
468
- const valid = fields[i].checkValidity();
469
- if (!valid) {
470
- return false;
471
- }
472
- }
473
- return true;
474
- },
475
- dispatchChanges: changes => handlers._dispatchChanges({
476
- fields: _merge({}, fields, changes)
477
- })
478
- };
479
- if (stateRef) stateRef.current = formState;
480
- return formState;
481
- }, [isFormInvalid]);
482
- const formComponent = React.useMemo(() => {
483
- const state = getFormState();
467
+ const fields = useFormSelector(state => state.fields);
468
+ const formComponent = React$1.useMemo(() => {
469
+ const state = _buildRNFormState(fields, handlers._dispatchChanges);
470
+ if (stateRef) stateRef.current = state;
484
471
  const formChildren = typeof children === 'function' ? children(state) : children;
485
472
  return React.createElement(El, _extends({}, rest, {
486
473
  ref: ref
487
474
  }), formChildren);
488
- }, [getFormState, children]);
489
- React.useEffect(() => {
490
- const state = getFormState();
475
+ }, [children, fields]);
476
+ React$1.useEffect(() => {
477
+ const initialStateFields = getState().fields;
478
+ const state = _buildRNFormState(initialStateFields, handlers._dispatchChanges);
491
479
  if (onInit) {
492
480
  const changes = onInit(state);
493
481
  if (changes) {
@@ -499,33 +487,21 @@ const FormRenderer = React.forwardRef(({
499
487
  } else _handler(changes);
500
488
  }
501
489
  }
502
- const dispatchers = {};
503
490
  const fields = getState().fields;
504
491
  for (const fieldKey in fields) {
505
- dispatchers[fieldKey] = {
506
- dispatchChanges: changes => handlers._dispatchChanges(changes, fieldKey),
507
- checkValidity: () => {
508
- const result = handlers._createInputChecker(state[fieldKey]);
509
- handlers._dispatchChanges(state[fieldKey], fieldKey);
510
- return result;
511
- }
512
- };
513
492
  const field = fields[fieldKey];
514
493
  if (!field.value) continue;
515
494
  handlers._viHandler(field);
516
495
  }
517
- handlers._dispatchChanges({
518
- fields: _merge(dispatchers, state)
519
- });
520
- }, [getFormState]);
496
+ }, []);
521
497
  return formComponent;
522
498
  });
523
- const RNGForm = React.forwardRef(({
499
+ const RNGForm = React$1.forwardRef(({
524
500
  children,
525
501
  validators,
526
502
  ...props
527
503
  }, ref) => {
528
- const initialState = React.useMemo(() => {
504
+ const initialState = React$1.useMemo(() => {
529
505
  return _buildFormInitialValues(typeof children === 'function' ? children({}) : children);
530
506
  }, [children]);
531
507
  return React.createElement(GFormContextProvider, {
@@ -536,7 +512,13 @@ const RNGForm = React.forwardRef(({
536
512
  }, props), children));
537
513
  });
538
514
 
539
- const _RNGInput = React.forwardRef(({
515
+ const selectFields = [state => state.fields];
516
+ const makeSelectFields = (keys = []) => createSelector(selectFields, fields => {
517
+ const selected = keys.map(key => JSON.stringify(fields[key].value)).join(', ');
518
+ return selected.length ? selected : null;
519
+ });
520
+
521
+ const _RNGInput = React$1.forwardRef(({
540
522
  formKey,
541
523
  element,
542
524
  type,
@@ -550,7 +532,7 @@ const _RNGInput = React.forwardRef(({
550
532
  }, ref) => {
551
533
  const inputState = useFormSelector(state => state.fields[formKey]);
552
534
  const store = useFormStore();
553
- const _element = React.useMemo(() => {
535
+ const _element = React$1.useMemo(() => {
554
536
  const value = inputState.value || '';
555
537
  const _props = {
556
538
  ...rest,
@@ -592,8 +574,7 @@ const _RNGInput = React.forwardRef(({
592
574
  return React.createElement(reactNative.TextInput, _props);
593
575
  }, [inputState, element]);
594
576
  const _fetchDeps = useFormSelector(makeSelectFields(fetchDeps));
595
- const stableFetchDeps = React.useMemo(() => JSON.stringify(_fetchDeps), [_fetchDeps]);
596
- React.useEffect(() => {
577
+ React$1.useEffect(() => {
597
578
  if (fetch) {
598
579
  _debounce(debounce, `${inputState.gid}-fetch`).then(() => {
599
580
  const res = fetch(inputState, store.getState().fields);
@@ -604,10 +585,10 @@ const _RNGInput = React.forwardRef(({
604
585
  }
605
586
  });
606
587
  }
607
- }, [stableFetchDeps]);
588
+ }, [_fetchDeps]);
608
589
  return _element;
609
590
  });
610
- const RNGInput = React.memo(_RNGInput);
591
+ const RNGInput = React$1.memo(_RNGInput);
611
592
 
612
593
  exports.RNGForm = RNGForm;
613
594
  exports.RNGInput = RNGInput;