@explita/formly 0.1.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/README.md +261 -0
- package/README.old.md +141 -0
- package/dist/components/field-error.d.ts +2 -0
- package/dist/components/field-error.js +14 -0
- package/dist/components/field.d.ts +4 -0
- package/dist/components/field.js +120 -0
- package/dist/components/form-spy.d.ts +16 -0
- package/dist/components/form-spy.js +66 -0
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +20 -0
- package/dist/components/label.d.ts +2 -0
- package/dist/components/label.js +46 -0
- package/dist/hooks/use-field.d.ts +21 -0
- package/dist/hooks/use-field.js +66 -0
- package/dist/hooks/use-form-by-id.d.ts +6 -0
- package/dist/hooks/use-form-by-id.js +25 -0
- package/dist/hooks/use-form-context.d.ts +5 -0
- package/dist/hooks/use-form-context.js +17 -0
- package/dist/hooks/use-form.d.ts +43 -0
- package/dist/hooks/use-form.js +961 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +25 -0
- package/dist/lib/array-helpers.d.ts +6 -0
- package/dist/lib/array-helpers.js +281 -0
- package/dist/lib/css.d.ts +1 -0
- package/dist/lib/css.js +45 -0
- package/dist/lib/debounce.d.ts +13 -0
- package/dist/lib/debounce.js +28 -0
- package/dist/lib/deep-path.d.ts +4 -0
- package/dist/lib/deep-path.js +60 -0
- package/dist/lib/drafts-helpter.d.ts +31 -0
- package/dist/lib/drafts-helpter.js +67 -0
- package/dist/lib/form-registry.d.ts +9 -0
- package/dist/lib/form-registry.js +24 -0
- package/dist/lib/group-helpers.d.ts +9 -0
- package/dist/lib/group-helpers.js +29 -0
- package/dist/lib/pub-sub.d.ts +13 -0
- package/dist/lib/pub-sub.js +38 -0
- package/dist/lib/utils.d.ts +17 -0
- package/dist/lib/utils.js +190 -0
- package/dist/lib/validation.d.ts +22 -0
- package/dist/lib/validation.js +46 -0
- package/dist/lib/zod-helpers.d.ts +5 -0
- package/dist/lib/zod-helpers.js +63 -0
- package/dist/providers/form.d.ts +51 -0
- package/dist/providers/form.js +63 -0
- package/dist/types/array.d.ts +197 -0
- package/dist/types/array.js +2 -0
- package/dist/types/field.d.ts +61 -0
- package/dist/types/field.js +2 -0
- package/dist/types/group.d.ts +16 -0
- package/dist/types/group.js +2 -0
- package/dist/types/path.d.ts +8 -0
- package/dist/types/path.js +2 -0
- package/dist/types/pub-sub.d.ts +2 -0
- package/dist/types/pub-sub.js +2 -0
- package/dist/types/utils.d.ts +310 -0
- package/dist/types/utils.js +2 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +14 -0
- package/package.json +53 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createChannel = createChannel;
|
|
4
|
+
exports.createFormBus = createFormBus;
|
|
5
|
+
function createChannel() {
|
|
6
|
+
const listeners = new Set();
|
|
7
|
+
return {
|
|
8
|
+
emit(payload) {
|
|
9
|
+
listeners.forEach((cb) => cb(payload));
|
|
10
|
+
},
|
|
11
|
+
subscribe(cb) {
|
|
12
|
+
listeners.add(cb);
|
|
13
|
+
return () => {
|
|
14
|
+
listeners.delete(cb);
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
clear() {
|
|
18
|
+
listeners.clear();
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function createFormBus() {
|
|
23
|
+
const channels = new Map();
|
|
24
|
+
// The hybrid callable-object
|
|
25
|
+
const channel = (name) => {
|
|
26
|
+
if (!name)
|
|
27
|
+
throw new Error("Channel name required");
|
|
28
|
+
if (!channels.has(name))
|
|
29
|
+
channels.set(name, createChannel());
|
|
30
|
+
return channels.get(name);
|
|
31
|
+
};
|
|
32
|
+
// Attach helper methods directly to the function
|
|
33
|
+
channel.clearAll = () => {
|
|
34
|
+
channels.forEach((c) => c.clear());
|
|
35
|
+
channels.clear();
|
|
36
|
+
};
|
|
37
|
+
return { channel };
|
|
38
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Path } from "../types/path";
|
|
2
|
+
/**
|
|
3
|
+
* Combines multiple class names into a single string.
|
|
4
|
+
* This function takes an array of class names and returns a single string
|
|
5
|
+
* with all the class names combined, separated by spaces.
|
|
6
|
+
* It filters out any falsey values (null, undefined, etc.) before joining.
|
|
7
|
+
*
|
|
8
|
+
* @param {string[]} classes - An array of class names to combine.
|
|
9
|
+
* @returns {string} A single string with all the class names combined.
|
|
10
|
+
*/
|
|
11
|
+
export declare function cn(...classes: (string | false | null | undefined)[]): string;
|
|
12
|
+
export declare function multiPathError<T>(paths: Path<T>[], message: string): Partial<Record<Path<T>, string>>;
|
|
13
|
+
export declare function mapErrors(obj: Record<string, any>, path?: string): Record<string, string>;
|
|
14
|
+
export declare function flattenFormValues<T extends any>(obj: T, prefix?: string): Record<string, any>;
|
|
15
|
+
export declare function nestFormValues<T extends any>(flat: T): T;
|
|
16
|
+
export declare function mergeValues<T extends any>(defaultValues: T, saved: T): T;
|
|
17
|
+
export declare function determineDirtyFields<T extends any>(defaultValues: T, saved: T): T;
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cn = cn;
|
|
4
|
+
exports.multiPathError = multiPathError;
|
|
5
|
+
exports.mapErrors = mapErrors;
|
|
6
|
+
exports.flattenFormValues = flattenFormValues;
|
|
7
|
+
exports.nestFormValues = nestFormValues;
|
|
8
|
+
exports.mergeValues = mergeValues;
|
|
9
|
+
exports.determineDirtyFields = determineDirtyFields;
|
|
10
|
+
/**
|
|
11
|
+
* Combines multiple class names into a single string.
|
|
12
|
+
* This function takes an array of class names and returns a single string
|
|
13
|
+
* with all the class names combined, separated by spaces.
|
|
14
|
+
* It filters out any falsey values (null, undefined, etc.) before joining.
|
|
15
|
+
*
|
|
16
|
+
* @param {string[]} classes - An array of class names to combine.
|
|
17
|
+
* @returns {string} A single string with all the class names combined.
|
|
18
|
+
*/
|
|
19
|
+
function cn(...classes) {
|
|
20
|
+
return classes.filter(Boolean).join(" ");
|
|
21
|
+
}
|
|
22
|
+
function multiPathError(paths, message) {
|
|
23
|
+
return paths.reduce((acc, path) => {
|
|
24
|
+
acc[path] = message;
|
|
25
|
+
return acc;
|
|
26
|
+
}, {});
|
|
27
|
+
}
|
|
28
|
+
function mapErrors(obj, path = "") {
|
|
29
|
+
const result = {};
|
|
30
|
+
for (const key in obj) {
|
|
31
|
+
const value = obj[key];
|
|
32
|
+
const currentPath = path ? `${path}.${key}` : key;
|
|
33
|
+
if (Array.isArray(value)) {
|
|
34
|
+
value.forEach((item, i) => {
|
|
35
|
+
// graceful fallback for _index or broken items
|
|
36
|
+
const index = item && typeof item === "object" && "_index" in item
|
|
37
|
+
? item._index
|
|
38
|
+
: i;
|
|
39
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
40
|
+
const keys = Object.keys(item);
|
|
41
|
+
const hasOtherKeys = keys.some((k) => k !== "_index" && k !== "error");
|
|
42
|
+
if (hasOtherKeys) {
|
|
43
|
+
// nested object or keyed structure
|
|
44
|
+
for (const subKey in item) {
|
|
45
|
+
if (subKey === "_index")
|
|
46
|
+
continue;
|
|
47
|
+
result[`${currentPath}.${index}.${subKey}`] = String(item[subKey]);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if ("error" in item) {
|
|
51
|
+
// simple indexed error: { _index, error }
|
|
52
|
+
result[`${currentPath}.${index}`] = String(item.error);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
// empty or malformed object
|
|
56
|
+
result[`${currentPath}.${index}`] = "Invalid value";
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else if (item != null && item !== "") {
|
|
60
|
+
// primitive value (string, number, etc.)
|
|
61
|
+
result[`${currentPath}.${index}`] = String(item);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// null, undefined, or empty
|
|
65
|
+
result[`${currentPath}.${index}`] = "Invalid value";
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else if (value && typeof value === "object") {
|
|
70
|
+
// nested object
|
|
71
|
+
Object.assign(result, mapErrors(value, currentPath));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// primitive (string, number, etc.)
|
|
75
|
+
result[currentPath] = String(value);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
function flattenFormValues(obj, prefix = "") {
|
|
81
|
+
const result = {};
|
|
82
|
+
for (const key in obj) {
|
|
83
|
+
const value = obj[key];
|
|
84
|
+
const path = prefix ? `${prefix}.${key}` : key;
|
|
85
|
+
if (Array.isArray(value)) {
|
|
86
|
+
if (value.length === 0) {
|
|
87
|
+
// always include the array itself
|
|
88
|
+
result[path] = [];
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
value.forEach((item, index) => {
|
|
92
|
+
if (typeof item === "object" && item !== null) {
|
|
93
|
+
Object.assign(result, flattenFormValues(item, `${path}.${index}`));
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
result[`${path}.${index}`] = item;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else if (typeof value === "object" &&
|
|
102
|
+
!(value instanceof Date) &&
|
|
103
|
+
value !== null) {
|
|
104
|
+
Object.assign(result, flattenFormValues(value, path));
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
result[path] = value;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
function nestFormValues(flat) {
|
|
113
|
+
const result = {};
|
|
114
|
+
for (const key in flat) {
|
|
115
|
+
const parts = key.split("."); // split by dot
|
|
116
|
+
let current = result;
|
|
117
|
+
for (let i = 0; i < parts.length; i++) {
|
|
118
|
+
const part = parts[i];
|
|
119
|
+
// If part is numeric (array index)
|
|
120
|
+
const arrayIndex = Number(part);
|
|
121
|
+
const isLast = i === parts.length - 1;
|
|
122
|
+
if (!isNaN(arrayIndex) && Number.isInteger(arrayIndex)) {
|
|
123
|
+
// ensure current is an array
|
|
124
|
+
if (!Array.isArray(current))
|
|
125
|
+
current = [];
|
|
126
|
+
if (current[arrayIndex] === undefined)
|
|
127
|
+
current[arrayIndex] = {};
|
|
128
|
+
if (isLast) {
|
|
129
|
+
current[arrayIndex] = flat[key];
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
current = current[arrayIndex];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
// normal object key
|
|
137
|
+
if (isLast) {
|
|
138
|
+
current[part] = flat[key];
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
if (current[part] === undefined ||
|
|
142
|
+
typeof current[part] !== "object") {
|
|
143
|
+
// check if next part is numeric to pre-create array
|
|
144
|
+
const nextPart = parts[i + 1];
|
|
145
|
+
current[part] = !isNaN(Number(nextPart)) ? [] : {};
|
|
146
|
+
}
|
|
147
|
+
current = current[part];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return result;
|
|
153
|
+
}
|
|
154
|
+
function mergeValues(defaultValues, saved) {
|
|
155
|
+
const flattenDefaultValues = flattenFormValues(defaultValues);
|
|
156
|
+
const flattenSaved = flattenFormValues(saved);
|
|
157
|
+
const result = {};
|
|
158
|
+
// Get all unique keys from both objects
|
|
159
|
+
const allKeys = new Set([
|
|
160
|
+
...Object.keys(flattenDefaultValues),
|
|
161
|
+
...Object.keys(flattenSaved),
|
|
162
|
+
]);
|
|
163
|
+
for (const key of allKeys) {
|
|
164
|
+
const savedValue = flattenSaved[key];
|
|
165
|
+
const defaultValue = flattenDefaultValues[key];
|
|
166
|
+
result[key] =
|
|
167
|
+
defaultValue !== undefined && defaultValue !== null && defaultValue !== ""
|
|
168
|
+
? defaultValue
|
|
169
|
+
: savedValue !== null && savedValue !== void 0 ? savedValue : defaultValue;
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
function determineDirtyFields(defaultValues, saved) {
|
|
174
|
+
const flattenDefaultValues = flattenFormValues(defaultValues);
|
|
175
|
+
const flattenSaved = flattenFormValues(saved);
|
|
176
|
+
const result = {};
|
|
177
|
+
// Get all unique keys from both objects
|
|
178
|
+
const allKeys = new Set([
|
|
179
|
+
...Object.keys(flattenDefaultValues),
|
|
180
|
+
...Object.keys(flattenSaved),
|
|
181
|
+
]);
|
|
182
|
+
for (const key of allKeys) {
|
|
183
|
+
const savedValue = flattenSaved[key];
|
|
184
|
+
const defaultValue = flattenDefaultValues[key];
|
|
185
|
+
if (savedValue === defaultValue)
|
|
186
|
+
continue;
|
|
187
|
+
result[key] = true;
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
type ValidationResponse<T> = {
|
|
3
|
+
success: true;
|
|
4
|
+
data: T;
|
|
5
|
+
} | {
|
|
6
|
+
success: false;
|
|
7
|
+
errors: Partial<Record<keyof T, string>>;
|
|
8
|
+
message: string;
|
|
9
|
+
data: T;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Validates form data against a Zod schema.
|
|
13
|
+
*
|
|
14
|
+
* @param {Schema} validationSchema - The Zod schema to validate the form data against.
|
|
15
|
+
* @param {FormData | Record<string, unknown> | undefined} formData - The form data to validate.
|
|
16
|
+
* @returns {Promise<ValidationResponse<z.infer<Schema>>>} - A promise that resolves to a validation response.
|
|
17
|
+
*
|
|
18
|
+
* @throws {Error} Throws an error if a valid Zod schema or valid FormData is not provided,
|
|
19
|
+
* or if an unexpected error occurs during validation.
|
|
20
|
+
*/
|
|
21
|
+
export declare function validateForm<Schema extends z.ZodObject>(validationSchema: Schema, formData: FormData | Record<string, unknown> | undefined): Promise<ValidationResponse<z.infer<Schema>>>;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateForm = validateForm;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
const zod_helpers_1 = require("./zod-helpers");
|
|
6
|
+
/**
|
|
7
|
+
* Validates form data against a Zod schema.
|
|
8
|
+
*
|
|
9
|
+
* @param {Schema} validationSchema - The Zod schema to validate the form data against.
|
|
10
|
+
* @param {FormData | Record<string, unknown> | undefined} formData - The form data to validate.
|
|
11
|
+
* @returns {Promise<ValidationResponse<z.infer<Schema>>>} - A promise that resolves to a validation response.
|
|
12
|
+
*
|
|
13
|
+
* @throws {Error} Throws an error if a valid Zod schema or valid FormData is not provided,
|
|
14
|
+
* or if an unexpected error occurs during validation.
|
|
15
|
+
*/
|
|
16
|
+
async function validateForm(validationSchema, formData) {
|
|
17
|
+
if (typeof (validationSchema === null || validationSchema === void 0 ? void 0 : validationSchema.safeParseAsync) !== "function") {
|
|
18
|
+
throw new Error("A valid Zod schema is required for form validation. Please provide a valid Zod schema and try again.");
|
|
19
|
+
}
|
|
20
|
+
if (!formData) {
|
|
21
|
+
throw new Error("A valid FormData object is required for form validation. Please provide a valid FormData object and try again.");
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
let form = formData;
|
|
25
|
+
if (formData instanceof FormData) {
|
|
26
|
+
form = Object.fromEntries(formData.entries());
|
|
27
|
+
}
|
|
28
|
+
const result = await validationSchema.safeParseAsync((0, utils_1.nestFormValues)(form));
|
|
29
|
+
if (result.success) {
|
|
30
|
+
return {
|
|
31
|
+
success: true,
|
|
32
|
+
data: result.data,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const errors = (0, zod_helpers_1.mapZodErrors)(result.error.issues);
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
errors,
|
|
39
|
+
message: "Validation failed",
|
|
40
|
+
data: form,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
throw new Error(`Validation failed due to an unexpected error: ${error.message || "Please make sure Zod is installed and try again."}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
export declare function isZodSchema(schema: unknown): schema is z.ZodObject;
|
|
3
|
+
export declare function createEmptyValues<T extends z.ZodObject<any>>(schema?: T): z.infer<T>;
|
|
4
|
+
export declare function mapZodErrors(error?: z.ZodError["issues"]): Record<string, string>;
|
|
5
|
+
export declare function isZodError(issues: any): issues is z.ZodError["issues"];
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isZodSchema = isZodSchema;
|
|
4
|
+
exports.createEmptyValues = createEmptyValues;
|
|
5
|
+
exports.mapZodErrors = mapZodErrors;
|
|
6
|
+
exports.isZodError = isZodError;
|
|
7
|
+
function isZodSchema(schema) {
|
|
8
|
+
return typeof schema === "object" && schema !== null && "def" in schema;
|
|
9
|
+
}
|
|
10
|
+
function createEmptyValues(schema) {
|
|
11
|
+
if (!schema)
|
|
12
|
+
return {};
|
|
13
|
+
const shape = schema.shape;
|
|
14
|
+
const result = {};
|
|
15
|
+
for (const key in shape) {
|
|
16
|
+
const field = shape[key];
|
|
17
|
+
result[key] = getEmptyValue(field);
|
|
18
|
+
}
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
function getEmptyValue(field) {
|
|
22
|
+
const { type } = field.def;
|
|
23
|
+
switch (type) {
|
|
24
|
+
case "object":
|
|
25
|
+
return createEmptyValues(field);
|
|
26
|
+
case "array":
|
|
27
|
+
// safe recursion into array element type
|
|
28
|
+
//@ts-ignore
|
|
29
|
+
return [getEmptyValue(field.def.element)];
|
|
30
|
+
case "boolean":
|
|
31
|
+
return false;
|
|
32
|
+
case "string":
|
|
33
|
+
case "number":
|
|
34
|
+
case "bigint":
|
|
35
|
+
case "date":
|
|
36
|
+
return "";
|
|
37
|
+
case "optional":
|
|
38
|
+
case "nullable":
|
|
39
|
+
// unwrap and recurse
|
|
40
|
+
//@ts-ignore
|
|
41
|
+
return getEmptyValue(field.def.innerType);
|
|
42
|
+
default:
|
|
43
|
+
return "";
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function mapZodErrors(error) {
|
|
47
|
+
if (!error)
|
|
48
|
+
return {};
|
|
49
|
+
const result = {};
|
|
50
|
+
for (const issue of error) {
|
|
51
|
+
const path = issue.path
|
|
52
|
+
.map((p) => (typeof p === "number" ? p : p.toString()))
|
|
53
|
+
.join(".");
|
|
54
|
+
result[path || "_root"] = issue.message;
|
|
55
|
+
}
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
function isZodError(issues) {
|
|
59
|
+
return (issues &&
|
|
60
|
+
typeof issues === "object" &&
|
|
61
|
+
Array.isArray(issues) &&
|
|
62
|
+
issues.every((i) => "path" in i && "message" in i));
|
|
63
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { useForm } from "../hooks/use-form";
|
|
3
|
+
import type { z } from "zod";
|
|
4
|
+
export type FormContextValue<TSchema extends z.ZodObject | undefined = undefined, DefaultValues = TSchema extends undefined ? Record<string, any> : Partial<z.infer<TSchema>>> = ReturnType<typeof useForm<TSchema, DefaultValues>>;
|
|
5
|
+
type FormProps<TSchema extends z.ZodObject | undefined = undefined, DefaultValues = TSchema extends undefined ? Record<string, any> : Partial<z.infer<TSchema>>> = {
|
|
6
|
+
use?: FormContextValue<TSchema, DefaultValues>;
|
|
7
|
+
children: React.ReactNode;
|
|
8
|
+
as?: "form" | "div" | "section";
|
|
9
|
+
className?: string;
|
|
10
|
+
} & React.HTMLAttributes<HTMLFormElement | HTMLDivElement>;
|
|
11
|
+
export declare const FormContext: React.Context<import("..").FormInstance<any> | null>;
|
|
12
|
+
/**
|
|
13
|
+
* A component that wraps the useForm hook and provides the form context
|
|
14
|
+
* to its children. It also provides a way to render the form as a
|
|
15
|
+
* different HTML element.
|
|
16
|
+
*
|
|
17
|
+
* @param {FormProps<TSchema, DefaultValues>} - The props for the Form component.
|
|
18
|
+
* @returns {ReactNode} - The rendered Form component.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
*
|
|
22
|
+
* const form = useForm({
|
|
23
|
+
* schema,
|
|
24
|
+
* defaultValues,
|
|
25
|
+
* errors,
|
|
26
|
+
* mode,
|
|
27
|
+
* errorParser,
|
|
28
|
+
* persistKey,
|
|
29
|
+
* check,
|
|
30
|
+
* })
|
|
31
|
+
*
|
|
32
|
+
* <Form use={form} onSubmit={form.handleSubmit((data, ctx) => {
|
|
33
|
+
console.log("before", data);
|
|
34
|
+
|
|
35
|
+
const after = ctx
|
|
36
|
+
.array("contacts")
|
|
37
|
+
.filter((item) => item.phone > 3 && item.phone !== null)
|
|
38
|
+
.map((item) => item)
|
|
39
|
+
.removeIf((item) => item.phone === 4);
|
|
40
|
+
|
|
41
|
+
const snapshot = after.snapshot();
|
|
42
|
+
const values = after.get();
|
|
43
|
+
|
|
44
|
+
console.log("after", snapshot, values);
|
|
45
|
+
})}>
|
|
46
|
+
* <Field name="name" label="Name" />
|
|
47
|
+
* <Field name="age" label="Age" type="number" />
|
|
48
|
+
* </Form>
|
|
49
|
+
*/
|
|
50
|
+
export declare function Form<TSchema extends z.ZodObject | undefined = undefined, DefaultValues = TSchema extends undefined ? Record<string, any> : Partial<z.infer<TSchema>>>({ children, use, as, className, onSubmit, ...rest }: FormProps<TSchema, DefaultValues>): React.JSX.Element;
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.FormContext = void 0;
|
|
8
|
+
exports.Form = Form;
|
|
9
|
+
const react_1 = __importDefault(require("react"));
|
|
10
|
+
const use_form_1 = require("../hooks/use-form");
|
|
11
|
+
const css_1 = require("../lib/css");
|
|
12
|
+
// export const FormContext = createContext<FormContextValue | null>(null);
|
|
13
|
+
exports.FormContext = react_1.default.createContext(null);
|
|
14
|
+
/**
|
|
15
|
+
* A component that wraps the useForm hook and provides the form context
|
|
16
|
+
* to its children. It also provides a way to render the form as a
|
|
17
|
+
* different HTML element.
|
|
18
|
+
*
|
|
19
|
+
* @param {FormProps<TSchema, DefaultValues>} - The props for the Form component.
|
|
20
|
+
* @returns {ReactNode} - The rendered Form component.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
*
|
|
24
|
+
* const form = useForm({
|
|
25
|
+
* schema,
|
|
26
|
+
* defaultValues,
|
|
27
|
+
* errors,
|
|
28
|
+
* mode,
|
|
29
|
+
* errorParser,
|
|
30
|
+
* persistKey,
|
|
31
|
+
* check,
|
|
32
|
+
* })
|
|
33
|
+
*
|
|
34
|
+
* <Form use={form} onSubmit={form.handleSubmit((data, ctx) => {
|
|
35
|
+
console.log("before", data);
|
|
36
|
+
|
|
37
|
+
const after = ctx
|
|
38
|
+
.array("contacts")
|
|
39
|
+
.filter((item) => item.phone > 3 && item.phone !== null)
|
|
40
|
+
.map((item) => item)
|
|
41
|
+
.removeIf((item) => item.phone === 4);
|
|
42
|
+
|
|
43
|
+
const snapshot = after.snapshot();
|
|
44
|
+
const values = after.get();
|
|
45
|
+
|
|
46
|
+
console.log("after", snapshot, values);
|
|
47
|
+
})}>
|
|
48
|
+
* <Field name="name" label="Name" />
|
|
49
|
+
* <Field name="age" label="Age" type="number" />
|
|
50
|
+
* </Form>
|
|
51
|
+
*/
|
|
52
|
+
function Form({ children, use, as = "form", className, onSubmit, ...rest }) {
|
|
53
|
+
const formInstance = use !== null && use !== void 0 ? use : (0, use_form_1.useForm)();
|
|
54
|
+
const Element = as;
|
|
55
|
+
//@ts-ignore
|
|
56
|
+
const submitFn = onSubmit || formInstance.onSubmit;
|
|
57
|
+
return (
|
|
58
|
+
// @ts-ignore
|
|
59
|
+
react_1.default.createElement(exports.FormContext.Provider, { value: formInstance },
|
|
60
|
+
react_1.default.createElement(Element, { onSubmit: submitFn, className: `explita-form ${className !== null && className !== void 0 ? className : ""}`, ...rest },
|
|
61
|
+
react_1.default.createElement("style", null, css_1.css),
|
|
62
|
+
children)));
|
|
63
|
+
}
|