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
@@ -1,8 +1,7 @@
1
1
  import _extends from '@babel/runtime/helpers/esm/extends';
2
2
  import _objectSpread from '@babel/runtime/helpers/esm/objectSpread2';
3
3
  import _objectWithoutProperties from '@babel/runtime/helpers/esm/objectWithoutProperties';
4
- import React, { useMemo, useState, createContext, useContext, forwardRef, useEffect } from 'react';
5
- import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
4
+ import React, { useContext, createContext, useSyncExternalStore, useRef, useCallback, useEffect, forwardRef, useMemo, memo } from 'react';
6
5
  import { TextInput } from '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 (_unused) {
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;
@@ -193,147 +201,13 @@ const _merge = (target = {}, ...nodes) => {
193
201
  return _merge(target, ...nodes);
194
202
  };
195
203
 
196
- let handlersMap;
197
- let validityMap;
198
- {
199
- handlersMap = {
200
- minLength: 'withMinLengthMessage',
201
- maxLength: 'withMaxLengthMessage',
202
- required: 'withRequiredMessage',
203
- pattern: 'withPatternMismatchMessage',
204
- min: 'withRangeUnderflowMessage',
205
- max: 'withRangeOverflowMessage',
206
- step: 'withStepMismatchMessage'
207
- };
208
- validityMap = {
209
- tooShort: 'minLength',
210
- valueMissing: 'required',
211
- tooLong: 'maxLength',
212
- patternMismatch: 'pattern',
213
- rangeOverflow: 'max',
214
- rangeUnderflow: 'min',
215
- stepMismatch: 'step'
216
- };
217
- }
218
- class GValidator {
219
- get handlers() {
220
- return this._handlers;
221
- }
222
- get constraintHandlers() {
223
- return this._constraintHandlers;
224
- }
225
- get asyncHandlers() {
226
- return this._asyncHandlers;
227
- }
228
- constructor(baseValidator) {
229
- _defineProperty(this, "_handlers", void 0);
230
- _defineProperty(this, "_constraintHandlers", void 0);
231
- _defineProperty(this, "_asyncHandlers", void 0);
232
- _defineProperty(this, "track", void 0);
233
- const baseHandlers = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.handlers) || [];
234
- const baseConstraintHandlers = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.constraintHandlers) || [];
235
- const baseHandlersAsync = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.asyncHandlers) || [];
236
- this._handlers = new Array().concat(baseHandlers);
237
- this._constraintHandlers = new Array().concat(baseConstraintHandlers);
238
- this._asyncHandlers = new Array().concat(baseHandlersAsync);
239
- {
240
- this.track = [];
241
- if (baseValidator !== null && baseValidator !== void 0 && baseValidator.track) {
242
- this.track = this.track.concat(baseValidator.track);
243
- }
244
- }
245
- }
246
- withRequiredMessage(message) {
247
- return this.__addConstraintValidationHandler('valueMissing', message);
248
- }
249
- withMaxLengthMessage(message) {
250
- return this.__addConstraintValidationHandler('tooLong', message);
251
- }
252
- withMinLengthMessage(message) {
253
- return this.__addConstraintValidationHandler('tooShort', message);
254
- }
255
- withPatternMismatchMessage(message) {
256
- return this.__addConstraintValidationHandler('patternMismatch', message);
257
- }
258
- withBadInputMessage(message) {
259
- return this.__addConstraintValidationHandler('badInput', message);
260
- }
261
- withRangeUnderflowMessage(message) {
262
- return this.__addConstraintValidationHandler('rangeUnderflow', message);
263
- }
264
- withRangeOverflowMessage(message) {
265
- return this.__addConstraintValidationHandler('rangeOverflow', message);
266
- }
267
- withTypeMismatchMessage(message) {
268
- return this.__addConstraintValidationHandler('typeMismatch', message);
269
- }
270
- withStepMismatchMessage(message) {
271
- return this.__addConstraintValidationHandler('stepMismatch', message);
272
- }
273
- withCustomValidation(handler) {
274
- this._handlers.push(handler);
275
- return this;
276
- }
277
- withCustomValidationAsync(handler) {
278
- this._asyncHandlers.push(handler);
279
- return this;
280
- }
281
- __addConstraintValidationHandler(validityKey, message) {
282
- if (this.track) {
283
- if (this.track.includes(validityKey)) {
284
- console.warn(`[Duplicate Handlers] - handler for '${validityKey}' has already been defined`);
285
- }
286
- this.track.push(validityKey);
287
- }
288
- this._constraintHandlers.push((input, key) => {
289
- {
290
- if (validityKey && validityMap[validityKey] && typeof input[validityMap[validityKey]] === 'undefined') {
291
- 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`);
292
- }
293
- }
294
- if (key === validityKey) {
295
- input.errorText = typeof message === 'string' ? message : message(input);
296
- return true;
297
- }
298
- return false;
299
- });
300
- return this;
301
- }
302
- }
303
-
304
- const useForm = (children, validators = {}, optimized = false) => {
305
- const initialValues = useMemo(() => {
306
- const values = _buildFormInitialValues(typeof children === 'function' ? children({}) : children);
307
- {
308
- Object.keys(values.state.fields).forEach(key => {
309
- const input = values.state.fields[key];
310
- const validator = validators[key];
311
- if (validator instanceof GValidator) {
312
- var _validator$track;
313
- const validityKeys = (_validator$track = validator.track) === null || _validator$track === void 0 ? void 0 : _validator$track.filter(key => validityMap[key]);
314
- validityKeys === null || validityKeys === void 0 || validityKeys.forEach(vKey => {
315
- if (typeof input[validityMap[vKey]] === 'undefined') {
316
- 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`);
317
- }
318
- });
319
- Object.entries(validityMap).forEach(([validityKey, constraint]) => {
320
- var _validator$track2;
321
- if (typeof input[constraint] !== 'undefined' && !((_validator$track2 = validator.track) !== null && _validator$track2 !== void 0 && _validator$track2.some(trackKey => validityKey === trackKey))) {
322
- 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}`);
323
- }
324
- });
325
- }
326
- });
327
- }
328
- return values;
329
- }, []);
330
- const [state, setState] = useState(initialValues.state);
204
+ const useFormHandlers = (getState, setState, validators = {}, optimized = false) => {
331
205
  const _viHandler = (input, e) => {
332
206
  if (!input) return;
333
207
  const element = e && e.target;
334
208
  if (typeof document !== 'undefined' && (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement)) {
335
209
  if (!input.checkValidity) input.checkValidity = () => element.checkValidity();
336
- if (!input.dirty && input.value) {
210
+ if (!input.dirty && input.value && !input.touched) {
337
211
  _checkInputManually(input);
338
212
  _dispatchChanges(input, input.formKey);
339
213
  return;
@@ -354,6 +228,7 @@ const useForm = (children, validators = {}, optimized = false) => {
354
228
  const _checkInputManually = input => {
355
229
  let validityKey = _findValidityKey({
356
230
  valueMissing: input.required && !input.value || false,
231
+ typeMismatch: _checkTypeMismatch(input),
357
232
  tooShort: input.minLength && input.value.toString().length < input.minLength || false,
358
233
  tooLong: input.maxLength && input.value.toString().length > input.maxLength || false,
359
234
  patternMismatch: input.pattern && _checkResult(input.pattern, input.value) || false,
@@ -366,22 +241,17 @@ const useForm = (children, validators = {}, optimized = false) => {
366
241
  _validateInput(input, validityKey);
367
242
  return !input.error;
368
243
  };
369
- const _updateInputHandler = (key, e, unknown) => {
370
- const value = _extractValue(e, unknown);
371
- const input = _updateInput(key, value);
244
+ const _updateInputHandler = (input, e, unknown) => {
245
+ input.value = _extractValue(e, unknown);
372
246
  _viHandler(input, e);
373
247
  };
374
248
  const _validateInput = (input, validityKey, setValidity) => {
375
249
  const inputValidator = validators[input.validatorKey || input.formKey] || validators['*'];
376
- inputValidator && __validateInput(input, inputValidator, validityKey, setValidity);
250
+ if (inputValidator) {
251
+ __validateInput(input, inputValidator, validityKey, setValidity);
252
+ }
377
253
  input.touched = true;
378
254
  };
379
- const _updateInput = (key, value) => {
380
- const input = state.fields[key];
381
- input.value = value;
382
- input.dirty = true;
383
- return input;
384
- };
385
255
  const _dispatchChanges = (changes, key) => setState(prev => {
386
256
  if (key) {
387
257
  return _objectSpread(_objectSpread({}, prev), {}, {
@@ -393,13 +263,14 @@ const useForm = (children, validators = {}, optimized = false) => {
393
263
  return _objectSpread(_objectSpread({}, prev), changes);
394
264
  });
395
265
  const __validateInput = (input, inputValidator, validityKey, setValidity) => {
266
+ const fields = getState().fields;
396
267
  for (const index in inputValidator.constraintHandlers) {
397
268
  const result = inputValidator.constraintHandlers[index](input, validityKey);
398
269
  input.error = _checkResult(result, input.value);
399
270
  if (input.error) return;
400
271
  }
401
272
  for (const index in inputValidator.handlers) {
402
- const result = inputValidator.handlers[index](input, state.fields);
273
+ const result = inputValidator.handlers[index](input, fields);
403
274
  input.error = _checkResult(result, input.value);
404
275
  if (input.error) return;
405
276
  }
@@ -409,7 +280,7 @@ const useForm = (children, validators = {}, optimized = false) => {
409
280
  _debounce(input.debounce || 300, `${input.gid}-async`).then(() => {
410
281
  const validateAsync = async () => {
411
282
  for (const index in inputValidator.asyncHandlers) {
412
- const result = await inputValidator.asyncHandlers[index](input, state.fields);
283
+ const result = await inputValidator.asyncHandlers[index](input, fields);
413
284
  input.error = _checkResult(result, input.value);
414
285
  if (input.error) break;
415
286
  }
@@ -418,141 +289,207 @@ const useForm = (children, validators = {}, optimized = false) => {
418
289
  error: input.error,
419
290
  errorText: input.errorText
420
291
  }, input.formKey);
421
- setValidity && setValidity(input.errorText);
292
+ if (setValidity) {
293
+ setValidity(input.errorText);
294
+ }
422
295
  };
423
296
  validateAsync();
424
297
  });
425
298
  }
426
299
  };
427
300
  return {
428
- state,
429
301
  _updateInputHandler,
430
302
  _viHandler,
431
303
  _dispatchChanges,
432
304
  optimized,
433
- key: initialValues.key,
434
305
  _createInputChecker: _checkInputManually
435
306
  };
436
307
  };
437
308
 
438
- const gFormContext = createContext({
439
- state: {
440
- fields: {},
441
- loading: false
442
- },
443
- _updateInputHandler: () => null,
444
- _viHandler: () => null,
445
- _dispatchChanges: () => null,
446
- _createInputChecker: () => false,
447
- optimized: false,
448
- key: ''
309
+ const GFormContext = createContext({});
310
+ const GFormContextProvider = ({
311
+ children,
312
+ initialState,
313
+ validators,
314
+ optimized
315
+ }) => {
316
+ const stateRef = useRef(initialState);
317
+ const listeners = useRef(new Set());
318
+ const setState = useCallback(updater => {
319
+ stateRef.current = typeof updater === 'function' ? updater(stateRef.current) : updater;
320
+ listeners.current.forEach(l => l());
321
+ }, []);
322
+ const handlers = useFormHandlers(() => stateRef.current, setState, validators, optimized);
323
+ const getState = useCallback(() => stateRef.current, []);
324
+ const subscribe = useCallback(listener => {
325
+ listeners.current.add(listener);
326
+ return () => listeners.current.delete(listener);
327
+ }, []);
328
+ useEffect(() => {
329
+ for (const fieldKey in initialState.fields) {
330
+ initialState.fields[fieldKey].dispatchChanges = changes => handlers._dispatchChanges(changes, fieldKey);
331
+ }
332
+ }, []);
333
+ const store = useRef({
334
+ getState,
335
+ setState,
336
+ subscribe,
337
+ handlers
338
+ });
339
+ return React.createElement(GFormContext.Provider, {
340
+ value: store.current
341
+ }, children);
342
+ };
343
+ const useFormStore = () => {
344
+ const store = useContext(GFormContext);
345
+ if (!store) throw new Error('useGFormStore must be used within `GForm` component');
346
+ return store;
347
+ };
348
+ const useFormSelector = selector => {
349
+ const store = useFormStore();
350
+ return useSyncExternalStore(store.subscribe, () => selector(store.getState()), () => selector(store.getState()));
351
+ };
352
+ function createSelector(selectors, combiner) {
353
+ let lastArgs = [];
354
+ let lastResult;
355
+ return state => {
356
+ const args = selectors.map(fn => fn(state));
357
+ if (lastArgs.length === args.length && args.every((val, i) => val === lastArgs[i])) {
358
+ return lastResult;
359
+ }
360
+ lastArgs = args;
361
+ lastResult = combiner(...args);
362
+ return lastResult;
363
+ };
364
+ }
365
+
366
+ const selectFields = [state => state.fields];
367
+ const selectFirstInvalidField = createSelector(selectFields, fields => {
368
+ for (const f in fields) {
369
+ if (fields[f].error) {
370
+ return true;
371
+ }
372
+ }
373
+ return false;
374
+ });
375
+ const makeSelectFields = (keys = []) => createSelector(selectFields, fields => {
376
+ const selected = keys.map(key => fields[key]).filter(Boolean);
377
+ return selected.length ? selected : null;
449
378
  });
450
- const useGenericFormContext = () => useContext(gFormContext);
451
- const GFormContextProvider = gFormContext.Provider;
452
379
 
453
- const _excluded$1 = ["loader", "stateRef", "children", "validators", "onInit", "el"];
454
- const RNGForm = (() => {
455
- return forwardRef((_ref, ref) => {
456
- let {
457
- loader = React.createElement("div", null, "loading"),
458
- stateRef,
459
- children,
460
- validators,
461
- onInit,
462
- el: El
463
- } = _ref,
464
- rest = _objectWithoutProperties(_ref, _excluded$1);
465
- const values = useForm(children, validators);
466
- const {
467
- state,
468
- _dispatchChanges,
469
- key,
470
- _viHandler
471
- } = values;
472
- const formState = useMemo(() => {
473
- const _isFormValid = _checkIfFormIsValid(state.fields);
474
- const formState = _objectSpread(_objectSpread({}, state.fields), {}, {
475
- isValid: _isFormValid,
476
- isInvalid: !_isFormValid,
477
- loading: state.loading,
478
- toRawData: options => _toRawData(state.fields, options),
479
- toURLSearchParams: _toURLSearchParams,
480
- checkValidity: () => {
481
- for (const i in state.fields) {
482
- const valid = state.fields[i].checkValidity();
483
- if (!valid) {
484
- return false;
485
- }
380
+ const _excluded$1 = ["stateRef", "children", "onInit", "el"],
381
+ _excluded2 = ["children", "validators"];
382
+ const FormRenderer = forwardRef((_ref, ref) => {
383
+ let {
384
+ stateRef,
385
+ children,
386
+ onInit,
387
+ el: El
388
+ } = _ref,
389
+ rest = _objectWithoutProperties(_ref, _excluded$1);
390
+ const {
391
+ getState,
392
+ handlers
393
+ } = useFormStore();
394
+ const isFormInvalid = useFormSelector(selectFirstInvalidField);
395
+ const getFormState = useCallback(() => {
396
+ const fields = getState().fields;
397
+ const formState = _objectSpread(_objectSpread({}, fields), {}, {
398
+ isValid: !isFormInvalid,
399
+ isInvalid: isFormInvalid,
400
+ toRawData: options => _toRawData(fields, options),
401
+ toURLSearchParams: _toURLSearchParams,
402
+ checkValidity: () => {
403
+ for (const i in fields) {
404
+ const valid = fields[i].checkValidity();
405
+ if (!valid) {
406
+ return false;
486
407
  }
487
- return true;
488
- },
489
- setLoading: p => _dispatchChanges({
490
- loading: typeof p === 'function' ? p(state.loading) : p
491
- }),
492
- dispatchChanges: changes => _dispatchChanges({
493
- fields: _merge({}, state.fields, changes)
494
- })
495
- });
496
- if (stateRef) stateRef.current = formState;
497
- return formState;
498
- }, [state.fields]);
499
- useEffect(() => {
500
- if (onInit) {
501
- const _handler = _c => _dispatchChanges({
502
- fields: _merge({}, state.fields, _c)
408
+ }
409
+ return true;
410
+ },
411
+ dispatchChanges: changes => handlers._dispatchChanges({
412
+ fields: _merge({}, fields, changes)
413
+ })
414
+ });
415
+ if (stateRef) stateRef.current = formState;
416
+ return formState;
417
+ }, [isFormInvalid]);
418
+ const formComponent = useMemo(() => {
419
+ const state = getFormState();
420
+ const formChildren = typeof children === 'function' ? children(state) : children;
421
+ return React.createElement(El, _extends({}, rest, {
422
+ ref: ref
423
+ }), formChildren);
424
+ }, [getFormState, children]);
425
+ useEffect(() => {
426
+ const state = getFormState();
427
+ if (onInit) {
428
+ const changes = onInit(state);
429
+ if (changes) {
430
+ const _handler = _c => handlers._dispatchChanges({
431
+ fields: _merge({}, state, _c)
503
432
  });
504
- const changes = onInit(formState);
505
- changes instanceof Promise ? changes.then(_handler) : _handler(changes);
433
+ if (changes instanceof Promise) {
434
+ changes.then(_handler);
435
+ } else _handler(changes);
506
436
  }
507
- const dipatchers = {};
508
- Object.values(state.fields).forEach(field => {
509
- dipatchers[field.formKey] = {
510
- dispatchChanges: changes => _dispatchChanges(changes, field.formKey)
511
- };
512
- if (!field.value) return;
513
- _viHandler(field);
514
- });
515
- _dispatchChanges({
516
- fields: _merge(dipatchers, state.fields)
517
- });
518
- }, []);
519
- const formComponent = useMemo(() => {
520
- const formChildren = typeof children === 'function' ? children(formState) : children;
521
- return React.createElement(El, _extends({}, rest, {
522
- ref: ref
523
- }), formChildren);
524
- }, [formState, children]);
525
- return React.createElement(GFormContextProvider, {
526
- value: values,
527
- key: key
528
- }, state.loading ? loader : formComponent);
529
- });
530
- })();
437
+ }
438
+ const dispatchers = {};
439
+ const fields = getState().fields;
440
+ for (const fieldKey in fields) {
441
+ dispatchers[fieldKey] = {
442
+ dispatchChanges: changes => handlers._dispatchChanges(changes, fieldKey),
443
+ checkValidity: () => {
444
+ const result = handlers._createInputChecker(state[fieldKey]);
445
+ handlers._dispatchChanges(state[fieldKey], fieldKey);
446
+ return result;
447
+ }
448
+ };
449
+ const field = fields[fieldKey];
450
+ if (!field.value) continue;
451
+ handlers._viHandler(field);
452
+ }
453
+ handlers._dispatchChanges({
454
+ fields: _merge(dispatchers, state)
455
+ });
456
+ }, [getFormState]);
457
+ return formComponent;
458
+ });
459
+ const RNGForm = forwardRef((_ref2, ref) => {
460
+ let {
461
+ children,
462
+ validators
463
+ } = _ref2,
464
+ props = _objectWithoutProperties(_ref2, _excluded2);
465
+ const initialState = useMemo(() => {
466
+ return _buildFormInitialValues(typeof children === 'function' ? children({}) : children);
467
+ }, [children]);
468
+ return React.createElement(GFormContextProvider, {
469
+ key: initialState.key,
470
+ initialState: initialState,
471
+ validators: validators
472
+ }, React.createElement(FormRenderer, _extends({
473
+ ref: ref
474
+ }, props), children));
475
+ });
531
476
 
532
- const _excluded = ["formKey", "element", "type", "validatorKey", "fetch", "fetchDeps", "defaultValue", "value", "debounce"];
533
- const RNGInput = forwardRef((_ref, ref) => {
477
+ const _excluded = ["formKey", "element", "type", "fetch", "fetchDeps", "debounce", "defaultValue", "validatorKey", "value"];
478
+ const _RNGInput = forwardRef((_ref, ref) => {
534
479
  let {
535
480
  formKey,
536
481
  element,
537
482
  type,
538
- validatorKey,
539
483
  fetch,
540
- fetchDeps = [],
484
+ fetchDeps,
485
+ debounce = 300,
541
486
  defaultValue,
542
- value,
543
- debounce = 300
487
+ validatorKey,
488
+ value
544
489
  } = _ref,
545
490
  rest = _objectWithoutProperties(_ref, _excluded);
546
- const {
547
- state: {
548
- fields
549
- },
550
- _updateInputHandler,
551
- _dispatchChanges,
552
- _viHandler,
553
- _createInputChecker
554
- } = useGenericFormContext();
555
- const inputState = fields[formKey];
491
+ const inputState = useFormSelector(state => state.fields[formKey]);
492
+ const store = useFormStore();
556
493
  const _element = useMemo(() => {
557
494
  const value = inputState.value || '';
558
495
  const _props = _objectSpread(_objectSpread({}, rest), {}, {
@@ -560,41 +497,44 @@ const RNGInput = forwardRef((_ref, ref) => {
560
497
  inputMode: type,
561
498
  ref
562
499
  });
563
- _props.onEndEditing = e => {
564
- _viHandler(inputState);
565
- rest.onEndEditing && rest.onEndEditing(e);
500
+ _props.onEndEditing = rest.onEndEditing ? e => {
501
+ store.handlers._viHandler(inputState);
502
+ rest.onEndEditing(e);
503
+ } : () => {
504
+ store.handlers._viHandler(inputState);
566
505
  };
567
- _props.onChangeText = e => {
568
- _updateInputHandler(formKey, undefined, {
506
+ _props.onChangeText = rest.onChangeText ? e => {
507
+ store.handlers._updateInputHandler(inputState, undefined, {
508
+ value: e
509
+ });
510
+ rest.onChangeText(e);
511
+ } : e => {
512
+ store.handlers._updateInputHandler(inputState, undefined, {
569
513
  value: e
570
514
  });
571
- rest.onChangeText && rest.onChangeText(e);
572
515
  };
573
516
  if (element) {
574
517
  return element(inputState, _props);
575
518
  }
576
519
  return React.createElement(TextInput, _props);
577
520
  }, [inputState, element]);
578
- const _fetchDeps = useMemo(() => fetchDeps.map(key => fields[key].value), [fields]);
579
- useEffect(() => {
580
- inputState.checkValidity = () => {
581
- const result = _createInputChecker(inputState);
582
- _dispatchChanges(inputState, formKey);
583
- return result;
584
- };
585
- inputState.dispatchChanges = changes => _dispatchChanges(changes, formKey);
586
- _dispatchChanges(inputState, formKey);
587
- }, []);
521
+ const _fetchDeps = useFormSelector(makeSelectFields(fetchDeps));
522
+ const stableFetchDeps = useMemo(() => JSON.stringify(_fetchDeps), [_fetchDeps]);
588
523
  useEffect(() => {
589
524
  if (fetch) {
590
525
  _debounce(debounce, `${inputState.gid}-fetch`).then(() => {
591
- const res = fetch(inputState, fields);
592
- res instanceof Promise ? res.then(state => state && _dispatchChanges(state, formKey)) : res && _dispatchChanges(res, formKey);
526
+ const res = fetch(inputState, store.getState().fields);
527
+ if (res instanceof Promise) {
528
+ res.then(state => state && store.handlers._dispatchChanges(state, formKey));
529
+ } else if (res) {
530
+ store.handlers._dispatchChanges(res, formKey);
531
+ }
593
532
  });
594
533
  }
595
- }, _fetchDeps);
534
+ }, [stableFetchDeps]);
596
535
  return _element;
597
536
  });
537
+ const RNGInput = memo(_RNGInput);
598
538
 
599
539
  export { RNGForm, RNGInput };
600
540
  //# sourceMappingURL=index.development.js.map