gform-react 1.11.1 → 2.5.0

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 (31) hide show
  1. package/README.md +4 -3
  2. package/dist/cjs/gform-react.development.js +280 -238
  3. package/dist/cjs/gform-react.development.js.map +1 -1
  4. package/dist/cjs/gform-react.production.js +1 -1
  5. package/dist/cjs/gform-react.production.js.map +1 -1
  6. package/dist/esm/GForm.production.js +1 -1
  7. package/dist/esm/GForm.production.js.map +1 -1
  8. package/dist/esm/GInput.production.js +1 -1
  9. package/dist/esm/GInput.production.js.map +1 -1
  10. package/dist/esm/GValidator.production.js +1 -1
  11. package/dist/esm/GValidator.production.js.map +1 -1
  12. package/dist/esm/index.development.js +286 -243
  13. package/dist/esm/index.development.js.map +1 -1
  14. package/dist/esm/index.js +2 -1
  15. package/dist/esm/shared.production.js +1 -1
  16. package/dist/esm/shared.production.js.map +1 -1
  17. package/dist/index.d.ts +25 -12
  18. package/native/dist/cjs/gform-react-native.development.js +222 -284
  19. package/native/dist/cjs/gform-react-native.development.js.map +1 -1
  20. package/native/dist/cjs/gform-react-native.production.js +1 -1
  21. package/native/dist/cjs/gform-react-native.production.js.map +1 -1
  22. package/native/dist/esm/RNGForm.production.js +1 -1
  23. package/native/dist/esm/RNGForm.production.js.map +1 -1
  24. package/native/dist/esm/RNGInput.production.js +1 -1
  25. package/native/dist/esm/RNGInput.production.js.map +1 -1
  26. package/native/dist/esm/index.development.js +228 -288
  27. package/native/dist/esm/index.development.js.map +1 -1
  28. package/native/dist/esm/shared.production.js +1 -1
  29. package/native/dist/esm/shared.production.js.map +1 -1
  30. package/native/dist/index.d.ts +4 -8
  31. package/package.json +27 -24
@@ -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
  var reactNative = require('react-native');
7
6
 
8
7
  const isObject = o => o && typeof o === 'object' && !Array.isArray(o);
@@ -25,7 +24,7 @@ const generateId = () => (+new Date()).toString(36) + (1 - Math.random()).toStri
25
24
  const _buildFormInitialValues = (rows = []) => {
26
25
  const fields = {};
27
26
  if (!Array.isArray(rows)) rows = [rows];
28
- rows.forEach(row => {
27
+ for (const row of rows) {
29
28
  const inputConfigs = _findInputs(row);
30
29
  inputConfigs.forEach(config => {
31
30
  if (fields[config.formKey]) {
@@ -71,12 +70,9 @@ const _buildFormInitialValues = (rows = []) => {
71
70
  if (typeof fields[config.formKey][key] === 'undefined') delete fields[config.formKey][key];
72
71
  });
73
72
  });
74
- });
73
+ }
75
74
  return {
76
- state: {
77
- fields,
78
- loading: false
79
- },
75
+ fields: fields,
80
76
  key: generateId()
81
77
  };
82
78
  };
@@ -100,13 +96,25 @@ const _findValidityKey = validity => {
100
96
  }
101
97
  }
102
98
  };
