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
@@ -2,7 +2,6 @@
2
2
 
3
3
  var _extends = require('@babel/runtime/helpers/extends');
4
4
  var React = require('react');
5
- var _defineProperty = require('@babel/runtime/helpers/defineProperty');
6
5
 
7
6
  const isObject = o => o && typeof o === 'object' && !Array.isArray(o);
8
7
  const defaultFieldProps = {
@@ -108,8 +107,7 @@ const _findValidityKey = (validity, exclude = []) => {
108
107
  }
109
108
  };
110
109
  const _checkTypeMismatch = input => {
111
- var _input$value;
112
- const value = (_input$value = input.value) === null || _input$value === void 0 ? void 0 : _input$value.toString().trim();
110
+ const value = input.value?.toString().trim();
113
111
  if (!value) return false;
114
112
  switch (input.type) {
115
113
  case 'email':
@@ -150,19 +148,15 @@ const _toRawData = (fields, options = {}) => {
150
148
  transform
151
149
  } = options;
152
150
  if (include) {
153
- include.forEach(key => {
154
- var _fields$key;
155
- return data[key] = (_fields$key = fields[key]) === null || _fields$key === void 0 ? void 0 : _fields$key.value;
156
- });
151
+ include.forEach(key => data[key] = fields[key]?.value);
157
152
  } else for (const f in fields) {
158
153
  data[f] = fields[f].value;
159
154
  }
160
- exclude === null || exclude === void 0 || exclude.forEach(key => delete data[key]);
155
+ exclude?.forEach(key => delete data[key]);
161
156
  if (transform) {
162
157
  for (const key in transform) {
163
- var _fields$key2;
164
158
  const set = transform[key];
165
- data[key] = set(((_fields$key2 = fields[key]) === null || _fields$key2 === void 0 ? void 0 : _fields$key2.value) || fields[key]);
159
+ data[key] = set(fields[key]?.value || fields[key]);
166
160
  }
167
161
  }
168
162
  return data;
@@ -181,19 +175,15 @@ function _toURLSearchParams(options) {
181
175
  } = options;
182
176
  if (include) {
183
177
  data = {};
184
- include.forEach(key => {
185
- var _this$key;
186
- return data[key] = (_this$key = this[key]) === null || _this$key === void 0 ? void 0 : _this$key.value;
187
- });
178
+ include.forEach(key => data[key] = this[key]?.value);
188
179
  } else {
189
180
  data = this.toRawData();
190
- exclude === null || exclude === void 0 || exclude.forEach(key => delete data[key]);
181
+ exclude?.forEach(key => delete data[key]);
191
182
  }
192
183
  if (transform) {
193
184
  for (const key in transform) {
194
- var _this$key2;
195
185
  const set = transform[key];
196
- data[key] = set((_this$key2 = this[key]) === null || _this$key2 === void 0 ? void 0 : _this$key2.value);
186
+ data[key] = set(this[key]?.value);
197
187
  }
198
188
  }
199
189
  } else data = this.toRawData();
@@ -201,8 +191,7 @@ function _toURLSearchParams(options) {
201
191
  }
202
192
  function __debounce(timeout, id) {
203
193
  return new Promise(resolve => {
204
- var _this$id;
205
- if ((_this$id = this[id]) !== null && _this$id !== void 0 && _this$id.timerId) clearTimeout(this[id].timerId);
194
+ if (this[id]?.timerId) clearTimeout(this[id].timerId);
206
195
  const timerId = setTimeout(() => resolve(), timeout);
207
196
  if (this[id]) {
208
197
  this[id].timerId = timerId;
@@ -213,11 +202,11 @@ function __debounce(timeout, id) {
213
202
  }
214
203
  const _debounce = __debounce.bind({});
215
204
  const _extractValue = (e, unknown) => {
216
- if (e !== null && e !== void 0 && e.target) {
205
+ if (e?.target) {
217
206
  if (Object.hasOwn(typeValueDict, e.target.type)) return e.target[typeValueDict[e.target.type]];
218
207
  return e.target.value;
219
208
  }
220
- return (e === null || e === void 0 ? void 0 : e.value) || (isObject(unknown) ? unknown.value : unknown);
209
+ return e?.value || (isObject(unknown) ? unknown.value : unknown);
221
210
  };
222
211
  const _checkResult = (handlerResult, value) => typeof handlerResult === 'boolean' ? handlerResult : typeof value === 'string' ? typeof handlerResult === 'string' ? !new RegExp(handlerResult).test(value) : !handlerResult.test(value) : false;
223
212
  const _merge = (target = {}, ...nodes) => {
@@ -233,6 +222,40 @@ const _merge = (target = {}, ...nodes) => {
233
222
  }
234
223
  return _merge(target, ...nodes);
235
224
  };
225
+ const _mergeRefs = (refA, refB) => {
226
+ return value => {
227
+ if (typeof refA === 'function') {
228
+ refA(value);
229
+ } else if (refA) {
230
+ refA.current = value;
231
+ }
232
+ if (typeof refB === 'function') {
233
+ refB(value);
234
+ } else if (refB) {
235
+ refB.current = value;
236
+ }
237
+ };
238
+ };
239
+ const _buildFormState = (fields, formElement, dispatchChanges) => {
240
+ const isFormValid = _checkIfFormIsValid(fields);
241
+ const formState = {
242
+ ...fields,
243
+ isValid: isFormValid,
244
+ isInvalid: !isFormValid,
245
+ toRawData: options => _toRawData(fields, options),
246
+ toFormData: () => _toFormData(formElement),
247
+ toURLSearchParams: _toURLSearchParams,
248
+ checkValidity: function () {
249
+ this.isValid = formElement && formElement.checkValidity() || false;
250
+ this.isInvalid = !this.isValid;
251
+ return this.isValid;
252
+ },
253
+ dispatchChanges: changes => dispatchChanges({
254
+ fields: _merge({}, fields, changes)
255
+ })
256
+ };
257
+ return formState;
258
+ };
236
259
 
237
260
  let handlersMap;
238
261
  let validityMap;
@@ -269,26 +292,21 @@ class GValidator {
269
292
  return this._asyncHandlers;
270
293
  }
271
294
  constructor(baseValidator) {
272
- _defineProperty(this, "_handlers", void 0);
273
- _defineProperty(this, "_constraintHandlers", void 0);
274
- _defineProperty(this, "_asyncHandlers", void 0);
275
- _defineProperty(this, "track", void 0);
276
- const baseHandlers = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.handlers) || [];
277
- const baseConstraintHandlers = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.constraintHandlers) || [];
278
- const baseHandlersAsync = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.asyncHandlers) || [];
295
+ const baseHandlers = baseValidator?.handlers || [];
296
+ const baseConstraintHandlers = baseValidator?.constraintHandlers || [];
297
+ const baseHandlersAsync = baseValidator?.asyncHandlers || [];
279
298
  this._handlers = [].concat(baseHandlers);
280
299
  this._constraintHandlers = [].concat(baseConstraintHandlers);
281
300
  this._asyncHandlers = [].concat(baseHandlersAsync);
282
301
  {
283
302
  this.track = [];
284
- if (baseValidator !== null && baseValidator !== void 0 && baseValidator.track) {
303
+ if (baseValidator?.track) {
285
304
  this.track = this.track.concat(baseValidator.track);
286
305
  }
287
306
  }
288
307
  }
289
308
  hasConstraint(constraint) {
290
- var _this$track;
291
- return ((_this$track = this.track) === null || _this$track === void 0 ? void 0 : _this$track.includes(constraint)) || false;
309
+ return this.track?.includes(constraint) || false;
292
310
  }
293
311
  withRequiredMessage(message) {
294
312
  return this.__addConstraintValidationHandler('valueMissing', message);
@@ -352,10 +370,9 @@ const useFormHandlers = (getState, setState, validators = {}, optimized = false)
352
370
  const _viHandler = (input, e) => {
353
371
  if (!input) return;
354
372
  const element = e && e.target;
355
- const hasInitialValue = !input.dirty && input.value && !input.touched;
356
- if (!element && !hasInitialValue) return;
357
373
  if (typeof document !== 'undefined' && (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement)) {
358
374
  if (!input.checkValidity) input.checkValidity = () => element.checkValidity();
375
+ const hasInitialValue = !input.dirty && input.value && !input.touched;
359
376
  if (hasInitialValue) {
360
377
  _checkInputManually(input);
361
378
  _dispatchChanges(input, input.formKey);
@@ -399,7 +416,7 @@ const useFormHandlers = (getState, setState, validators = {}, optimized = false)
399
416
  const _validateInput = (input, validityKey, setValidity) => {
400
417
  const inputValidator = validators[input.validatorKey || input.formKey] || validators['*'];
401
418
  {
402
- if (validityKey && !(inputValidator !== null && inputValidator !== void 0 && inputValidator.hasConstraint(validityKey))) {
419
+ if (validityKey && !inputValidator?.hasConstraint(validityKey)) {
403
420
  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`);
404
421
  }
405
422
  }
@@ -484,7 +501,12 @@ const GFormContextProvider = ({
484
501
  const stateRef = React.useRef(initialState);
485
502
  const listeners = React.useRef(null);
486
503
  const setState = React.useCallback(updater => {
487
- stateRef.current = typeof updater === 'function' ? updater(stateRef.current) : updater;
504
+ const prevState = stateRef.current;
505
+ const nextState = typeof updater === "function" ? updater(prevState) : updater;
506
+ if (Object.is(prevState, nextState)) {
507
+ return;
508
+ }
509
+ stateRef.current = nextState;
488
510
  listeners.current.forEach(l => l());
489
511
  }, []);
490
512
  const handlers = useFormHandlers(() => stateRef.current, setState, validators, optimized);
@@ -549,46 +571,15 @@ const FormRenderer = React.forwardRef(({
549
571
  }, ref) => {
550
572
  const formRef = React.useRef(null);
551
573
  const {
552
- getState,
553
- handlers
574
+ handlers,
575
+ getState
554
576
  } = useFormStore();
555
577
  const fields = useFormSelector(state => state.fields);
556
- const refHandler = React.useCallback(element => {
557
- if (ref) {
558
- if (typeof ref === 'function') {
559
- ref(element);
560
- } else {
561
- ref.current = element;
562
- }
563
- }
564
- formRef.current = element;
565
- }, [ref]);
566
- const getFormState = React.useCallback(() => {
567
- const isFormValid = _checkIfFormIsValid(fields);
568
- const formState = {
569
- ...fields,
570
- isValid: isFormValid,
571
- isInvalid: !isFormValid,
572
- toRawData: options => _toRawData(fields, options),
573
- toFormData: () => _toFormData(formRef.current),
574
- toURLSearchParams: _toURLSearchParams,
575
- checkValidity: function () {
576
- this.isValid = formRef.current && formRef.current.checkValidity() || false;
577
- this.isInvalid = !this.isValid;
578
- return this.isValid;
579
- },
580
- dispatchChanges: changes => handlers._dispatchChanges({
581
- fields: _merge({}, fields, changes)
582
- })
583
- };
584
- if (stateRef) stateRef.current = formState;
585
- return formState;
586
- }, [fields]);
587
578
  const formComponent = React.useMemo(() => {
588
- const state = getFormState();
579
+ const state = _buildFormState(fields, formRef.current, handlers._dispatchChanges);
589
580
  const formChildren = typeof children === 'function' ? children(state) : children;
590
581
  const _onSubmit = e => {
591
- const state = getFormState();
582
+ const state = _buildFormState(fields, formRef.current, handlers._dispatchChanges);
592
583
  if (state.isValid && onSubmit) {
593
584
  onSubmit(state, e);
594
585
  }
@@ -603,6 +594,7 @@ const FormRenderer = React.forwardRef(({
603
594
  if (onKeyUp) {
604
595
  _onKeyUp = e => onKeyUp(state, e);
605
596
  }
597
+ if (stateRef) stateRef.current = state;
606
598
  if (handlers.optimized) {
607
599
  if (onChange) {
608
600
  _onChange = (e, unknown) => {
@@ -615,7 +607,7 @@ const FormRenderer = React.forwardRef(({
615
607
  };
616
608
  }
617
609
  return React.createElement("form", _extends({}, rest, {
618
- ref: refHandler,
610
+ ref: _mergeRefs(ref, formRef),
619
611
  onPaste: _onPaste,
620
612
  onKeyDown: _onKeyDown,
621
613
  onKeyUp: _onKeyUp,
@@ -632,16 +624,17 @@ const FormRenderer = React.forwardRef(({
632
624
  _onChange = e => onChange(state, e);
633
625
  }
634
626
  return React.createElement("form", _extends({}, rest, {
635
- ref: refHandler,
627
+ ref: _mergeRefs(ref, formRef),
636
628
  onSubmit: _onSubmit,
637
629
  onChange: _onChange,
638
630
  onPaste: _onPaste,
639
631
  onKeyDown: _onKeyDown,
640
632
  onKeyUp: _onKeyUp
641
633
  }), formChildren);
642
- }, [children, getFormState]);
634
+ }, [children, fields]);
643
635
  React.useEffect(() => {
644
- const state = getFormState();
636
+ const initialStateFields = getState().fields;
637
+ const state = _buildFormState(initialStateFields, formRef.current, handlers._dispatchChanges);
645
638
  if (!_hasSubmitter(formRef.current)) {
646
639
  console.warn(`DEV ONLY - [No Submit Button] - you have created a form without a button type=submit, this will prevent the onSubmit event from being fired.\nif you have a button with onClick event that handle the submission of the form then ignore this warning\nbut don't forget to manually invoke the checkValidity() function to check if the form is valid before perfoming any action, for example:\nif (formState.checkValidity()) { \n\t//do somthing\n}\n`);
647
640
  }
@@ -656,13 +649,12 @@ const FormRenderer = React.forwardRef(({
656
649
  } else _handler(changes);
657
650
  }
658
651
  }
659
- const fields = getState().fields;
660
652
  for (const fieldKey in fields) {
661
653
  const field = fields[fieldKey];
662
654
  if (!field.value) continue;
663
655
  handlers._viHandler(field);
664
656
  }
665
- }, [getFormState]);
657
+ }, []);
666
658
  return formComponent;
667
659
  });
668
660
  const GForm = React.forwardRef(({
@@ -685,7 +677,7 @@ const GForm = React.forwardRef(({
685
677
 
686
678
  const selectFields = [state => state.fields];
687
679
  const makeSelectFields = (keys = []) => createSelector(selectFields, fields => {
688
- const selected = keys.map(key => fields[key]).filter(Boolean);
680
+ const selected = keys.map(key => JSON.stringify(fields[key].value)).join(', ');
689
681
  return selected.length ? selected : null;
690
682
  });
691
683
 
@@ -761,7 +753,6 @@ const _GInput = React.forwardRef(({
761
753
  return React.createElement("input", _props);
762
754
  }, [inputState, element]);
763
755
  const _fetchDeps = useFormSelector(makeSelectFields(fetchDeps));
764
- const stableFetchDeps = React.useMemo(() => JSON.stringify(_fetchDeps), [_fetchDeps]);
765
756
  React.useEffect(() => {
766
757
  if (fetch) {
767
758
  _debounce(debounce, `${inputState.gid}-fetch`).then(() => {
@@ -773,7 +764,7 @@ const _GInput = React.forwardRef(({
773
764
  }
774
765
  });
775
766
  }
776
- }, [stableFetchDeps]);
767
+ }, [_fetchDeps]);
777
768
  return _element;
778
769
  });
779
770
  const GInput = React.memo(_GInput);