gform-react 2.7.0 → 2.7.5
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 +108 -31
- package/dist/cjs/gform-react.development.js +16 -32
- 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.development.js +1 -2
- package/dist/esm/GForm.development.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.development.js +3 -2
- package/dist/esm/GInput.development.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.development.js +0 -6
- package/dist/esm/GValidator.development.js.map +1 -1
- package/dist/esm/GValidator.production.js +1 -1
- package/dist/esm/GValidator.production.js.map +1 -1
- package/dist/esm/shared.development.js +8 -4
- package/dist/esm/shared.development.js.map +1 -1
- package/dist/esm/shared.production.js +1 -1
- package/dist/esm/shared.production.js.map +1 -1
- package/dist/esm/useFormSelector.development.js +1 -2
- package/dist/esm/useFormSelector.development.js.map +1 -1
- package/dist/esm/useFormSelector.production.js +1 -1
- package/dist/index.d.ts +1 -4
- package/native/dist/cjs/gform-react.development.js +78 -101
- package/native/dist/cjs/gform-react.development.js.map +1 -1
- package/native/dist/cjs/gform-react.production.js +1 -1
- package/native/dist/cjs/gform-react.production.js.map +1 -1
- package/native/dist/esm/RNGForm.development.js +11 -45
- package/native/dist/esm/RNGForm.development.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.development.js +12 -6
- package/native/dist/esm/RNGInput.development.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/shared.development.js +38 -19
- package/native/dist/esm/shared.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 -5
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -1,42 +1,119 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
https://gform-react
|
|
1
|
+
<div align="center">
|
|
2
|
+
<a href="https://gform-react.onrender.com" title="GForm React – A lightweight React form library built for performance, validation, and clean form logic">
|
|
3
|
+
<img src="https://gform-react.onrender.com/gform-logo.png" alt="gform-react logo" />
|
|
4
|
+
</a>
|
|
5
|
+
<h1>gform-react</h1>
|
|
6
|
+
<p>A lightweight React form library built for <b>performance</b>, <b>validation</b>, and clean <b>form logic</b></p>
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Lightweight**
|
|
12
|
+
- **Tree‑shakeable**
|
|
13
|
+
- **Minimal re-renders** — only updates fields that change
|
|
14
|
+
- **Native HTML Constraint Validations**
|
|
15
|
+
- **Custom Validations**
|
|
16
|
+
- **Custom Async Validations**
|
|
17
|
+
- **Supports Yup, Zod, and more**
|
|
18
|
+
- **Dynamic forms** — add/remove fields on the fly
|
|
19
|
+
- **Accessibility‑friendly**
|
|
20
|
+
Automatically sets `aria-required` and `aria-invalid`
|
|
21
|
+
- **React Native support**
|
|
22
|
+
|
|
23
|
+
<br/>
|
|
24
|
+
<div align="center">
|
|
25
|
+
<a href="https://bundlephobia.com/package/gform-react">
|
|
26
|
+
<img src="https://img.shields.io/bundlephobia/min/gform-react?label=minified%20size&color=darkergreen" alt="Minified size">
|
|
27
|
+
</a>
|
|
28
|
+
|
|
29
|
+
<a href="https://bundlephobia.com/package/gform-react">
|
|
30
|
+
<img src="https://img.shields.io/bundlephobia/minzip/gform-react?label=gzip%20size&color=darkergreen" alt="Gzip size">
|
|
31
|
+
</a>
|
|
32
|
+
|
|
33
|
+
<img src="https://img.shields.io/npm/dm/gform-react" alt="npm downloads">
|
|
34
|
+
|
|
35
|
+
<img src="https://img.shields.io/npm/dependency-version/gform-react/peer/react" alt="React peer dependency">
|
|
36
|
+
|
|
37
|
+
<img src="https://img.shields.io/npm/dependency-version/gform-react/peer/react-dom" alt="React DOM peer dependency">
|
|
38
|
+
|
|
39
|
+
<a href="https://unpkg.com/gform-react@latest/LICENSE.md">
|
|
40
|
+
<img src="https://img.shields.io/npm/l/gform-react" alt="MIT License">
|
|
41
|
+
</a>
|
|
42
|
+
</div>
|
|
43
|
+
<br/>
|
|
44
|
+
|
|
45
|
+
## QuickStart
|
|
46
|
+
```tsx
|
|
47
|
+
import {GForm, GInput, GValidator, type GValidators} from "gform-react";
|
|
26
48
|
|
|
27
|
-
|
|
28
|
-
|
|
49
|
+
interface SignInForm {
|
|
50
|
+
username: string;
|
|
51
|
+
password: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const baseValidator = new GValidator().withRequiredMessage('this field is required');
|
|
55
|
+
|
|
56
|
+
const validators: GValidators<SignInForm> = {
|
|
57
|
+
'*': baseValidator, // a default validator for all other fields in the form
|
|
58
|
+
|
|
59
|
+
password: new GValidator(baseValidator)
|
|
60
|
+
.withMinLengthMessage((input) => `${input.formKey} must contain atleast ${input.minLength} chars`),
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
const App: FC = () => {
|
|
64
|
+
return (
|
|
65
|
+
<GForm<SignInForm> className='some-class'
|
|
66
|
+
validators={validators}
|
|
67
|
+
onSubmit={(formState, e) => { //can be used with native `action` or with Next.js `server actions`
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
console.log(formState);
|
|
70
|
+
}}>
|
|
71
|
+
<GInput formKey='username'
|
|
72
|
+
required
|
|
73
|
+
element={(input, props) => <div>
|
|
74
|
+
<input {...props} placeholder='username'/>
|
|
75
|
+
{input.error && <small className="p-error">{input.errorText}</small>}
|
|
76
|
+
</div>}
|
|
77
|
+
/>
|
|
78
|
+
<GInput formKey='password'
|
|
79
|
+
type='password'
|
|
80
|
+
required
|
|
81
|
+
minLength={5}
|
|
82
|
+
element={(input, props) => <div>
|
|
83
|
+
<input {...props} placeholder='password'/>
|
|
84
|
+
{input.error && <small className="p-error">{input.errorText}</small>}
|
|
85
|
+
</div>}
|
|
86
|
+
/>
|
|
87
|
+
<button>Submit</button>
|
|
88
|
+
</GForm>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Documentation
|
|
94
|
+
|
|
95
|
+
Full documentation, examples, and API reference:
|
|
96
|
+
|
|
97
|
+
https://gform-react.onrender.com
|
|
29
98
|
|
|
30
99
|
## Installation
|
|
100
|
+
|
|
31
101
|
npm:
|
|
32
|
-
|
|
102
|
+
|
|
103
|
+
```sh
|
|
33
104
|
npm install gform-react
|
|
34
105
|
```
|
|
35
106
|
|
|
36
107
|
yarn:
|
|
37
|
-
|
|
108
|
+
|
|
109
|
+
```sh
|
|
38
110
|
yarn add gform-react
|
|
39
111
|
```
|
|
40
112
|
|
|
41
|
-
|
|
42
|
-
react >=16.8.0, react-dom >=16.8.0 are peer dependencies
|
|
113
|
+
## Peer dependencies
|
|
114
|
+
react >=16.8.0, react-dom >=16.8.0 are peer dependencies
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
MIT © Tal
|
|
119
|
+
https://www.npmjs.com/package/gform-react
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var _extends = require('@babel/runtime/helpers/extends');
|
|
4
4
|
var React = require('react');
|
|
5
|
-
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
|
|
6
5
|
|
|
7
6
|
const isObject = o => o && typeof o === 'object' && !Array.isArray(o);
|
|
8
7
|
const defaultFieldProps = {
|
|
@@ -108,8 +107,7 @@ const _findValidityKey = (validity, exclude = []) => {
|
|
|
108
107
|
}
|
|
109
108
|
};
|
|
110
109
|
const _checkTypeMismatch = input => {
|
|
111
|
-
|
|
112
|
-
const value = (_input$value = input.value) === null || _input$value === void 0 ? void 0 : _input$value.toString().trim();
|
|
110
|
+
const value = input.value?.toString().trim();
|
|
113
111
|
if (!value) return false;
|
|
114
112
|
switch (input.type) {
|
|
115
113
|
case 'email':
|
|
@@ -150,19 +148,15 @@ const _toRawData = (fields, options = {}) => {
|
|
|
150
148
|
transform
|
|
151
149
|
} = options;
|
|
152
150
|
if (include) {
|
|
153
|
-
include.forEach(key =>
|
|
154
|
-
var _fields$key;
|
|
155
|
-
return data[key] = (_fields$key = fields[key]) === null || _fields$key === void 0 ? void 0 : _fields$key.value;
|
|
156
|
-
});
|
|
151
|
+
include.forEach(key => data[key] = fields[key]?.value);
|
|
157
152
|
} else for (const f in fields) {
|
|
158
153
|
data[f] = fields[f].value;
|
|
159
154
|
}
|
|
160
|
-
exclude
|
|
155
|
+
exclude?.forEach(key => delete data[key]);
|
|
161
156
|
if (transform) {
|
|
162
157
|
for (const key in transform) {
|
|
163
|
-
var _fields$key2;
|
|
164
158
|
const set = transform[key];
|
|
165
|
-
data[key] = set(
|
|
159
|
+
data[key] = set(fields[key]?.value || fields[key]);
|
|
166
160
|
}
|
|
167
161
|
}
|
|
168
162
|
return data;
|
|
@@ -181,19 +175,15 @@ function _toURLSearchParams(options) {
|
|
|
181
175
|
} = options;
|
|
182
176
|
if (include) {
|
|
183
177
|
data = {};
|
|
184
|
-
include.forEach(key =>
|
|
185
|
-
var _this$key;
|
|
186
|
-
return data[key] = (_this$key = this[key]) === null || _this$key === void 0 ? void 0 : _this$key.value;
|
|
187
|
-
});
|
|
178
|
+
include.forEach(key => data[key] = this[key]?.value);
|
|
188
179
|
} else {
|
|
189
180
|
data = this.toRawData();
|
|
190
|
-
exclude
|
|
181
|
+
exclude?.forEach(key => delete data[key]);
|
|
191
182
|
}
|
|
192
183
|
if (transform) {
|
|
193
184
|
for (const key in transform) {
|
|
194
|
-
var _this$key2;
|
|
195
185
|
const set = transform[key];
|
|
196
|
-
data[key] = set(
|
|
186
|
+
data[key] = set(this[key]?.value);
|
|
197
187
|
}
|
|
198
188
|
}
|
|
199
189
|
} else data = this.toRawData();
|
|
@@ -201,8 +191,7 @@ function _toURLSearchParams(options) {
|
|
|
201
191
|
}
|
|
202
192
|
function __debounce(timeout, id) {
|
|
203
193
|
return new Promise(resolve => {
|
|
204
|
-
|
|
205
|
-
if ((_this$id = this[id]) !== null && _this$id !== void 0 && _this$id.timerId) clearTimeout(this[id].timerId);
|
|
194
|
+
if (this[id]?.timerId) clearTimeout(this[id].timerId);
|
|
206
195
|
const timerId = setTimeout(() => resolve(), timeout);
|
|
207
196
|
if (this[id]) {
|
|
208
197
|
this[id].timerId = timerId;
|
|
@@ -213,11 +202,11 @@ function __debounce(timeout, id) {
|
|
|
213
202
|
}
|
|
214
203
|
const _debounce = __debounce.bind({});
|
|
215
204
|
const _extractValue = (e, unknown) => {
|
|
216
|
-
if (e
|
|
205
|
+
if (e?.target) {
|
|
217
206
|
if (Object.hasOwn(typeValueDict, e.target.type)) return e.target[typeValueDict[e.target.type]];
|
|
218
207
|
return e.target.value;
|
|
219
208
|
}
|
|
220
|
-
return
|
|
209
|
+
return e?.value || (isObject(unknown) ? unknown.value : unknown);
|
|
221
210
|
};
|
|
222
211
|
const _checkResult = (handlerResult, value) => typeof handlerResult === 'boolean' ? handlerResult : typeof value === 'string' ? typeof handlerResult === 'string' ? !new RegExp(handlerResult).test(value) : !handlerResult.test(value) : false;
|
|
223
212
|
const _merge = (target = {}, ...nodes) => {
|
|
@@ -303,26 +292,21 @@ class GValidator {
|
|
|
303
292
|
return this._asyncHandlers;
|
|
304
293
|
}
|
|
305
294
|
constructor(baseValidator) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
_defineProperty(this, "track", void 0);
|
|
310
|
-
const baseHandlers = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.handlers) || [];
|
|
311
|
-
const baseConstraintHandlers = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.constraintHandlers) || [];
|
|
312
|
-
const baseHandlersAsync = (baseValidator === null || baseValidator === void 0 ? void 0 : baseValidator.asyncHandlers) || [];
|
|
295
|
+
const baseHandlers = baseValidator?.handlers || [];
|
|
296
|
+
const baseConstraintHandlers = baseValidator?.constraintHandlers || [];
|
|
297
|
+
const baseHandlersAsync = baseValidator?.asyncHandlers || [];
|
|
313
298
|
this._handlers = [].concat(baseHandlers);
|
|
314
299
|
this._constraintHandlers = [].concat(baseConstraintHandlers);
|
|
315
300
|
this._asyncHandlers = [].concat(baseHandlersAsync);
|
|
316
301
|
{
|
|
317
302
|
this.track = [];
|
|
318
|
-
if (baseValidator
|
|
303
|
+
if (baseValidator?.track) {
|
|
319
304
|
this.track = this.track.concat(baseValidator.track);
|
|
320
305
|
}
|
|
321
306
|
}
|
|
322
307
|
}
|
|
323
308
|
hasConstraint(constraint) {
|
|
324
|
-
|
|
325
|
-
return ((_this$track = this.track) === null || _this$track === void 0 ? void 0 : _this$track.includes(constraint)) || false;
|
|
309
|
+
return this.track?.includes(constraint) || false;
|
|
326
310
|
}
|
|
327
311
|
withRequiredMessage(message) {
|
|
328
312
|
return this.__addConstraintValidationHandler('valueMissing', message);
|
|
@@ -432,7 +416,7 @@ const useFormHandlers = (getState, setState, validators = {}, optimized = false)
|
|
|
432
416
|
const _validateInput = (input, validityKey, setValidity) => {
|
|
433
417
|
const inputValidator = validators[input.validatorKey || input.formKey] || validators['*'];
|
|
434
418
|
{
|
|
435
|
-
if (validityKey && !
|
|
419
|
+
if (validityKey && !inputValidator?.hasConstraint(validityKey)) {
|
|
436
420
|
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 is 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`);
|
|
437
421
|
}
|
|
438
422
|
}
|