gform-react 2.5.0 → 2.5.3
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 +59 -27
- 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 +59 -27
- package/dist/esm/index.development.js.map +1 -1
- package/dist/esm/shared.production.js +1 -1
- package/dist/esm/shared.production.js.map +1 -1
- package/dist/index.d.ts +8 -1
- package/native/dist/cjs/gform-react-native.development.js +57 -5
- 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/RNGInput.production.js +1 -1
- package/native/dist/esm/RNGInput.production.js.map +1 -1
- package/native/dist/esm/index.development.js +57 -5
- 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/package.json +1 -1
|
@@ -28,7 +28,7 @@ const _buildFormInitialValues = (rows = []) => {
|
|
|
28
28
|
const inputConfigs = _findInputs(row);
|
|
29
29
|
inputConfigs.forEach(config => {
|
|
30
30
|
if (fields[config.formKey]) {
|
|
31
|
-
console.warn(`[Duplicate Keys] - field with key '${config.formKey}' has already been defined.`);
|
|
31
|
+
console.warn(`DEV ONLY - [Duplicate Keys] - field with key '${config.formKey}' has already been defined.`);
|
|
32
32
|
}
|
|
33
33
|
const {
|
|
34
34
|
required = false,
|
|
@@ -89,8 +89,9 @@ const _findInputs = (root, total = []) => {
|
|
|
89
89
|
}
|
|
90
90
|
return _findInputs((_root$props2 = root.props) === null || _root$props2 === void 0 ? void 0 : _root$props2.children, total);
|
|
91
91
|
};
|
|
92
|
-
const _findValidityKey = validity => {
|
|
92
|
+
const _findValidityKey = (validity, exclude = []) => {
|
|
93
93
|
for (const key in validity) {
|
|
94
|
+
if (exclude.includes(key)) continue;
|
|
94
95
|
if (key !== 'valid' && validity[key]) {
|
|
95
96
|
return key;
|
|
96
97
|
}
|
|
@@ -123,6 +124,14 @@ const hasSubmitter = form => {
|
|
|
123
124
|
}
|
|
124
125
|
return false;
|
|
125
126
|
};
|
|
127
|
+
const _checkIfFormIsValid = fields => {
|
|
128
|
+
for (const f in fields) {
|
|
129
|
+
if (fields[f].error) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return true;
|
|
134
|
+
};
|
|
126
135
|
const _toRawData = (fields, options = {}) => {
|
|
127
136
|
const data = {};
|
|
128
137
|
const {
|
|
@@ -225,7 +234,8 @@ let validityMap;
|
|
|
225
234
|
pattern: 'withPatternMismatchMessage',
|
|
226
235
|
min: 'withRangeUnderflowMessage',
|
|
227
236
|
max: 'withRangeOverflowMessage',
|
|
228
|
-
step: 'withStepMismatchMessage'
|
|
237
|
+
step: 'withStepMismatchMessage',
|
|
238
|
+
type: 'withTypeMismatchMessage'
|
|
229
239
|
};
|
|
230
240
|
validityMap = {
|
|
231
241
|
tooShort: 'minLength',
|
|
@@ -234,7 +244,8 @@ let validityMap;
|
|
|
234
244
|
patternMismatch: 'pattern',
|
|
235
245
|
rangeOverflow: 'max',
|
|
236
246
|
rangeUnderflow: 'min',
|
|
237
|
-
stepMismatch: 'step'
|
|
247
|
+
stepMismatch: 'step',
|
|
248
|
+
typeMismatch: 'type'
|
|
238
249
|
};
|
|
239
250
|
}
|
|
240
251
|
class GValidator {
|
|
@@ -265,6 +276,10 @@ class GValidator {
|
|
|
265
276
|
}
|
|
266
277
|
}
|
|
267
278
|
}
|
|
279
|
+
hasConstraint(constraint) {
|
|
280
|
+
var _this$track;
|
|
281
|
+
return ((_this$track = this.track) === null || _this$track === void 0 ? void 0 : _this$track.includes(constraint)) || false;
|
|
282
|
+
}
|
|
268
283
|
withRequiredMessage(message) {
|
|
269
284
|
return this.__addConstraintValidationHandler('valueMissing', message);
|
|
270
285
|
}
|
|
@@ -303,14 +318,14 @@ class GValidator {
|
|
|
303
318
|
__addConstraintValidationHandler(validityKey, message) {
|
|
304
319
|
if (this.track) {
|
|
305
320
|
if (this.track.includes(validityKey)) {
|
|
306
|
-
console.warn(`[Duplicate Handlers] - handler for '${validityKey}' has already been defined`);
|
|
321
|
+
console.warn(`DEV ONLY - [Duplicate Handlers] - handler for '${validityKey}' has already been defined`);
|
|
307
322
|
}
|
|
308
323
|
this.track.push(validityKey);
|
|
309
324
|
}
|
|
310
325
|
this._constraintHandlers.push((input, key) => {
|
|
311
326
|
{
|
|
312
327
|
if (validityKey && validityMap[validityKey] && typeof input[validityMap[validityKey]] === 'undefined') {
|
|
313
|
-
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`);
|
|
328
|
+
console.warn(`DEV ONLY - [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`);
|
|
314
329
|
}
|
|
315
330
|
}
|
|
316
331
|
if (key === validityKey) {
|
|
@@ -327,15 +342,18 @@ const useFormHandlers = (getState, setState, validators = {}, optimized = false)
|
|
|
327
342
|
const _viHandler = (input, e) => {
|
|
328
343
|
if (!input) return;
|
|
329
344
|
const element = e && e.target;
|
|
345
|
+
const hasInitialValue = !input.dirty && input.value && !input.touched;
|
|
346
|
+
if (!element && !hasInitialValue) return;
|
|
330
347
|
if (typeof document !== 'undefined' && (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement)) {
|
|
331
348
|
if (!input.checkValidity) input.checkValidity = () => element.checkValidity();
|
|
332
|
-
if (
|
|
349
|
+
if (hasInitialValue) {
|
|
333
350
|
_checkInputManually(input);
|
|
334
351
|
_dispatchChanges(input, input.formKey);
|
|
335
352
|
return;
|
|
336
353
|
}
|
|
337
354
|
element.setCustomValidity('');
|
|
338
|
-
const
|
|
355
|
+
const exclude = input.type && (input.pattern || hasCustomValidation(input)) ? ['typeMismatch'] : [];
|
|
356
|
+
const validityKey = _findValidityKey(element.validity, exclude);
|
|
339
357
|
_validateInput(input, validityKey, v => element.setCustomValidity(v));
|
|
340
358
|
if (!validityKey && input.error) {
|
|
341
359
|
element.setCustomValidity(input.errorText || 'error');
|
|
@@ -348,6 +366,7 @@ const useFormHandlers = (getState, setState, validators = {}, optimized = false)
|
|
|
348
366
|
}
|
|
349
367
|
};
|
|
350
368
|
const _checkInputManually = input => {
|
|
369
|
+
const exclude = input.type && (input.pattern || hasCustomValidation(input)) ? ['typeMismatch'] : [];
|
|
351
370
|
let validityKey = _findValidityKey({
|
|
352
371
|
valueMissing: input.required && !input.value || false,
|
|
353
372
|
typeMismatch: _checkTypeMismatch(input),
|
|
@@ -356,7 +375,7 @@ const useFormHandlers = (getState, setState, validators = {}, optimized = false)
|
|
|
356
375
|
patternMismatch: input.pattern && _checkResult(input.pattern, input.value) || false,
|
|
357
376
|
rangeUnderflow: input.min && Number(input.value) < Number(input.min) || false,
|
|
358
377
|
rangeOverflow: input.max && Number(input.value) > Number(input.max) || false
|
|
359
|
-
});
|
|
378
|
+
}, exclude);
|
|
360
379
|
if (!validityKey && input.error) {
|
|
361
380
|
validityKey = 'customError';
|
|
362
381
|
}
|
|
@@ -369,6 +388,11 @@ const useFormHandlers = (getState, setState, validators = {}, optimized = false)
|
|
|
369
388
|
};
|
|
370
389
|
const _validateInput = (input, validityKey, setValidity) => {
|
|
371
390
|
const inputValidator = validators[input.validatorKey || input.formKey] || validators['*'];
|
|
391
|
+
{
|
|
392
|
+
if (validityKey && !(inputValidator !== null && inputValidator !== void 0 && inputValidator.hasConstraint(validityKey))) {
|
|
393
|
+
if (validityKey === 'typeMismatch') console.warn(`DEV ONLY - [Missing Validator] - the input '${input.formKey}' has described the constraint '${validityMap[validityKey]}' however, a correspond validator / custom validation / pattern validator are missing.\nadd '${handlersMap[validityMap[validityKey]]}' or 'withCustomValidation' or '${handlersMap[validityMap.patternMismatch]}' to the input validator.\nexample:\nconst validators: GValidators = {\n\temail: new GValidator().withPatternMismatchMessage('pattern mismatch'),\n\t...\n}\n\nor either remove the constraint '${validityMap[validityKey]}' from the input props`);else console.warn(`DEV ONLY - [Missing Validator] - the input '${input.formKey}' has described the constraint '${validityMap[validityKey]}' however, a correspond validator is missing.\nadd '${handlersMap[validityMap[validityKey]]}' to the input validator.\nexample:\nconst validators: GValidators = {\n\temail: new GValidator().withPatternMismatchMessage('pattern mismatch'),\n\t...\n}\n\nor either remove the constraint '${validityMap[validityKey]}' from the input props`);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
372
396
|
if (inputValidator) {
|
|
373
397
|
__validateInput(input, inputValidator, validityKey, setValidity);
|
|
374
398
|
}
|
|
@@ -427,6 +451,10 @@ const useFormHandlers = (getState, setState, validators = {}, optimized = false)
|
|
|
427
451
|
});
|
|
428
452
|
}
|
|
429
453
|
};
|
|
454
|
+
const hasCustomValidation = input => {
|
|
455
|
+
const validator = validators[input.validatorKey || input.formKey] || validators['*'];
|
|
456
|
+
return validator && (validator.asyncHandlers.length > 0 || validator.handlers.length > 0);
|
|
457
|
+
};
|
|
430
458
|
return {
|
|
431
459
|
_updateInputHandler,
|
|
432
460
|
_viHandler,
|
|
@@ -493,20 +521,6 @@ function createSelector(selectors, combiner) {
|
|
|
493
521
|
};
|
|
494
522
|
}
|
|
495
523
|
|
|
496
|
-
const selectFields = [state => state.fields];
|
|
497
|
-
const selectFirstInvalidField = createSelector(selectFields, fields => {
|
|
498
|
-
for (const f in fields) {
|
|
499
|
-
if (fields[f].error) {
|
|
500
|
-
return true;
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
return false;
|
|
504
|
-
});
|
|
505
|
-
const makeSelectFields = (keys = []) => createSelector(selectFields, fields => {
|
|
506
|
-
const selected = keys.map(key => fields[key]).filter(Boolean);
|
|
507
|
-
return selected.length ? selected : null;
|
|
508
|
-
});
|
|
509
|
-
|
|
510
524
|
const FormRenderer = React.forwardRef(({
|
|
511
525
|
stateRef,
|
|
512
526
|
onSubmit,
|
|
@@ -523,7 +537,7 @@ const FormRenderer = React.forwardRef(({
|
|
|
523
537
|
getState,
|
|
524
538
|
handlers
|
|
525
539
|
} = useFormStore();
|
|
526
|
-
const
|
|
540
|
+
const fields = useFormSelector(state => state.fields);
|
|
527
541
|
const refHandler = React.useCallback(element => {
|
|
528
542
|
if (ref) {
|
|
529
543
|
if (typeof ref === 'function') {
|
|
@@ -535,7 +549,7 @@ const FormRenderer = React.forwardRef(({
|
|
|
535
549
|
formRef.current = element;
|
|
536
550
|
}, [ref]);
|
|
537
551
|
const getFormState = React.useCallback(() => {
|
|
538
|
-
const
|
|
552
|
+
const isFormInvalid = _checkIfFormIsValid(fields);
|
|
539
553
|
const formState = {
|
|
540
554
|
...fields,
|
|
541
555
|
isValid: !isFormInvalid,
|
|
@@ -554,7 +568,7 @@ const FormRenderer = React.forwardRef(({
|
|
|
554
568
|
};
|
|
555
569
|
if (stateRef) stateRef.current = formState;
|
|
556
570
|
return formState;
|
|
557
|
-
}, [
|
|
571
|
+
}, [fields]);
|
|
558
572
|
const formComponent = React.useMemo(() => {
|
|
559
573
|
const state = getFormState();
|
|
560
574
|
const formChildren = typeof children === 'function' ? children(state) : children;
|
|
@@ -614,7 +628,7 @@ const FormRenderer = React.forwardRef(({
|
|
|
614
628
|
React.useEffect(() => {
|
|
615
629
|
const state = getFormState();
|
|
616
630
|
if (!hasSubmitter(formRef.current)) {
|
|
617
|
-
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`);
|
|
631
|
+
console.warn(`DEV ONLY - [No Submit Button] - you have created a form without a button type=submit, this will prevent the onSubmit event from being fired.\nif you have a button with onClick event that handle the submission of the form then ignore this warning\nbut don't forget to manually invoke the checkValidity() function to check if the form is valid before perfoming any action, for example:\nif (formState.checkValidity()) { \n\t//do somthing\n}\n`);
|
|
618
632
|
}
|
|
619
633
|
if (onInit) {
|
|
620
634
|
const changes = onInit(state);
|
|
@@ -655,6 +669,12 @@ const GForm = React.forwardRef(({
|
|
|
655
669
|
}, props), children));
|
|
656
670
|
});
|
|
657
671
|
|
|
672
|
+
const selectFields = [state => state.fields];
|
|
673
|
+
const makeSelectFields = (keys = []) => createSelector(selectFields, fields => {
|
|
674
|
+
const selected = keys.map(key => fields[key]).filter(Boolean);
|
|
675
|
+
return selected.length ? selected : null;
|
|
676
|
+
});
|
|
677
|
+
|
|
658
678
|
const _GInput = React.forwardRef(({
|
|
659
679
|
formKey,
|
|
660
680
|
element,
|
|
@@ -708,6 +728,18 @@ const _GInput = React.forwardRef(({
|
|
|
708
728
|
} : (e, unknown) => {
|
|
709
729
|
store.handlers._updateInputHandler(inputState, e, unknown);
|
|
710
730
|
};
|
|
731
|
+
if (!inputState.touched) {
|
|
732
|
+
_props.onFocus = rest.onFocus ? e => {
|
|
733
|
+
rest.onFocus(e);
|
|
734
|
+
inputState.dispatchChanges({
|
|
735
|
+
touched: true
|
|
736
|
+
});
|
|
737
|
+
} : () => {
|
|
738
|
+
inputState.dispatchChanges({
|
|
739
|
+
touched: true
|
|
740
|
+
});
|
|
741
|
+
};
|
|
742
|
+
}
|
|
711
743
|
}
|
|
712
744
|
if (element) {
|
|
713
745
|
return element(inputState, _props);
|