gform-react 2.0.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.
- package/dist/cjs/gform-react.development.js +274 -205
- package/dist/cjs/gform-react.development.js.map +1 -1
- package/dist/cjs/gform-react.production.js +1 -1
- package/dist/cjs/gform-react.production.js.map +1 -1
- package/dist/esm/GForm.production.js +1 -1
- package/dist/esm/GForm.production.js.map +1 -1
- package/dist/esm/GInput.production.js +1 -1
- package/dist/esm/GInput.production.js.map +1 -1
- package/dist/esm/index.development.js +280 -210
- package/dist/esm/index.development.js.map +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/shared.production.js +1 -1
- package/dist/esm/shared.production.js.map +1 -1
- package/dist/index.d.ts +5 -12
- package/native/dist/cjs/gform-react-native.development.js +219 -281
- package/native/dist/cjs/gform-react-native.development.js.map +1 -1
- package/native/dist/cjs/gform-react-native.production.js +1 -1
- package/native/dist/cjs/gform-react-native.production.js.map +1 -1
- package/native/dist/esm/RNGForm.production.js +1 -1
- package/native/dist/esm/RNGForm.production.js.map +1 -1
- package/native/dist/esm/RNGInput.production.js +1 -1
- package/native/dist/esm/RNGInput.production.js.map +1 -1
- package/native/dist/esm/index.development.js +225 -285
- package/native/dist/esm/index.development.js.map +1 -1
- package/native/dist/esm/shared.production.js +1 -1
- package/native/dist/esm/shared.production.js.map +1 -1
- package/native/dist/index.d.ts +4 -8
- package/package.json +2 -2
|
@@ -1,7 +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, {
|
|
4
|
+
import React, { useSyncExternalStore, useRef, useCallback, useEffect, createContext, useContext, forwardRef, useMemo, memo } from 'react';
|
|
5
5
|
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
|
|
6
6
|
|
|
7
7
|
const isObject = o => o && typeof o === 'object' && !Array.isArray(o);
|
|
@@ -72,10 +72,7 @@ const _buildFormInitialValues = (rows = []) => {
|
|
|
72
72
|
});
|
|
73
73
|
}
|
|
74
74
|
return {
|
|
75
|
-
|
|
76
|
-
fields,
|
|
77
|
-
loading: false
|
|
78
|
-
},
|
|
75
|
+
fields: fields,
|
|
79
76
|
key: generateId()
|
|
80
77
|
};
|
|
81
78
|
};
|
|
@@ -99,6 +96,26 @@ const _findValidityKey = validity => {
|
|
|
99
96
|
}
|
|
100
97
|
}
|
|
101
98
|
};
|
|
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:
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
102
119
|
const hasSubmitter = form => {
|
|
103
120
|
if (!form) return false;
|
|
104
121
|
for (const element of form) {
|
|
@@ -106,14 +123,6 @@ const hasSubmitter = form => {
|
|
|
106
123
|
}
|
|
107
124
|
return false;
|
|
108
125
|
};
|
|
109
|
-
const _checkIfFormIsValid = fields => {
|
|
110
|
-
for (const f in fields) {
|
|
111
|
-
if (fields[f].error) {
|
|
112
|
-
return false;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return true;
|
|
116
|
-
};
|
|
117
126
|
const _toRawData = (fields, options = {}) => {
|
|
118
127
|
const data = {};
|
|
119
128
|
const {
|
|
@@ -311,39 +320,13 @@ class GValidator {
|
|
|
311
320
|
}
|
|
312
321
|
}
|
|
313
322
|
|
|
314
|
-
const
|
|
315
|
-
const initialValues = useMemo(() => {
|
|
316
|
-
const values = _buildFormInitialValues(typeof children === 'function' ? children({}) : children);
|
|
317
|
-
{
|
|
318
|
-
Object.keys(values.state.fields).forEach(key => {
|
|
319
|
-
const input = values.state.fields[key];
|
|
320
|
-
const validator = validators[key];
|
|
321
|
-
if (validator instanceof GValidator) {
|
|
322
|
-
var _validator$track;
|
|
323
|
-
const validityKeys = (_validator$track = validator.track) === null || _validator$track === void 0 ? void 0 : _validator$track.filter(key => validityMap[key]);
|
|
324
|
-
validityKeys === null || validityKeys === void 0 || validityKeys.forEach(vKey => {
|
|
325
|
-
if (typeof input[validityMap[vKey]] === 'undefined') {
|
|
326
|
-
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`);
|
|
327
|
-
}
|
|
328
|
-
});
|
|
329
|
-
Object.entries(validityMap).forEach(([validityKey, constraint]) => {
|
|
330
|
-
var _validator$track2;
|
|
331
|
-
if (typeof input[constraint] !== 'undefined' && !((_validator$track2 = validator.track) !== null && _validator$track2 !== void 0 && _validator$track2.some(trackKey => validityKey === trackKey))) {
|
|
332
|
-
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}`);
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
return values;
|
|
339
|
-
}, []);
|
|
340
|
-
const [state, setState] = useState(initialValues.state);
|
|
323
|
+
const useFormHandlers = (getState, setState, validators = {}, optimized = false) => {
|
|
341
324
|
const _viHandler = (input, e) => {
|
|
342
325
|
if (!input) return;
|
|
343
326
|
const element = e && e.target;
|
|
344
327
|
if (typeof document !== 'undefined' && (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement)) {
|
|
345
328
|
if (!input.checkValidity) input.checkValidity = () => element.checkValidity();
|
|
346
|
-
if (!input.dirty && input.value) {
|
|
329
|
+
if (!input.dirty && input.value && !input.touched) {
|
|
347
330
|
_checkInputManually(input);
|
|
348
331
|
_dispatchChanges(input, input.formKey);
|
|
349
332
|
return;
|
|
@@ -364,6 +347,7 @@ const useForm = (children, validators = {}, optimized = false) => {
|
|
|
364
347
|
const _checkInputManually = input => {
|
|
365
348
|
let validityKey = _findValidityKey({
|
|
366
349
|
valueMissing: input.required && !input.value || false,
|
|
350
|
+
typeMismatch: _checkTypeMismatch(input),
|
|
367
351
|
tooShort: input.minLength && input.value.toString().length < input.minLength || false,
|
|
368
352
|
tooLong: input.maxLength && input.value.toString().length > input.maxLength || false,
|
|
369
353
|
patternMismatch: input.pattern && _checkResult(input.pattern, input.value) || false,
|
|
@@ -376,22 +360,17 @@ const useForm = (children, validators = {}, optimized = false) => {
|
|
|
376
360
|
_validateInput(input, validityKey);
|
|
377
361
|
return !input.error;
|
|
378
362
|
};
|
|
379
|
-
const _updateInputHandler = (
|
|
380
|
-
|
|
381
|
-
const input = _updateInput(key, value);
|
|
363
|
+
const _updateInputHandler = (input, e, unknown) => {
|
|
364
|
+
input.value = _extractValue(e, unknown);
|
|
382
365
|
_viHandler(input, e);
|
|
383
366
|
};
|
|
384
367
|
const _validateInput = (input, validityKey, setValidity) => {
|
|
385
368
|
const inputValidator = validators[input.validatorKey || input.formKey] || validators['*'];
|
|
386
|
-
|
|
369
|
+
if (inputValidator) {
|
|
370
|
+
__validateInput(input, inputValidator, validityKey, setValidity);
|
|
371
|
+
}
|
|
387
372
|
input.touched = true;
|
|
388
373
|
};
|
|
389
|
-
const _updateInput = (key, value) => {
|
|
390
|
-
const input = state.fields[key];
|
|
391
|
-
input.value = value;
|
|
392
|
-
input.dirty = true;
|
|
393
|
-
return input;
|
|
394
|
-
};
|
|
395
374
|
const _dispatchChanges = (changes, key) => setState(prev => {
|
|
396
375
|
if (key) {
|
|
397
376
|
return _objectSpread(_objectSpread({}, prev), {}, {
|
|
@@ -403,13 +382,14 @@ const useForm = (children, validators = {}, optimized = false) => {
|
|
|
403
382
|
return _objectSpread(_objectSpread({}, prev), changes);
|
|
404
383
|
});
|
|
405
384
|
const __validateInput = (input, inputValidator, validityKey, setValidity) => {
|
|
385
|
+
const fields = getState().fields;
|
|
406
386
|
for (const index in inputValidator.constraintHandlers) {
|
|
407
387
|
const result = inputValidator.constraintHandlers[index](input, validityKey);
|
|
408
388
|
input.error = _checkResult(result, input.value);
|
|
409
389
|
if (input.error) return;
|
|
410
390
|
}
|
|
411
391
|
for (const index in inputValidator.handlers) {
|
|
412
|
-
const result = inputValidator.handlers[index](input,
|
|
392
|
+
const result = inputValidator.handlers[index](input, fields);
|
|
413
393
|
input.error = _checkResult(result, input.value);
|
|
414
394
|
if (input.error) return;
|
|
415
395
|
}
|
|
@@ -419,7 +399,7 @@ const useForm = (children, validators = {}, optimized = false) => {
|
|
|
419
399
|
_debounce(input.debounce || 300, `${input.gid}-async`).then(() => {
|
|
420
400
|
const validateAsync = async () => {
|
|
421
401
|
for (const index in inputValidator.asyncHandlers) {
|
|
422
|
-
const result = await inputValidator.asyncHandlers[index](input,
|
|
402
|
+
const result = await inputValidator.asyncHandlers[index](input, fields);
|
|
423
403
|
input.error = _checkResult(result, input.value);
|
|
424
404
|
if (input.error) break;
|
|
425
405
|
}
|
|
@@ -428,187 +408,265 @@ const useForm = (children, validators = {}, optimized = false) => {
|
|
|
428
408
|
error: input.error,
|
|
429
409
|
errorText: input.errorText
|
|
430
410
|
}, input.formKey);
|
|
431
|
-
|
|
411
|
+
if (setValidity) {
|
|
412
|
+
setValidity(input.errorText);
|
|
413
|
+
}
|
|
432
414
|
};
|
|
433
415
|
validateAsync();
|
|
434
416
|
});
|
|
435
417
|
}
|
|
436
418
|
};
|
|
437
419
|
return {
|
|
438
|
-
state,
|
|
439
420
|
_updateInputHandler,
|
|
440
421
|
_viHandler,
|
|
441
422
|
_dispatchChanges,
|
|
442
423
|
optimized,
|
|
443
|
-
key: initialValues.key,
|
|
444
424
|
_createInputChecker: _checkInputManually
|
|
445
425
|
};
|
|
446
426
|
};
|
|
447
427
|
|
|
448
|
-
const
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
428
|
+
const GFormContext = createContext({});
|
|
429
|
+
const GFormContextProvider = ({
|
|
430
|
+
children,
|
|
431
|
+
initialState,
|
|
432
|
+
validators,
|
|
433
|
+
optimized
|
|
434
|
+
}) => {
|
|
435
|
+
const stateRef = useRef(initialState);
|
|
436
|
+
const listeners = useRef(new Set());
|
|
437
|
+
const setState = useCallback(updater => {
|
|
438
|
+
stateRef.current = typeof updater === 'function' ? updater(stateRef.current) : updater;
|
|
439
|
+
listeners.current.forEach(l => l());
|
|
440
|
+
}, []);
|
|
441
|
+
const handlers = useFormHandlers(() => stateRef.current, setState, validators, optimized);
|
|
442
|
+
const getState = useCallback(() => stateRef.current, []);
|
|
443
|
+
const subscribe = useCallback(listener => {
|
|
444
|
+
listeners.current.add(listener);
|
|
445
|
+
return () => listeners.current.delete(listener);
|
|
446
|
+
}, []);
|
|
447
|
+
useEffect(() => {
|
|
448
|
+
for (const fieldKey in initialState.fields) {
|
|
449
|
+
initialState.fields[fieldKey].dispatchChanges = changes => handlers._dispatchChanges(changes, fieldKey);
|
|
450
|
+
}
|
|
451
|
+
}, []);
|
|
452
|
+
const store = useRef({
|
|
453
|
+
getState,
|
|
454
|
+
setState,
|
|
455
|
+
subscribe,
|
|
456
|
+
handlers
|
|
457
|
+
});
|
|
458
|
+
return React.createElement(GFormContext.Provider, {
|
|
459
|
+
value: store.current
|
|
460
|
+
}, children);
|
|
461
|
+
};
|
|
462
|
+
const useFormStore = () => {
|
|
463
|
+
const store = useContext(GFormContext);
|
|
464
|
+
if (!store) throw new Error('useGFormStore must be used within `GForm` component');
|
|
465
|
+
return store;
|
|
466
|
+
};
|
|
467
|
+
const useFormSelector = selector => {
|
|
468
|
+
const store = useFormStore();
|
|
469
|
+
return useSyncExternalStore(store.subscribe, () => selector(store.getState()), () => selector(store.getState()));
|
|
470
|
+
};
|
|
471
|
+
function createSelector(selectors, combiner) {
|
|
472
|
+
let lastArgs = [];
|
|
473
|
+
let lastResult;
|
|
474
|
+
return state => {
|
|
475
|
+
const args = selectors.map(fn => fn(state));
|
|
476
|
+
if (lastArgs.length === args.length && args.every((val, i) => val === lastArgs[i])) {
|
|
477
|
+
return lastResult;
|
|
478
|
+
}
|
|
479
|
+
lastArgs = args;
|
|
480
|
+
lastResult = combiner(...args);
|
|
481
|
+
return lastResult;
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
const selectFields = [state => state.fields];
|
|
486
|
+
const selectFirstInvalidField = createSelector(selectFields, fields => {
|
|
487
|
+
for (const f in fields) {
|
|
488
|
+
if (fields[f].error) {
|
|
489
|
+
return true;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return false;
|
|
493
|
+
});
|
|
494
|
+
const makeSelectFields = (keys = []) => createSelector(selectFields, fields => {
|
|
495
|
+
const selected = keys.map(key => fields[key]).filter(Boolean);
|
|
496
|
+
return selected.length ? selected : null;
|
|
459
497
|
});
|
|
460
|
-
const useGenericFormContext = () => useContext(gFormContext);
|
|
461
|
-
const GFormContextProvider = gFormContext.Provider;
|
|
462
498
|
|
|
463
|
-
const _excluded$1 = ["
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
499
|
+
const _excluded$1 = ["stateRef", "onSubmit", "onChange", "onPaste", "onKeyDown", "onKeyUp", "children", "onInit"],
|
|
500
|
+
_excluded2 = ["children", "validators", "optimized"];
|
|
501
|
+
const FormRenderer = forwardRef((_ref, ref) => {
|
|
502
|
+
let {
|
|
503
|
+
stateRef,
|
|
504
|
+
onSubmit,
|
|
505
|
+
onChange,
|
|
506
|
+
onPaste,
|
|
507
|
+
onKeyDown,
|
|
508
|
+
onKeyUp,
|
|
509
|
+
children,
|
|
510
|
+
onInit
|
|
511
|
+
} = _ref,
|
|
512
|
+
rest = _objectWithoutProperties(_ref, _excluded$1);
|
|
513
|
+
const formRef = useRef(null);
|
|
514
|
+
const {
|
|
515
|
+
getState,
|
|
516
|
+
handlers
|
|
517
|
+
} = useFormStore();
|
|
518
|
+
const isFormInvalid = useFormSelector(selectFirstInvalidField);
|
|
519
|
+
const refHandler = useCallback(element => {
|
|
520
|
+
if (ref) {
|
|
521
|
+
if (typeof ref === 'function') {
|
|
522
|
+
ref(element);
|
|
523
|
+
} else {
|
|
524
|
+
ref.current = element;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
formRef.current = element;
|
|
528
|
+
}, [ref]);
|
|
529
|
+
const getFormState = useCallback(() => {
|
|
530
|
+
const fields = getState().fields;
|
|
531
|
+
const formState = _objectSpread(_objectSpread({}, fields), {}, {
|
|
532
|
+
isValid: !isFormInvalid,
|
|
533
|
+
isInvalid: isFormInvalid,
|
|
534
|
+
toRawData: options => _toRawData(fields, options),
|
|
535
|
+
toFormData: () => _toFormData(formRef.current),
|
|
536
|
+
toURLSearchParams: _toURLSearchParams,
|
|
537
|
+
checkValidity: function () {
|
|
538
|
+
this.isValid = formRef.current && formRef.current.checkValidity() || false;
|
|
539
|
+
this.isInvalid = !this.isValid;
|
|
540
|
+
return this.isValid;
|
|
541
|
+
},
|
|
542
|
+
dispatchChanges: changes => handlers._dispatchChanges({
|
|
543
|
+
fields: _merge({}, fields, changes)
|
|
544
|
+
})
|
|
545
|
+
});
|
|
546
|
+
if (stateRef) stateRef.current = formState;
|
|
547
|
+
return formState;
|
|
548
|
+
}, [isFormInvalid]);
|
|
549
|
+
const formComponent = useMemo(() => {
|
|
550
|
+
const state = getFormState();
|
|
551
|
+
const formChildren = typeof children === 'function' ? children(state) : children;
|
|
552
|
+
const _onSubmit = e => {
|
|
553
|
+
const state = getFormState();
|
|
554
|
+
if (state.isValid && onSubmit) {
|
|
555
|
+
onSubmit(state, e);
|
|
494
556
|
}
|
|
495
|
-
formRef.current = element;
|
|
496
557
|
};
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
}
|
|
517
|
-
});
|
|
518
|
-
if (stateRef) stateRef.current = formState;
|
|
519
|
-
return formState;
|
|
520
|
-
}, [state.fields]);
|
|
521
|
-
const formComponent = useMemo(() => {
|
|
522
|
-
const formChildren = typeof children === 'function' ? children(formState) : children;
|
|
523
|
-
const _onSubmit = e => {
|
|
524
|
-
if (formState.isValid && onSubmit) {
|
|
525
|
-
onSubmit(formState, e);
|
|
526
|
-
}
|
|
527
|
-
};
|
|
528
|
-
let _onPaste;
|
|
529
|
-
if (onPaste) {
|
|
530
|
-
_onPaste = e => onPaste(formState, e);
|
|
558
|
+
let _onPaste, _onChange, _onKeyDown, _onKeyUp;
|
|
559
|
+
if (onPaste) {
|
|
560
|
+
_onPaste = e => onPaste(state, e);
|
|
561
|
+
}
|
|
562
|
+
if (onKeyDown) {
|
|
563
|
+
_onKeyDown = e => onKeyDown(state, e);
|
|
564
|
+
}
|
|
565
|
+
if (onKeyUp) {
|
|
566
|
+
_onKeyUp = e => onKeyUp(state, e);
|
|
567
|
+
}
|
|
568
|
+
if (handlers.optimized) {
|
|
569
|
+
if (onChange) {
|
|
570
|
+
_onChange = (e, unknown) => {
|
|
571
|
+
handlers._updateInputHandler(state[e.target.name], e, unknown);
|
|
572
|
+
onChange(state, e);
|
|
573
|
+
};
|
|
574
|
+
} else {
|
|
575
|
+
_onChange = (e, unknown) => {
|
|
576
|
+
handlers._updateInputHandler(state[e.target.name], e, unknown);
|
|
577
|
+
};
|
|
531
578
|
}
|
|
532
|
-
return
|
|
579
|
+
return React.createElement("form", _extends({}, rest, {
|
|
533
580
|
ref: refHandler,
|
|
534
581
|
onPaste: _onPaste,
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
582
|
+
onKeyDown: _onKeyDown,
|
|
583
|
+
onKeyUp: _onKeyUp,
|
|
584
|
+
onBlur: e => handlers._viHandler(state[e.target.name], e),
|
|
538
585
|
onInvalid: e => {
|
|
539
586
|
e.preventDefault();
|
|
540
|
-
_viHandler(state
|
|
541
|
-
},
|
|
542
|
-
onChange: (e, unknown) => {
|
|
543
|
-
_updateInputHandler(e.target.name, e, unknown);
|
|
544
|
-
onChange && onChange(formState, e);
|
|
587
|
+
handlers._viHandler(state[e.target.name], e);
|
|
545
588
|
},
|
|
589
|
+
onChange: _onChange,
|
|
546
590
|
onSubmit: _onSubmit
|
|
547
|
-
}), formChildren) : React.createElement("form", _extends({}, rest, {
|
|
548
|
-
onChange: e => onChange && onChange(formState, e),
|
|
549
|
-
ref: refHandler,
|
|
550
|
-
onSubmit: _onSubmit,
|
|
551
|
-
onPaste: _onPaste
|
|
552
591
|
}), formChildren);
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
592
|
+
}
|
|
593
|
+
if (onChange) {
|
|
594
|
+
_onChange = e => onChange(state, e);
|
|
595
|
+
}
|
|
596
|
+
return React.createElement("form", _extends({}, rest, {
|
|
597
|
+
ref: refHandler,
|
|
598
|
+
onSubmit: _onSubmit,
|
|
599
|
+
onChange: _onChange,
|
|
600
|
+
onPaste: _onPaste,
|
|
601
|
+
onKeyDown: _onKeyDown,
|
|
602
|
+
onKeyUp: _onKeyUp
|
|
603
|
+
}), formChildren);
|
|
604
|
+
}, [children, getFormState]);
|
|
605
|
+
useEffect(() => {
|
|
606
|
+
const state = getFormState();
|
|
607
|
+
if (!hasSubmitter(formRef.current)) {
|
|
608
|
+
console.warn(`[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`);
|
|
609
|
+
}
|
|
610
|
+
if (onInit) {
|
|
611
|
+
const changes = onInit(state);
|
|
612
|
+
if (changes) {
|
|
613
|
+
const _handler = _c => handlers._dispatchChanges({
|
|
614
|
+
fields: _merge({}, state, _c)
|
|
561
615
|
});
|
|
562
|
-
|
|
563
|
-
|
|
616
|
+
if (changes instanceof Promise) {
|
|
617
|
+
changes.then(_handler);
|
|
618
|
+
} else _handler(changes);
|
|
564
619
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
|
|
620
|
+
}
|
|
621
|
+
const fields = getState().fields;
|
|
622
|
+
for (const fieldKey in fields) {
|
|
623
|
+
const field = fields[fieldKey];
|
|
624
|
+
if (!field.value) continue;
|
|
625
|
+
handlers._viHandler(field);
|
|
626
|
+
}
|
|
627
|
+
}, [getFormState]);
|
|
628
|
+
return formComponent;
|
|
629
|
+
});
|
|
630
|
+
const GForm = forwardRef((_ref2, ref) => {
|
|
631
|
+
let {
|
|
632
|
+
children,
|
|
633
|
+
validators,
|
|
634
|
+
optimized
|
|
635
|
+
} = _ref2,
|
|
636
|
+
props = _objectWithoutProperties(_ref2, _excluded2);
|
|
637
|
+
const initialState = useMemo(() => {
|
|
638
|
+
return _buildFormInitialValues(typeof children === 'function' ? children({}) : children);
|
|
639
|
+
}, [children]);
|
|
640
|
+
return React.createElement(GFormContextProvider, {
|
|
641
|
+
key: initialState.key,
|
|
642
|
+
initialState: initialState,
|
|
643
|
+
validators: validators,
|
|
644
|
+
optimized: optimized
|
|
645
|
+
}, React.createElement(FormRenderer, _extends({
|
|
646
|
+
ref: ref
|
|
647
|
+
}, props), children));
|
|
648
|
+
});
|
|
583
649
|
|
|
584
|
-
const _excluded = ["formKey", "element", "title", "type", "
|
|
585
|
-
const
|
|
650
|
+
const _excluded = ["formKey", "element", "title", "type", "fetch", "fetchDeps", "optimized", "debounce", "defaultChecked", "defaultValue", "checked", "validatorKey", "value"];
|
|
651
|
+
const _GInput = forwardRef((_ref, ref) => {
|
|
586
652
|
let {
|
|
587
653
|
formKey,
|
|
588
654
|
element,
|
|
589
655
|
title,
|
|
590
|
-
type,
|
|
591
|
-
validatorKey,
|
|
656
|
+
type = 'text',
|
|
592
657
|
fetch,
|
|
593
|
-
fetchDeps
|
|
658
|
+
fetchDeps,
|
|
594
659
|
optimized,
|
|
660
|
+
debounce = 300,
|
|
595
661
|
defaultChecked,
|
|
596
662
|
defaultValue,
|
|
597
663
|
checked,
|
|
598
|
-
|
|
599
|
-
|
|
664
|
+
validatorKey,
|
|
665
|
+
value
|
|
600
666
|
} = _ref,
|
|
601
667
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
fields
|
|
605
|
-
},
|
|
606
|
-
_updateInputHandler,
|
|
607
|
-
_dispatchChanges,
|
|
608
|
-
optimized: formOptimized,
|
|
609
|
-
_viHandler
|
|
610
|
-
} = useGenericFormContext();
|
|
611
|
-
const inputState = fields[formKey];
|
|
668
|
+
const inputState = useFormSelector(state => state.fields[formKey]);
|
|
669
|
+
const store = useFormStore();
|
|
612
670
|
const _element = useMemo(() => {
|
|
613
671
|
let value, checked;
|
|
614
672
|
if (type === 'checkbox') checked = inputState.value || false;else value = inputState.value || '';
|
|
@@ -622,19 +680,26 @@ const GInput = forwardRef((_ref, ref) => {
|
|
|
622
680
|
'aria-required': inputState.required,
|
|
623
681
|
title: title || inputState.errorText
|
|
624
682
|
});
|
|
625
|
-
if (!
|
|
626
|
-
_props.onBlur = e => {
|
|
627
|
-
_viHandler(inputState, e);
|
|
628
|
-
rest.onBlur
|
|
683
|
+
if (!store.handlers.optimized || !optimized) {
|
|
684
|
+
_props.onBlur = rest.onBlur ? e => {
|
|
685
|
+
store.handlers._viHandler(inputState, e);
|
|
686
|
+
rest.onBlur(e);
|
|
687
|
+
} : e => {
|
|
688
|
+
store.handlers._viHandler(inputState, e);
|
|
629
689
|
};
|
|
630
|
-
_props.onInvalid = e => {
|
|
690
|
+
_props.onInvalid = rest.onInvalid ? e => {
|
|
631
691
|
e.preventDefault();
|
|
632
|
-
_viHandler(inputState, e);
|
|
633
|
-
rest.onInvalid
|
|
692
|
+
store.handlers._viHandler(inputState, e);
|
|
693
|
+
rest.onInvalid(e);
|
|
694
|
+
} : e => {
|
|
695
|
+
e.preventDefault();
|
|
696
|
+
store.handlers._viHandler(inputState, e);
|
|
634
697
|
};
|
|
635
|
-
_props.onChange = (e, unknown) => {
|
|
636
|
-
_updateInputHandler(
|
|
637
|
-
rest.onChange
|
|
698
|
+
_props.onChange = rest.onChange ? (e, unknown) => {
|
|
699
|
+
store.handlers._updateInputHandler(inputState, e, unknown);
|
|
700
|
+
rest.onChange(e);
|
|
701
|
+
} : (e, unknown) => {
|
|
702
|
+
store.handlers._updateInputHandler(inputState, e, unknown);
|
|
638
703
|
};
|
|
639
704
|
}
|
|
640
705
|
if (element) {
|
|
@@ -642,18 +707,23 @@ const GInput = forwardRef((_ref, ref) => {
|
|
|
642
707
|
}
|
|
643
708
|
return React.createElement("input", _props);
|
|
644
709
|
}, [inputState, element]);
|
|
645
|
-
const _fetchDeps =
|
|
710
|
+
const _fetchDeps = useFormSelector(makeSelectFields(fetchDeps));
|
|
711
|
+
const stableFetchDeps = useMemo(() => JSON.stringify(_fetchDeps), [_fetchDeps]);
|
|
646
712
|
useEffect(() => {
|
|
647
713
|
if (fetch) {
|
|
648
|
-
inputState.dispatchChanges = changes => _dispatchChanges(changes, formKey);
|
|
649
714
|
_debounce(debounce, `${inputState.gid}-fetch`).then(() => {
|
|
650
|
-
const res = fetch(inputState, fields);
|
|
651
|
-
res instanceof Promise
|
|
715
|
+
const res = fetch(inputState, store.getState().fields);
|
|
716
|
+
if (res instanceof Promise) {
|
|
717
|
+
res.then(state => state && store.handlers._dispatchChanges(state, formKey));
|
|
718
|
+
} else if (res) {
|
|
719
|
+
store.handlers._dispatchChanges(res, formKey);
|
|
720
|
+
}
|
|
652
721
|
});
|
|
653
722
|
}
|
|
654
|
-
},
|
|
723
|
+
}, [stableFetchDeps]);
|
|
655
724
|
return _element;
|
|
656
725
|
});
|
|
726
|
+
const GInput = memo(_GInput);
|
|
657
727
|
|
|
658
|
-
export { GForm, GInput, GValidator };
|
|
728
|
+
export { GForm, GInput, GValidator, useFormSelector };
|
|
659
729
|
//# sourceMappingURL=index.development.js.map
|