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.
- package/README.md +4 -3
- package/dist/cjs/gform-react.development.js +280 -238
- 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/GValidator.production.js +1 -1
- package/dist/esm/GValidator.production.js.map +1 -1
- package/dist/esm/index.development.js +286 -243
- 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 +25 -12
- package/native/dist/cjs/gform-react-native.development.js +222 -284
- 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 +228 -288
- 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 +27 -24
|
@@ -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);
|
|
@@ -24,7 +24,7 @@ const generateId = () => (+new Date()).toString(36) + (1 - Math.random()).toStri
|
|
|
24
24
|
const _buildFormInitialValues = (rows = []) => {
|
|
25
25
|
const fields = {};
|
|
26
26
|
if (!Array.isArray(rows)) rows = [rows];
|
|
27
|
-
|
|
27
|
+
for (const row of rows) {
|
|
28
28
|
const inputConfigs = _findInputs(row);
|
|
29
29
|
inputConfigs.forEach(config => {
|
|
30
30
|
if (fields[config.formKey]) {
|
|
@@ -70,12 +70,9 @@ const _buildFormInitialValues = (rows = []) => {
|
|
|
70
70
|
if (typeof fields[config.formKey][key] === 'undefined') delete fields[config.formKey][key];
|
|
71
71
|
});
|
|
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 {
|
|
@@ -134,39 +143,13 @@ const _toRawData = (fields, options = {}) => {
|
|
|
134
143
|
for (const key in transform) {
|
|
135
144
|
var _fields$key2;
|
|
136
145
|
const set = transform[key];
|
|
137
|
-
data[key] = set((_fields$key2 = fields[key]) === null || _fields$key2 === void 0 ? void 0 : _fields$key2.value);
|
|
146
|
+
data[key] = set(((_fields$key2 = fields[key]) === null || _fields$key2 === void 0 ? void 0 : _fields$key2.value) || fields[key]);
|
|
138
147
|
}
|
|
139
148
|
}
|
|
140
149
|
return data;
|
|
141
150
|
};
|
|
142
151
|
const _toFormData = (form, options) => {
|
|
143
152
|
if (!form) return new FormData();
|
|
144
|
-
if (options) {
|
|
145
|
-
const {
|
|
146
|
-
exclude,
|
|
147
|
-
include,
|
|
148
|
-
transform
|
|
149
|
-
} = options;
|
|
150
|
-
let formData;
|
|
151
|
-
if (include) {
|
|
152
|
-
formData = new FormData();
|
|
153
|
-
include.forEach(key => {
|
|
154
|
-
var _form;
|
|
155
|
-
return formData.set(key, (_form = form[key]) === null || _form === void 0 ? void 0 : _form.value);
|
|
156
|
-
});
|
|
157
|
-
} else {
|
|
158
|
-
formData = new FormData(form);
|
|
159
|
-
exclude === null || exclude === void 0 || exclude.forEach(key => formData.delete(key));
|
|
160
|
-
}
|
|
161
|
-
if (transform) {
|
|
162
|
-
for (const key in transform) {
|
|
163
|
-
var _form$key;
|
|
164
|
-
const set = transform[key];
|
|
165
|
-
formData.set(key, set((_form$key = form[key]) === null || _form$key === void 0 ? void 0 : _form$key.value));
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return formData;
|
|
169
|
-
}
|
|
170
153
|
return new FormData(form);
|
|
171
154
|
};
|
|
172
155
|
function _toURLSearchParams(options) {
|
|
@@ -269,9 +252,9 @@ class GValidator {
|
|
|
269
252
|
const baseHandlers = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.handlers) || [];
|
|
270
253
|
const baseConstraintHandlers = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.constraintHandlers) || [];
|
|
271
254
|
const baseHandlersAsync = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.asyncHandlers) || [];
|
|
272
|
-
this._handlers =
|
|
273
|
-
this._constraintHandlers =
|
|
274
|
-
this._asyncHandlers =
|
|
255
|
+
this._handlers = [].concat(baseHandlers);
|
|
256
|
+
this._constraintHandlers = [].concat(baseConstraintHandlers);
|
|
257
|
+
this._asyncHandlers = [].concat(baseHandlersAsync);
|
|
275
258
|
{
|
|
276
259
|
this.track = [];
|
|
277
260
|
if (baseValidator !== null && baseValidator !== void 0 && baseValidator.track) {
|
|
@@ -337,39 +320,13 @@ class GValidator {
|
|
|
337
320
|
}
|
|
338
321
|
}
|
|
339
322
|
|
|
340
|
-
const
|
|
341
|
-
const initialValues = useMemo(() => {
|
|
342
|
-
const values = _buildFormInitialValues(typeof children === 'function' ? children({}) : children);
|
|
343
|
-
{
|
|
344
|
-
Object.keys(values.state.fields).forEach(key => {
|
|
345
|
-
const input = values.state.fields[key];
|
|
346
|
-
const validator = validators[key];
|
|
347
|
-
if (validator instanceof GValidator) {
|
|
348
|
-
var _validator$track;
|
|
349
|
-
const validityKeys = (_validator$track = validator.track) === null || _validator$track === void 0 ? void 0 : _validator$track.filter(key => validityMap[key]);
|
|
350
|
-
validityKeys === null || validityKeys === void 0 || validityKeys.forEach(vKey => {
|
|
351
|
-
if (typeof input[validityMap[vKey]] === 'undefined') {
|
|
352
|
-
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`);
|
|
353
|
-
}
|
|
354
|
-
});
|
|
355
|
-
Object.entries(validityMap).forEach(([validityKey, constraint]) => {
|
|
356
|
-
var _validator$track2;
|
|
357
|
-
if (typeof input[constraint] !== 'undefined' && !((_validator$track2 = validator.track) !== null && _validator$track2 !== void 0 && _validator$track2.some(trackKey => validityKey === trackKey))) {
|
|
358
|
-
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}`);
|
|
359
|
-
}
|
|
360
|
-
});
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
}
|
|
364
|
-
return values;
|
|
365
|
-
}, []);
|
|
366
|
-
const [state, setState] = useState(initialValues.state);
|
|
323
|
+
const useFormHandlers = (getState, setState, validators = {}, optimized = false) => {
|
|
367
324
|
const _viHandler = (input, e) => {
|
|
368
325
|
if (!input) return;
|
|
369
326
|
const element = e && e.target;
|
|
370
327
|
if (typeof document !== 'undefined' && (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement)) {
|
|
371
328
|
if (!input.checkValidity) input.checkValidity = () => element.checkValidity();
|
|
372
|
-
if (!input.dirty && input.value) {
|
|
329
|
+
if (!input.dirty && input.value && !input.touched) {
|
|
373
330
|
_checkInputManually(input);
|
|
374
331
|
_dispatchChanges(input, input.formKey);
|
|
375
332
|
return;
|
|
@@ -390,6 +347,7 @@ const useForm = (children, validators = {}, optimized = false) => {
|
|
|
390
347
|
const _checkInputManually = input => {
|
|
391
348
|
let validityKey = _findValidityKey({
|
|
392
349
|
valueMissing: input.required && !input.value || false,
|
|
350
|
+
typeMismatch: _checkTypeMismatch(input),
|
|
393
351
|
tooShort: input.minLength && input.value.toString().length < input.minLength || false,
|
|
394
352
|
tooLong: input.maxLength && input.value.toString().length > input.maxLength || false,
|
|
395
353
|
patternMismatch: input.pattern && _checkResult(input.pattern, input.value) || false,
|
|
@@ -402,22 +360,17 @@ const useForm = (children, validators = {}, optimized = false) => {
|
|
|
402
360
|
_validateInput(input, validityKey);
|
|
403
361
|
return !input.error;
|
|
404
362
|
};
|
|
405
|
-
const _updateInputHandler = (
|
|
406
|
-
|
|
407
|
-
const input = _updateInput(key, value);
|
|
363
|
+
const _updateInputHandler = (input, e, unknown) => {
|
|
364
|
+
input.value = _extractValue(e, unknown);
|
|
408
365
|
_viHandler(input, e);
|
|
409
366
|
};
|
|
410
367
|
const _validateInput = (input, validityKey, setValidity) => {
|
|
411
368
|
const inputValidator = validators[input.validatorKey || input.formKey] || validators['*'];
|
|
412
|
-
|
|
369
|
+
if (inputValidator) {
|
|
370
|
+
__validateInput(input, inputValidator, validityKey, setValidity);
|
|
371
|
+
}
|
|
413
372
|
input.touched = true;
|
|
414
373
|
};
|
|
415
|
-
const _updateInput = (key, value) => {
|
|
416
|
-
const input = state.fields[key];
|
|
417
|
-
input.value = value;
|
|
418
|
-
input.dirty = true;
|
|
419
|
-
return input;
|
|
420
|
-
};
|
|
421
374
|
const _dispatchChanges = (changes, key) => setState(prev => {
|
|
422
375
|
if (key) {
|
|
423
376
|
return _objectSpread(_objectSpread({}, prev), {}, {
|
|
@@ -429,13 +382,14 @@ const useForm = (children, validators = {}, optimized = false) => {
|
|
|
429
382
|
return _objectSpread(_objectSpread({}, prev), changes);
|
|
430
383
|
});
|
|
431
384
|
const __validateInput = (input, inputValidator, validityKey, setValidity) => {
|
|
385
|
+
const fields = getState().fields;
|
|
432
386
|
for (const index in inputValidator.constraintHandlers) {
|
|
433
387
|
const result = inputValidator.constraintHandlers[index](input, validityKey);
|
|
434
388
|
input.error = _checkResult(result, input.value);
|
|
435
389
|
if (input.error) return;
|
|
436
390
|
}
|
|
437
391
|
for (const index in inputValidator.handlers) {
|
|
438
|
-
const result = inputValidator.handlers[index](input,
|
|
392
|
+
const result = inputValidator.handlers[index](input, fields);
|
|
439
393
|
input.error = _checkResult(result, input.value);
|
|
440
394
|
if (input.error) return;
|
|
441
395
|
}
|
|
@@ -445,7 +399,7 @@ const useForm = (children, validators = {}, optimized = false) => {
|
|
|
445
399
|
_debounce(input.debounce || 300, `${input.gid}-async`).then(() => {
|
|
446
400
|
const validateAsync = async () => {
|
|
447
401
|
for (const index in inputValidator.asyncHandlers) {
|
|
448
|
-
const result = await inputValidator.asyncHandlers[index](input,
|
|
402
|
+
const result = await inputValidator.asyncHandlers[index](input, fields);
|
|
449
403
|
input.error = _checkResult(result, input.value);
|
|
450
404
|
if (input.error) break;
|
|
451
405
|
}
|
|
@@ -454,188 +408,265 @@ const useForm = (children, validators = {}, optimized = false) => {
|
|
|
454
408
|
error: input.error,
|
|
455
409
|
errorText: input.errorText
|
|
456
410
|
}, input.formKey);
|
|
457
|
-
|
|
411
|
+
if (setValidity) {
|
|
412
|
+
setValidity(input.errorText);
|
|
413
|
+
}
|
|
458
414
|
};
|
|
459
415
|
validateAsync();
|
|
460
416
|
});
|
|
461
417
|
}
|
|
462
418
|
};
|
|
463
419
|
return {
|
|
464
|
-
state,
|
|
465
420
|
_updateInputHandler,
|
|
466
421
|
_viHandler,
|
|
467
422
|
_dispatchChanges,
|
|
468
423
|
optimized,
|
|
469
|
-
key: initialValues.key,
|
|
470
424
|
_createInputChecker: _checkInputManually
|
|
471
425
|
};
|
|
472
426
|
};
|
|
473
427
|
|
|
474
|
-
const
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
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;
|
|
485
497
|
});
|
|
486
|
-
const useGenericFormContext = () => useContext(gFormContext);
|
|
487
|
-
const GFormContextProvider = gFormContext.Provider;
|
|
488
498
|
|
|
489
|
-
const _excluded$1 = ["
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
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);
|
|
520
556
|
}
|
|
521
|
-
formRef.current = element;
|
|
522
557
|
};
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
}
|
|
543
|
-
});
|
|
544
|
-
if (stateRef) stateRef.current = formState;
|
|
545
|
-
return formState;
|
|
546
|
-
}, [state.fields]);
|
|
547
|
-
const formComponent = useMemo(() => {
|
|
548
|
-
const formChildren = typeof children === 'function' ? children(formState) : children;
|
|
549
|
-
const _onSubmit = e => {
|
|
550
|
-
e.preventDefault();
|
|
551
|
-
if (formState.isValid && onSubmit) {
|
|
552
|
-
onSubmit(formState, e);
|
|
553
|
-
}
|
|
554
|
-
};
|
|
555
|
-
let _onPaste;
|
|
556
|
-
if (onPaste) {
|
|
557
|
-
_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
|
+
};
|
|
558
578
|
}
|
|
559
|
-
return
|
|
579
|
+
return React.createElement("form", _extends({}, rest, {
|
|
560
580
|
ref: refHandler,
|
|
561
581
|
onPaste: _onPaste,
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
582
|
+
onKeyDown: _onKeyDown,
|
|
583
|
+
onKeyUp: _onKeyUp,
|
|
584
|
+
onBlur: e => handlers._viHandler(state[e.target.name], e),
|
|
565
585
|
onInvalid: e => {
|
|
566
586
|
e.preventDefault();
|
|
567
|
-
_viHandler(state
|
|
568
|
-
},
|
|
569
|
-
onChange: (e, unknown) => {
|
|
570
|
-
_updateInputHandler(e.target.name, e, unknown);
|
|
571
|
-
onChange && onChange(formState, e);
|
|
587
|
+
handlers._viHandler(state[e.target.name], e);
|
|
572
588
|
},
|
|
589
|
+
onChange: _onChange,
|
|
573
590
|
onSubmit: _onSubmit
|
|
574
|
-
}), formChildren) : React.createElement("form", _extends({}, rest, {
|
|
575
|
-
onChange: e => onChange && onChange(formState, e),
|
|
576
|
-
ref: refHandler,
|
|
577
|
-
onSubmit: _onSubmit,
|
|
578
|
-
onPaste: _onPaste
|
|
579
591
|
}), formChildren);
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
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)
|
|
588
615
|
});
|
|
589
|
-
|
|
590
|
-
|
|
616
|
+
if (changes instanceof Promise) {
|
|
617
|
+
changes.then(_handler);
|
|
618
|
+
} else _handler(changes);
|
|
591
619
|
}
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
|
|
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
|
+
});
|
|
610
649
|
|
|
611
|
-
const _excluded = ["formKey", "element", "title", "type", "
|
|
612
|
-
const
|
|
650
|
+
const _excluded = ["formKey", "element", "title", "type", "fetch", "fetchDeps", "optimized", "debounce", "defaultChecked", "defaultValue", "checked", "validatorKey", "value"];
|
|
651
|
+
const _GInput = forwardRef((_ref, ref) => {
|
|
613
652
|
let {
|
|
614
653
|
formKey,
|
|
615
654
|
element,
|
|
616
655
|
title,
|
|
617
|
-
type,
|
|
618
|
-
validatorKey,
|
|
656
|
+
type = 'text',
|
|
619
657
|
fetch,
|
|
620
|
-
fetchDeps
|
|
658
|
+
fetchDeps,
|
|
621
659
|
optimized,
|
|
660
|
+
debounce = 300,
|
|
622
661
|
defaultChecked,
|
|
623
662
|
defaultValue,
|
|
624
663
|
checked,
|
|
625
|
-
|
|
626
|
-
|
|
664
|
+
validatorKey,
|
|
665
|
+
value
|
|
627
666
|
} = _ref,
|
|
628
667
|
rest = _objectWithoutProperties(_ref, _excluded);
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
fields
|
|
632
|
-
},
|
|
633
|
-
_updateInputHandler,
|
|
634
|
-
_dispatchChanges,
|
|
635
|
-
optimized: formOptimized,
|
|
636
|
-
_viHandler
|
|
637
|
-
} = useGenericFormContext();
|
|
638
|
-
const inputState = fields[formKey];
|
|
668
|
+
const inputState = useFormSelector(state => state.fields[formKey]);
|
|
669
|
+
const store = useFormStore();
|
|
639
670
|
const _element = useMemo(() => {
|
|
640
671
|
let value, checked;
|
|
641
672
|
if (type === 'checkbox') checked = inputState.value || false;else value = inputState.value || '';
|
|
@@ -649,19 +680,26 @@ const GInput = forwardRef((_ref, ref) => {
|
|
|
649
680
|
'aria-required': inputState.required,
|
|
650
681
|
title: title || inputState.errorText
|
|
651
682
|
});
|
|
652
|
-
if (!
|
|
653
|
-
_props.onBlur = e => {
|
|
654
|
-
_viHandler(inputState, e);
|
|
655
|
-
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);
|
|
656
689
|
};
|
|
657
|
-
_props.onInvalid = e => {
|
|
690
|
+
_props.onInvalid = rest.onInvalid ? e => {
|
|
691
|
+
e.preventDefault();
|
|
692
|
+
store.handlers._viHandler(inputState, e);
|
|
693
|
+
rest.onInvalid(e);
|
|
694
|
+
} : e => {
|
|
658
695
|
e.preventDefault();
|
|
659
|
-
_viHandler(inputState, e);
|
|
660
|
-
rest.onInvalid && rest.onInvalid(e);
|
|
696
|
+
store.handlers._viHandler(inputState, e);
|
|
661
697
|
};
|
|
662
|
-
_props.onChange = (e, unknown) => {
|
|
663
|
-
_updateInputHandler(
|
|
664
|
-
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);
|
|
665
703
|
};
|
|
666
704
|
}
|
|
667
705
|
if (element) {
|
|
@@ -669,18 +707,23 @@ const GInput = forwardRef((_ref, ref) => {
|
|
|
669
707
|
}
|
|
670
708
|
return React.createElement("input", _props);
|
|
671
709
|
}, [inputState, element]);
|
|
672
|
-
const _fetchDeps =
|
|
710
|
+
const _fetchDeps = useFormSelector(makeSelectFields(fetchDeps));
|
|
711
|
+
const stableFetchDeps = useMemo(() => JSON.stringify(_fetchDeps), [_fetchDeps]);
|
|
673
712
|
useEffect(() => {
|
|
674
713
|
if (fetch) {
|
|
675
|
-
inputState.dispatchChanges = changes => _dispatchChanges(changes, formKey);
|
|
676
714
|
_debounce(debounce, `${inputState.gid}-fetch`).then(() => {
|
|
677
|
-
const res = fetch(inputState, fields);
|
|
678
|
-
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
|
+
}
|
|
679
721
|
});
|
|
680
722
|
}
|
|
681
|
-
},
|
|
723
|
+
}, [stableFetchDeps]);
|
|
682
724
|
return _element;
|
|
683
725
|
});
|
|
726
|
+
const GInput = memo(_GInput);
|
|
684
727
|
|
|
685
|
-
export { GForm, GInput, GValidator };
|
|
728
|
+
export { GForm, GInput, GValidator, useFormSelector };
|
|
686
729
|
//# sourceMappingURL=index.development.js.map
|