feature-form 0.0.4 → 0.0.7
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 +82 -6
- package/dist/cjs/create-form.js +1 -1
- package/dist/cjs/form-field/create-form-field.js +1 -1
- package/dist/cjs/form-field/create-status.js +1 -1
- package/dist/cjs/form-field/validator/create-validator.js +1 -1
- package/dist/cjs/form-field/validator/valibot.js +1 -1
- package/dist/cjs/form-field/validator/yup.js +1 -1
- package/dist/cjs/form-field/validator/zod.js +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/types/form-field.js +1 -0
- package/dist/esm/create-form.js +1 -1
- package/dist/esm/form-field/create-form-field.js +1 -1
- package/dist/esm/form-field/create-status.js +1 -1
- package/dist/esm/form-field/validator/create-validator.js +1 -1
- package/dist/esm/form-field/validator/valibot.js +1 -1
- package/dist/esm/form-field/validator/yup.js +1 -1
- package/dist/esm/form-field/validator/zod.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/types/form-field.js +1 -0
- package/dist/types/create-form.d.ts +13 -6
- package/dist/types/create-form.d.ts.map +1 -1
- package/dist/types/form-field/create-form-field.d.ts.map +1 -1
- package/dist/types/form-field/create-status.d.ts.map +1 -1
- package/dist/types/form-field/validator/create-validator.d.ts.map +1 -1
- package/dist/types/form-field/validator/yup.d.ts +2 -1
- package/dist/types/form-field/validator/yup.d.ts.map +1 -1
- package/dist/types/form-field/validator/zod.d.ts +2 -1
- package/dist/types/form-field/validator/zod.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types/form-field.d.ts +20 -8
- package/dist/types/types/form-field.d.ts.map +1 -1
- package/dist/types/types/form.d.ts +26 -9
- package/dist/types/types/form.d.ts.map +1 -1
- package/package.json +12 -7
package/README.md
CHANGED
|
@@ -1,11 +1,87 @@
|
|
|
1
|
-
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/inbeta-group/monorepo/develop/packages/feature-form/.github/banner.svg" alt="feature-form banner">
|
|
3
|
+
</h1>
|
|
2
4
|
|
|
3
|
-
|
|
4
|
-
https://github.com/
|
|
5
|
+
<p align="left">
|
|
6
|
+
<a href="https://github.com/inbeta-group/monorepo/blob/develop/LICENSE">
|
|
7
|
+
<img src="https://img.shields.io/github/license/inbeta-group/monorepo.svg?label=license&style=flat&colorA=293140&colorB=F0E81A" alt="GitHub License"/>
|
|
8
|
+
</a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/feature-form">
|
|
10
|
+
<img src="https://img.shields.io/bundlephobia/minzip/feature-form.svg?label=minzipped%20size&style=flat&colorA=293140&colorB=F0E81A" alt="NPM bundle minzipped size"/>
|
|
11
|
+
</a>
|
|
12
|
+
<a href="https://www.npmjs.com/package/feature-form">
|
|
13
|
+
<img src="https://img.shields.io/npm/dt/feature-form.svg?label=downloads&style=flat&colorA=293140&colorB=F0E81A" alt="NPM total downloads"/>
|
|
14
|
+
</a>
|
|
15
|
+
<a href="https://dyn.art/s/discord/?source=inbeta-group-readme">
|
|
16
|
+
<img src="https://img.shields.io/discord/795291052897992724.svg?label=&logo=discord&logoColor=000000&color=293140&labelColor=F0E81A" alt="Join Discord"/>
|
|
17
|
+
</a>
|
|
18
|
+
</p>
|
|
5
19
|
|
|
20
|
+
> Status: Experimental
|
|
6
21
|
|
|
7
|
-
|
|
22
|
+
`feature-form` is a straightforward, typesafe, and feature-based form library.
|
|
8
23
|
|
|
24
|
+
- **Lightweight & Tree Shakable**: Function-based and modular design
|
|
25
|
+
- **Fast**: Optimized for speed and efficiency, ensuring smooth user experience
|
|
26
|
+
- **Modular & Extendable**: Easily extendable with features
|
|
27
|
+
- **Typesafe**: Build with TypeScript for strong type safety
|
|
28
|
+
- **Standalone**: Zero external dependencies, ensuring ease of use in various environments
|
|
9
29
|
|
|
10
|
-
|
|
11
|
-
|
|
30
|
+
### 🏖️ Code Sandbox
|
|
31
|
+
- [ReactJs Basic](https://codesandbox.io/p/sandbox/basic-c4gd3t)
|
|
32
|
+
|
|
33
|
+
### Motivation
|
|
34
|
+
|
|
35
|
+
Provide a typesafe, straightforward, and lightweight form library designed to be modular and extendable with features.
|
|
36
|
+
|
|
37
|
+
### Alternatives
|
|
38
|
+
- [react-hook-form](https://github.com/react-hook-form/react-hook-form)
|
|
39
|
+
|
|
40
|
+
## 📖 Usage
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { createForm, zodValidator } from 'feature-form';
|
|
44
|
+
import { useForm } from 'feature-react/form';
|
|
45
|
+
import * as z from 'zod';
|
|
46
|
+
|
|
47
|
+
const $form = createForm({
|
|
48
|
+
fields: {
|
|
49
|
+
firstName: {
|
|
50
|
+
validator: zodValidator(z.string().min(2).max(10)),
|
|
51
|
+
defaultValue: ''
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
onValidSubmit: (data) => console.log('ValidSubmit', data),
|
|
55
|
+
onInvalidSubmit: (errors) => console.log('InvalidSubmit', errors)
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const Component: React.FC = () => {
|
|
59
|
+
const { handleSubmit, register, status } = useForm($form);
|
|
60
|
+
|
|
61
|
+
return (
|
|
62
|
+
<form onSubmit={handleSubmit()}>
|
|
63
|
+
<input {...register('firstName')} />
|
|
64
|
+
<ErrorMessage status={status('firstName')} />
|
|
65
|
+
<button type="submit">Submit</button>
|
|
66
|
+
</form>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Validators
|
|
72
|
+
|
|
73
|
+
Supports various validators such as [Zod](https://github.com/colinhacks/zod), [Yup](https://github.com/jquense/yup), [Valibot](https://github.com/fabian-hiller/valibot) and more.
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
import { zodValidator, valibotValidator } from 'feature-form';
|
|
77
|
+
import * as z from 'zod';
|
|
78
|
+
import * as v from 'valibot';
|
|
79
|
+
|
|
80
|
+
const zodNameValidator = zodValidator(
|
|
81
|
+
z.string().min(2).max(10).regex(/^([^0-9]*)$/)
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const valibotNameValidator = valibotValidator(
|
|
85
|
+
v.pipe(v.string(), v.minLength(2), v.maxLength(10), v.regex(/^([^0-9]*)$/))
|
|
86
|
+
);
|
|
87
|
+
```
|
package/dist/cjs/create-form.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var p=require("@ibg/utils"),_=require("./form-field/create-form-field.js");require("feature-state"),require("valibot"),require("yup"),require("zod");var u=require("./types/form-field.js"),j=Object.defineProperty,O=Object.getOwnPropertySymbols,w=Object.prototype.hasOwnProperty,E=Object.prototype.propertyIsEnumerable,F=(s,a,i)=>a in s?j(s,a,{enumerable:!0,configurable:!0,writable:!0,value:i}):s[a]=i,P=(s,a)=>{for(var i in a||(a={}))w.call(a,i)&&F(s,i,a[i]);if(O)for(var i of O(a))E.call(a,i)&&F(s,i,a[i]);return s},v=(s,a,i)=>new Promise((V,g)=>{var S=o=>{try{c(i.next(o))}catch(d){g(d)}},y=o=>{try{c(i.throw(o))}catch(d){g(d)}},c=o=>o.done?V(o.value):Promise.resolve(o.value).then(S,y);c((i=i.apply(s,a)).next())});function k(s){const{fields:a,collectErrorMode:i="firstError",disabled:V=!1,validateMode:g=p.bitwiseFlag(u.FormFieldValidateMode.OnSubmit),reValidateMode:S=p.bitwiseFlag(u.FormFieldReValidateMode.OnBlur),onValidSubmit:y,onInvalidSubmit:c,notifyOnStatusChange:o=!0}=s,d={_:null,_features:["base"],_config:{collectErrorMode:i,disabled:V},_validSubmitCallbacks:y!=null?[y]:[],_invalidSubmitCallbacks:c!=null?[c]:[],fields:Object.fromEntries(Object.entries(a).map(([e,t])=>{var l,b,f,h;return[e,_.createFormField(t.defaultValue,{key:e,validator:t.validator,collectErrorMode:(l=t.collectErrorMode)!=null?l:i,validateMode:(b=t.validateMode)!=null?b:g,reValidateMode:(f=t.reValidateMode)!=null?f:S,editable:(h=t.editable)!=null?h:!0,notifyOnStatusChange:o})]})),isValid:!1,isValidating:!1,isSubmitted:!1,isSubmitting:!1,_revalidate(e=!1){return v(this,null,function*(){const t=Object.values(this.fields);return e||(this.isValidating=!0,yield Promise.all(t.map(l=>l.validate())),this.isValidating=!1),this.isValid=t.every(l=>l.isValid()),this.isValid})},submit(){return v(this,arguments,function*(e={}){const{additionalData:t,assignToInitial:l=!1,onInvalidSubmit:b,onValidSubmit:f}=e;this.isSubmitting=!0;const h=[];for(const r of Object.values(this.fields))(r.isSubmitted&&r._config.reValidateMode.has(u.FormFieldReValidateMode.OnSubmit)||!r.isSubmitted&&r._config.validateMode.has(u.FormFieldValidateMode.OnSubmit))&&h.push(r.validate()),this.isSubmitting=!0;yield Promise.all(h);const m=this.getData();if(m!=null){const r=this._validSubmitCallbacks.map(n=>n(m,t));typeof f=="function"&&r.push(f(m,t)),yield Promise.all(r)}else{const r=this.getErrors(),n=this._invalidSubmitCallbacks.map(M=>M(r,t));typeof b=="function"&&n.push(b(r,t)),yield Promise.all(n)}for(const[r,n]of Object.entries(this.fields))m!=null&&Object.prototype.hasOwnProperty.call(m,r)&&l&&(n._intialValue=p.deepCopy(m[r])),n.isSubmitted=!0,n.isSubmitting=!1;return this.isSubmitted=!0,this.isSubmitting=!1,this.isValid})},validate(){return v(this,null,function*(){return this._revalidate(!1)})},getField(e){return this.fields[e]},getData(){if(!this.isValid)return null;const e={};for(const[t,l]of Object.entries(this.fields))e[t]=l.get();return e},getErrors(){const e={};for(const[t,l]of Object.entries(this.fields))switch(l.status._value.type){case"INVALID":e[t]=l.status._value.errors;break;case"UNVALIDATED":e[t]=[{code:"unvalidated",message:`${t.toString()} was not yet validated!`,path:t}];break}return e},reset(){for(const e of Object.values(this.fields))e.reset();this.isSubmitted=!1}};for(const e of Object.values(d.fields))e.listen(t=>v(this,[t],function*({source:l}){l==="set"&&(e.isSubmitted&&e._config.reValidateMode.has(u.FormFieldReValidateMode.OnChange)||!e.isSubmitted&&e._config.validateMode.has(u.FormFieldValidateMode.OnChange)||e._config.validateMode.has(u.FormFieldValidateMode.OnTouched)&&e.isTouched)&&(yield e.validate())}),{key:"form"}),e.status.listen(()=>v(this,null,function*(){yield d._revalidate(!0)}),{key:"form"});return d}function C(s,a){return P({validator:s},a)}exports.createForm=k,exports.fromValidator=C;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var F=require("feature-state"),h=require("@ibg/utils"),r=require("../types/form-field.js"),f=require("./create-status.js"),V=(d,l,i)=>new Promise((o,s)=>{var u=e=>{try{a(i.next(e))}catch(t){s(t)}},n=e=>{try{a(i.throw(e))}catch(t){s(t)}},a=e=>e.done?o(e.value):Promise.resolve(e.value).then(u,n);a((i=i.apply(d,l)).next())});function M(d,l){const{key:i,validator:o,editable:s=!0,reValidateMode:u=h.bitwiseFlag(r.FormFieldReValidateMode.OnBlur),validateMode:n=h.bitwiseFlag(r.FormFieldValidateMode.OnSubmit),collectErrorMode:a="firstError",notifyOnStatusChange:e=!0}=l,t=F.createState(d),c=f.createStatus({type:"UNVALIDATED"});e&&c.listen(()=>{t._notify({additionalData:{source:"status"}})},{key:"form-field"});const v={_config:{editable:s,validateMode:n,reValidateMode:u,collectErrorMode:a},_intialValue:h.deepCopy(t._value),key:i,isTouched:!1,isSubmitted:!1,isSubmitting:!1,validator:o,status:c,validate(){return V(this,null,function*(){return this.validator.validate(this)})},isValid(){return this.status.get().type==="VALID"},blur(){(this.isSubmitted&&this._config.reValidateMode.has(r.FormFieldReValidateMode.OnBlur)||!this.isSubmitted&&(this._config.validateMode.has(r.FormFieldValidateMode.OnBlur)||this._config.validateMode.has(r.FormFieldValidateMode.OnTouched)&&!this.isTouched))&&this.validate(),this.isTouched=!0},reset(){this.set(this._intialValue),this.isTouched=!1,this.isSubmitted=!1,this.isSubmitting=!1,this.status.set({type:"UNVALIDATED"})}},m=Object.assign(t,v);return m._features.push("form-field"),m}exports.createFormField=M;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var u=require("feature-state");function i(s){const a=u.createState(s),t=Object.assign(a,{_nextValue:void 0,registerNextError(e){var r;((r=this._nextValue)==null?void 0:r.type)==="INVALID"?this._nextValue.errors.push(e):this._nextValue={type:"INVALID",errors:[e]}}});return t._features.push("form-field-status"),t}exports.createStatus=i;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var d=require("@ibg/utils"),v=(
|
|
1
|
+
"use strict";var d=require("@ibg/utils"),v=(a,t,i)=>new Promise((n,l)=>{var o=e=>{try{s(i.next(e))}catch(r){l(r)}},h=e=>{try{s(i.throw(e))}catch(r){l(r)}},s=e=>e.done?n(e.value):Promise.resolve(e.value).then(o,h);s((i=i.apply(a,t)).next())});function u(a){return{_validationChain:a,isValidating:!1,push(t){this._validationChain.push(t)},append(t){return this._validationChain.push(...t._validationChain),this},validate(t){return v(this,null,function*(){var i;this.isValidating=!0;for(const n of this._validationChain)if(yield n.validate(t),t._config.collectErrorMode==="firstError"&&((i=t.status._nextValue)==null?void 0:i.type)==="INVALID")break;return t.status._nextValue==null?t.status.set({type:"VALID"}):t.status.set(t.status._nextValue),t.status._nextValue=void 0,this.isValidating=!1,t.status.get().type==="VALID"})},clone(){return u(d.deepCopy(this._validationChain))}}}exports.createValidator=u;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var n=require("valibot"),v=require("./create-validator.js"),d=(i,a,e)=>new Promise((o,r)=>{var c=t=>{try{s(e.next(t))}catch(l){r(l)}},u=t=>{try{s(e.throw(t))}catch(l){r(l)}},s=t=>t.done?o(t.value):Promise.resolve(t.value).then(c,u);s((e=e.apply(i,a)).next())});function f(i){return v.createValidator([{key:"valibot",validate:a=>d(this,null,function*(){var e;const o=yield n.safeParseAsync(i,a.get(),{abortPipeEarly:a._config.collectErrorMode==="firstError"});if(o.issues!=null)for(const r of o.issues)a.status.
|
|
1
|
+
"use strict";var n=require("valibot"),v=require("./create-validator.js"),d=(i,a,e)=>new Promise((o,r)=>{var c=t=>{try{s(e.next(t))}catch(l){r(l)}},u=t=>{try{s(e.throw(t))}catch(l){r(l)}},s=t=>t.done?o(t.value):Promise.resolve(t.value).then(c,u);s((e=e.apply(i,a)).next())});function f(i){return v.createValidator([{key:"valibot",validate:a=>d(this,null,function*(){var e;const o=yield n.safeParseAsync(i,a.get(),{abortPipeEarly:a._config.collectErrorMode==="firstError"});if(o.issues!=null)for(const r of o.issues)a.status.registerNextError({code:r.type,message:r.message,path:(e=n.getDotPath(r))!=null?e:void 0})})}])}exports.valibotValidator=f;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var p=require("yup"),y=require("./create-validator.js"),d=(e,t,a)=>new Promise((i,r)=>{var o=n=>{try{s(a.next(n))}catch(l){r(l)}},u=n=>{try{s(a.throw(n))}catch(l){r(l)}},s=n=>n.done?i(n.value):Promise.resolve(n.value).then(o,u);s((a=a.apply(e,t)).next())});function h(e){return y.createValidator([{key:"yup",validate:t=>d(this,null,function*(){var a,i;try{yield e.validate(t.get(),{abortEarly:t._config.collectErrorMode==="firstError"})}catch(r){if(c(r)){r.inner.length===0&&t.status.registerNextError({code:(a=r.type)!=null?a:"unknown",message:r.message.replace("this",t.key),path:r.path});for(const o of r.inner)t.status.registerNextError({code:(i=o.type)!=null?i:"unknown",message:o.message.replace("this",t.key),path:o.path})}else console.warn("Parse error is not an instance of a ValidationError. Ensure Yup is correctly installed.",r)}})}])}function c(e){return e instanceof p.ValidationError||e instanceof Error&&"inner"in e&&Array.isArray(e.inner)}exports.isYupError=c,exports.yupValidator=h;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var s=require("zod"),i=require("./create-validator.js");function n(r){return i.createValidator([{key:"zod",validate:a=>{try{r.parse(a.get())}catch(e){if(t(e))for(const o of e.errors)a.status.registerNextError({code:o.code,message:o.message,path:o.path.join(".")});else console.warn("Parse error is not an instance of a ZodError. Ensure Zod is correctly installed.",e)}}}])}function t(r){return r instanceof s.ZodError||r instanceof Error&&"errors"in r&&Array.isArray(r.errors)}exports.isZodError=t,exports.zodValidator=n;
|
package/dist/cjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var r=require("./create-form.js"),
|
|
1
|
+
"use strict";var r=require("@ibg/utils"),e=require("./create-form.js"),o=require("./form-field/create-form-field.js"),d=require("./form-field/create-status.js"),l=require("./form-field/is-form-field.js"),u=require("./form-field/validator/create-validator.js"),F=require("./form-field/validator/valibot.js"),a=require("./form-field/validator/yup.js"),i=require("./form-field/validator/zod.js"),t=require("./types/form-field.js");Object.defineProperty(exports,"BitwiseFlag",{enumerable:!0,get:function(){return r.BitwiseFlag}}),Object.defineProperty(exports,"bitwiseFlag",{enumerable:!0,get:function(){return r.bitwiseFlag}}),exports.createForm=e.createForm,exports.fromValidator=e.fromValidator,exports.createFormField=o.createFormField,exports.createStatus=d.createStatus,exports.isFormField=l.isFormField,exports.createValidator=u.createValidator,exports.valibotValidator=F.valibotValidator,exports.isYupError=a.isYupError,exports.yupValidator=a.yupValidator,exports.isZodError=i.isZodError,exports.zodValidator=i.zodValidator,exports.FormFieldReValidateMode=t.FormFieldReValidateMode,exports.FormFieldValidateMode=t.FormFieldValidateMode;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var d=(n=>(n[n.OnBlur=1]="OnBlur",n[n.OnChange=2]="OnChange",n[n.OnSubmit=4]="OnSubmit",n[n.OnTouched=8]="OnTouched",n))(d||{}),O=(n=>(n[n.OnBlur=1]="OnBlur",n[n.OnChange=2]="OnChange",n[n.OnSubmit=4]="OnSubmit",n))(O||{});exports.FormFieldReValidateMode=O,exports.FormFieldValidateMode=d;
|
package/dist/esm/create-form.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createFormField as
|
|
1
|
+
import{bitwiseFlag as V,deepCopy as E}from"@ibg/utils";import{createFormField as F}from"./form-field/create-form-field.js";import"feature-state";import"valibot";import"yup";import"zod";import{FormFieldValidateMode as g,FormFieldReValidateMode as O}from"./types/form-field.js";var P=Object.defineProperty,_=Object.getOwnPropertySymbols,k=Object.prototype.hasOwnProperty,w=Object.prototype.propertyIsEnumerable,M=(r,a,i)=>a in r?P(r,a,{enumerable:!0,configurable:!0,writable:!0,value:i}):r[a]=i,C=(r,a)=>{for(var i in a||(a={}))k.call(a,i)&&M(r,i,a[i]);if(_)for(var i of _(a))w.call(a,i)&&M(r,i,a[i]);return r},h=(r,a,i)=>new Promise((y,v)=>{var S=o=>{try{u(i.next(o))}catch(d){v(d)}},p=o=>{try{u(i.throw(o))}catch(d){v(d)}},u=o=>o.done?y(o.value):Promise.resolve(o.value).then(S,p);u((i=i.apply(r,a)).next())});function D(r){const{fields:a,collectErrorMode:i="firstError",disabled:y=!1,validateMode:v=V(g.OnSubmit),reValidateMode:S=V(O.OnBlur),onValidSubmit:p,onInvalidSubmit:u,notifyOnStatusChange:o=!0}=r,d={_:null,_features:["base"],_config:{collectErrorMode:i,disabled:y},_validSubmitCallbacks:p!=null?[p]:[],_invalidSubmitCallbacks:u!=null?[u]:[],fields:Object.fromEntries(Object.entries(a).map(([t,e])=>{var l,m,f,b;return[t,F(e.defaultValue,{key:t,validator:e.validator,collectErrorMode:(l=e.collectErrorMode)!=null?l:i,validateMode:(m=e.validateMode)!=null?m:v,reValidateMode:(f=e.reValidateMode)!=null?f:S,editable:(b=e.editable)!=null?b:!0,notifyOnStatusChange:o})]})),isValid:!1,isValidating:!1,isSubmitted:!1,isSubmitting:!1,_revalidate(t=!1){return h(this,null,function*(){const e=Object.values(this.fields);return t||(this.isValidating=!0,yield Promise.all(e.map(l=>l.validate())),this.isValidating=!1),this.isValid=e.every(l=>l.isValid()),this.isValid})},submit(){return h(this,arguments,function*(t={}){const{additionalData:e,assignToInitial:l=!1,onInvalidSubmit:m,onValidSubmit:f}=t;this.isSubmitting=!0;const b=[];for(const s of Object.values(this.fields))(s.isSubmitted&&s._config.reValidateMode.has(O.OnSubmit)||!s.isSubmitted&&s._config.validateMode.has(g.OnSubmit))&&b.push(s.validate()),this.isSubmitting=!0;yield Promise.all(b);const c=this.getData();if(c!=null){const s=this._validSubmitCallbacks.map(n=>n(c,e));typeof f=="function"&&s.push(f(c,e)),yield Promise.all(s)}else{const s=this.getErrors(),n=this._invalidSubmitCallbacks.map(j=>j(s,e));typeof m=="function"&&n.push(m(s,e)),yield Promise.all(n)}for(const[s,n]of Object.entries(this.fields))c!=null&&Object.prototype.hasOwnProperty.call(c,s)&&l&&(n._intialValue=E(c[s])),n.isSubmitted=!0,n.isSubmitting=!1;return this.isSubmitted=!0,this.isSubmitting=!1,this.isValid})},validate(){return h(this,null,function*(){return this._revalidate(!1)})},getField(t){return this.fields[t]},getData(){if(!this.isValid)return null;const t={};for(const[e,l]of Object.entries(this.fields))t[e]=l.get();return t},getErrors(){const t={};for(const[e,l]of Object.entries(this.fields))switch(l.status._value.type){case"INVALID":t[e]=l.status._value.errors;break;case"UNVALIDATED":t[e]=[{code:"unvalidated",message:`${e.toString()} was not yet validated!`,path:e}];break}return t},reset(){for(const t of Object.values(this.fields))t.reset();this.isSubmitted=!1}};for(const t of Object.values(d.fields))t.listen(e=>h(this,[e],function*({source:l}){l==="set"&&(t.isSubmitted&&t._config.reValidateMode.has(O.OnChange)||!t.isSubmitted&&t._config.validateMode.has(g.OnChange)||t._config.validateMode.has(g.OnTouched)&&t.isTouched)&&(yield t.validate())}),{key:"form"}),t.status.listen(()=>h(this,null,function*(){yield d._revalidate(!0)}),{key:"form"});return d}function I(r,a){return C({validator:r},a)}export{D as createForm,I as fromValidator};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createState as
|
|
1
|
+
import{createState as p}from"feature-state";import{bitwiseFlag as m,deepCopy as b}from"@ibg/utils";import{FormFieldReValidateMode as f,FormFieldValidateMode as n}from"../types/form-field.js";import{createStatus as y}from"./create-status.js";var V=(o,r,i)=>new Promise((d,s)=>{var l=t=>{try{a(i.next(t))}catch(e){s(e)}},u=t=>{try{a(i.throw(t))}catch(e){s(e)}},a=t=>t.done?d(t.value):Promise.resolve(t.value).then(l,u);a((i=i.apply(o,r)).next())});function M(o,r){const{key:i,validator:d,editable:s=!0,reValidateMode:l=m(f.OnBlur),validateMode:u=m(n.OnSubmit),collectErrorMode:a="firstError",notifyOnStatusChange:t=!0}=r,e=p(o),h=y({type:"UNVALIDATED"});t&&h.listen(()=>{e._notify({additionalData:{source:"status"}})},{key:"form-field"});const v={_config:{editable:s,validateMode:u,reValidateMode:l,collectErrorMode:a},_intialValue:b(e._value),key:i,isTouched:!1,isSubmitted:!1,isSubmitting:!1,validator:d,status:h,validate(){return V(this,null,function*(){return this.validator.validate(this)})},isValid(){return this.status.get().type==="VALID"},blur(){(this.isSubmitted&&this._config.reValidateMode.has(f.OnBlur)||!this.isSubmitted&&(this._config.validateMode.has(n.OnBlur)||this._config.validateMode.has(n.OnTouched)&&!this.isTouched))&&this.validate(),this.isTouched=!0},reset(){this.set(this._intialValue),this.isTouched=!1,this.isSubmitted=!1,this.isSubmitting=!1,this.status.set({type:"UNVALIDATED"})}},c=Object.assign(e,v);return c._features.push("form-field"),c}export{M as createFormField};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createState as
|
|
1
|
+
import{createState as u}from"feature-state";function o(s){const a=u(s),t=Object.assign(a,{_nextValue:void 0,registerNextError(e){var r;((r=this._nextValue)==null?void 0:r.type)==="INVALID"?this._nextValue.errors.push(e):this._nextValue={type:"INVALID",errors:[e]}}});return t._features.push("form-field-status"),t}export{o as createStatus};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{deepCopy as
|
|
1
|
+
import{deepCopy as d}from"@ibg/utils";var v=(a,t,i)=>new Promise((n,l)=>{var u=e=>{try{s(i.next(e))}catch(r){l(r)}},h=e=>{try{s(i.throw(e))}catch(r){l(r)}},s=e=>e.done?n(e.value):Promise.resolve(e.value).then(u,h);s((i=i.apply(a,t)).next())});function o(a){return{_validationChain:a,isValidating:!1,push(t){this._validationChain.push(t)},append(t){return this._validationChain.push(...t._validationChain),this},validate(t){return v(this,null,function*(){var i;this.isValidating=!0;for(const n of this._validationChain)if(yield n.validate(t),t._config.collectErrorMode==="firstError"&&((i=t.status._nextValue)==null?void 0:i.type)==="INVALID")break;return t.status._nextValue==null?t.status.set({type:"VALID"}):t.status.set(t.status._nextValue),t.status._nextValue=void 0,this.isValidating=!1,t.status.get().type==="VALID"})},clone(){return o(d(this._validationChain))}}}export{o as createValidator};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{safeParseAsync as u,getDotPath as f}from"valibot";import{createValidator as v}from"./create-validator.js";var d=(s,o,t)=>new Promise((a,r)=>{var n=e=>{try{i(t.next(e))}catch(l){r(l)}},c=e=>{try{i(t.throw(e))}catch(l){r(l)}},i=e=>e.done?a(e.value):Promise.resolve(e.value).then(n,c);i((t=t.apply(s,o)).next())});function m(s){return v([{key:"valibot",validate:o=>d(this,null,function*(){var t;const a=yield u(s,o.get(),{abortPipeEarly:o._config.collectErrorMode==="firstError"});if(a.issues!=null)for(const r of a.issues)o.status.
|
|
1
|
+
import{safeParseAsync as u,getDotPath as f}from"valibot";import{createValidator as v}from"./create-validator.js";var d=(s,o,t)=>new Promise((a,r)=>{var n=e=>{try{i(t.next(e))}catch(l){r(l)}},c=e=>{try{i(t.throw(e))}catch(l){r(l)}},i=e=>e.done?a(e.value):Promise.resolve(e.value).then(n,c);i((t=t.apply(s,o)).next())});function m(s){return v([{key:"valibot",validate:o=>d(this,null,function*(){var t;const a=yield u(s,o.get(),{abortPipeEarly:o._config.collectErrorMode==="firstError"});if(a.issues!=null)for(const r of a.issues)o.status.registerNextError({code:r.type,message:r.message,path:(t=f(r))!=null?t:void 0})})}])}export{m as valibotValidator};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ValidationError as p}from"yup";import{createValidator as
|
|
1
|
+
import{ValidationError as p}from"yup";import{createValidator as y}from"./create-validator.js";var f=(e,t,n)=>new Promise((i,r)=>{var a=o=>{try{s(n.next(o))}catch(l){r(l)}},u=o=>{try{s(n.throw(o))}catch(l){r(l)}},s=o=>o.done?i(o.value):Promise.resolve(o.value).then(a,u);s((n=n.apply(e,t)).next())});function h(e){return y([{key:"yup",validate:t=>f(this,null,function*(){var n,i;try{yield e.validate(t.get(),{abortEarly:t._config.collectErrorMode==="firstError"})}catch(r){if(c(r)){r.inner.length===0&&t.status.registerNextError({code:(n=r.type)!=null?n:"unknown",message:r.message.replace("this",t.key),path:r.path});for(const a of r.inner)t.status.registerNextError({code:(i=a.type)!=null?i:"unknown",message:a.message.replace("this",t.key),path:a.path})}else console.warn("Parse error is not an instance of a ValidationError. Ensure Yup is correctly installed.",r)}})}])}function c(e){return e instanceof p||e instanceof Error&&"inner"in e&&Array.isArray(e.inner)}export{c as isYupError,h as yupValidator};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{ZodError as a}from"zod";import{createValidator as
|
|
1
|
+
import{ZodError as a}from"zod";import{createValidator as n}from"./create-validator.js";function i(r){return n([{key:"zod",validate:t=>{try{r.parse(t.get())}catch(o){if(s(o))for(const e of o.errors)t.status.registerNextError({code:e.code,message:e.message,path:e.path.join(".")});else console.warn("Parse error is not an instance of a ZodError. Ensure Zod is correctly installed.",o)}}}])}function s(r){return r instanceof a||r instanceof Error&&"errors"in r&&Array.isArray(r.errors)}export{s as isZodError,i as zodValidator};
|
package/dist/esm/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createForm as
|
|
1
|
+
import{BitwiseFlag as e,bitwiseFlag as t}from"@ibg/utils";import{createForm as i,fromValidator as m}from"./create-form.js";import{createFormField as l}from"./form-field/create-form-field.js";import{createStatus as f}from"./form-field/create-status.js";import{isFormField as x}from"./form-field/is-form-field.js";import{createValidator as s}from"./form-field/validator/create-validator.js";import{valibotValidator as u}from"./form-field/validator/valibot.js";import{isYupError as g,yupValidator as w}from"./form-field/validator/yup.js";import{isZodError as M,zodValidator as v}from"./form-field/validator/zod.js";import{FormFieldReValidateMode as z,FormFieldValidateMode as B}from"./types/form-field.js";export{e as BitwiseFlag,z as FormFieldReValidateMode,B as FormFieldValidateMode,t as bitwiseFlag,i as createForm,l as createFormField,f as createStatus,s as createValidator,m as fromValidator,x as isFormField,g as isYupError,M as isZodError,u as valibotValidator,w as yupValidator,v as zodValidator};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var O=(n=>(n[n.OnBlur=1]="OnBlur",n[n.OnChange=2]="OnChange",n[n.OnSubmit=4]="OnSubmit",n[n.OnTouched=8]="OnTouched",n))(O||{}),u=(n=>(n[n.OnBlur=1]="OnBlur",n[n.OnChange=2]="OnChange",n[n.OnSubmit=4]="OnSubmit",n))(u||{});export{u as FormFieldReValidateMode,O as FormFieldValidateMode};
|
|
@@ -1,18 +1,25 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type BitwiseFlag } from '@ibg/utils';
|
|
2
|
+
import { FormFieldReValidateMode, FormFieldValidateMode, type TForm, type TFormConfig, type TFormData, type TFormFieldStateConfig, type TFormFieldValidator, type TInvalidSubmitCallback, type TValidSubmitCallback } from './types';
|
|
2
3
|
export declare function createForm<GFormData extends TFormData>(config: TCreateFormConfig<GFormData>): TForm<GFormData, ['base']>;
|
|
3
|
-
export interface TCreateFormConfig<GFormData extends TFormData> extends Partial<TFormConfig
|
|
4
|
+
export interface TCreateFormConfig<GFormData extends TFormData> extends Partial<TFormConfig> {
|
|
4
5
|
/**
|
|
5
6
|
* Form fields
|
|
6
7
|
*/
|
|
7
8
|
fields: TCreateFormConfigFormFields<GFormData>;
|
|
8
9
|
/**
|
|
9
|
-
* Validation strategy
|
|
10
|
+
* Validation strategy **before** submitting.
|
|
10
11
|
*/
|
|
11
|
-
validateMode?:
|
|
12
|
+
validateMode?: BitwiseFlag<FormFieldValidateMode>;
|
|
12
13
|
/**
|
|
13
|
-
* Validation strategy
|
|
14
|
+
* Validation strategy **after** submitting.
|
|
14
15
|
*/
|
|
15
|
-
reValidateMode?:
|
|
16
|
+
reValidateMode?: BitwiseFlag<FormFieldReValidateMode>;
|
|
17
|
+
/**
|
|
18
|
+
* Whether to notify the form field if its status has changed
|
|
19
|
+
*/
|
|
20
|
+
notifyOnStatusChange?: boolean;
|
|
21
|
+
onInvalidSubmit?: TInvalidSubmitCallback<GFormData>;
|
|
22
|
+
onValidSubmit?: TValidSubmitCallback<GFormData>;
|
|
16
23
|
}
|
|
17
24
|
export type TCreateFormConfigFormFields<GFormData extends TFormData> = {
|
|
18
25
|
[Key in keyof GFormData]: TCreateFormConfigFormField<GFormData[Key]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-form.d.ts","sourceRoot":"","sources":["../../src/create-form.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"create-form.d.ts","sourceRoot":"","sources":["../../src/create-form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,KAAK,WAAW,EAAiB,MAAM,YAAY,CAAC;AAGpF,OAAO,EACN,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,SAAS,EAEd,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EAGxB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,MAAM,SAAS,CAAC;AAEjB,wBAAgB,UAAU,CAAC,SAAS,SAAS,SAAS,EACrD,MAAM,EAAE,iBAAiB,CAAC,SAAS,CAAC,GAClC,KAAK,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC,CAAC,CAyM5B;AAED,MAAM,WAAW,iBAAiB,CAAC,SAAS,SAAS,SAAS,CAAE,SAAQ,OAAO,CAAC,WAAW,CAAC;IAC3F;;OAEG;IACH,MAAM,EAAE,2BAA2B,CAAC,SAAS,CAAC,CAAC;IAC/C;;OAEG;IACH,YAAY,CAAC,EAAE,WAAW,CAAC,qBAAqB,CAAC,CAAC;IAClD;;OAEG;IACH,cAAc,CAAC,EAAE,WAAW,CAAC,uBAAuB,CAAC,CAAC;IACtD;;OAEG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAE/B,eAAe,CAAC,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IACpD,aAAa,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;CAChD;AAED,MAAM,MAAM,2BAA2B,CAAC,SAAS,SAAS,SAAS,IAAI;KACrE,GAAG,IAAI,MAAM,SAAS,GAAG,0BAA0B,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;CACpE,CAAC;AAEF,MAAM,WAAW,0BAA0B,CAAC,MAAM,CAAE,SAAQ,OAAO,CAAC,qBAAqB,CAAC;IACzF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;CACvC;AAID,wBAAgB,aAAa,CAAC,MAAM,EACnC,SAAS,EAAE,mBAAmB,CAAC,MAAM,CAAC,EACtC,MAAM,EAAE,IAAI,CAAC,0BAA0B,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,GAC3D,0BAA0B,CAAC,MAAM,CAAC,CAEpC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-form-field.d.ts","sourceRoot":"","sources":["../../../src/form-field/create-form-field.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"create-form-field.d.ts","sourceRoot":"","sources":["../../../src/form-field/create-form-field.ts"],"names":[],"mappings":"AAGA,OAAO,EAGN,KAAK,UAAU,EACf,KAAK,qBAAqB,EAE1B,KAAK,mBAAmB,EACxB,MAAM,UAAU,CAAC;AAGlB,wBAAgB,eAAe,CAAC,MAAM,EACrC,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,MAAM,EAAE,sBAAsB,CAAC,MAAM,CAAC,GACpC,UAAU,CAAC,MAAM,CAAC,CAyEpB;AAED,MAAM,WAAW,sBAAsB,CAAC,MAAM,CAAE,SAAQ,OAAO,CAAC,qBAAqB,CAAC;IACrF,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACvC,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAC/B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-status.d.ts","sourceRoot":"","sources":["../../../src/form-field/create-status.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAE7E,wBAAgB,YAAY,CAAC,YAAY,EAAE,qBAAqB,GAAG,gBAAgB,
|
|
1
|
+
{"version":3,"file":"create-status.d.ts","sourceRoot":"","sources":["../../../src/form-field/create-status.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAE7E,wBAAgB,YAAY,CAAC,YAAY,EAAE,qBAAqB,GAAG,gBAAgB,CAsBlF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-validator.d.ts","sourceRoot":"","sources":["../../../../src/form-field/validator/create-validator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvF,wBAAgB,eAAe,CAAC,MAAM,EACrC,eAAe,EAAE,yBAAyB,CAAC,MAAM,CAAC,GAChD,mBAAmB,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"create-validator.d.ts","sourceRoot":"","sources":["../../../../src/form-field/validator/create-validator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,yBAAyB,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvF,wBAAgB,eAAe,CAAC,MAAM,EACrC,eAAe,EAAE,yBAAyB,CAAC,MAAM,CAAC,GAChD,mBAAmB,CAAC,MAAM,CAAC,CAwC7B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type Schema } from 'yup';
|
|
1
|
+
import { ValidationError, type Schema } from 'yup';
|
|
2
2
|
import { type TFormFieldValidator } from '../../types';
|
|
3
3
|
export declare function yupValidator<GValue>(schema: Schema<GValue>): TFormFieldValidator<GValue>;
|
|
4
|
+
export declare function isYupError(err: unknown): err is ValidationError;
|
|
4
5
|
//# sourceMappingURL=yup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"yup.d.ts","sourceRoot":"","sources":["../../../../src/form-field/validator/yup.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"yup.d.ts","sourceRoot":"","sources":["../../../../src/form-field/validator/yup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,MAAM,EAAE,MAAM,KAAK,CAAC;AAEnD,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAmCxF;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,eAAe,CAK/D"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { type Schema } from 'zod';
|
|
1
|
+
import { ZodError, type Schema } from 'zod';
|
|
2
2
|
import { type TFormFieldValidator } from '../../types';
|
|
3
3
|
export declare function zodValidator<GValue>(schema: Schema<GValue>): TFormFieldValidator<GValue>;
|
|
4
|
+
export declare function isZodError(err: unknown): err is ZodError;
|
|
4
5
|
//# sourceMappingURL=zod.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../../../src/form-field/validator/zod.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"zod.d.ts","sourceRoot":"","sources":["../../../../src/form-field/validator/zod.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,MAAM,EAAE,MAAM,KAAK,CAAC;AAE5C,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGvD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,mBAAmB,CAAC,MAAM,CAAC,CA0BxF;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,IAAI,QAAQ,CAKxD"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAEnF,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AAExB,OAAO,QAAQ,eAAe,CAAC;IAC9B,UAAU,mBAAmB,CAAC,MAAM;QACnC,YAAY,EAAE,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAC7C,mBAAmB,EAAE,2BAA2B,CAAC;KACjD;CACD"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,SAAS,CAAC;AAEnF,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACtD,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC;AAExB,OAAO,QAAQ,eAAe,CAAC;IAC9B,UAAU,mBAAmB,CAAC,MAAM;QACnC,YAAY,EAAE,sBAAsB,CAAC,MAAM,CAAC,CAAC;QAC7C,mBAAmB,EAAE,2BAA2B,CAAC;KACjD;CACD"}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { type TState } from 'feature-state';
|
|
2
|
+
import { type BitwiseFlag } from '@ibg/utils';
|
|
2
3
|
import { type TCollectErrorMode } from './form';
|
|
3
4
|
export type TFormField<GValue> = TState<GValue | undefined, ['base', 'form-field']>;
|
|
4
5
|
export interface TFormFieldStateFeature<GValue> {
|
|
5
6
|
_config: TFormFieldStateConfig;
|
|
6
7
|
_intialValue: GValue | undefined;
|
|
7
|
-
_validator: TFormFieldValidator<GValue>;
|
|
8
8
|
key: string;
|
|
9
|
-
isValid: boolean;
|
|
10
9
|
isTouched: boolean;
|
|
11
10
|
isSubmitted: boolean;
|
|
11
|
+
isSubmitting: boolean;
|
|
12
|
+
validator: TFormFieldValidator<GValue>;
|
|
12
13
|
status: TFormFieldStatus;
|
|
13
14
|
validate: () => Promise<boolean>;
|
|
15
|
+
isValid: () => boolean;
|
|
14
16
|
blur: () => void;
|
|
15
17
|
reset: () => void;
|
|
16
18
|
}
|
|
@@ -19,18 +21,28 @@ export interface TFormFieldStateConfig {
|
|
|
19
21
|
/**
|
|
20
22
|
* Validation strategy before submitting.
|
|
21
23
|
*/
|
|
22
|
-
validateMode:
|
|
24
|
+
validateMode: BitwiseFlag<FormFieldValidateMode>;
|
|
23
25
|
/**
|
|
24
26
|
* Validation strategy after submitting.
|
|
25
27
|
*/
|
|
26
|
-
reValidateMode:
|
|
28
|
+
reValidateMode: BitwiseFlag<FormFieldReValidateMode>;
|
|
27
29
|
collectErrorMode: TCollectErrorMode;
|
|
28
30
|
}
|
|
29
|
-
export
|
|
30
|
-
|
|
31
|
+
export declare enum FormFieldValidateMode {
|
|
32
|
+
OnBlur = 1,// 1
|
|
33
|
+
OnChange = 2,// 2
|
|
34
|
+
OnSubmit = 4,// 4
|
|
35
|
+
OnTouched = 8
|
|
36
|
+
}
|
|
37
|
+
export declare enum FormFieldReValidateMode {
|
|
38
|
+
OnBlur = 1,// 1
|
|
39
|
+
OnChange = 2,// 2
|
|
40
|
+
OnSubmit = 4
|
|
41
|
+
}
|
|
31
42
|
export type TFormFieldStatus = TState<TFormFieldStatusValue, ['base', 'form-field-status']>;
|
|
32
43
|
export interface TFormFielStatusStateFeature {
|
|
33
|
-
|
|
44
|
+
_nextValue?: TFormFieldStatusValue;
|
|
45
|
+
registerNextError: (error: TInvalidFormFieldError) => void;
|
|
34
46
|
}
|
|
35
47
|
export type TFormFieldStatusValue = TInvalidFormFieldStatus | TValidFormFieldStatus | TUnvalidatedFormFieldStatus;
|
|
36
48
|
export interface TInvalidFormFieldStatus {
|
|
@@ -58,7 +70,7 @@ export interface TFormFieldValidator<GValue> {
|
|
|
58
70
|
_validationChain: TFormFieldValidationChain<GValue>;
|
|
59
71
|
isValidating: boolean;
|
|
60
72
|
validate: (formField: TFormField<GValue>) => Promise<boolean>;
|
|
61
|
-
append: (validator: TFormFieldValidator<GValue>) =>
|
|
73
|
+
append: (validator: TFormFieldValidator<GValue>) => TFormFieldValidator<GValue>;
|
|
62
74
|
clone: () => TFormFieldValidator<GValue>;
|
|
63
75
|
push: (...validateFunctions: TFormFieldValidationLink<GValue>[]) => void;
|
|
64
76
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form-field.d.ts","sourceRoot":"","sources":["../../../src/types/form-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"form-field.d.ts","sourceRoot":"","sources":["../../../src/types/form-field.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAEhD,MAAM,MAAM,UAAU,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,SAAS,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;AAEpF,MAAM,WAAW,sBAAsB,CAAC,MAAM;IAC7C,OAAO,EAAE,qBAAqB,CAAC;IAC/B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACvC,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC,OAAO,EAAE,MAAM,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,KAAK,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB;;OAEG;IAEH,YAAY,EAAE,WAAW,CAAC,qBAAqB,CAAC,CAAC;IACjD;;OAEG;IAEH,cAAc,EAAE,WAAW,CAAC,uBAAuB,CAAC,CAAC;IACrD,gBAAgB,EAAE,iBAAiB,CAAC;CACpC;AAED,oBAAY,qBAAqB;IAEhC,MAAM,IAAS,CAAE,IAAI;IAErB,QAAQ,IAAS,CAAE,IAAI;IAEvB,QAAQ,IAAS,CAAE,IAAI;IAEvB,SAAS,IAAS;CAClB;AAED,oBAAY,uBAAuB;IAElC,MAAM,IAAS,CAAE,IAAI;IAErB,QAAQ,IAAS,CAAE,IAAI;IAEvB,QAAQ,IAAS;CACjB;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,qBAAqB,EAAE,CAAC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAE5F,MAAM,WAAW,2BAA2B;IAC3C,UAAU,CAAC,EAAE,qBAAqB,CAAC;IACnC,iBAAiB,EAAE,CAAC,KAAK,EAAE,sBAAsB,KAAK,IAAI,CAAC;CAC3D;AAED,MAAM,MAAM,qBAAqB,GAC9B,uBAAuB,GACvB,qBAAqB,GACrB,2BAA2B,CAAC;AAE/B,MAAM,WAAW,uBAAuB;IACvC,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,EAAE,sBAAsB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,qBAAqB;IACrC,IAAI,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,2BAA2B;IAC3C,IAAI,EAAE,aAAa,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,0BAA0B,CAAC,MAAM,IAAI,CAChD,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,KACzB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAC1B,MAAM,WAAW,wBAAwB,CAAC,MAAM;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,0BAA0B,CAAC,MAAM,CAAC,CAAC;CAC7C;AACD,MAAM,MAAM,yBAAyB,CAAC,MAAM,IAAI,wBAAwB,CAAC,MAAM,CAAC,EAAE,CAAC;AAEnF,MAAM,WAAW,mBAAmB,CAAC,MAAM;IAC1C,gBAAgB,EAAE,yBAAyB,CAAC,MAAM,CAAC,CAAC;IACpD,YAAY,EAAE,OAAO,CAAC;IACtB,QAAQ,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,MAAM,EAAE,CAAC,SAAS,EAAE,mBAAmB,CAAC,MAAM,CAAC,KAAK,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAChF,KAAK,EAAE,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,EAAE,CAAC,GAAG,iBAAiB,EAAE,wBAAwB,CAAC,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC;CACzE"}
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { type TFeatureKeys, type TSelectFeatures } from './features';
|
|
2
|
-
import { type TFormField, type TFormFieldValidator } from './form-field';
|
|
2
|
+
import { type TFormField, type TFormFieldValidator, type TInvalidFormFieldError } from './form-field';
|
|
3
3
|
export type TForm<GFormData extends TFormData, GSelectedFeatureKeys extends TFeatureKeys[]> = {
|
|
4
4
|
_features: string[];
|
|
5
|
-
_config: TFormConfig
|
|
5
|
+
_config: TFormConfig;
|
|
6
|
+
_validSubmitCallbacks: TValidSubmitCallback<GFormData>[];
|
|
7
|
+
_invalidSubmitCallbacks: TInvalidSubmitCallback<GFormData>[];
|
|
6
8
|
fields: TFormFields<GFormData>;
|
|
7
9
|
isValid: boolean;
|
|
10
|
+
isValidating: boolean;
|
|
8
11
|
isSubmitted: boolean;
|
|
12
|
+
isSubmitting: boolean;
|
|
9
13
|
_revalidate: (cached?: boolean) => Promise<boolean>;
|
|
10
|
-
submit: () => Promise<boolean>;
|
|
14
|
+
submit: (options?: TSubmitOptions<GFormData>) => Promise<boolean>;
|
|
11
15
|
validate: () => Promise<boolean>;
|
|
12
16
|
getField: <GKey extends keyof TFormFields<GFormData>>(key: GKey) => TFormFields<GFormData>[GKey];
|
|
17
|
+
getData: () => Readonly<GFormData> | null;
|
|
18
|
+
getErrors: () => TInvalidFormFieldErrors<GFormData>;
|
|
13
19
|
reset: () => void;
|
|
14
20
|
} & TSelectFeatures<GFormData, GSelectedFeatureKeys>;
|
|
15
21
|
export type TFormFields<GFormData extends TFormData> = {
|
|
@@ -18,8 +24,23 @@ export type TFormFields<GFormData extends TFormData> = {
|
|
|
18
24
|
export type TFormValidators<GFormData extends TFormData> = {
|
|
19
25
|
[Key in keyof GFormData]: TFormFieldValidator<GFormData[Key]>;
|
|
20
26
|
};
|
|
21
|
-
export type TFormData = Record<string,
|
|
22
|
-
export interface
|
|
27
|
+
export type TFormData = Record<string, any>;
|
|
28
|
+
export interface TSubmitOptions<GFormData extends TFormData> {
|
|
29
|
+
onValidSubmit?: TValidSubmitCallback<GFormData>;
|
|
30
|
+
onInvalidSubmit?: TInvalidSubmitCallback<GFormData>;
|
|
31
|
+
additionalData?: TAdditionalSubmitCallbackData;
|
|
32
|
+
assignToInitial?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export type TValidSubmitCallback<GFormData extends TFormData> = (formData: Readonly<GFormData>, additionalData?: TAdditionalSubmitCallbackData) => Promise<void> | void;
|
|
35
|
+
export type TInvalidSubmitCallback<GFormData extends TFormData> = (errors: TInvalidFormFieldErrors<GFormData>, additionalData?: TAdditionalSubmitCallbackData) => Promise<void> | void;
|
|
36
|
+
export interface TAdditionalSubmitCallbackData {
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
event?: unknown;
|
|
39
|
+
}
|
|
40
|
+
export type TInvalidFormFieldErrors<GFormData extends TFormData> = {
|
|
41
|
+
[Key in keyof GFormData]?: Readonly<TInvalidFormFieldError[]>;
|
|
42
|
+
};
|
|
43
|
+
export interface TFormConfig {
|
|
23
44
|
/**
|
|
24
45
|
* Indicates if the form is disabled.
|
|
25
46
|
*/
|
|
@@ -28,10 +49,6 @@ export interface TFormConfig<GFormData extends TFormData> {
|
|
|
28
49
|
* Error collection mode. 'firstError' gathers only the first error per field, 'all' gathers all errors.
|
|
29
50
|
*/
|
|
30
51
|
collectErrorMode: TCollectErrorMode;
|
|
31
|
-
/**
|
|
32
|
-
* Called once form is submitted
|
|
33
|
-
*/
|
|
34
|
-
onSubmit: ((data: GFormData) => void) | null;
|
|
35
52
|
}
|
|
36
53
|
export type TCollectErrorMode = 'firstError' | 'all';
|
|
37
54
|
//# sourceMappingURL=form.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../../src/types/form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,
|
|
1
|
+
{"version":3,"file":"form.d.ts","sourceRoot":"","sources":["../../../src/types/form.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACrE,OAAO,EACN,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,MAAM,cAAc,CAAC;AAKtB,MAAM,MAAM,KAAK,CAAC,SAAS,SAAS,SAAS,EAAE,oBAAoB,SAAS,YAAY,EAAE,IAAI;IAC7F,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,WAAW,CAAC;IACrB,qBAAqB,EAAE,oBAAoB,CAAC,SAAS,CAAC,EAAE,CAAC;IACzD,uBAAuB,EAAE,sBAAsB,CAAC,SAAS,CAAC,EAAE,CAAC;IAC7D,MAAM,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACpD,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,cAAc,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAClE,QAAQ,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC,QAAQ,EAAE,CAAC,IAAI,SAAS,MAAM,WAAW,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,KAAK,WAAW,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC;IACjG,OAAO,EAAE,MAAM,QAAQ,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IAC1C,SAAS,EAAE,MAAM,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACpD,KAAK,EAAE,MAAM,IAAI,CAAC;CAClB,GAAG,eAAe,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;AAErD,MAAM,MAAM,WAAW,CAAC,SAAS,SAAS,SAAS,IAAI;KACrD,GAAG,IAAI,MAAM,SAAS,GAAG,UAAU,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,eAAe,CAAC,SAAS,SAAS,SAAS,IAAI;KACzD,GAAG,IAAI,MAAM,SAAS,GAAG,mBAAmB,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;CAC7D,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE5C,MAAM,WAAW,cAAc,CAAC,SAAS,SAAS,SAAS;IAC1D,aAAa,CAAC,EAAE,oBAAoB,CAAC,SAAS,CAAC,CAAC;IAChD,eAAe,CAAC,EAAE,sBAAsB,CAAC,SAAS,CAAC,CAAC;IACpD,cAAc,CAAC,EAAE,6BAA6B,CAAC;IAC/C,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,MAAM,oBAAoB,CAAC,SAAS,SAAS,SAAS,IAAI,CAC/D,QAAQ,EAAE,QAAQ,CAAC,SAAS,CAAC,EAC7B,cAAc,CAAC,EAAE,6BAA6B,KAC1C,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE1B,MAAM,MAAM,sBAAsB,CAAC,SAAS,SAAS,SAAS,IAAI,CACjE,MAAM,EAAE,uBAAuB,CAAC,SAAS,CAAC,EAC1C,cAAc,CAAC,EAAE,6BAA6B,KAC1C,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAE1B,MAAM,WAAW,6BAA6B;IAC7C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,uBAAuB,CAAC,SAAS,SAAS,SAAS,IAAI;KACjE,GAAG,IAAI,MAAM,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,sBAAsB,EAAE,CAAC;CAC7D,CAAC;AAEF,MAAM,WAAW,WAAW;IAC3B;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,gBAAgB,EAAE,iBAAiB,CAAC;CACpC;AAED,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,KAAK,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "feature-form",
|
|
3
3
|
"description": "Straightforward, typesafe, and feature-based form library for ReactJs",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.7",
|
|
5
5
|
"private": false,
|
|
6
6
|
"source": "./src/index.ts",
|
|
7
7
|
"main": "./dist/cjs/index.js",
|
|
@@ -19,15 +19,15 @@
|
|
|
19
19
|
},
|
|
20
20
|
"homepage": "https://inbeta.group/?source=github",
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@ibg/utils": "0.0.
|
|
23
|
-
"feature-state": "0.0.
|
|
22
|
+
"@ibg/utils": "0.0.8",
|
|
23
|
+
"feature-state": "0.0.13"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@types/node": "^20.14.1",
|
|
27
|
-
"valibot": "^0.
|
|
27
|
+
"valibot": "^0.35.0",
|
|
28
28
|
"yup": "^1.4.0",
|
|
29
29
|
"zod": "^3.23.8",
|
|
30
|
-
"@ibg/config": "0.0.
|
|
30
|
+
"@ibg/config": "0.0.12"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"dist",
|
|
@@ -35,7 +35,12 @@
|
|
|
35
35
|
],
|
|
36
36
|
"size-limit": [
|
|
37
37
|
{
|
|
38
|
-
"path": "dist/esm/index.js"
|
|
38
|
+
"path": "dist/esm/index.js",
|
|
39
|
+
"ignore": [
|
|
40
|
+
"zod",
|
|
41
|
+
"yup",
|
|
42
|
+
"valibot"
|
|
43
|
+
]
|
|
39
44
|
}
|
|
40
45
|
],
|
|
41
46
|
"scripts": {
|
|
@@ -46,7 +51,7 @@
|
|
|
46
51
|
"install:clean": "pnpm run clean && pnpm install",
|
|
47
52
|
"test": "vitest run",
|
|
48
53
|
"update:latest": "pnpm update --latest",
|
|
49
|
-
"publish:patch": "pnpm version patch && pnpm publish --no-git-checks",
|
|
54
|
+
"publish:patch": "pnpm build && pnpm version patch && pnpm publish --no-git-checks",
|
|
50
55
|
"size": "size-limit --why"
|
|
51
56
|
}
|
|
52
57
|
}
|