@ahrowe/ui 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/common/animatedLogo/animatedLogo.mjs +2 -0
- package/dist/esm/common/animatedLogo/animatedLogo.mjs.map +1 -0
- package/dist/esm/common/animatedLogo/animatedLogo.module.mjs +2 -0
- package/dist/esm/common/animatedLogo/animatedLogo.module.mjs.map +1 -0
- package/dist/esm/common/datePicker/datePicker.mjs.map +1 -1
- package/dist/esm/common/dropdown/dropdown.mjs +1 -1
- package/dist/esm/common/dropdown/dropdown.mjs.map +1 -1
- package/dist/esm/common/input/input.types.mjs.map +1 -1
- package/dist/esm/common/numberInput/numberInput.mjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/services/formValidation/FormValidatorGroupWithForm.mjs +1 -1
- package/dist/esm/services/formValidation/FormValidatorGroupWithForm.mjs.map +1 -1
- package/dist/esm/services/formValidation/index.mjs +1 -0
- package/dist/esm/services/formValidation/useFormValidatorGroup.mjs +1 -1
- package/dist/esm/services/formValidation/useFormValidatorGroup.mjs.map +1 -1
- package/dist/esm/services/formValidation/validatableComponent.mjs.map +1 -1
- package/dist/index.cjs +4 -4
- package/dist/index.cjs.map +1 -1
- package/dist/style.css +1 -1
- package/dist/types/package/common/animatedLogo/animatedLogo.d.ts +4 -0
- package/dist/types/package/common/animatedLogo/animatedLogo.types.d.ts +27 -0
- package/dist/types/package/common/animatedLogo/index.d.ts +2 -0
- package/dist/types/package/common/checkbox/checkbox.types.d.ts +1 -1
- package/dist/types/package/common/datePicker/datePicker.d.ts +1 -1
- package/dist/types/package/common/dropdown/dropdown.types.d.ts +1 -1
- package/dist/types/package/common/iconPicker/iconPicker.types.d.ts +1 -1
- package/dist/types/package/common/input/input.types.d.ts +1 -1
- package/dist/types/package/common/inputDropdown/inputDropdown.types.d.ts +1 -1
- package/dist/types/package/common/numberInput/numberInput.d.ts +1 -1
- package/dist/types/package/common/switch/switch.types.d.ts +1 -1
- package/dist/types/package/common/timeInput/timeInput.types.d.ts +1 -1
- package/dist/types/package/index.d.ts +3 -1
- package/dist/types/package/services/formValidation/FormValidatorGroupWithForm.d.ts +1 -1
- package/dist/types/package/services/formValidation/index.d.ts +2 -5
- package/dist/types/package/services/formValidation/useFormValidatorGroup.d.ts +8 -24
- package/dist/types/package/services/formValidation/validatableComponent.d.ts +1 -1
- package/docs/AnimatedLogo.md +60 -0
- package/docs/CLAUDE.md +1 -0
- package/package.json +2 -1
- package/dist/esm/services/formValidation/FormValidatorGroupForm.mjs +0 -2
- package/dist/esm/services/formValidation/FormValidatorGroupForm.mjs.map +0 -1
- package/dist/esm/services/formValidation/formValidator.mjs +0 -2
- package/dist/esm/services/formValidation/formValidator.mjs.map +0 -1
- package/dist/esm/services/formValidation/formValidatorGroup.mjs +0 -2
- package/dist/esm/services/formValidation/formValidatorGroup.mjs.map +0 -1
- package/dist/esm/services/formValidation/useFormValidator.mjs +0 -2
- package/dist/esm/services/formValidation/useFormValidator.mjs.map +0 -1
- package/dist/esm/services/formValidation/validators.mjs +0 -2
- package/dist/esm/services/formValidation/validators.mjs.map +0 -1
- package/dist/esm/services/regexp.mjs +0 -2
- package/dist/esm/services/regexp.mjs.map +0 -1
- package/dist/types/package/services/formValidation/FormValidatorGroupForm.d.ts +0 -7
- package/dist/types/package/services/formValidation/formValidator.d.ts +0 -39
- package/dist/types/package/services/formValidation/formValidatorGroup.d.ts +0 -64
- package/dist/types/package/services/formValidation/types.d.ts +0 -10
- package/dist/types/package/services/formValidation/useFormValidator.d.ts +0 -9
- package/dist/types/package/services/formValidation/validators.d.ts +0 -20
- package/dist/types/package/services/regexp.d.ts +0 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ahrowe/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
"react-dom": ">=18.0.0"
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
|
+
"@ahrowe/form-validation": "^0.2.0",
|
|
78
79
|
"@dnd-kit/core": "^6.3.1",
|
|
79
80
|
"@dnd-kit/sortable": "^10.0.0",
|
|
80
81
|
"@dnd-kit/utilities": "^3.2.2",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"FormValidatorGroupForm.mjs","names":[],"sources":["../../../../package/services/formValidation/FormValidatorGroupForm.tsx"],"sourcesContent":["import React from 'react';\nimport type FormValidatorGroup from './formValidatorGroup';\n\n/**\n * Creates the Form component for a FormValidatorGroup instance.\n * Kept in a separate .tsx file so formValidatorGroup.ts stays framework-agnostic.\n */\nexport function createFormComponent(group: Pick<FormValidatorGroup, 'submit'>): React.FC<React.FormHTMLAttributes<HTMLFormElement>> {\n return function Form({ children, ...rest }) {\n return (\n <form onSubmit={group.submit} noValidate {...rest}>\n {children}\n </form>\n );\n };\n}\n"],"mappings":"sDAOA,SAAgB,EAAoB,EAAgG,CAClI,OAAO,SAAc,CAAE,WAAU,GAAG,GAAQ,CAC1C,OACE,EAAC,OAAD,CAAM,SAAU,EAAM,OAAQ,WAAA,GAAW,GAAI,EAC1C,UACG,CAAA,CAEV,CACF"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var e=class{#e;#t;#n;#r;#i;constructor(e,t){this.addError=e=>{this.#r.push(e),this.onUpdate()},this.removeErrors=e=>{this.#r=this.#r.filter(t=>!e.includes(t.id)),this.onUpdate()},this.clearErrors=()=>{this.#r=[],this.onUpdate()},this.hasError=e=>!e&&this.errors.length>0?!0:!!this.errors.find(t=>t.id===e),this.getCurrentErrorMessage=()=>this.errors.length===0?null:this.errors[0].message,this.validate=()=>{this.clearErrors(),this.validators.forEach(e=>{let t=e(this.value,this.label);t&&this.addError(t)})},this.onUpdate=()=>{this.onUpdateCallbacks.forEach(e=>e(this))},this.registerOnUpdateListener=e=>{this.onUpdateCallbacks.push(e)},this.removeOnUpdateListener=e=>{this.onUpdateCallbacks.splice(this.onUpdateCallbacks.indexOf(e),1)},this.set=(e,t=!0)=>(this.value=e,t&&!this.dirty&&(this.dirty=!0),this.validate(),this),this.#e=e,this.validators=t??[],this.#t=!1,this.#n=!1,this.#r=[],this.#i=``,this.onUpdateCallbacks=[],this.validate()}get touched(){return this.#t}set touched(e){this.#t=e,this.onUpdate()}get label(){return this.#i}set label(e){this.#i=e}get dirty(){return this.#n}set dirty(e){this.#n=e,this.onUpdate()}get value(){return this.#e}set value(e){this.#e=e,this.onUpdate()}get errors(){return this.#r}};e.prototype.toString=function(){return`${this.value}`};export{e as default};
|
|
2
|
-
//# sourceMappingURL=formValidator.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formValidator.mjs","names":["#errors","#value","#touched","#dirty","#label"],"sources":["../../../../package/services/formValidation/formValidator.ts"],"sourcesContent":["import type { ValidatorFunction, ValidationError, UpdateListener } from './types';\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport default class FormValidator<T = any> {\n #value: T;\n #touched: boolean;\n #dirty: boolean;\n #errors: ValidationError[];\n #label: string;\n\n validators: ValidatorFunction[];\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n onUpdateCallbacks: Array<(validator: FormValidator<any>) => void>;\n\n /**\n * Create a FormValidator to use standalone or inside a FormValidatorGroup.\n * @param initialValue - Default value of the field\n * @param validators - Array of validator functions\n */\n constructor(initialValue: T, validators?: ValidatorFunction[]) {\n this.#value = initialValue;\n this.validators = validators ?? [];\n this.#touched = false;\n this.#dirty = false;\n this.#errors = [];\n this.#label = '';\n this.onUpdateCallbacks = [];\n this.validate();\n }\n\n /** Whether the user has entered and left the field. */\n get touched(): boolean { return this.#touched; }\n set touched(value: boolean) { this.#touched = value; this.onUpdate(); }\n\n get label(): string { return this.#label; }\n set label(value: string) { this.#label = value; }\n\n /** Whether the user has changed the value since initialisation. */\n get dirty(): boolean { return this.#dirty; }\n set dirty(value: boolean) { this.#dirty = value; this.onUpdate(); }\n\n get value(): T { return this.#value; }\n /** Sets value without validation (use `set()` for validated updates). */\n set value(val: T) { this.#value = val; this.onUpdate(); }\n\n get errors(): ValidationError[] { return this.#errors; }\n\n addError = (error: ValidationError): void => {\n this.#errors.push(error);\n this.onUpdate();\n };\n\n removeErrors = (errorIds: string[]): void => {\n this.#errors = this.#errors.filter((error) => !errorIds.includes(error.id));\n this.onUpdate();\n };\n\n clearErrors = (): void => {\n this.#errors = [];\n this.onUpdate();\n };\n\n hasError = (error?: string): boolean => {\n if (!error && this.errors.length > 0) return true;\n return !!(this.errors.find((err) => err.id === error));\n };\n\n getCurrentErrorMessage = (): string | null => {\n if (this.errors.length === 0) return null;\n return this.errors[0].message;\n };\n\n validate = (): void => {\n this.clearErrors();\n this.validators.forEach((validator) => {\n const res = validator(this.value, this.label);\n if (res) this.addError(res);\n });\n };\n\n onUpdate = (): void => {\n this.onUpdateCallbacks.forEach((cb) => cb(this));\n };\n\n registerOnUpdateListener = (callback: UpdateListener): void => {\n this.onUpdateCallbacks.push(callback);\n };\n\n removeOnUpdateListener = (callback: UpdateListener): void => {\n this.onUpdateCallbacks.splice(this.onUpdateCallbacks.indexOf(callback), 1);\n };\n\n /**\n * Sets the field value with optional dirty tracking and re-validates.\n * @param newValue - New field value\n * @param wasUser - Whether the change was user-initiated (marks field dirty). Defaults to true.\n */\n set = (newValue: T, wasUser: boolean = true): this => {\n this.value = newValue;\n if (wasUser && !this.dirty) this.dirty = true;\n this.validate();\n return this;\n };\n}\n\nFormValidator.prototype.toString = function getValidatorValue() {\n return `${this.value}`;\n};\n"],"mappings":"AAGA,IAAqB,EAArB,KAA4C,CAC1C,GACA,GACA,GACA,GACA,GAWA,YAAY,EAAiB,EAAkC,eA4BnD,GAAiC,CAC3C,KAAKA,GAAQ,KAAK,CAAK,EACvB,KAAK,SAAS,CAChB,oBAEgB,GAA6B,CAC3C,KAAKA,GAAU,KAAKA,GAAQ,OAAQ,GAAU,CAAC,EAAS,SAAS,EAAM,EAAE,CAAC,EAC1E,KAAK,SAAS,CAChB,uBAE0B,CACxB,KAAKA,GAAU,CAAC,EAChB,KAAK,SAAS,CAChB,gBAEY,GACN,CAAC,GAAS,KAAK,OAAO,OAAS,EAAU,GACtC,CAAC,CAAE,KAAK,OAAO,KAAM,GAAQ,EAAI,KAAO,CAAK,kCAIhD,KAAK,OAAO,SAAW,EAAU,KAC9B,KAAK,OAAO,GAAG,0BAGD,CACrB,KAAK,YAAY,EACjB,KAAK,WAAW,QAAS,GAAc,CACrC,IAAM,EAAM,EAAU,KAAK,MAAO,KAAK,KAAK,EACxC,GAAK,KAAK,SAAS,CAAG,CAC5B,CAAC,CACH,oBAEuB,CACrB,KAAK,kBAAkB,QAAS,GAAO,EAAG,IAAI,CAAC,CACjD,gCAE4B,GAAmC,CAC7D,KAAK,kBAAkB,KAAK,CAAQ,CACtC,8BAE0B,GAAmC,CAC3D,KAAK,kBAAkB,OAAO,KAAK,kBAAkB,QAAQ,CAAQ,EAAG,CAAC,CAC3E,YAOO,EAAa,EAAmB,MACrC,KAAK,MAAQ,EACT,GAAW,CAAC,KAAK,QAAO,KAAK,MAAQ,IACzC,KAAK,SAAS,EACP,MAjFP,KAAKC,GAAS,EACd,KAAK,WAAa,GAAc,CAAC,EACjC,KAAKC,GAAW,GAChB,KAAKC,GAAS,GACd,KAAKH,GAAU,CAAC,EAChB,KAAKI,GAAS,GACd,KAAK,kBAAoB,CAAC,EAC1B,KAAK,SAAS,CAChB,CAGA,IAAI,SAAmB,CAAE,OAAO,KAAKF,EAAU,CAC/C,IAAI,QAAQ,EAAgB,CAAE,KAAKA,GAAW,EAAO,KAAK,SAAS,CAAG,CAEtE,IAAI,OAAgB,CAAE,OAAO,KAAKE,EAAQ,CAC1C,IAAI,MAAM,EAAe,CAAE,KAAKA,GAAS,CAAO,CAGhD,IAAI,OAAiB,CAAE,OAAO,KAAKD,EAAQ,CAC3C,IAAI,MAAM,EAAgB,CAAE,KAAKA,GAAS,EAAO,KAAK,SAAS,CAAG,CAElE,IAAI,OAAW,CAAE,OAAO,KAAKF,EAAQ,CAErC,IAAI,MAAM,EAAQ,CAAE,KAAKA,GAAS,EAAK,KAAK,SAAS,CAAG,CAExD,IAAI,QAA4B,CAAE,OAAO,KAAKD,EAAS,CA0DzD,EAEA,EAAc,UAAU,SAAW,UAA6B,CAC9D,MAAO,GAAG,KAAK,OACjB"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
function e(e){let t=e;return t?.errors&&Array.isArray(t.errors)?t.errors.flatMap(e=>Object.entries(e).map(([e,t])=>({id:e,message:t}))):[]}var t=class{#e;#t;#n;#r;#i;constructor(t,n=null,{initialValues:r,onSubmit:i=()=>void 0,onValidate:a=()=>void 0,errorParser:o=e,onSubmitError:s=()=>void 0}={}){this.#t=!1,this.#i=[],this.getFormError=()=>{let e=Object.keys(this.group);for(let t=0;t<e.length;t+=1){let n=e[t];if(this.group[n].errors.length>0)return this.group[n].errors[0]}return null},this.set=(e,t)=>(this.group[e].set(t),this),this.reset=(e={})=>{this.submitCount=0;let t=Object.keys(e);Object.keys(this.group).forEach(n=>{this.group[n].set(t.includes(n)?e[n]:this.#r[n],!1)}),this.resetDirtyAndTouched(),this.onReset&&this.onReset(this,this.#r,this.#e)},this.resetDirtyAndTouched=()=>{Object.keys(this.group).forEach(e=>{this.group[e].dirty=!1,this.group[e].touched=!1})},this.parseError=(e,t=!1)=>{let n=this.errorParser(e);n.length>0?(n.forEach(({id:e,message:t})=>{this.group[e]&&this.group[e].addError({id:e,message:t})}),t&&this.onSubmitError(n)):this.onSubmitError([{id:`generic`,message:`An error occurred`}])},this.#a=()=>{this.component&&this.component.forceUpdate(),this.#i.forEach(e=>e())},this.registerOnUpdateListener=e=>{this.#i.push(e)},this.removeOnUpdateListener=e=>{this.#i.splice(this.#i.indexOf(e),1)},this.setSubmitting=e=>{this.#t!==e&&(this.#t=e,this.#a())},this.submit=async e=>{e&&(e.preventDefault&&e.preventDefault(),e.stopPropagation&&e.stopPropagation()),this.setSubmitting(!0);let t=null;this.submitCount===0?t=await Promise.resolve(this.validate()):this.onValidateCallback&&(t=await Promise.resolve(this.onValidateCallback(this)));let n=this.getFormError()||t;if(n){this.setSubmitting(!1),this.submitCount>-1&&this.onSubmitError([n]),this.submitCount+=1,this.#a();return}try{await this.onSubmitCallback(this.getValues(),this),this.resetDirtyAndTouched()}catch(e){this.parseError(e,!0)}this.setSubmitting(!1),this.#a(),this.submitCount+=1},this.getValues=()=>{let e={};return Object.keys(this.group).forEach(t=>{e[t]=this.group[t].value}),{...this.#e,...e}},this.validate=()=>{if(Object.keys(this.group).forEach(e=>{this.group[e].validate(),this.group[e].touched=!0}),this.onValidateCallback)return this.onValidateCallback(this)},this.setValidator=(e,t)=>(this.group[e]=t,this),this.group=t,this.#e=r??{},this.#r={},this.submitCount=0,this.onDebounce=()=>{},this.onReset=()=>{},Object.keys(this.group).forEach(e=>{let t=this.group[e],n=this.#e;n[e]!==void 0&&t.set(n[e],!1),this.#r[e]=t.value,this.group[e].registerOnUpdateListener(()=>{this.#a(),this.submitCount=0,this.#n&&clearTimeout(this.#n),this.#n=setTimeout(()=>this.onDebounce(this.getValues()),500)})}),this.component=n,this.onSubmitCallback=i,this.onValidateCallback=a,this.errorParser=o,this.onSubmitError=s,this.setSubmitting(!1)}get isSubmitting(){return this.#t}get wasTouched(){return Object.keys(this.group).some(e=>this.group[e].touched)}get isDirty(){return Object.keys(this.group).some(e=>this.group[e].dirty)}get hasErrors(){return Object.keys(this.group).some(e=>this.group[e].errors.length>0)}get initialValues(){return{...this.#e}}#a};export{t as default};
|
|
2
|
-
//# sourceMappingURL=formValidatorGroup.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formValidatorGroup.mjs","names":["#valuesAfterCreation","#initialValues","#updateListeners","#isSubmitting","#notifyListeners","#debounceTimer"],"sources":["../../../../package/services/formValidation/formValidatorGroup.ts"],"sourcesContent":["// import polyglot from 'services/localization';\n\nimport type FormValidator from './formValidator';\nimport type { ValidationError, ErrorParser, UpdateListener } from './types';\n\n/** @internal */\nfunction defaultErrorParser(err: unknown): ValidationError[] {\n const e = err as { errors?: Record<string, string>[] };\n if (e?.errors && Array.isArray(e.errors)) {\n return e.errors.flatMap((errorObj) =>\n Object.entries(errorObj).map(([id, message]) => ({ id, message }))\n );\n }\n return [];\n}\n\nexport type FormGroup = Record<string, FormValidator<any>>; // eslint-disable-line @typescript-eslint/no-explicit-any\nexport type FormValues = Record<string, unknown>;\n\nexport type InferGroupValues<TGroup extends FormGroup> = {\n [K in keyof TGroup]: TGroup[K] extends FormValidator<infer V> ? V : never;\n};\n\n/**\n * The submitted result type: TInitial with all group-field keys replaced by\n * their typed validator values.\n */\nexport type MergedValues<TInitial, TGroup extends FormGroup> =\n Omit<TInitial, keyof TGroup & string> & InferGroupValues<TGroup>;\n\nexport interface FormValidatorGroupOptions<\n TGroup extends FormGroup = FormGroup,\n TInitial = InferGroupValues<TGroup>\n> {\n initialValues?: TInitial;\n onSubmit?: (\n values: MergedValues<TInitial, TGroup>,\n group: FormValidatorGroup<TGroup, TInitial>\n ) => Promise<void> | void;\n onValidate?: (group: FormValidatorGroup<TGroup, TInitial>) => ValidationError | null | void;\n errorParser?: ErrorParser;\n onSubmitError?: (errors: ValidationError[]) => void;\n}\n\ninterface ComponentLike {\n forceUpdate: () => void;\n}\n\nexport default class FormValidatorGroup<\n TGroup extends FormGroup = FormGroup,\n TInitial = InferGroupValues<TGroup>\n> {\n #initialValues: TInitial;\n #isSubmitting: boolean = false;\n #debounceTimer: ReturnType<typeof setTimeout> | undefined;\n #valuesAfterCreation: FormValues;\n #updateListeners: UpdateListener[] = [];\n\n group: TGroup;\n component: ComponentLike | null;\n onSubmitCallback: (values: MergedValues<TInitial, TGroup>, group: FormValidatorGroup<TGroup, TInitial>) => Promise<void> | void;\n onValidateCallback: (group: FormValidatorGroup<TGroup, TInitial>) => ValidationError | null | void;\n errorParser: ErrorParser;\n onSubmitError: (errors: ValidationError[]) => void;\n submitCount: number;\n onDebounce: (values: MergedValues<TInitial, TGroup>) => void;\n onReset: (group: FormValidatorGroup<TGroup, TInitial>, valuesAfterCreation: FormValues, initialValues: TInitial) => void;\n\n /**\n * @param formValidatorGroup - Map of field name → FormValidator\n * @param component - Class component instance for forceUpdate (pass null when using hooks)\n * @param options - initialValues, onSubmit, onValidate, errorParser\n */\n constructor(\n formValidatorGroup: TGroup,\n component: ComponentLike | null = null,\n {\n initialValues,\n onSubmit = () => undefined,\n onValidate = () => undefined,\n errorParser = defaultErrorParser,\n onSubmitError = () => undefined,\n }: FormValidatorGroupOptions<TGroup, TInitial> = {}\n ) {\n this.group = formValidatorGroup;\n this.#initialValues = (initialValues ?? {}) as TInitial;\n this.#valuesAfterCreation = {};\n this.submitCount = 0;\n this.onDebounce = () => {};\n this.onReset = () => {};\n\n Object.keys(this.group).forEach((validatorKey) => {\n const currentValidator = this.group[validatorKey];\n const iv = this.#initialValues as FormValues;\n if (iv[validatorKey] !== undefined) {\n currentValidator.set(iv[validatorKey], false);\n }\n this.#valuesAfterCreation[validatorKey] = currentValidator.value;\n this.group[validatorKey].registerOnUpdateListener(() => {\n this.#notifyListeners();\n this.submitCount = 0;\n if (this.#debounceTimer) clearTimeout(this.#debounceTimer);\n this.#debounceTimer = setTimeout(() => this.onDebounce(this.getValues()), 500);\n });\n });\n\n this.component = component;\n this.onSubmitCallback = onSubmit as typeof this.onSubmitCallback;\n this.onValidateCallback = onValidate as typeof this.onValidateCallback;\n this.errorParser = errorParser;\n this.onSubmitError = onSubmitError;\n this.setSubmitting(false);\n }\n\n get isSubmitting(): boolean { return this.#isSubmitting; }\n\n get wasTouched(): boolean {\n return Object.keys(this.group).some((key) => this.group[key].touched);\n }\n\n get isDirty(): boolean {\n return Object.keys(this.group).some((key) => this.group[key].dirty);\n }\n\n get hasErrors(): boolean {\n return Object.keys(this.group).some((key) => this.group[key].errors.length > 0);\n }\n\n get initialValues(): TInitial {\n return { ...this.#initialValues } as TInitial;\n }\n\n getFormError = (): ValidationError | null => {\n const groupKeys = Object.keys(this.group);\n for (let i = 0; i < groupKeys.length; i += 1) {\n const key = groupKeys[i];\n if (this.group[key].errors.length > 0) return this.group[key].errors[0];\n }\n return null;\n };\n\n set = (validatorName: keyof TGroup & string, value: unknown): this => {\n this.group[validatorName].set(value);\n return this;\n };\n\n reset = (toOverride: FormValues = {}): void => {\n this.submitCount = 0;\n const toOverrideKeys = Object.keys(toOverride);\n Object.keys(this.group).forEach((validatorKey) => {\n this.group[validatorKey].set(\n toOverrideKeys.includes(validatorKey)\n ? toOverride[validatorKey]\n : this.#valuesAfterCreation[validatorKey],\n false\n );\n });\n this.resetDirtyAndTouched();\n if (this.onReset) this.onReset(this, this.#valuesAfterCreation, this.#initialValues);\n };\n\n resetDirtyAndTouched = (): void => {\n Object.keys(this.group).forEach((key) => {\n this.group[key].dirty = false;\n this.group[key].touched = false;\n });\n };\n\n /**\n * Parses an API error and pushes field-level errors into the matching validators.\n * When field errors are found and isInternal is set, surfaces the first field message.\n * When the error shape isn't recognised (no field errors), always surfaces a generic message.\n */\n parseError = (err: unknown, isInternal: boolean = false): void => {\n const fieldErrors = this.errorParser(err);\n if (fieldErrors.length > 0) {\n fieldErrors.forEach(({ id, message }) => {\n if (this.group[id]) this.group[id].addError({ id, message });\n });\n if (isInternal) {\n this.onSubmitError(fieldErrors);\n }\n } else {\n this.onSubmitError([{ id: 'generic', message: 'An error occurred' }]);\n }\n };\n\n #notifyListeners = (): void => {\n if (this.component) this.component.forceUpdate();\n this.#updateListeners.forEach((cb) => cb());\n };\n\n registerOnUpdateListener = (callback: UpdateListener): void => {\n this.#updateListeners.push(callback);\n };\n\n removeOnUpdateListener = (callback: UpdateListener): void => {\n this.#updateListeners.splice(this.#updateListeners.indexOf(callback), 1);\n };\n\n setSubmitting = (isSubmitting: boolean): void => {\n if (this.#isSubmitting !== isSubmitting) {\n this.#isSubmitting = isSubmitting;\n this.#notifyListeners();\n }\n };\n\n submit = async (event?: Event | React.SyntheticEvent | null): Promise<void> => {\n if (event) {\n if ((event as Event).preventDefault) (event as Event).preventDefault();\n if ((event as Event).stopPropagation) (event as Event).stopPropagation();\n }\n this.setSubmitting(true);\n\n let customError: ValidationError | null | void = null;\n if (this.submitCount === 0) {\n customError = await Promise.resolve(this.validate());\n } else if (this.onValidateCallback) {\n customError = await Promise.resolve(this.onValidateCallback(this));\n }\n const currentError = this.getFormError() || customError;\n\n if (currentError) {\n this.setSubmitting(false);\n if (this.submitCount > -1) {\n this.onSubmitError([currentError]);\n }\n this.submitCount += 1;\n this.#notifyListeners();\n return;\n }\n\n try {\n await this.onSubmitCallback(this.getValues(), this);\n this.resetDirtyAndTouched();\n } catch (err) {\n this.parseError(err, true);\n }\n this.setSubmitting(false);\n this.#notifyListeners();\n this.submitCount += 1;\n };\n\n getValues = (): MergedValues<TInitial, TGroup> => {\n const retObj: FormValues = {};\n Object.keys(this.group).forEach((key) => {\n retObj[key] = this.group[key].value;\n });\n return { ...this.#initialValues, ...retObj } as MergedValues<TInitial, TGroup>;\n };\n\n validate = (): ValidationError | null | void => {\n Object.keys(this.group).forEach((validator) => {\n this.group[validator].validate();\n this.group[validator].touched = true;\n });\n if (this.onValidateCallback) return this.onValidateCallback(this);\n };\n\n setValidator = <K extends keyof TGroup & string>(validatorName: K, validator: TGroup[K]): this => {\n this.group[validatorName] = validator;\n return this;\n };\n}\n\n// Needed for the submit method's event type\nimport type React from 'react';\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useFormValidator.mjs","names":[],"sources":["../../../../package/services/formValidation/useFormValidator.ts"],"sourcesContent":["import { useEffect, useReducer } from 'react';\nimport type FormValidator from './formValidator';\n\n/**\n * Subscribes a function component to a FormValidator instance.\n * Triggers a re-render whenever value, errors, touched, or dirty changes.\n *\n * @param formValidator - The FormValidator instance to subscribe to (or null)\n * @returns The same formValidator for convenience\n */\nexport function useFormValidator<T extends FormValidator | null>(formValidator: T): T {\n const [, rerender] = useReducer((n: number) => n + 1, 0);\n\n useEffect(() => {\n if (!formValidator) return;\n formValidator.registerOnUpdateListener(rerender);\n return () => formValidator.removeOnUpdateListener(rerender);\n }, [formValidator]);\n\n return formValidator;\n}\n"],"mappings":"kDAUA,SAAgB,EAAiD,EAAqB,CACpF,GAAM,EAAG,GAAY,EAAY,GAAc,EAAI,EAAG,CAAC,EAQvD,OANA,MAAgB,CACT,KAEL,OADA,EAAc,yBAAyB,CAAQ,MAClC,EAAc,uBAAuB,CAAQ,CAC5D,EAAG,CAAC,CAAa,CAAC,EAEX,CACT"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{isBic as e,isDate as t,isEmail as n,isISODate as r,isURL as i}from"../regexp.mjs";var a={t:(e,t)=>({"formValidators.minLength":`Must be at least ${t?.min} characters long`,"formValidators.maxLength":`Must be at most ${t?.max} characters long`,"formValidators.email":`Must be a valid email address`,"formValidators.required":`${t?.label||`Value`} is required`,"formValidators.value":`Value`,"formValidators.mustBeNumber":`Must be a number`,"formValidators.oneOf":`Must be one of the following values: ${t?.allowedValues}`,"formValidators.typeOf":`Must have type of ${t?.allowedTypes}`,"formValidators.multiEmail":`Must be a comma or semicolon separated list of valid email addresses`,"formValidators.date":`Must be a valid date`,"garages.errors.website":`Must be a valid URL`,"garages.errors.bic":`Must be a valid BIC`,"formValidators.minLetters":`Must contain at least ${t?.smart_count} letters`,"formValidators.minDigits":`Must contain at least ${t?.smart_count} digits`})[e]||e},o=class o{static{this.minLength=(e,t)=>n=>!n||n.length<e?{id:`minLength`,message:t||a.t(`formValidators.minLength`,{min:e})}:null}static{this.maxLength=(e,t)=>n=>n&&n.length>e?{id:`maxLength`,message:t||a.t(`formValidators.maxLength`,{max:e})}:null}static{this.email=e=>t=>t&&!n(t)?{id:`email`,message:e||a.t(`formValidators.email`)}:null}static{this.required=e=>{function t(t,n){return!t&&t!==0?{id:`required`,message:e||a.t(`formValidators.required`,{label:n||a.t(`formValidators.value`)})}:null}return t.validatorId=`required`,t}}static{this.mustBeNumber=e=>t=>t&&Number.isNaN(+t)?{id:`mustBeNumber`,message:e||a.t(`formValidators.mustBeNumber`)}:null}static{this.oneOf=(e,t)=>n=>n&&!e.includes(n)?{id:`oneOf`,message:t||a.t(`formValidators.oneOf`,{allowedValues:e})}:null}static{this.typeOf=(e,t)=>n=>{if(Array.isArray(e)){for(let t=0;t<e.length;t+=1)if(typeof n===e[t])return null}else if(typeof n===e)return null;return{id:`typeOf`,message:t||`Must have type of ${e}`}}}static{this.multiEmail=e=>t=>{if(t){let r=t.replace(/ /g,``).replace(/,/g,`;`).split(`;`);for(let t=0;t<r.length;t+=1)if(!n(r[t]))return{id:`multiEmail`,message:e||a.t(`formValidators.multiEmail`)}}return null}}static{this.date=e=>n=>n&&!t(n)&&!r(n)?{id:`date`,message:e||a.t(`formValidators.date`)}:null}static{this.dateObject=e=>t=>t&&!t.isValid?{id:`date`,message:e||a.t(`formValidators.date`)}:null}static{this.website=e=>t=>t&&!i(t)?{id:`website`,message:e||a.t(`garages.errors.website`)}:null}static{this.bic=t=>n=>n&&!e(n)?{id:`bic`,message:t||a.t(`garages.errors.bic`)}:null}static{this.minLetters=(e,t)=>n=>n&&n.replace(/[^a-zöäüA-ZÖÄÜß]/g,``).length<e?{id:`minLetters`,message:t||a.t(`formValidators.minLetters`,{smart_count:e})}:null}static{this.minDigits=(e,t)=>n=>n&&n.replace(/[\D]/g,``).length<e?{id:`minDigits`,message:t||a.t(`formValidators.minDigits`,{smart_count:e})}:null}static{this.password=e=>t=>{let n=o.minLength(8)(t)||o.minLetters(1)(t)||o.minDigits(1)(t);return n?e?{id:`password`,message:e}:n:null}}};export{o as default};
|
|
2
|
-
//# sourceMappingURL=validators.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validators.mjs","names":[],"sources":["../../../../package/services/formValidation/validators.ts"],"sourcesContent":["import { isEmail, isDate, isISODate, isURL, isBic } from 'services/regexp';\nimport type { ValidatorFunction, ValidationError } from './types';\n\nconst polyglot = {\n t: (key: string, options?: Record<string, unknown>): string => {\n const translations: Record<string, string> = {\n 'formValidators.minLength': `Must be at least ${options?.min} characters long`,\n 'formValidators.maxLength': `Must be at most ${options?.max} characters long`,\n 'formValidators.email': 'Must be a valid email address',\n 'formValidators.required': `${options?.label || 'Value'} is required`,\n 'formValidators.value': 'Value',\n 'formValidators.mustBeNumber': 'Must be a number',\n 'formValidators.oneOf': `Must be one of the following values: ${options?.allowedValues}`,\n 'formValidators.typeOf': `Must have type of ${options?.allowedTypes}`,\n 'formValidators.multiEmail': 'Must be a comma or semicolon separated list of valid email addresses',\n 'formValidators.date': 'Must be a valid date',\n 'garages.errors.website': 'Must be a valid URL',\n 'garages.errors.bic': 'Must be a valid BIC',\n 'formValidators.minLetters': `Must contain at least ${options?.smart_count} letters`,\n 'formValidators.minDigits': `Must contain at least ${options?.smart_count} digits`,\n };\n return translations[key] || key;\n },\n};\n\nexport default class Validators {\n static minLength = (min: number, errorMsg?: string): ValidatorFunction => (value) => {\n if (!value || (value as string).length < min) return { id: 'minLength', message: errorMsg || polyglot.t('formValidators.minLength', { min }) };\n return null;\n };\n\n static maxLength = (max: number, errorMsg?: string): ValidatorFunction => (value) => {\n if (value && (value as string).length > max) return { id: 'maxLength', message: errorMsg || polyglot.t('formValidators.maxLength', { max }) };\n return null;\n };\n\n static email = (errorMsg?: string): ValidatorFunction => (value) => {\n if (value && !isEmail(value as string)) return { id: 'email', message: errorMsg || polyglot.t('formValidators.email') };\n return null;\n };\n\n static required = (errorMsg?: string): ValidatorFunction & { validatorId: string } => {\n function required(value: unknown, label?: string): ValidationError | null {\n if (!value && value !== 0) return { id: 'required', message: errorMsg || polyglot.t('formValidators.required', { label: label || polyglot.t('formValidators.value') }) };\n return null;\n }\n required.validatorId = 'required';\n return required;\n };\n\n static mustBeNumber = (errorMsg?: string): ValidatorFunction => (value) => {\n if (value && Number.isNaN(+(value as string))) return { id: 'mustBeNumber', message: errorMsg || polyglot.t('formValidators.mustBeNumber') };\n return null;\n };\n\n static oneOf = (allowedValues: unknown[], errorMsg?: string): ValidatorFunction => (value) => {\n if (value && !allowedValues.includes(value)) return { id: 'oneOf', message: errorMsg || polyglot.t('formValidators.oneOf', { allowedValues }) };\n return null;\n };\n\n static typeOf = (allowedTypes: string | string[], errorMsg?: string): ValidatorFunction => (value) => {\n if (Array.isArray(allowedTypes)) {\n for (let i = 0; i < allowedTypes.length; i += 1) {\n if (typeof value === allowedTypes[i]) return null;\n }\n } else if (typeof value === allowedTypes) {\n return null;\n }\n return { id: 'typeOf', message: errorMsg || `Must have type of ${allowedTypes}` };\n };\n\n static multiEmail = (errorMessage?: string): ValidatorFunction => (value) => {\n if (value) {\n const emailParts = (value as string).replace(/ /g, '').replace(/,/g, ';').split(';');\n for (let i = 0; i < emailParts.length; i += 1) {\n if (!isEmail(emailParts[i])) {\n return { id: 'multiEmail', message: errorMessage || polyglot.t('formValidators.multiEmail') };\n }\n }\n }\n return null;\n };\n\n static date = (errorMessage?: string): ValidatorFunction => (value) => {\n if (value && (!isDate(value as string) && !isISODate(value as string))) return { id: 'date', message: errorMessage || polyglot.t('formValidators.date') };\n return null;\n };\n\n static dateObject = (errorMessage?: string): ValidatorFunction => (value) => {\n if (value && !(value as { isValid: boolean }).isValid) return { id: 'date', message: errorMessage || polyglot.t('formValidators.date') };\n return null;\n };\n\n static website = (errorMsg?: string): ValidatorFunction => (value) => {\n if (value && !isURL(value as string)) return { id: 'website', message: errorMsg || polyglot.t('garages.errors.website') };\n return null;\n };\n\n static bic = (errorMsg?: string): ValidatorFunction => (value) => {\n if (value && !isBic(value as string)) return { id: 'bic', message: errorMsg || polyglot.t('garages.errors.bic') };\n return null;\n };\n\n static minLetters = (min: number, errorMsg?: string): ValidatorFunction => (value) => {\n if (value && (value as string).replace(/[^a-zöäüA-ZÖÄÜß]/g, '').length < min) return { id: 'minLetters', message: errorMsg || polyglot.t('formValidators.minLetters', { smart_count: min }) };\n return null;\n };\n\n static minDigits = (min: number, errorMsg?: string): ValidatorFunction => (value) => {\n if (value && (value as string).replace(/[\\D]/g, '').length < min) return { id: 'minDigits', message: errorMsg || polyglot.t('formValidators.minDigits', { smart_count: min }) };\n return null;\n };\n\n static password = (errorMsg?: string): ValidatorFunction => (value) => {\n const result = Validators.minLength(8)(value)\n || Validators.minLetters(1)(value)\n || Validators.minDigits(1)(value);\n if (result) return errorMsg ? { id: 'password', message: errorMsg } : result;\n return null;\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
function e(e){return/^[0-9]+$/.test(e)}function t(e){return/^[0-9]{2}.[0-9]{2}.[0-9]{4}$/.test(e)}function n(e){return/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}Z$/.test(e)}function r(e){return/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-ZöäüÜÖÄß\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(e)}function i(e){return/^[A-Z]{6}[A-Z\d]{2}([A-Z\d]{3})?$/.test(e)}function a(e){return/[-a-zA-Z0-9@:%._+~#=]{2,256}\.[a-z]{2,63}(\/[-a-zA-Z0-9@:%_+.~#?&//=]*)?$/.test(e)}function o(e){return/^[\w!@#$%^&*?±§~`'"/\\[\]{}\-,.();:><+=|öäüÖÄÜß €μ]{8,}$/.test(e)}function s(e){return/^(?=.*[a-zöäüA-ZÖÄÜß])/.test(e)}function c(e){return/^(?=.*\d)/.test(e)}function l(e){return o(e)&&s(e)&&c(e)}export{o as hasEightPasswordChars,c as hasOnePasswordDigit,s as hasOnePasswordLetter,i as isBic,t as isDate,r as isEmail,n as isISODate,e as isNumber,l as isPassword,a as isURL};
|
|
2
|
-
//# sourceMappingURL=regexp.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"regexp.mjs","names":[],"sources":["../../../package/services/regexp.ts"],"sourcesContent":["export function isNumber(string: string): boolean {\n return /^[0-9]+$/.test(string);\n}\n\nexport function isDate(string: string): boolean {\n return /^[0-9]{2}.[0-9]{2}.[0-9]{4}$/.test(string);\n}\n\nexport function isISODate(string: string): boolean {\n return /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}.[0-9]{3}Z$/.test(string);\n}\n\nexport function isEmail(string: string): boolean {\n return /^(([^<>()[\\]\\\\.,;:\\s@\"]+(\\.[^<>()[\\]\\\\.,;:\\s@\"]+)*)|(\".+\"))@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\])|(([a-zA-ZöäüÜÖÄß\\-0-9]+\\.)+[a-zA-Z]{2,}))$/.test(string);\n}\n\nexport function isBic(string: string): boolean {\n return /^[A-Z]{6}[A-Z\\d]{2}([A-Z\\d]{3})?$/.test(string);\n}\n\nexport function isURL(string: string): boolean {\n return /[-a-zA-Z0-9@:%._+~#=]{2,256}\\.[a-z]{2,63}(\\/[-a-zA-Z0-9@:%_+.~#?&//=]*)?$/.test(string);\n}\n\nexport function hasEightPasswordChars(string: string): boolean {\n return /^[\\w!@#$%^&*?±§~`'\"/\\\\[\\]{}\\-,.();:><+=|öäüÖÄÜß €μ]{8,}$/.test(string);\n}\n\nexport function hasOnePasswordLetter(string: string): boolean {\n return /^(?=.*[a-zöäüA-ZÖÄÜß])/.test(string);\n}\n\nexport function hasOnePasswordDigit(string: string): boolean {\n return /^(?=.*\\d)/.test(string);\n}\n\nexport function isPassword(string: string): boolean {\n return hasEightPasswordChars(string) && hasOnePasswordLetter(string) && hasOnePasswordDigit(string);\n}\n"],"mappings":"AAAA,SAAgB,EAAS,EAAyB,CAChD,MAAO,WAAW,KAAK,CAAM,CAC/B,CAEA,SAAgB,EAAO,EAAyB,CAC9C,MAAO,+BAA+B,KAAK,CAAM,CACnD,CAEA,SAAgB,EAAU,EAAyB,CACjD,MAAO,oEAAoE,KAAK,CAAM,CACxF,CAEA,SAAgB,EAAQ,EAAyB,CAC/C,MAAO,+JAA+J,KAAK,CAAM,CACnL,CAEA,SAAgB,EAAM,EAAyB,CAC7C,MAAO,oCAAoC,KAAK,CAAM,CACxD,CAEA,SAAgB,EAAM,EAAyB,CAC7C,MAAO,4EAA4E,KAAK,CAAM,CAChG,CAEA,SAAgB,EAAsB,EAAyB,CAC7D,MAAO,2DAA2D,KAAK,CAAM,CAC/E,CAEA,SAAgB,EAAqB,EAAyB,CAC5D,MAAO,yBAAyB,KAAK,CAAM,CAC7C,CAEA,SAAgB,EAAoB,EAAyB,CAC3D,MAAO,YAAY,KAAK,CAAM,CAChC,CAEA,SAAgB,EAAW,EAAyB,CAClD,OAAO,EAAsB,CAAM,GAAK,EAAqB,CAAM,GAAK,EAAoB,CAAM,CACpG"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { default as React } from 'react';
|
|
2
|
-
import { default as FormValidatorGroup } from './formValidatorGroup';
|
|
3
|
-
/**
|
|
4
|
-
* Creates the Form component for a FormValidatorGroup instance.
|
|
5
|
-
* Kept in a separate .tsx file so formValidatorGroup.ts stays framework-agnostic.
|
|
6
|
-
*/
|
|
7
|
-
export declare function createFormComponent(group: Pick<FormValidatorGroup, 'submit'>): React.FC<React.FormHTMLAttributes<HTMLFormElement>>;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { ValidatorFunction, ValidationError, UpdateListener } from './types';
|
|
2
|
-
export default class FormValidator<T = any> {
|
|
3
|
-
#private;
|
|
4
|
-
validators: ValidatorFunction[];
|
|
5
|
-
onUpdateCallbacks: Array<(validator: FormValidator<any>) => void>;
|
|
6
|
-
/**
|
|
7
|
-
* Create a FormValidator to use standalone or inside a FormValidatorGroup.
|
|
8
|
-
* @param initialValue - Default value of the field
|
|
9
|
-
* @param validators - Array of validator functions
|
|
10
|
-
*/
|
|
11
|
-
constructor(initialValue: T, validators?: ValidatorFunction[]);
|
|
12
|
-
/** Whether the user has entered and left the field. */
|
|
13
|
-
get touched(): boolean;
|
|
14
|
-
set touched(value: boolean);
|
|
15
|
-
get label(): string;
|
|
16
|
-
set label(value: string);
|
|
17
|
-
/** Whether the user has changed the value since initialisation. */
|
|
18
|
-
get dirty(): boolean;
|
|
19
|
-
set dirty(value: boolean);
|
|
20
|
-
get value(): T;
|
|
21
|
-
/** Sets value without validation (use `set()` for validated updates). */
|
|
22
|
-
set value(val: T);
|
|
23
|
-
get errors(): ValidationError[];
|
|
24
|
-
addError: (error: ValidationError) => void;
|
|
25
|
-
removeErrors: (errorIds: string[]) => void;
|
|
26
|
-
clearErrors: () => void;
|
|
27
|
-
hasError: (error?: string) => boolean;
|
|
28
|
-
getCurrentErrorMessage: () => string | null;
|
|
29
|
-
validate: () => void;
|
|
30
|
-
onUpdate: () => void;
|
|
31
|
-
registerOnUpdateListener: (callback: UpdateListener) => void;
|
|
32
|
-
removeOnUpdateListener: (callback: UpdateListener) => void;
|
|
33
|
-
/**
|
|
34
|
-
* Sets the field value with optional dirty tracking and re-validates.
|
|
35
|
-
* @param newValue - New field value
|
|
36
|
-
* @param wasUser - Whether the change was user-initiated (marks field dirty). Defaults to true.
|
|
37
|
-
*/
|
|
38
|
-
set: (newValue: T, wasUser?: boolean) => this;
|
|
39
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { default as FormValidator } from './formValidator';
|
|
2
|
-
import { ValidationError, ErrorParser, UpdateListener } from './types';
|
|
3
|
-
import { default as React } from 'react';
|
|
4
|
-
export type FormGroup = Record<string, FormValidator<any>>;
|
|
5
|
-
export type FormValues = Record<string, unknown>;
|
|
6
|
-
export type InferGroupValues<TGroup extends FormGroup> = {
|
|
7
|
-
[K in keyof TGroup]: TGroup[K] extends FormValidator<infer V> ? V : never;
|
|
8
|
-
};
|
|
9
|
-
/**
|
|
10
|
-
* The submitted result type: TInitial with all group-field keys replaced by
|
|
11
|
-
* their typed validator values.
|
|
12
|
-
*/
|
|
13
|
-
export type MergedValues<TInitial, TGroup extends FormGroup> = Omit<TInitial, keyof TGroup & string> & InferGroupValues<TGroup>;
|
|
14
|
-
export interface FormValidatorGroupOptions<TGroup extends FormGroup = FormGroup, TInitial = InferGroupValues<TGroup>> {
|
|
15
|
-
initialValues?: TInitial;
|
|
16
|
-
onSubmit?: (values: MergedValues<TInitial, TGroup>, group: FormValidatorGroup<TGroup, TInitial>) => Promise<void> | void;
|
|
17
|
-
onValidate?: (group: FormValidatorGroup<TGroup, TInitial>) => ValidationError | null | void;
|
|
18
|
-
errorParser?: ErrorParser;
|
|
19
|
-
onSubmitError?: (errors: ValidationError[]) => void;
|
|
20
|
-
}
|
|
21
|
-
interface ComponentLike {
|
|
22
|
-
forceUpdate: () => void;
|
|
23
|
-
}
|
|
24
|
-
export default class FormValidatorGroup<TGroup extends FormGroup = FormGroup, TInitial = InferGroupValues<TGroup>> {
|
|
25
|
-
#private;
|
|
26
|
-
group: TGroup;
|
|
27
|
-
component: ComponentLike | null;
|
|
28
|
-
onSubmitCallback: (values: MergedValues<TInitial, TGroup>, group: FormValidatorGroup<TGroup, TInitial>) => Promise<void> | void;
|
|
29
|
-
onValidateCallback: (group: FormValidatorGroup<TGroup, TInitial>) => ValidationError | null | void;
|
|
30
|
-
errorParser: ErrorParser;
|
|
31
|
-
onSubmitError: (errors: ValidationError[]) => void;
|
|
32
|
-
submitCount: number;
|
|
33
|
-
onDebounce: (values: MergedValues<TInitial, TGroup>) => void;
|
|
34
|
-
onReset: (group: FormValidatorGroup<TGroup, TInitial>, valuesAfterCreation: FormValues, initialValues: TInitial) => void;
|
|
35
|
-
/**
|
|
36
|
-
* @param formValidatorGroup - Map of field name → FormValidator
|
|
37
|
-
* @param component - Class component instance for forceUpdate (pass null when using hooks)
|
|
38
|
-
* @param options - initialValues, onSubmit, onValidate, errorParser
|
|
39
|
-
*/
|
|
40
|
-
constructor(formValidatorGroup: TGroup, component?: ComponentLike | null, { initialValues, onSubmit, onValidate, errorParser, onSubmitError, }?: FormValidatorGroupOptions<TGroup, TInitial>);
|
|
41
|
-
get isSubmitting(): boolean;
|
|
42
|
-
get wasTouched(): boolean;
|
|
43
|
-
get isDirty(): boolean;
|
|
44
|
-
get hasErrors(): boolean;
|
|
45
|
-
get initialValues(): TInitial;
|
|
46
|
-
getFormError: () => ValidationError | null;
|
|
47
|
-
set: (validatorName: keyof TGroup & string, value: unknown) => this;
|
|
48
|
-
reset: (toOverride?: FormValues) => void;
|
|
49
|
-
resetDirtyAndTouched: () => void;
|
|
50
|
-
/**
|
|
51
|
-
* Parses an API error and pushes field-level errors into the matching validators.
|
|
52
|
-
* When field errors are found and isInternal is set, surfaces the first field message.
|
|
53
|
-
* When the error shape isn't recognised (no field errors), always surfaces a generic message.
|
|
54
|
-
*/
|
|
55
|
-
parseError: (err: unknown, isInternal?: boolean) => void;
|
|
56
|
-
registerOnUpdateListener: (callback: UpdateListener) => void;
|
|
57
|
-
removeOnUpdateListener: (callback: UpdateListener) => void;
|
|
58
|
-
setSubmitting: (isSubmitting: boolean) => void;
|
|
59
|
-
submit: (event?: Event | React.SyntheticEvent | null) => Promise<void>;
|
|
60
|
-
getValues: () => MergedValues<TInitial, TGroup>;
|
|
61
|
-
validate: () => ValidationError | null | void;
|
|
62
|
-
setValidator: <K extends keyof TGroup & string>(validatorName: K, validator: TGroup[K]) => this;
|
|
63
|
-
}
|
|
64
|
-
export {};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export interface ValidationError {
|
|
2
|
-
id: string;
|
|
3
|
-
message: string;
|
|
4
|
-
}
|
|
5
|
-
/** A validator function receives the current value and an optional field label. */
|
|
6
|
-
export type ValidatorFunction = (value: unknown, label?: string) => ValidationError | null;
|
|
7
|
-
/** Callback registered on a FormValidator or FormValidatorGroup for re-render triggers. */
|
|
8
|
-
export type UpdateListener = () => void;
|
|
9
|
-
/** Parses a raw API error into a list of field errors. */
|
|
10
|
-
export type ErrorParser = (err: unknown) => ValidationError[];
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { default as FormValidator } from './formValidator';
|
|
2
|
-
/**
|
|
3
|
-
* Subscribes a function component to a FormValidator instance.
|
|
4
|
-
* Triggers a re-render whenever value, errors, touched, or dirty changes.
|
|
5
|
-
*
|
|
6
|
-
* @param formValidator - The FormValidator instance to subscribe to (or null)
|
|
7
|
-
* @returns The same formValidator for convenience
|
|
8
|
-
*/
|
|
9
|
-
export declare function useFormValidator<T extends FormValidator | null>(formValidator: T): T;
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { ValidatorFunction } from './types';
|
|
2
|
-
export default class Validators {
|
|
3
|
-
static minLength: (min: number, errorMsg?: string) => ValidatorFunction;
|
|
4
|
-
static maxLength: (max: number, errorMsg?: string) => ValidatorFunction;
|
|
5
|
-
static email: (errorMsg?: string) => ValidatorFunction;
|
|
6
|
-
static required: (errorMsg?: string) => ValidatorFunction & {
|
|
7
|
-
validatorId: string;
|
|
8
|
-
};
|
|
9
|
-
static mustBeNumber: (errorMsg?: string) => ValidatorFunction;
|
|
10
|
-
static oneOf: (allowedValues: unknown[], errorMsg?: string) => ValidatorFunction;
|
|
11
|
-
static typeOf: (allowedTypes: string | string[], errorMsg?: string) => ValidatorFunction;
|
|
12
|
-
static multiEmail: (errorMessage?: string) => ValidatorFunction;
|
|
13
|
-
static date: (errorMessage?: string) => ValidatorFunction;
|
|
14
|
-
static dateObject: (errorMessage?: string) => ValidatorFunction;
|
|
15
|
-
static website: (errorMsg?: string) => ValidatorFunction;
|
|
16
|
-
static bic: (errorMsg?: string) => ValidatorFunction;
|
|
17
|
-
static minLetters: (min: number, errorMsg?: string) => ValidatorFunction;
|
|
18
|
-
static minDigits: (min: number, errorMsg?: string) => ValidatorFunction;
|
|
19
|
-
static password: (errorMsg?: string) => ValidatorFunction;
|
|
20
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export declare function isNumber(string: string): boolean;
|
|
2
|
-
export declare function isDate(string: string): boolean;
|
|
3
|
-
export declare function isISODate(string: string): boolean;
|
|
4
|
-
export declare function isEmail(string: string): boolean;
|
|
5
|
-
export declare function isBic(string: string): boolean;
|
|
6
|
-
export declare function isURL(string: string): boolean;
|
|
7
|
-
export declare function hasEightPasswordChars(string: string): boolean;
|
|
8
|
-
export declare function hasOnePasswordLetter(string: string): boolean;
|
|
9
|
-
export declare function hasOnePasswordDigit(string: string): boolean;
|
|
10
|
-
export declare function isPassword(string: string): boolean;
|