103
- const _checkIfFormIsValid = fields => {
104
- for (const f in fields) {
105
- if (fields[f].error) {
99
+ const _checkTypeMismatch = input => {
100
+ var _input$value;
101
+ const value = (_input$value = input.value) === null || _input$value === void 0 ? void 0 : _input$value.toString().trim();
102
+ if (!value) return false;
103
+ switch (input.type) {
104
+ case 'email':
105
+ return !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value);
106
+ case 'url':
107
+ try {
108
+ new URL(value);
109
+ return false;
110
+ } catch {
111
+ return true;
112
+ }
113
+ case 'tel':
114
+ return !/^\+?[0-9\s\-().]{7,}$/.test(value);
115
+ default:
106
116
  return false;
107
- }
108
117
  }
109
- return true;
110
118
  };
111
119
  const _toRawData = (fields, options = {}) => {
112
120
  const data = {};
@@ -128,7 +136,7 @@ const _toRawData = (fields, options = {}) => {
128
136
  for (const key in transform) {
129
137
  var _fields$key2;
130
138
  const set = transform[key];
131
- data[key] = set((_fields$key2 = fields[key]) === null || _fields$key2 === void 0 ? void 0 : _fields$key2.value);
139
+ data[key] = set(((_fields$key2 = fields[key]) === null || _fields$key2 === void 0 ? void 0 : _fields$key2.value) || fields[key]);
132
140
  }
133
141
  }
134
142
  return data;
@@ -196,147 +204,13 @@ const _merge = (target = {}, ...nodes) => {
196
204
  return _merge(target, ...nodes);
197
205
  };
198
206
 
199
- let handlersMap;
200
- let validityMap;
201
- {
202
- handlersMap = {
203
- minLength: 'withMinLengthMessage',
204
- maxLength: 'withMaxLengthMessage',
205
- required: 'withRequiredMessage',
206
- pattern: 'withPatternMismatchMessage',
207
- min: 'withRangeUnderflowMessage',
208
- max: 'withRangeOverflowMessage',
209
- step: 'withStepMismatchMessage'
210
- };
211
- validityMap = {
212
- tooShort: 'minLength',
213
- valueMissing: 'required',
214
- tooLong: 'maxLength',
215
- patternMismatch: 'pattern',
216
- rangeOverflow: 'max',
217
- rangeUnderflow: 'min',
218
- stepMismatch: 'step'
219
- };
220
- }
221
- class GValidator {
222
- get handlers() {
223
- return this._handlers;
224
- }
225
- get constraintHandlers() {
226
- return this._constraintHandlers;
227
- }
228
- get asyncHandlers() {
229
- return this._asyncHandlers;
230
- }
231
- constructor(baseValidator) {
232
- _defineProperty(this, "_handlers", void 0);
233
- _defineProperty(this, "_constraintHandlers", void 0);
234
- _defineProperty(this, "_asyncHandlers", void 0);
235
- _defineProperty(this, "track", void 0);
236
- const baseHandlers = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.handlers) || [];
237
- const baseConstraintHandlers = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.constraintHandlers) || [];
238
- const baseHandlersAsync = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.asyncHandlers) || [];
239
- this._handlers = new Array().concat(baseHandlers);
240
- this._constraintHandlers = new Array().concat(baseConstraintHandlers);
241
- this._asyncHandlers = new Array().concat(baseHandlersAsync);
242
- {
243
- this.track = [];
244
- if (baseValidator !== null && baseValidator !== void 0 && baseValidator.track) {
245
- this.track = this.track.concat(baseValidator.track);
246
- }
247
- }
248
- }
249
- withRequiredMessage(message) {
250
- return this.__addConstraintValidationHandler('valueMissing', message);
251
- }
252
- withMaxLengthMessage(message) {
253
- return this.__addConstraintValidationHandler('tooLong', message);
254
- }
255
- withMinLengthMessage(message) {
256
- return this.__addConstraintValidationHandler('tooShort', message);
257
- }
258
- withPatternMismatchMessage(message) {
259
- return this.__addConstraintValidationHandler('patternMismatch', message);
260
- }
261
- withBadInputMessage(message) {
262
- return this.__addConstraintValidationHandler('badInput', message);
263
- }
264
- withRangeUnderflowMessage(message) {
265
- return this.__addConstraintValidationHandler('rangeUnderflow', message);
266
- }
267
- withRangeOverflowMessage(message) {
268
- return this.__addConstraintValidationHandler('rangeOverflow', message);
269
- }
270
- withTypeMismatchMessage(message) {
271
- return this.__addConstraintValidationHandler('typeMismatch', message);
272
- }
273
- withStepMismatchMessage(message) {
274
- return this.__addConstraintValidationHandler('stepMismatch', message);
275
- }
276
- withCustomValidation(handler) {
277
- this._handlers.push(handler);
278
- return this;
279
- }
280
- withCustomValidationAsync(handler) {
281
- this._asyncHandlers.push(handler);
282
- return this;
283
- }
284
- __addConstraintValidationHandler(validityKey, message) {
285
- if (this.track) {
286
- if (this.track.includes(validityKey)) {
287
- console.warn(`[Duplicate Handlers] - handler for '${validityKey}' has already been defined`);
288
- }
289
- this.track.push(validityKey);
290
- }
291
- this._constraintHandlers.push((input, key) => {
292
- {
293
- if (validityKey && validityMap[validityKey] && typeof input[validityMap[validityKey]] === 'undefined') {
294
- console.warn(`[Missing Prop] - the input '${input.formKey}' has registered validator for the violation '${validityKey}' but the input hasn't described the constraint '${validityMap[validityKey]}'.\nadd '${validityMap[validityKey]}' to the input props.\nexample:\n<GInput formKey='${input.formKey}' ${validityMap[validityKey]}={...} />\n\nor either remove '.${handlersMap[validityMap[validityKey]]}(...)' validation`);
295
- }
296
- }
297
- if (key === validityKey) {
298
- input.errorText = typeof message === 'string' ? message : message(input);
299
- return true;
300
- }
301
- return false;
302
- });
303
- return this;
304
- }
305
- }
306
-
307
- const useForm = (children, validators = {}, optimized = false) => {
308
- const initialValues = React.useMemo(() => {
309
- const values = _buildFormInitialValues(typeof children === 'function' ? children({}) : children);
310
- {
311
- Object.keys(values.state.fields).forEach(key => {
312
- const input = values.state.fields[key];
313
- const validator = validators[key];
314
- if (validator instanceof GValidator) {
315
- var _validator$track;
316
- const validityKeys = (_validator$track = validator.track) === null || _validator$track === void 0 ? void 0 : _validator$track.filter(key => validityMap[key]);
317
- validityKeys === null || validityKeys === void 0 || validityKeys.forEach(vKey => {
318
- if (typeof input[validityMap[vKey]] === 'undefined') {
319
- console.warn(`[Missing Prop] - the input '${input.formKey}' has registered validator for the violation '${vKey}' but the input hasn't described the constraint '${validityMap[vKey]}'.\nadd '${validityMap[vKey]}' to the input props.\nexample:\n<GInput formKey='${input.formKey}' ${validityMap[vKey]}={...} />\n\nor either remove '.${handlersMap[validityMap[vKey]]}(...)' validation`);
320
- }
321
- });
322
- Object.entries(validityMap).forEach(([validityKey, constraint]) => {
323
- var _validator$track2;
324
- if (typeof input[constraint] !== 'undefined' && !((_validator$track2 = validator.track) !== null && _validator$track2 !== void 0 && _validator$track2.some(trackKey => validityKey === trackKey))) {
325
- console.warn(`[Missing Validator] - the input '${input.formKey}' has described the constraint '${constraint}' but the input hasn't registered a validator to handle it.\nregister a handler '${handlersMap[constraint]}' for the input validator to handle the '${validityKey}' violation.\nexample:\ncosnt validators = {\n\t${input.formKey}: new GValidator().${handlersMap[constraint]}(...)\n}`);
326
- }
327
- });
328
- }
329
- });
330
- }
331
- return values;
332
- }, []);
333
- const [state, setState] = React.useState(initialValues.state);
207
+ const useFormHandlers = (getState, setState, validators = {}, optimized = false) => {
334
208
  const _viHandler = (input, e) => {
335
209
  if (!input) return;
336
210
  const element = e && e.target;
337
211
  if (typeof document !== 'undefined' && (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement)) {
338
212
  if (!input.checkValidity) input.checkValidity = () => element.checkValidity();
339
- if (!input.dirty && input.value) {
213
+ if (!input.dirty && input.value && !input.touched) {
340
214
  _checkInputManually(input);
341
215
  _dispatchChanges(input, input.formKey);
342
216
  return;
@@ -357,6 +231,7 @@ const useForm = (children, validators = {}, optimized = false) => {
357
231
  const _checkInputManually = input => {
358
232
  let validityKey = _findValidityKey({
359
233
  valueMissing: input.required && !input.value || false,
234
+ typeMismatch: _checkTypeMismatch(input),
360
235
  tooShort: input.minLength && input.value.toString().length < input.minLength || false,
361
236
  tooLong: input.maxLength && input.value.toString().length > input.maxLength || false,
362
237
  patternMismatch: input.pattern && _checkResult(input.pattern, input.value) || false,
@@ -369,22 +244,17 @@ const useForm = (children, validators = {}, optimized = false) => {
369
244
  _validateInput(input, validityKey);
370
245
  return !input.error;
371
246
  };
372
- const _updateInputHandler = (key, e, unknown) => {
373
- const value = _extractValue(e, unknown);
374
- const input = _updateInput(key, value);
247
+ const _updateInputHandler = (input, e, unknown) => {
248
+ input.value = _extractValue(e, unknown);
375
249
  _viHandler(input, e);
376
250
  };
377
251
  const _validateInput = (input, validityKey, setValidity) => {
378
252
  const inputValidator = validators[input.validatorKey || input.formKey] || validators['*'];
379
- inputValidator && __validateInput(input, inputValidator, validityKey, setValidity);
253
+ if (inputValidator) {
254
+ __validateInput(input, inputValidator, validityKey, setValidity);
255
+ }
380
256
  input.touched = true;
381
257
  };
382
- const _updateInput = (key, value) => {
383
- const input = state.fields[key];
384
- input.value = value;
385
- input.dirty = true;
386
- return input;
387
- };
388
258
  const _dispatchChanges = (changes, key) => setState(prev => {
389
259
  if (key) {
390
260
  return {
@@ -404,13 +274,14 @@ const useForm = (children, validators = {}, optimized = false) => {
404
274
  };
405
275
  });
406
276
  const __validateInput = (input, inputValidator, validityKey, setValidity) => {
277
+ const fields = getState().fields;
407
278
  for (const index in inputValidator.constraintHandlers) {
408
279
  const result = inputValidator.constraintHandlers[index](input, validityKey);
409
280
  input.error = _checkResult(result, input.value);
410
281
  if (input.error) return;
411
282
  }
412
283
  for (const index in inputValidator.handlers) {
413
- const result = inputValidator.handlers[index](input, state.fields);
284
+ const result = inputValidator.handlers[index](input, fields);
414
285
  input.error = _checkResult(result, input.value);
415
286
  if (input.error) return;
416
287
  }
@@ -420,7 +291,7 @@ const useForm = (children, validators = {}, optimized = false) => {
420
291
  _debounce(input.debounce || 300, `${input.gid}-async`).then(() => {
421
292
  const validateAsync = async () => {
422
293
  for (const index in inputValidator.asyncHandlers) {
423
- const result = await inputValidator.asyncHandlers[index](input, state.fields);
294
+ const result = await inputValidator.asyncHandlers[index](input, fields);
424
295
  input.error = _checkResult(result, input.value);
425
296
  if (input.error) break;
426
297
  }
@@ -429,138 +300,202 @@ const useForm = (children, validators = {}, optimized = false) => {
429
300
  error: input.error,
430
301
  errorText: input.errorText
431
302
  }, input.formKey);
432
- setValidity && setValidity(input.errorText);
303
+ if (setValidity) {
304
+ setValidity(input.errorText);
305
+ }
433
306
  };
434
307
  validateAsync();
435
308
  });
436
309
  }
437
310
  };
438
311
  return {
439
- state,
440
312
  _updateInputHandler,
441
313
  _viHandler,
442
314
  _dispatchChanges,
443
315
  optimized,
444
- key: initialValues.key,
445
316
  _createInputChecker: _checkInputManually
446
317
  };
447
318
  };
448
319
 
449
- const gFormContext = React.createContext({
450
- state: {
451
- fields: {},
452
- loading: false
453
- },
454
- _updateInputHandler: () => null,
455
- _viHandler: () => null,
456
- _dispatchChanges: () => null,
457
- _createInputChecker: () => false,
458
- optimized: false,
459
- key: ''
320
+ const GFormContext = React.createContext({});
321
+ const GFormContextProvider = ({
322
+ children,
323
+ initialState,
324
+ validators,
325
+ optimized
326
+ }) => {
327
+ const stateRef = React.useRef(initialState);
328
+ const listeners = React.useRef(new Set());
329
+ const setState = React.useCallback(updater => {
330
+ stateRef.current = typeof updater === 'function' ? updater(stateRef.current) : updater;
331
+ listeners.current.forEach(l => l());
332
+ }, []);
333
+ const handlers = useFormHandlers(() => stateRef.current, setState, validators, optimized);
334
+ const getState = React.useCallback(() => stateRef.current, []);
335
+ const subscribe = React.useCallback(listener => {
336
+ listeners.current.add(listener);
337
+ return () => listeners.current.delete(listener);
338
+ }, []);
339
+ React.useEffect(() => {
340
+ for (const fieldKey in initialState.fields) {
341
+ initialState.fields[fieldKey].dispatchChanges = changes => handlers._dispatchChanges(changes, fieldKey);
342
+ }
343
+ }, []);
344
+ const store = React.useRef({
345
+ getState,
346
+ setState,
347
+ subscribe,
348
+ handlers
349
+ });
350
+ return React.createElement(GFormContext.Provider, {
351
+ value: store.current
352
+ }, children);
353
+ };
354
+ const useFormStore = () => {
355
+ const store = React.useContext(GFormContext);
356
+ if (!store) throw new Error('useGFormStore must be used within `GForm` component');
357
+ return store;
358
+ };
359
+ const useFormSelector = selector => {
360
+ const store = useFormStore();
361
+ return React.useSyncExternalStore(store.subscribe, () => selector(store.getState()), () => selector(store.getState()));
362
+ };
363
+ function createSelector(selectors, combiner) {
364
+ let lastArgs = [];
365
+ let lastResult;
366
+ return state => {
367
+ const args = selectors.map(fn => fn(state));
368
+ if (lastArgs.length === args.length && args.every((val, i) => val === lastArgs[i])) {
369
+ return lastResult;
370
+ }
371
+ lastArgs = args;
372
+ lastResult = combiner(...args);
373
+ return lastResult;
374
+ };
375
+ }
376
+
377
+ const selectFields = [state => state.fields];
378
+ const selectFirstInvalidField = createSelector(selectFields, fields => {
379
+ for (const f in fields) {
380
+ if (fields[f].error) {
381
+ return true;
382
+ }
383
+ }
384
+ return false;
385
+ });
386
+ const makeSelectFields = (keys = []) => createSelector(selectFields, fields => {
387
+ const selected = keys.map(key => fields[key]).filter(Boolean);
388
+ return selected.length ? selected : null;
460
389
  });
461
- const useGenericFormContext = () => React.useContext(gFormContext);
462
- const GFormContextProvider = gFormContext.Provider;
463
390
 
464
- const RNGForm = (() => {
465
- return React.forwardRef(({
466
- loader = React.createElement("div", null, "loading"),
467
- stateRef,
468
- children,
469
- validators,
470
- onInit,
471
- el: El,
472
- ...rest
473
- }, ref) => {
474
- const values = useForm(children, validators);
475
- const {
476
- state,
477
- _dispatchChanges,
478
- key,
479
- _viHandler
480
- } = values;
481
- const formState = React.useMemo(() => {
482
- const _isFormValid = _checkIfFormIsValid(state.fields);
483
- const formState = {
484
- ...state.fields,
485
- isValid: _isFormValid,
486
- isInvalid: !_isFormValid,
487
- loading: state.loading,
488
- toRawData: options => _toRawData(state.fields, options),
489
- toURLSearchParams: _toURLSearchParams,
490
- checkValidity: () => {
491
- for (const i in state.fields) {
492
- const valid = state.fields[i].checkValidity();
493
- if (!valid) {
494
- return false;
495
- }
391
+ const FormRenderer = React.forwardRef(({
392
+ stateRef,
393
+ children,
394
+ onInit,
395
+ el: El,
396
+ ...rest
397
+ }, ref) => {
398
+ const {
399
+ getState,
400
+ handlers
401
+ } = useFormStore();
402
+ const isFormInvalid = useFormSelector(selectFirstInvalidField);
403
+ const getFormState = React.useCallback(() => {
404
+ const fields = getState().fields;
405
+ const formState = {
406
+ ...fields,
407
+ isValid: !isFormInvalid,
408
+ isInvalid: isFormInvalid,
409
+ toRawData: options => _toRawData(fields, options),
410
+ toURLSearchParams: _toURLSearchParams,
411
+ checkValidity: () => {
412
+ for (const i in fields) {
413
+ const valid = fields[i].checkValidity();
414
+ if (!valid) {
415
+ return false;
496
416
  }
497
- return true;
498
- },
499
- setLoading: p => _dispatchChanges({
500
- loading: typeof p === 'function' ? p(state.loading) : p
501
- }),
502
- dispatchChanges: changes => _dispatchChanges({
503
- fields: _merge({}, state.fields, changes)
504
- })
505
- };
506
- if (stateRef) stateRef.current = formState;
507
- return formState;
508
- }, [state.fields]);
509
- React.useEffect(() => {
510
- if (onInit) {
511
- const _handler = _c => _dispatchChanges({
512
- fields: _merge({}, state.fields, _c)
417
+ }
418
+ return true;
419
+ },
420
+ dispatchChanges: changes => handlers._dispatchChanges({
421
+ fields: _merge({}, fields, changes)
422
+ })
423
+ };
424
+ if (stateRef) stateRef.current = formState;
425
+ return formState;
426
+ }, [isFormInvalid]);
427
+ const formComponent = React.useMemo(() => {
428
+ const state = getFormState();
429
+ const formChildren = typeof children === 'function' ? children(state) : children;
430
+ return React.createElement(El, _extends({}, rest, {
431
+ ref: ref
432
+ }), formChildren);
433
+ }, [getFormState, children]);
434
+ React.useEffect(() => {
435
+ const state = getFormState();
436
+ if (onInit) {
437
+ const changes = onInit(state);
438
+ if (changes) {
439
+ const _handler = _c => handlers._dispatchChanges({
440
+ fields: _merge({}, state, _c)
513
441
  });
514
- const changes = onInit(formState);
515
- changes instanceof Promise ? changes.then(_handler) : _handler(changes);
442
+ if (changes instanceof Promise) {
443
+ changes.then(_handler);
444
+ } else _handler(changes);
516
445
  }
517
- const dipatchers = {};
518
- Object.values(state.fields).forEach(field => {
519
- dipatchers[field.formKey] = {
520
- dispatchChanges: changes => _dispatchChanges(changes, field.formKey)
521
- };
522
- if (!field.value) return;
523
- _viHandler(field);
524
- });
525
- _dispatchChanges({
526
- fields: _merge(dipatchers, state.fields)
527
- });
528
- }, []);
529
- const formComponent = React.useMemo(() => {
530
- const formChildren = typeof children === 'function' ? children(formState) : children;
531
- return React.createElement(El, _extends({}, rest, {
532
- ref: ref
533
- }), formChildren);
534
- }, [formState, children]);
535
- return React.createElement(GFormContextProvider, {
536
- value: values,
537
- key: key
538
- }, state.loading ? loader : formComponent);
539
- });
540
- })();
446
+ }
447
+ const dispatchers = {};
448
+ const fields = getState().fields;
449
+ for (const fieldKey in fields) {
450
+ dispatchers[fieldKey] = {
451
+ dispatchChanges: changes => handlers._dispatchChanges(changes, fieldKey),
452
+ checkValidity: () => {
453
+ const result = handlers._createInputChecker(state[fieldKey]);
454
+ handlers._dispatchChanges(state[fieldKey], fieldKey);
455
+ return result;
456
+ }
457
+ };
458
+ const field = fields[fieldKey];
459
+ if (!field.value) continue;
460
+ handlers._viHandler(field);
461
+ }
462
+ handlers._dispatchChanges({
463
+ fields: _merge(dispatchers, state)
464
+ });
465
+ }, [getFormState]);
466
+ return formComponent;
467
+ });
468
+ const RNGForm = React.forwardRef(({
469
+ children,
470
+ validators,
471
+ ...props
472
+ }, ref) => {
473
+ const initialState = React.useMemo(() => {
474
+ return _buildFormInitialValues(typeof children === 'function' ? children({}) : children);
475
+ }, [children]);
476
+ return React.createElement(GFormContextProvider, {
477
+ key: initialState.key,
478
+ initialState: initialState,
479
+ validators: validators
480
+ }, React.createElement(FormRenderer, _extends({
481
+ ref: ref
482
+ }, props), children));
483
+ });
541
484
 
542
- const RNGInput = React.forwardRef(({
485
+ const _RNGInput = React.forwardRef(({
543
486
  formKey,
544
487
  element,
545
488
  type,
546
- validatorKey,
547
489
  fetch,
548
- fetchDeps = [],
490
+ fetchDeps,
491
+ debounce = 300,
549
492
  defaultValue,
493
+ validatorKey,
550
494
  value,
551
- debounce = 300,
552
495
  ...rest
553
496
  }, ref) => {
554
- const {
555
- state: {
556
- fields
557
- },
558
- _updateInputHandler,
559
- _dispatchChanges,
560
- _viHandler,
561
- _createInputChecker
562
- } = useGenericFormContext();
563
- const inputState = fields[formKey];
497
+ const inputState = useFormSelector(state => state.fields[formKey]);
498
+ const store = useFormStore();
564
499
  const _element = React.useMemo(() => {
565
500
  const value = inputState.value || '';
566
501
  const _props = {
@@ -569,41 +504,44 @@ const RNGInput = React.forwardRef(({
569
504
  inputMode: type,
570
505
  ref
571
506
  };
572
- _props.onEndEditing = e => {
573
- _viHandler(inputState);
574
- rest.onEndEditing && rest.onEndEditing(e);
507
+ _props.onEndEditing = rest.onEndEditing ? e => {
508
+ store.handlers._viHandler(inputState);
509
+ rest.onEndEditing(e);
510
+ } : () => {
511
+ store.handlers._viHandler(inputState);
575
512
  };
576
- _props.onChangeText = e => {
577
- _updateInputHandler(formKey, undefined, {
513
+ _props.onChangeText = rest.onChangeText ? e => {
514
+ store.handlers._updateInputHandler(inputState, undefined, {
515
+ value: e
516
+ });
517
+ rest.onChangeText(e);
518
+ } : e => {
519
+ store.handlers._updateInputHandler(inputState, undefined, {
578
520
  value: e
579
521
  });
580
- rest.onChangeText && rest.onChangeText(e);
581
522
  };
582
523
  if (element) {
583
524
  return element(inputState, _props);
584
525
  }
585
526
  return React.createElement(reactNative.TextInput, _props);
586
527
  }, [inputState, element]);
587
- const _fetchDeps = React.useMemo(() => fetchDeps.map(key => fields[key].value), [fields]);
588
- React.useEffect(() => {
589
- inputState.checkValidity = () => {
590
- const result = _createInputChecker(inputState);
591
- _dispatchChanges(inputState, formKey);
592
- return result;
593
- };
594
- inputState.dispatchChanges = changes => _dispatchChanges(changes, formKey);
595
- _dispatchChanges(inputState, formKey);
596
- }, []);
528
+ const _fetchDeps = useFormSelector(makeSelectFields(fetchDeps));
529
+ const stableFetchDeps = React.useMemo(() => JSON.stringify(_fetchDeps), [_fetchDeps]);
597
530
  React.useEffect(() => {
598
531
  if (fetch) {
599
532
  _debounce(debounce, `${inputState.gid}-fetch`).then(() => {
600
- const res = fetch(inputState, fields);
601
- res instanceof Promise ? res.then(state => state && _dispatchChanges(state, formKey)) : res && _dispatchChanges(res, formKey);
533
+ const res = fetch(inputState, store.getState().fields);
534
+ if (res instanceof Promise) {
535
+ res.then(state => state && store.handlers._dispatchChanges(state, formKey));
536
+ } else if (res) {
537
+ store.handlers._dispatchChanges(res, formKey);
538
+ }
602
539
  });
603
540
  }
604
- }, _fetchDeps);
541
+ }, [stableFetchDeps]);
605
542
  return _element;
606
543
  });
544
+ const RNGInput = React.memo(_RNGInput);
607
545
 
608
546
  exports.RNGForm = RNGForm;
609
547
  exports.RNGInput = RNGInput;