remix-validated-form 4.5.6 → 4.5.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +13 -13
- package/browser/ValidatedForm.js +12 -4
- package/browser/validation/createValidator.js +5 -1
- package/dist/remix-validated-form.cjs.js +4 -4
- package/dist/remix-validated-form.cjs.js.map +1 -1
- package/dist/remix-validated-form.es.js +710 -244
- package/dist/remix-validated-form.es.js.map +1 -1
- package/dist/remix-validated-form.umd.js +4 -4
- package/dist/remix-validated-form.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/ValidatedForm.tsx +19 -5
- package/src/validation/createValidator.ts +5 -1
- package/src/validation/validation.test.ts +26 -0
package/package.json
CHANGED
package/src/ValidatedForm.tsx
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
Form as RemixForm,
|
3
|
+
FormMethod,
|
4
|
+
useFetcher,
|
5
|
+
useSubmit,
|
6
|
+
} from "@remix-run/react";
|
2
7
|
import uniq from "lodash/uniq";
|
3
8
|
import React, {
|
4
9
|
ComponentProps,
|
@@ -303,7 +308,13 @@ export function ValidatedForm<DataType>({
|
|
303
308
|
nativeEvent: HTMLSubmitEvent["nativeEvent"]
|
304
309
|
) => {
|
305
310
|
startSubmit();
|
306
|
-
const
|
311
|
+
const submitter = nativeEvent.submitter as HTMLFormSubmitter | null;
|
312
|
+
const formDataToValidate = getDataFromForm(e.currentTarget);
|
313
|
+
if (submitter?.name) {
|
314
|
+
formDataToValidate.append(submitter.name, submitter.value);
|
315
|
+
}
|
316
|
+
|
317
|
+
const result = await validator.validate(formDataToValidate);
|
307
318
|
if (result.error) {
|
308
319
|
setFieldErrors(result.error.fieldErrors);
|
309
320
|
endSubmit();
|
@@ -315,6 +326,7 @@ export function ValidatedForm<DataType>({
|
|
315
326
|
);
|
316
327
|
}
|
317
328
|
} else {
|
329
|
+
setFieldErrors({});
|
318
330
|
const eventProxy = formEventProxy(e);
|
319
331
|
await onSubmit?.(result.data, eventProxy);
|
320
332
|
if (eventProxy.defaultPrevented) {
|
@@ -322,15 +334,17 @@ export function ValidatedForm<DataType>({
|
|
322
334
|
return;
|
323
335
|
}
|
324
336
|
|
325
|
-
const submitter = nativeEvent.submitter as HTMLFormSubmitter | null;
|
326
|
-
|
327
337
|
// We deviate from the remix code here a bit because of our async submit.
|
328
338
|
// In remix's `FormImpl`, they use `event.currentTarget` to get the form,
|
329
339
|
// but we already have the form in `formRef.current` so we can just use that.
|
330
340
|
// If we use `event.currentTarget` here, it will break because `currentTarget`
|
331
341
|
// will have changed since the start of the submission.
|
332
342
|
if (fetcher) fetcher.submit(submitter || e.currentTarget);
|
333
|
-
else
|
343
|
+
else
|
344
|
+
submit(submitter || target, {
|
345
|
+
replace,
|
346
|
+
method: (submitter?.formMethod as FormMethod) || method,
|
347
|
+
});
|
334
348
|
}
|
335
349
|
};
|
336
350
|
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import omit from "lodash/omit";
|
1
2
|
import { CreateValidatorArg, GenericObject, Validator } from "..";
|
2
3
|
import { FORM_ID_FIELD } from "../internal/constants";
|
3
4
|
import { objectFromPathEntries } from "../internal/flatten";
|
@@ -10,6 +11,9 @@ const preprocessFormData = (data: GenericObject | FormData): GenericObject => {
|
|
10
11
|
return objectFromPathEntries(Object.entries(data));
|
11
12
|
};
|
12
13
|
|
14
|
+
const omitInternalFields = (data: GenericObject): GenericObject =>
|
15
|
+
omit(data, FORM_ID_FIELD);
|
16
|
+
|
13
17
|
/**
|
14
18
|
* Used to create a validator for a form.
|
15
19
|
* It provides built-in handling for unflattening nested objects and
|
@@ -21,7 +25,7 @@ export function createValidator<T>(
|
|
21
25
|
return {
|
22
26
|
validate: async (value) => {
|
23
27
|
const data = preprocessFormData(value);
|
24
|
-
const result = await validator.validate(data);
|
28
|
+
const result = await validator.validate(omitInternalFields(data));
|
25
29
|
|
26
30
|
if (result.error) {
|
27
31
|
return {
|
@@ -1,11 +1,13 @@
|
|
1
1
|
import { anyString, TestFormData } from "@remix-validated-form/test-utils";
|
2
2
|
import { withYup } from "@remix-validated-form/with-yup/src";
|
3
3
|
import { withZod } from "@remix-validated-form/with-zod";
|
4
|
+
import omit from "lodash/omit";
|
4
5
|
import { Validator } from "remix-validated-form/src";
|
5
6
|
import { objectFromPathEntries } from "remix-validated-form/src/internal/flatten";
|
6
7
|
import { describe, it, expect } from "vitest";
|
7
8
|
import * as yup from "yup";
|
8
9
|
import { z } from "zod";
|
10
|
+
import { FORM_ID_FIELD } from "../internal/constants";
|
9
11
|
|
10
12
|
// If adding an adapter, write a validator that validates this shape
|
11
13
|
type Person = {
|
@@ -101,6 +103,30 @@ describe("Validation", () => {
|
|
101
103
|
});
|
102
104
|
});
|
103
105
|
|
106
|
+
it("should omit internal fields", async () => {
|
107
|
+
const person: Person = {
|
108
|
+
firstName: "John",
|
109
|
+
lastName: "Doe",
|
110
|
+
age: 30,
|
111
|
+
address: {
|
112
|
+
streetAddress: "123 Main St",
|
113
|
+
city: "Anytown",
|
114
|
+
country: "USA",
|
115
|
+
},
|
116
|
+
pets: [{ animal: "dog", name: "Fido" }],
|
117
|
+
|
118
|
+
// @ts-expect-error
|
119
|
+
// internal filed technically not part of person type
|
120
|
+
[FORM_ID_FIELD]: "something",
|
121
|
+
};
|
122
|
+
expect(await validator.validate(person)).toEqual({
|
123
|
+
data: omit(person, FORM_ID_FIELD),
|
124
|
+
error: undefined,
|
125
|
+
submittedData: person,
|
126
|
+
formId: "something",
|
127
|
+
});
|
128
|
+
});
|
129
|
+
|
104
130
|
it("should return field errors when invalid", async () => {
|
105
131
|
const obj = { age: "hi!", pets: [{ animal: "dog" }] };
|
106
132
|
expect(await validator.validate(obj)).toEqual({
|