@axenstudio/axen-form 0.1.1
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 +665 -0
- package/dist/adapters/yupAdapter.cjs +61 -0
- package/dist/adapters/yupAdapter.d.ts +21 -0
- package/dist/adapters/yupAdapter.d.ts.map +1 -0
- package/dist/adapters/yupAdapter.js +61 -0
- package/dist/adapters/zodAdapter.cjs +59 -0
- package/dist/adapters/zodAdapter.d.ts +22 -0
- package/dist/adapters/zodAdapter.d.ts.map +1 -0
- package/dist/adapters/zodAdapter.js +59 -0
- package/dist/core/dateUtils.cjs +69 -0
- package/dist/core/dateUtils.d.ts +28 -0
- package/dist/core/dateUtils.d.ts.map +1 -0
- package/dist/core/dateUtils.js +69 -0
- package/dist/core/formStore.cjs +184 -0
- package/dist/core/formStore.d.ts +39 -0
- package/dist/core/formStore.d.ts.map +1 -0
- package/dist/core/formStore.js +184 -0
- package/dist/core/numberUtils.cjs +59 -0
- package/dist/core/numberUtils.d.ts +26 -0
- package/dist/core/numberUtils.d.ts.map +1 -0
- package/dist/core/numberUtils.js +59 -0
- package/dist/core/pathUtils.cjs +44 -0
- package/dist/core/pathUtils.d.ts +15 -0
- package/dist/core/pathUtils.d.ts.map +1 -0
- package/dist/core/pathUtils.js +44 -0
- package/dist/core/payloadUtils.cjs +26 -0
- package/dist/core/payloadUtils.d.ts +22 -0
- package/dist/core/payloadUtils.d.ts.map +1 -0
- package/dist/core/payloadUtils.js +26 -0
- package/dist/core/validation.cjs +41 -0
- package/dist/core/validation.d.ts +7 -0
- package/dist/core/validation.d.ts.map +1 -0
- package/dist/core/validation.js +41 -0
- package/dist/fields/AutocompleteField/AutocompleteField.cjs +242 -0
- package/dist/fields/AutocompleteField/AutocompleteField.d.ts +6 -0
- package/dist/fields/AutocompleteField/AutocompleteField.d.ts.map +1 -0
- package/dist/fields/AutocompleteField/AutocompleteField.js +242 -0
- package/dist/fields/AutocompleteField/AutocompleteField.module.css +168 -0
- package/dist/fields/AutocompleteField/AutocompleteField.module.css.cjs +44 -0
- package/dist/fields/AutocompleteField/AutocompleteField.module.css.js +44 -0
- package/dist/fields/AutocompleteMultiField/AutocompleteMultiField.cjs +286 -0
- package/dist/fields/AutocompleteMultiField/AutocompleteMultiField.d.ts +6 -0
- package/dist/fields/AutocompleteMultiField/AutocompleteMultiField.d.ts.map +1 -0
- package/dist/fields/AutocompleteMultiField/AutocompleteMultiField.js +286 -0
- package/dist/fields/AutocompletePredictField/AutocompletePredictField.cjs +289 -0
- package/dist/fields/AutocompletePredictField/AutocompletePredictField.d.ts +10 -0
- package/dist/fields/AutocompletePredictField/AutocompletePredictField.d.ts.map +1 -0
- package/dist/fields/AutocompletePredictField/AutocompletePredictField.js +289 -0
- package/dist/fields/CheckboxField/CheckboxField.cjs +60 -0
- package/dist/fields/CheckboxField/CheckboxField.d.ts +3 -0
- package/dist/fields/CheckboxField/CheckboxField.d.ts.map +1 -0
- package/dist/fields/CheckboxField/CheckboxField.js +60 -0
- package/dist/fields/CheckboxField/CheckboxField.module.css +29 -0
- package/dist/fields/CheckboxField/CheckboxField.module.css.cjs +11 -0
- package/dist/fields/CheckboxField/CheckboxField.module.css.js +11 -0
- package/dist/fields/ColorField/ColorField.cjs +69 -0
- package/dist/fields/ColorField/ColorField.d.ts +3 -0
- package/dist/fields/ColorField/ColorField.d.ts.map +1 -0
- package/dist/fields/ColorField/ColorField.js +69 -0
- package/dist/fields/ColorField/ColorField.module.css +33 -0
- package/dist/fields/ColorField/ColorField.module.css.cjs +14 -0
- package/dist/fields/ColorField/ColorField.module.css.js +14 -0
- package/dist/fields/CurrencyField/CurrencyField.cjs +120 -0
- package/dist/fields/CurrencyField/CurrencyField.d.ts +10 -0
- package/dist/fields/CurrencyField/CurrencyField.d.ts.map +1 -0
- package/dist/fields/CurrencyField/CurrencyField.js +120 -0
- package/dist/fields/DateField/DateField.cjs +70 -0
- package/dist/fields/DateField/DateField.d.ts +7 -0
- package/dist/fields/DateField/DateField.d.ts.map +1 -0
- package/dist/fields/DateField/DateField.js +70 -0
- package/dist/fields/DateTimeField/DateTimeField.cjs +71 -0
- package/dist/fields/DateTimeField/DateTimeField.d.ts +8 -0
- package/dist/fields/DateTimeField/DateTimeField.d.ts.map +1 -0
- package/dist/fields/DateTimeField/DateTimeField.js +71 -0
- package/dist/fields/EmailField/EmailField.cjs +57 -0
- package/dist/fields/EmailField/EmailField.d.ts +3 -0
- package/dist/fields/EmailField/EmailField.d.ts.map +1 -0
- package/dist/fields/EmailField/EmailField.js +57 -0
- package/dist/fields/NumberField/NumberField.cjs +110 -0
- package/dist/fields/NumberField/NumberField.d.ts +10 -0
- package/dist/fields/NumberField/NumberField.d.ts.map +1 -0
- package/dist/fields/NumberField/NumberField.js +110 -0
- package/dist/fields/PasswordField/PasswordField.cjs +77 -0
- package/dist/fields/PasswordField/PasswordField.d.ts +3 -0
- package/dist/fields/PasswordField/PasswordField.d.ts.map +1 -0
- package/dist/fields/PasswordField/PasswordField.js +77 -0
- package/dist/fields/PasswordField/PasswordField.module.css +41 -0
- package/dist/fields/PasswordField/PasswordField.module.css.cjs +14 -0
- package/dist/fields/PasswordField/PasswordField.module.css.js +14 -0
- package/dist/fields/PhoneField/PhoneField.cjs +58 -0
- package/dist/fields/PhoneField/PhoneField.d.ts +3 -0
- package/dist/fields/PhoneField/PhoneField.d.ts.map +1 -0
- package/dist/fields/PhoneField/PhoneField.js +58 -0
- package/dist/fields/RadioField/RadioField.cjs +66 -0
- package/dist/fields/RadioField/RadioField.d.ts +3 -0
- package/dist/fields/RadioField/RadioField.d.ts.map +1 -0
- package/dist/fields/RadioField/RadioField.js +66 -0
- package/dist/fields/RadioField/RadioField.module.css +34 -0
- package/dist/fields/RadioField/RadioField.module.css.cjs +14 -0
- package/dist/fields/RadioField/RadioField.module.css.js +14 -0
- package/dist/fields/SelectField/SelectField.cjs +58 -0
- package/dist/fields/SelectField/SelectField.d.ts +3 -0
- package/dist/fields/SelectField/SelectField.d.ts.map +1 -0
- package/dist/fields/SelectField/SelectField.js +58 -0
- package/dist/fields/SliderField/SliderField.cjs +79 -0
- package/dist/fields/SliderField/SliderField.d.ts +7 -0
- package/dist/fields/SliderField/SliderField.d.ts.map +1 -0
- package/dist/fields/SliderField/SliderField.js +79 -0
- package/dist/fields/SliderField/SliderField.module.css +76 -0
- package/dist/fields/SliderField/SliderField.module.css.cjs +14 -0
- package/dist/fields/SliderField/SliderField.module.css.js +14 -0
- package/dist/fields/SwitchField/SwitchField.cjs +65 -0
- package/dist/fields/SwitchField/SwitchField.d.ts +3 -0
- package/dist/fields/SwitchField/SwitchField.d.ts.map +1 -0
- package/dist/fields/SwitchField/SwitchField.js +65 -0
- package/dist/fields/SwitchField/SwitchField.module.css +79 -0
- package/dist/fields/SwitchField/SwitchField.module.css.cjs +17 -0
- package/dist/fields/SwitchField/SwitchField.module.css.js +17 -0
- package/dist/fields/TextField/TextField.cjs +56 -0
- package/dist/fields/TextField/TextField.d.ts +3 -0
- package/dist/fields/TextField/TextField.d.ts.map +1 -0
- package/dist/fields/TextField/TextField.js +56 -0
- package/dist/fields/TextareaField/TextareaField.cjs +57 -0
- package/dist/fields/TextareaField/TextareaField.d.ts +5 -0
- package/dist/fields/TextareaField/TextareaField.d.ts.map +1 -0
- package/dist/fields/TextareaField/TextareaField.js +57 -0
- package/dist/fields/TimeField/TimeField.cjs +67 -0
- package/dist/fields/TimeField/TimeField.d.ts +6 -0
- package/dist/fields/TimeField/TimeField.d.ts.map +1 -0
- package/dist/fields/TimeField/TimeField.js +67 -0
- package/dist/fields/defaultComponentMap.cjs +43 -0
- package/dist/fields/defaultComponentMap.d.ts +7 -0
- package/dist/fields/defaultComponentMap.d.ts.map +1 -0
- package/dist/fields/defaultComponentMap.js +43 -0
- package/dist/fields/fieldBase.module.css +201 -0
- package/dist/fields/fieldBase.module.css.cjs +50 -0
- package/dist/fields/fieldBase.module.css.js +50 -0
- package/dist/fields/fieldUtils.cjs +26 -0
- package/dist/fields/fieldUtils.d.ts +24 -0
- package/dist/fields/fieldUtils.d.ts.map +1 -0
- package/dist/fields/fieldUtils.js +26 -0
- package/dist/index.cjs +99 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +99 -0
- package/dist/layout/Box/Box.cjs +70 -0
- package/dist/layout/Box/Box.d.ts +6 -0
- package/dist/layout/Box/Box.d.ts.map +1 -0
- package/dist/layout/Box/Box.js +70 -0
- package/dist/layout/Box/Box.module.css +3 -0
- package/dist/layout/Box/Box.module.css.cjs +8 -0
- package/dist/layout/Box/Box.module.css.js +8 -0
- package/dist/layout/Divider/Divider.cjs +20 -0
- package/dist/layout/Divider/Divider.d.ts +6 -0
- package/dist/layout/Divider/Divider.d.ts.map +1 -0
- package/dist/layout/Divider/Divider.js +20 -0
- package/dist/layout/Divider/Divider.module.css +25 -0
- package/dist/layout/Divider/Divider.module.css.cjs +14 -0
- package/dist/layout/Divider/Divider.module.css.js +14 -0
- package/dist/layout/Grid/Grid.cjs +106 -0
- package/dist/layout/Grid/Grid.d.ts +7 -0
- package/dist/layout/Grid/Grid.d.ts.map +1 -0
- package/dist/layout/Grid/Grid.js +106 -0
- package/dist/layout/Grid/Grid.module.css +43 -0
- package/dist/layout/Grid/Grid.module.css.cjs +23 -0
- package/dist/layout/Grid/Grid.module.css.js +23 -0
- package/dist/layout/Spacer/Spacer.cjs +30 -0
- package/dist/layout/Spacer/Spacer.d.ts +21 -0
- package/dist/layout/Spacer/Spacer.d.ts.map +1 -0
- package/dist/layout/Spacer/Spacer.js +30 -0
- package/dist/layout/Stack/Stack.cjs +52 -0
- package/dist/layout/Stack/Stack.d.ts +7 -0
- package/dist/layout/Stack/Stack.d.ts.map +1 -0
- package/dist/layout/Stack/Stack.js +52 -0
- package/dist/layout/Stack/Stack.module.css +3 -0
- package/dist/layout/Stack/Stack.module.css.cjs +8 -0
- package/dist/layout/Stack/Stack.module.css.js +8 -0
- package/dist/layout/index.d.ts +6 -0
- package/dist/layout/index.d.ts.map +1 -0
- package/dist/react/AxenArrayField.cjs +80 -0
- package/dist/react/AxenArrayField.d.ts +15 -0
- package/dist/react/AxenArrayField.d.ts.map +1 -0
- package/dist/react/AxenArrayField.js +80 -0
- package/dist/react/AxenField.cjs +62 -0
- package/dist/react/AxenField.d.ts +13 -0
- package/dist/react/AxenField.d.ts.map +1 -0
- package/dist/react/AxenField.js +62 -0
- package/dist/react/AxenForm.cjs +134 -0
- package/dist/react/AxenForm.d.ts +7 -0
- package/dist/react/AxenForm.d.ts.map +1 -0
- package/dist/react/AxenForm.js +134 -0
- package/dist/react/FormContext.cjs +13 -0
- package/dist/react/FormContext.d.ts +11 -0
- package/dist/react/FormContext.d.ts.map +1 -0
- package/dist/react/FormContext.js +13 -0
- package/dist/react/useAxenForm.cjs +88 -0
- package/dist/react/useAxenForm.d.ts +8 -0
- package/dist/react/useAxenForm.d.ts.map +1 -0
- package/dist/react/useAxenForm.js +88 -0
- package/dist/react/useField.cjs +41 -0
- package/dist/react/useField.d.ts +13 -0
- package/dist/react/useField.d.ts.map +1 -0
- package/dist/react/useField.js +41 -0
- package/dist/react/useFieldArray.cjs +74 -0
- package/dist/react/useFieldArray.d.ts +5 -0
- package/dist/react/useFieldArray.d.ts.map +1 -0
- package/dist/react/useFieldArray.js +74 -0
- package/dist/types.d.ts +226 -0
- package/dist/types.d.ts.map +1 -0
- package/package.json +87 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
function yupAdapter(yup) {
|
|
4
|
+
return {
|
|
5
|
+
buildSchema(fields) {
|
|
6
|
+
const shape = {};
|
|
7
|
+
for (const field of fields) {
|
|
8
|
+
if (field.validation) {
|
|
9
|
+
shape[field.name] = field.validation;
|
|
10
|
+
} else if (field.required) {
|
|
11
|
+
const msg = field.requiredMessage ?? `${field.label ?? field.name} is required`;
|
|
12
|
+
switch (field.type) {
|
|
13
|
+
case "checkbox":
|
|
14
|
+
case "switch":
|
|
15
|
+
shape[field.name] = yup.boolean().oneOf([true], msg).required(msg);
|
|
16
|
+
break;
|
|
17
|
+
case "number":
|
|
18
|
+
case "currency":
|
|
19
|
+
case "slider":
|
|
20
|
+
shape[field.name] = yup.number().required(msg).typeError(msg);
|
|
21
|
+
break;
|
|
22
|
+
case "autocomplete-multi":
|
|
23
|
+
shape[field.name] = yup.array().min(1, msg).required(msg);
|
|
24
|
+
break;
|
|
25
|
+
default:
|
|
26
|
+
shape[field.name] = yup.string().required(msg);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return yup.object(shape);
|
|
31
|
+
},
|
|
32
|
+
async validate(schema, values) {
|
|
33
|
+
const yupSchema = schema;
|
|
34
|
+
try {
|
|
35
|
+
await yupSchema.validate(values, { abortEarly: false });
|
|
36
|
+
return {};
|
|
37
|
+
} catch (err) {
|
|
38
|
+
const validationError = err;
|
|
39
|
+
const errors = {};
|
|
40
|
+
if (validationError.inner) {
|
|
41
|
+
for (const e of validationError.inner) {
|
|
42
|
+
if (e.path && !errors[e.path]) {
|
|
43
|
+
errors[e.path] = e.message;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return errors;
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
async validateField(schema, name, value) {
|
|
51
|
+
const yupSchema = schema;
|
|
52
|
+
try {
|
|
53
|
+
await yupSchema.validateAt(name, { [name]: value });
|
|
54
|
+
return void 0;
|
|
55
|
+
} catch (err) {
|
|
56
|
+
return err.message;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
exports.yupAdapter = yupAdapter;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { ValidationAdapter } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Yup validation adapter.
|
|
4
|
+
* Uses yup's ObjectSchema for form-level and field-level validation.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import * as yup from 'yup';
|
|
8
|
+
* import { yupAdapter } from '@axenstudio/axen-form/yupAdapter';
|
|
9
|
+
*
|
|
10
|
+
* const adapter = yupAdapter(yup);
|
|
11
|
+
*/
|
|
12
|
+
interface YupLike {
|
|
13
|
+
boolean(): any;
|
|
14
|
+
number(): any;
|
|
15
|
+
string(): any;
|
|
16
|
+
array(): any;
|
|
17
|
+
object(shape: Record<string, any>): any;
|
|
18
|
+
}
|
|
19
|
+
export declare function yupAdapter(yup: YupLike): ValidationAdapter;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=yupAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yupAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/yupAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE/D;;;;;;;;;GASG;AAGH,UAAU,OAAO;IACf,OAAO,IAAI,GAAG,CAAC;IACf,MAAM,IAAI,GAAG,CAAC;IACd,MAAM,IAAI,GAAG,CAAC;IACd,KAAK,IAAI,GAAG,CAAC;IACb,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;CACzC;AAOD,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,CA6D1D"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
function yupAdapter(yup) {
|
|
2
|
+
return {
|
|
3
|
+
buildSchema(fields) {
|
|
4
|
+
const shape = {};
|
|
5
|
+
for (const field of fields) {
|
|
6
|
+
if (field.validation) {
|
|
7
|
+
shape[field.name] = field.validation;
|
|
8
|
+
} else if (field.required) {
|
|
9
|
+
const msg = field.requiredMessage ?? `${field.label ?? field.name} is required`;
|
|
10
|
+
switch (field.type) {
|
|
11
|
+
case "checkbox":
|
|
12
|
+
case "switch":
|
|
13
|
+
shape[field.name] = yup.boolean().oneOf([true], msg).required(msg);
|
|
14
|
+
break;
|
|
15
|
+
case "number":
|
|
16
|
+
case "currency":
|
|
17
|
+
case "slider":
|
|
18
|
+
shape[field.name] = yup.number().required(msg).typeError(msg);
|
|
19
|
+
break;
|
|
20
|
+
case "autocomplete-multi":
|
|
21
|
+
shape[field.name] = yup.array().min(1, msg).required(msg);
|
|
22
|
+
break;
|
|
23
|
+
default:
|
|
24
|
+
shape[field.name] = yup.string().required(msg);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return yup.object(shape);
|
|
29
|
+
},
|
|
30
|
+
async validate(schema, values) {
|
|
31
|
+
const yupSchema = schema;
|
|
32
|
+
try {
|
|
33
|
+
await yupSchema.validate(values, { abortEarly: false });
|
|
34
|
+
return {};
|
|
35
|
+
} catch (err) {
|
|
36
|
+
const validationError = err;
|
|
37
|
+
const errors = {};
|
|
38
|
+
if (validationError.inner) {
|
|
39
|
+
for (const e of validationError.inner) {
|
|
40
|
+
if (e.path && !errors[e.path]) {
|
|
41
|
+
errors[e.path] = e.message;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return errors;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
async validateField(schema, name, value) {
|
|
49
|
+
const yupSchema = schema;
|
|
50
|
+
try {
|
|
51
|
+
await yupSchema.validateAt(name, { [name]: value });
|
|
52
|
+
return void 0;
|
|
53
|
+
} catch (err) {
|
|
54
|
+
return err.message;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export {
|
|
60
|
+
yupAdapter
|
|
61
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
function zodAdapter(z) {
|
|
4
|
+
return {
|
|
5
|
+
buildSchema(fields) {
|
|
6
|
+
const shape = {};
|
|
7
|
+
for (const field of fields) {
|
|
8
|
+
if (field.validation) {
|
|
9
|
+
shape[field.name] = field.validation;
|
|
10
|
+
} else if (field.required) {
|
|
11
|
+
const msg = field.requiredMessage ?? `${field.label ?? field.name} is required`;
|
|
12
|
+
switch (field.type) {
|
|
13
|
+
case "checkbox":
|
|
14
|
+
case "switch":
|
|
15
|
+
shape[field.name] = z.literal(true, { errorMap: () => ({ message: msg }) });
|
|
16
|
+
break;
|
|
17
|
+
case "number":
|
|
18
|
+
case "currency":
|
|
19
|
+
case "slider":
|
|
20
|
+
shape[field.name] = z.number({ required_error: msg, invalid_type_error: msg });
|
|
21
|
+
break;
|
|
22
|
+
case "autocomplete-multi":
|
|
23
|
+
shape[field.name] = z.array(z.unknown()).min(1, msg);
|
|
24
|
+
break;
|
|
25
|
+
default:
|
|
26
|
+
shape[field.name] = z.string({ required_error: msg }).min(1, msg);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return z.object(shape);
|
|
31
|
+
},
|
|
32
|
+
async validate(schema, values) {
|
|
33
|
+
var _a;
|
|
34
|
+
const zodSchema = schema;
|
|
35
|
+
const result = zodSchema.safeParse(values);
|
|
36
|
+
if (result.success) {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
const errors = {};
|
|
40
|
+
for (const issue of ((_a = result.error) == null ? void 0 : _a.issues) ?? []) {
|
|
41
|
+
const path = issue.path.join(".");
|
|
42
|
+
if (path && !errors[path]) {
|
|
43
|
+
errors[path] = issue.message;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return errors;
|
|
47
|
+
},
|
|
48
|
+
async validateField(schema, name, value) {
|
|
49
|
+
var _a, _b;
|
|
50
|
+
const zodSchema = schema;
|
|
51
|
+
const fieldSchema = zodSchema.shape[name];
|
|
52
|
+
if (!fieldSchema) return void 0;
|
|
53
|
+
const result = fieldSchema.safeParse(value);
|
|
54
|
+
if (result.success) return void 0;
|
|
55
|
+
return (_b = (_a = result.error) == null ? void 0 : _a.issues[0]) == null ? void 0 : _b.message;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
exports.zodAdapter = zodAdapter;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ValidationAdapter } from '../types';
|
|
2
|
+
/**
|
|
3
|
+
* Zod validation adapter.
|
|
4
|
+
* Uses Zod's schema for form-level and field-level validation.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* import { z } from 'zod';
|
|
8
|
+
* import { zodAdapter } from '@axenstudio/axen-form/zodAdapter';
|
|
9
|
+
*
|
|
10
|
+
* const adapter = zodAdapter(z);
|
|
11
|
+
*/
|
|
12
|
+
interface ZodLike {
|
|
13
|
+
literal(value: any, params?: any): any;
|
|
14
|
+
number(params?: any): any;
|
|
15
|
+
string(params?: any): any;
|
|
16
|
+
array(schema: any): any;
|
|
17
|
+
unknown(): any;
|
|
18
|
+
object(shape: Record<string, any>): any;
|
|
19
|
+
}
|
|
20
|
+
export declare function zodAdapter(z: ZodLike): ValidationAdapter;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=zodAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zodAdapter.d.ts","sourceRoot":"","sources":["../../src/adapters/zodAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE/D;;;;;;;;;GASG;AAGH,UAAU,OAAO;IACf,OAAO,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;IACvC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;IAC1B,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;IAC1B,KAAK,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;IACxB,OAAO,IAAI,GAAG,CAAC;IACf,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;CACzC;AAOD,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,iBAAiB,CA4DxD"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
function zodAdapter(z) {
|
|
2
|
+
return {
|
|
3
|
+
buildSchema(fields) {
|
|
4
|
+
const shape = {};
|
|
5
|
+
for (const field of fields) {
|
|
6
|
+
if (field.validation) {
|
|
7
|
+
shape[field.name] = field.validation;
|
|
8
|
+
} else if (field.required) {
|
|
9
|
+
const msg = field.requiredMessage ?? `${field.label ?? field.name} is required`;
|
|
10
|
+
switch (field.type) {
|
|
11
|
+
case "checkbox":
|
|
12
|
+
case "switch":
|
|
13
|
+
shape[field.name] = z.literal(true, { errorMap: () => ({ message: msg }) });
|
|
14
|
+
break;
|
|
15
|
+
case "number":
|
|
16
|
+
case "currency":
|
|
17
|
+
case "slider":
|
|
18
|
+
shape[field.name] = z.number({ required_error: msg, invalid_type_error: msg });
|
|
19
|
+
break;
|
|
20
|
+
case "autocomplete-multi":
|
|
21
|
+
shape[field.name] = z.array(z.unknown()).min(1, msg);
|
|
22
|
+
break;
|
|
23
|
+
default:
|
|
24
|
+
shape[field.name] = z.string({ required_error: msg }).min(1, msg);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return z.object(shape);
|
|
29
|
+
},
|
|
30
|
+
async validate(schema, values) {
|
|
31
|
+
var _a;
|
|
32
|
+
const zodSchema = schema;
|
|
33
|
+
const result = zodSchema.safeParse(values);
|
|
34
|
+
if (result.success) {
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
const errors = {};
|
|
38
|
+
for (const issue of ((_a = result.error) == null ? void 0 : _a.issues) ?? []) {
|
|
39
|
+
const path = issue.path.join(".");
|
|
40
|
+
if (path && !errors[path]) {
|
|
41
|
+
errors[path] = issue.message;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return errors;
|
|
45
|
+
},
|
|
46
|
+
async validateField(schema, name, value) {
|
|
47
|
+
var _a, _b;
|
|
48
|
+
const zodSchema = schema;
|
|
49
|
+
const fieldSchema = zodSchema.shape[name];
|
|
50
|
+
if (!fieldSchema) return void 0;
|
|
51
|
+
const result = fieldSchema.safeParse(value);
|
|
52
|
+
if (result.success) return void 0;
|
|
53
|
+
return (_b = (_a = result.error) == null ? void 0 : _a.issues[0]) == null ? void 0 : _b.message;
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export {
|
|
58
|
+
zodAdapter
|
|
59
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
function formatDateLocale(isoDate, locale) {
|
|
4
|
+
if (!isoDate) return "";
|
|
5
|
+
const date = /* @__PURE__ */ new Date(isoDate + "T00:00:00");
|
|
6
|
+
if (Number.isNaN(date.getTime())) return isoDate;
|
|
7
|
+
return date.toLocaleDateString(locale ?? navigator.language, {
|
|
8
|
+
year: "numeric",
|
|
9
|
+
month: "2-digit",
|
|
10
|
+
day: "2-digit"
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
function formatTimeLocale(isoTime, locale, ampm) {
|
|
14
|
+
if (!isoTime) return "";
|
|
15
|
+
const [hours, minutes] = isoTime.split(":").map(Number);
|
|
16
|
+
if (Number.isNaN(hours) || Number.isNaN(minutes)) return isoTime;
|
|
17
|
+
const date = new Date(2e3, 0, 1, hours, minutes);
|
|
18
|
+
if (Number.isNaN(date.getTime())) return isoTime;
|
|
19
|
+
return date.toLocaleTimeString(locale ?? navigator.language, {
|
|
20
|
+
hour: "2-digit",
|
|
21
|
+
minute: "2-digit",
|
|
22
|
+
hour12: ampm
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function formatDateTimeLocale(isoDateTime, locale, ampm) {
|
|
26
|
+
if (!isoDateTime) return "";
|
|
27
|
+
const date = new Date(isoDateTime);
|
|
28
|
+
if (Number.isNaN(date.getTime())) return isoDateTime;
|
|
29
|
+
return date.toLocaleString(locale ?? navigator.language, {
|
|
30
|
+
year: "numeric",
|
|
31
|
+
month: "2-digit",
|
|
32
|
+
day: "2-digit",
|
|
33
|
+
hour: "2-digit",
|
|
34
|
+
minute: "2-digit",
|
|
35
|
+
hour12: ampm
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function toISODateString(date) {
|
|
39
|
+
const y = date.getFullYear();
|
|
40
|
+
const m = String(date.getMonth() + 1).padStart(2, "0");
|
|
41
|
+
const d = String(date.getDate()).padStart(2, "0");
|
|
42
|
+
return `${y}-${m}-${d}`;
|
|
43
|
+
}
|
|
44
|
+
function toISODateTimeLocalString(date) {
|
|
45
|
+
const y = date.getFullYear();
|
|
46
|
+
const mo = String(date.getMonth() + 1).padStart(2, "0");
|
|
47
|
+
const d = String(date.getDate()).padStart(2, "0");
|
|
48
|
+
const h = String(date.getHours()).padStart(2, "0");
|
|
49
|
+
const mi = String(date.getMinutes()).padStart(2, "0");
|
|
50
|
+
return `${y}-${mo}-${d}T${h}:${mi}`;
|
|
51
|
+
}
|
|
52
|
+
function toISOTimeString(date) {
|
|
53
|
+
const h = String(date.getHours()).padStart(2, "0");
|
|
54
|
+
const m = String(date.getMinutes()).padStart(2, "0");
|
|
55
|
+
return `${h}:${m}`;
|
|
56
|
+
}
|
|
57
|
+
function getDefaultLocale() {
|
|
58
|
+
if (typeof navigator !== "undefined" && navigator.language) {
|
|
59
|
+
return navigator.language;
|
|
60
|
+
}
|
|
61
|
+
return "en-US";
|
|
62
|
+
}
|
|
63
|
+
exports.formatDateLocale = formatDateLocale;
|
|
64
|
+
exports.formatDateTimeLocale = formatDateTimeLocale;
|
|
65
|
+
exports.formatTimeLocale = formatTimeLocale;
|
|
66
|
+
exports.getDefaultLocale = getDefaultLocale;
|
|
67
|
+
exports.toISODateString = toISODateString;
|
|
68
|
+
exports.toISODateTimeLocalString = toISODateTimeLocalString;
|
|
69
|
+
exports.toISOTimeString = toISOTimeString;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Date/Time locale-aware utilities.
|
|
3
|
+
*
|
|
4
|
+
* Display: locale-aware (user sees dates/times in their locale format)
|
|
5
|
+
* Storage/Payload: always ISO standard (YYYY-MM-DD, HH:MM, YYYY-MM-DDTHH:MM)
|
|
6
|
+
*/
|
|
7
|
+
/** Format an ISO date string to locale display */
|
|
8
|
+
export declare function formatDateLocale(isoDate: string, locale?: string): string;
|
|
9
|
+
/** Format an ISO time string (HH:MM or HH:MM:SS) to locale display */
|
|
10
|
+
export declare function formatTimeLocale(isoTime: string, locale?: string, ampm?: boolean): string;
|
|
11
|
+
/** Format an ISO datetime-local string to locale display */
|
|
12
|
+
export declare function formatDateTimeLocale(isoDateTime: string, locale?: string, ampm?: boolean): string;
|
|
13
|
+
/** Parse a locale-formatted date back to ISO (YYYY-MM-DD) */
|
|
14
|
+
export declare function parseDateToISO(displayValue: string, _locale?: string): string;
|
|
15
|
+
/** Parse a locale-formatted datetime back to ISO datetime-local */
|
|
16
|
+
export declare function parseDateTimeToISO(displayValue: string): string;
|
|
17
|
+
/** Convert Date to YYYY-MM-DD */
|
|
18
|
+
export declare function toISODateString(date: Date): string;
|
|
19
|
+
/** Convert Date to YYYY-MM-DDTHH:MM (datetime-local format) */
|
|
20
|
+
export declare function toISODateTimeLocalString(date: Date): string;
|
|
21
|
+
/** Convert Date to HH:MM */
|
|
22
|
+
export declare function toISOTimeString(date: Date): string;
|
|
23
|
+
/**
|
|
24
|
+
* Get the user's default locale.
|
|
25
|
+
* Falls back to 'en-US' in non-browser environments (SSR/tests).
|
|
26
|
+
*/
|
|
27
|
+
export declare function getDefaultLocale(): string;
|
|
28
|
+
//# sourceMappingURL=dateUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dateUtils.d.ts","sourceRoot":"","sources":["../../src/core/dateUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CASzE;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAYzF;AAED,4DAA4D;AAC5D,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAYjG;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ7E;AAED,mEAAmE;AACnE,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAO/D;AAED,iCAAiC;AACjC,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAKlD;AAED,+DAA+D;AAC/D,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAO3D;AAED,4BAA4B;AAC5B,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAIlD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAKzC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
function formatDateLocale(isoDate, locale) {
|
|
2
|
+
if (!isoDate) return "";
|
|
3
|
+
const date = /* @__PURE__ */ new Date(isoDate + "T00:00:00");
|
|
4
|
+
if (Number.isNaN(date.getTime())) return isoDate;
|
|
5
|
+
return date.toLocaleDateString(locale ?? navigator.language, {
|
|
6
|
+
year: "numeric",
|
|
7
|
+
month: "2-digit",
|
|
8
|
+
day: "2-digit"
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
function formatTimeLocale(isoTime, locale, ampm) {
|
|
12
|
+
if (!isoTime) return "";
|
|
13
|
+
const [hours, minutes] = isoTime.split(":").map(Number);
|
|
14
|
+
if (Number.isNaN(hours) || Number.isNaN(minutes)) return isoTime;
|
|
15
|
+
const date = new Date(2e3, 0, 1, hours, minutes);
|
|
16
|
+
if (Number.isNaN(date.getTime())) return isoTime;
|
|
17
|
+
return date.toLocaleTimeString(locale ?? navigator.language, {
|
|
18
|
+
hour: "2-digit",
|
|
19
|
+
minute: "2-digit",
|
|
20
|
+
hour12: ampm
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function formatDateTimeLocale(isoDateTime, locale, ampm) {
|
|
24
|
+
if (!isoDateTime) return "";
|
|
25
|
+
const date = new Date(isoDateTime);
|
|
26
|
+
if (Number.isNaN(date.getTime())) return isoDateTime;
|
|
27
|
+
return date.toLocaleString(locale ?? navigator.language, {
|
|
28
|
+
year: "numeric",
|
|
29
|
+
month: "2-digit",
|
|
30
|
+
day: "2-digit",
|
|
31
|
+
hour: "2-digit",
|
|
32
|
+
minute: "2-digit",
|
|
33
|
+
hour12: ampm
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
function toISODateString(date) {
|
|
37
|
+
const y = date.getFullYear();
|
|
38
|
+
const m = String(date.getMonth() + 1).padStart(2, "0");
|
|
39
|
+
const d = String(date.getDate()).padStart(2, "0");
|
|
40
|
+
return `${y}-${m}-${d}`;
|
|
41
|
+
}
|
|
42
|
+
function toISODateTimeLocalString(date) {
|
|
43
|
+
const y = date.getFullYear();
|
|
44
|
+
const mo = String(date.getMonth() + 1).padStart(2, "0");
|
|
45
|
+
const d = String(date.getDate()).padStart(2, "0");
|
|
46
|
+
const h = String(date.getHours()).padStart(2, "0");
|
|
47
|
+
const mi = String(date.getMinutes()).padStart(2, "0");
|
|
48
|
+
return `${y}-${mo}-${d}T${h}:${mi}`;
|
|
49
|
+
}
|
|
50
|
+
function toISOTimeString(date) {
|
|
51
|
+
const h = String(date.getHours()).padStart(2, "0");
|
|
52
|
+
const m = String(date.getMinutes()).padStart(2, "0");
|
|
53
|
+
return `${h}:${m}`;
|
|
54
|
+
}
|
|
55
|
+
function getDefaultLocale() {
|
|
56
|
+
if (typeof navigator !== "undefined" && navigator.language) {
|
|
57
|
+
return navigator.language;
|
|
58
|
+
}
|
|
59
|
+
return "en-US";
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
formatDateLocale,
|
|
63
|
+
formatDateTimeLocale,
|
|
64
|
+
formatTimeLocale,
|
|
65
|
+
getDefaultLocale,
|
|
66
|
+
toISODateString,
|
|
67
|
+
toISODateTimeLocalString,
|
|
68
|
+
toISOTimeString
|
|
69
|
+
};
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const pathUtils = require("./pathUtils.cjs");
|
|
4
|
+
function createFormStore(options) {
|
|
5
|
+
const {
|
|
6
|
+
initialValues,
|
|
7
|
+
validationAdapter,
|
|
8
|
+
validateOnChange = true,
|
|
9
|
+
validateOnBlur = true
|
|
10
|
+
} = options;
|
|
11
|
+
let state = {
|
|
12
|
+
values: structuredClone(initialValues),
|
|
13
|
+
errors: {},
|
|
14
|
+
touched: {},
|
|
15
|
+
dirty: false,
|
|
16
|
+
isSubmitting: false,
|
|
17
|
+
submitCount: 0,
|
|
18
|
+
initialValues: structuredClone(initialValues)
|
|
19
|
+
};
|
|
20
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
21
|
+
const fieldSubscribers = /* @__PURE__ */ new Map();
|
|
22
|
+
let validationSchema = options.validationSchema;
|
|
23
|
+
if (validationAdapter && options.fields && !validationSchema) {
|
|
24
|
+
validationSchema = validationAdapter.buildSchema(options.fields);
|
|
25
|
+
}
|
|
26
|
+
function getState() {
|
|
27
|
+
return state;
|
|
28
|
+
}
|
|
29
|
+
function subscribe(listener) {
|
|
30
|
+
subscribers.add(listener);
|
|
31
|
+
return () => subscribers.delete(listener);
|
|
32
|
+
}
|
|
33
|
+
function subscribeField(name, listener) {
|
|
34
|
+
var _a;
|
|
35
|
+
if (!fieldSubscribers.has(name)) {
|
|
36
|
+
fieldSubscribers.set(name, /* @__PURE__ */ new Set());
|
|
37
|
+
}
|
|
38
|
+
(_a = fieldSubscribers.get(name)) == null ? void 0 : _a.add(listener);
|
|
39
|
+
return () => {
|
|
40
|
+
var _a2;
|
|
41
|
+
return (_a2 = fieldSubscribers.get(name)) == null ? void 0 : _a2.delete(listener);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function notify() {
|
|
45
|
+
subscribers.forEach((fn) => fn());
|
|
46
|
+
}
|
|
47
|
+
function notifyField(name) {
|
|
48
|
+
var _a;
|
|
49
|
+
(_a = fieldSubscribers.get(name)) == null ? void 0 : _a.forEach((fn) => fn());
|
|
50
|
+
}
|
|
51
|
+
function setFieldValue(name, value) {
|
|
52
|
+
state = {
|
|
53
|
+
...state,
|
|
54
|
+
values: pathUtils.set(state.values, name, value),
|
|
55
|
+
dirty: true
|
|
56
|
+
};
|
|
57
|
+
notifyField(name);
|
|
58
|
+
notify();
|
|
59
|
+
if (validateOnChange && validationAdapter && validationSchema) {
|
|
60
|
+
runFieldValidation(name);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function setFieldTouched(name, touched = true) {
|
|
64
|
+
state = {
|
|
65
|
+
...state,
|
|
66
|
+
touched: { ...state.touched, [name]: touched }
|
|
67
|
+
};
|
|
68
|
+
notifyField(name);
|
|
69
|
+
notify();
|
|
70
|
+
if (validateOnBlur && touched && validationAdapter && validationSchema) {
|
|
71
|
+
runFieldValidation(name);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function setFieldError(name, error) {
|
|
75
|
+
const next = { ...state.errors };
|
|
76
|
+
if (error) {
|
|
77
|
+
next[name] = error;
|
|
78
|
+
} else {
|
|
79
|
+
delete next[name];
|
|
80
|
+
}
|
|
81
|
+
state = { ...state, errors: next };
|
|
82
|
+
notifyField(name);
|
|
83
|
+
notify();
|
|
84
|
+
}
|
|
85
|
+
function setValues(values) {
|
|
86
|
+
state = { ...state, values, dirty: true };
|
|
87
|
+
notify();
|
|
88
|
+
subscribers.forEach((fn) => fn());
|
|
89
|
+
}
|
|
90
|
+
function setErrors(errors) {
|
|
91
|
+
state = { ...state, errors };
|
|
92
|
+
notify();
|
|
93
|
+
}
|
|
94
|
+
function resetForm(nextValues) {
|
|
95
|
+
const newValues = nextValues ? { ...state.initialValues, ...nextValues } : structuredClone(state.initialValues);
|
|
96
|
+
state = {
|
|
97
|
+
values: newValues,
|
|
98
|
+
errors: {},
|
|
99
|
+
touched: {},
|
|
100
|
+
dirty: false,
|
|
101
|
+
isSubmitting: false,
|
|
102
|
+
submitCount: state.submitCount,
|
|
103
|
+
initialValues: state.initialValues
|
|
104
|
+
};
|
|
105
|
+
notify();
|
|
106
|
+
}
|
|
107
|
+
async function validateForm() {
|
|
108
|
+
if (!validationAdapter || !validationSchema) return {};
|
|
109
|
+
const errors = await validationAdapter.validate(validationSchema, state.values);
|
|
110
|
+
state = { ...state, errors };
|
|
111
|
+
notify();
|
|
112
|
+
return errors;
|
|
113
|
+
}
|
|
114
|
+
async function validateField(name) {
|
|
115
|
+
if (!(validationAdapter == null ? void 0 : validationAdapter.validateField) || !validationSchema) return void 0;
|
|
116
|
+
const fieldValue = pathUtils.get(state.values, name);
|
|
117
|
+
const error = await validationAdapter.validateField(validationSchema, name, fieldValue);
|
|
118
|
+
setFieldError(name, error);
|
|
119
|
+
return error;
|
|
120
|
+
}
|
|
121
|
+
async function runFieldValidation(name) {
|
|
122
|
+
if (validationAdapter == null ? void 0 : validationAdapter.validateField) {
|
|
123
|
+
await validateField(name);
|
|
124
|
+
} else {
|
|
125
|
+
await validateForm();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async function submitForm(onSubmit) {
|
|
129
|
+
state = { ...state, isSubmitting: true, submitCount: state.submitCount + 1 };
|
|
130
|
+
notify();
|
|
131
|
+
const allTouched = {};
|
|
132
|
+
if (options.fields) {
|
|
133
|
+
for (const field of options.fields) {
|
|
134
|
+
allTouched[field.name] = true;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
state = { ...state, touched: { ...state.touched, ...allTouched } };
|
|
138
|
+
const errors = await validateForm();
|
|
139
|
+
if (Object.keys(errors).length > 0) {
|
|
140
|
+
state = { ...state, isSubmitting: false };
|
|
141
|
+
notify();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const handler = onSubmit ?? options.onSubmit;
|
|
145
|
+
if (handler) {
|
|
146
|
+
try {
|
|
147
|
+
await handler(state.values);
|
|
148
|
+
} finally {
|
|
149
|
+
state = { ...state, isSubmitting: false };
|
|
150
|
+
notify();
|
|
151
|
+
}
|
|
152
|
+
} else {
|
|
153
|
+
state = { ...state, isSubmitting: false };
|
|
154
|
+
notify();
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function getFieldValue(name) {
|
|
158
|
+
return pathUtils.get(state.values, name);
|
|
159
|
+
}
|
|
160
|
+
function getFieldError(name) {
|
|
161
|
+
return state.errors[name];
|
|
162
|
+
}
|
|
163
|
+
function getFieldTouched(name) {
|
|
164
|
+
return state.touched[name] ?? false;
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
getState,
|
|
168
|
+
subscribe,
|
|
169
|
+
subscribeField,
|
|
170
|
+
setFieldValue,
|
|
171
|
+
setFieldTouched,
|
|
172
|
+
setFieldError,
|
|
173
|
+
setValues,
|
|
174
|
+
setErrors,
|
|
175
|
+
resetForm,
|
|
176
|
+
validateForm,
|
|
177
|
+
validateField,
|
|
178
|
+
submitForm,
|
|
179
|
+
getFieldValue,
|
|
180
|
+
getFieldError,
|
|
181
|
+
getFieldTouched
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
exports.createFormStore = createFormStore;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { FieldConfig, ValidationAdapter } from '../types';
|
|
2
|
+
export interface FormState<TValues extends Record<string, unknown> = Record<string, unknown>> {
|
|
3
|
+
values: TValues;
|
|
4
|
+
errors: Record<string, string>;
|
|
5
|
+
touched: Record<string, boolean>;
|
|
6
|
+
dirty: boolean;
|
|
7
|
+
isSubmitting: boolean;
|
|
8
|
+
submitCount: number;
|
|
9
|
+
initialValues: TValues;
|
|
10
|
+
}
|
|
11
|
+
export type Subscriber = () => void;
|
|
12
|
+
export interface FormStoreOptions<TValues extends Record<string, unknown>> {
|
|
13
|
+
initialValues: TValues;
|
|
14
|
+
validationAdapter?: ValidationAdapter;
|
|
15
|
+
validationSchema?: unknown;
|
|
16
|
+
fields?: FieldConfig[];
|
|
17
|
+
validateOnChange?: boolean;
|
|
18
|
+
validateOnBlur?: boolean;
|
|
19
|
+
onSubmit?: (values: TValues) => void | Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export declare function createFormStore<TValues extends Record<string, unknown>>(options: FormStoreOptions<TValues>): {
|
|
22
|
+
getState: () => FormState<TValues>;
|
|
23
|
+
subscribe: (listener: Subscriber) => () => void;
|
|
24
|
+
subscribeField: (name: string, listener: Subscriber) => () => void;
|
|
25
|
+
setFieldValue: (name: string, value: unknown) => void;
|
|
26
|
+
setFieldTouched: (name: string, touched?: boolean) => void;
|
|
27
|
+
setFieldError: (name: string, error: string | undefined) => void;
|
|
28
|
+
setValues: (values: TValues) => void;
|
|
29
|
+
setErrors: (errors: Record<string, string>) => void;
|
|
30
|
+
resetForm: (nextValues?: Partial<TValues>) => void;
|
|
31
|
+
validateForm: () => Promise<Record<string, string>>;
|
|
32
|
+
validateField: (name: string) => Promise<string | undefined>;
|
|
33
|
+
submitForm: (onSubmit?: (values: TValues) => void | Promise<void>) => Promise<void>;
|
|
34
|
+
getFieldValue: (name: string) => unknown;
|
|
35
|
+
getFieldError: (name: string) => string | undefined;
|
|
36
|
+
getFieldTouched: (name: string) => boolean;
|
|
37
|
+
};
|
|
38
|
+
export type FormStore<TValues extends Record<string, unknown> = Record<string, unknown>> = ReturnType<typeof createFormStore<TValues>>;
|
|
39
|
+
//# sourceMappingURL=formStore.d.ts.map
|