remix-validated-form 4.5.2 → 4.5.5
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 +8 -9
- package/browser/internal/logic/requestSubmit.d.ts +5 -0
- package/browser/internal/logic/requestSubmit.js +41 -0
- package/browser/internal/state/createFormStore.js +3 -6
- package/browser/server.d.ts +2 -2
- package/browser/server.js +1 -1
- package/dist/remix-validated-form.cjs.js +12 -3
- package/dist/remix-validated-form.cjs.js.map +1 -1
- package/dist/remix-validated-form.es.js +469 -347
- package/dist/remix-validated-form.es.js.map +1 -1
- package/dist/remix-validated-form.umd.js +12 -3
- package/dist/remix-validated-form.umd.js.map +1 -1
- package/dist/types/internal/logic/requestSubmit.d.ts +5 -0
- package/dist/types/server.d.ts +2 -2
- package/package.json +2 -3
- package/src/internal/logic/requestSubmit.test.tsx +24 -0
- package/src/internal/logic/requestSubmit.ts +103 -0
- package/src/internal/state/createFormStore.ts +3 -10
- package/src/server.ts +1 -1
- package/vite.config.ts +1 -1
@@ -0,0 +1,5 @@
|
|
1
|
+
/**
|
2
|
+
* Ponyfill of the HTMLFormElement.requestSubmit() method.
|
3
|
+
* Based on polyfill from: https://github.com/javan/form-request-submit-polyfill/blob/main/form-request-submit-polyfill.js
|
4
|
+
*/
|
5
|
+
export declare const requestSubmit: (element: HTMLFormElement, submitter?: HTMLElement | undefined) => void;
|
package/dist/types/server.d.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { FORM_DEFAULTS_FIELD } from "./internal/constants";
|
2
|
-
import { ValidatorError } from "./validation/types";
|
2
|
+
import { ValidatorError, ValidationErrorResponseData } from "./validation/types";
|
3
3
|
/**
|
4
4
|
* Takes the errors from a `Validator` and returns a `Response`.
|
5
5
|
* When you return this from your action, `ValidatedForm` on the frontend will automatically
|
@@ -14,7 +14,7 @@ import { ValidatorError } from "./validation/types";
|
|
14
14
|
* if (result.error) return validationError(result.error, result.submittedData);
|
15
15
|
* ```
|
16
16
|
*/
|
17
|
-
export declare function validationError(error: ValidatorError, repopulateFields?: unknown, init?: ResponseInit):
|
17
|
+
export declare function validationError(error: ValidatorError, repopulateFields?: unknown, init?: ResponseInit): import("@remix-run/server-runtime").TypedResponse<ValidationErrorResponseData>;
|
18
18
|
export declare type FormDefaults = {
|
19
19
|
[formDefaultsKey: `${typeof FORM_DEFAULTS_FIELD}_${string}`]: any;
|
20
20
|
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "remix-validated-form",
|
3
|
-
"version": "4.5.
|
3
|
+
"version": "4.5.5",
|
4
4
|
"description": "Form component and utils for easy form validation in remix",
|
5
5
|
"browser": "./dist/remix-validated-form.cjs.js",
|
6
6
|
"main": "./dist/remix-validated-form.umd.js",
|
@@ -34,12 +34,11 @@
|
|
34
34
|
],
|
35
35
|
"peerDependencies": {
|
36
36
|
"@remix-run/react": "1.x",
|
37
|
-
"@remix-run/server-runtime": "1.x",
|
38
37
|
"react": "^17.0.2 || ^18.0.0"
|
39
38
|
},
|
40
39
|
"devDependencies": {
|
41
40
|
"@remix-run/react": "^1.6.5",
|
42
|
-
"@
|
41
|
+
"@testing-library/react": "^13.3.0",
|
43
42
|
"@types/lodash": "^4.14.178",
|
44
43
|
"@types/react": "^18.0.9",
|
45
44
|
"fetch-blob": "^3.1.3",
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import { render } from "@testing-library/react";
|
2
|
+
import React, { createRef } from "react";
|
3
|
+
import { describe, expect, it, vi } from "vitest";
|
4
|
+
import { requestSubmit } from "./requestSubmit";
|
5
|
+
|
6
|
+
describe("requestSubmit polyfill", () => {
|
7
|
+
it("should polyfill requestSubmit", () => {
|
8
|
+
const submit = vi.fn();
|
9
|
+
const ref = createRef<HTMLFormElement>();
|
10
|
+
render(
|
11
|
+
<form
|
12
|
+
onSubmit={(event) => {
|
13
|
+
event.preventDefault();
|
14
|
+
submit();
|
15
|
+
}}
|
16
|
+
ref={ref}
|
17
|
+
>
|
18
|
+
<input name="test" value="testing" />
|
19
|
+
</form>
|
20
|
+
);
|
21
|
+
requestSubmit(ref.current!);
|
22
|
+
expect(submit).toHaveBeenCalledTimes(1);
|
23
|
+
});
|
24
|
+
});
|
@@ -0,0 +1,103 @@
|
|
1
|
+
/**
|
2
|
+
* Ponyfill of the HTMLFormElement.requestSubmit() method.
|
3
|
+
* Based on polyfill from: https://github.com/javan/form-request-submit-polyfill/blob/main/form-request-submit-polyfill.js
|
4
|
+
*/
|
5
|
+
export const requestSubmit = (
|
6
|
+
element: HTMLFormElement,
|
7
|
+
submitter?: HTMLElement
|
8
|
+
) => {
|
9
|
+
// In vitest, let's test the polyfill.
|
10
|
+
// Cypress will test the native implementation by nature of using chrome.
|
11
|
+
if (
|
12
|
+
typeof Object.getPrototypeOf(element).requestSubmit === "function" &&
|
13
|
+
!import.meta.vitest
|
14
|
+
) {
|
15
|
+
element.requestSubmit(submitter);
|
16
|
+
return;
|
17
|
+
}
|
18
|
+
|
19
|
+
if (submitter) {
|
20
|
+
validateSubmitter(element, submitter);
|
21
|
+
submitter.click();
|
22
|
+
return;
|
23
|
+
}
|
24
|
+
|
25
|
+
const dummySubmitter = document.createElement("input");
|
26
|
+
dummySubmitter.type = "submit";
|
27
|
+
dummySubmitter.hidden = true;
|
28
|
+
element.appendChild(dummySubmitter);
|
29
|
+
dummySubmitter.click();
|
30
|
+
element.removeChild(dummySubmitter);
|
31
|
+
};
|
32
|
+
|
33
|
+
function validateSubmitter(element: HTMLFormElement, submitter: HTMLElement) {
|
34
|
+
// Should be redundant, but here for completeness
|
35
|
+
const isHtmlElement = submitter instanceof HTMLElement;
|
36
|
+
if (!isHtmlElement) {
|
37
|
+
raise(TypeError, "parameter 1 is not of type 'HTMLElement'");
|
38
|
+
}
|
39
|
+
|
40
|
+
const hasSubmitType =
|
41
|
+
"type" in submitter && (submitter as HTMLInputElement).type === "submit";
|
42
|
+
if (!hasSubmitType)
|
43
|
+
raise(TypeError, "The specified element is not a submit button");
|
44
|
+
|
45
|
+
const isForCorrectForm =
|
46
|
+
"form" in submitter && (submitter as HTMLInputElement).form === element;
|
47
|
+
if (!isForCorrectForm)
|
48
|
+
raise(
|
49
|
+
DOMException,
|
50
|
+
"The specified element is not owned by this form element",
|
51
|
+
"NotFoundError"
|
52
|
+
);
|
53
|
+
}
|
54
|
+
|
55
|
+
interface ErrorConstructor {
|
56
|
+
new (message: string, name?: string): Error;
|
57
|
+
}
|
58
|
+
|
59
|
+
function raise(
|
60
|
+
errorConstructor: ErrorConstructor,
|
61
|
+
message: string,
|
62
|
+
name?: string
|
63
|
+
): never {
|
64
|
+
throw new errorConstructor(
|
65
|
+
"Failed to execute 'requestSubmit' on 'HTMLFormElement': " + message + ".",
|
66
|
+
name
|
67
|
+
);
|
68
|
+
}
|
69
|
+
|
70
|
+
if (import.meta.vitest) {
|
71
|
+
const { it, expect } = import.meta.vitest;
|
72
|
+
it("should validate the submitter", () => {
|
73
|
+
const form = document.createElement("form");
|
74
|
+
document.body.appendChild(form);
|
75
|
+
|
76
|
+
const submitter = document.createElement("input");
|
77
|
+
expect(() => validateSubmitter(null as any, null as any)).toThrow();
|
78
|
+
expect(() => validateSubmitter(form, null as any)).toThrow();
|
79
|
+
expect(() => validateSubmitter(form, submitter)).toThrow();
|
80
|
+
expect(() =>
|
81
|
+
validateSubmitter(form, document.createElement("div"))
|
82
|
+
).toThrow();
|
83
|
+
|
84
|
+
submitter.type = "submit";
|
85
|
+
expect(() => validateSubmitter(form, submitter)).toThrow();
|
86
|
+
|
87
|
+
form.appendChild(submitter);
|
88
|
+
expect(() => validateSubmitter(form, submitter)).not.toThrow();
|
89
|
+
|
90
|
+
form.removeChild(submitter);
|
91
|
+
expect(() => validateSubmitter(form, submitter)).toThrow();
|
92
|
+
|
93
|
+
document.body.appendChild(submitter);
|
94
|
+
form.id = "test-form";
|
95
|
+
submitter.setAttribute("form", "test-form");
|
96
|
+
expect(() => validateSubmitter(form, submitter)).not.toThrow();
|
97
|
+
|
98
|
+
const button = document.createElement("button");
|
99
|
+
button.type = "submit";
|
100
|
+
form.appendChild(button);
|
101
|
+
expect(() => validateSubmitter(form, button)).not.toThrow();
|
102
|
+
});
|
103
|
+
}
|
@@ -8,6 +8,7 @@ import {
|
|
8
8
|
ValidationResult,
|
9
9
|
Validator,
|
10
10
|
} from "../../validation/types";
|
11
|
+
import { requestSubmit } from "../logic/requestSubmit";
|
11
12
|
import { useControlledFieldStore } from "./controlledFieldStore";
|
12
13
|
import { InternalFormId } from "./types";
|
13
14
|
|
@@ -206,18 +207,10 @@ const createFormState = (
|
|
206
207
|
"Cannot find reference to form. This is probably a bug in remix-validated-form."
|
207
208
|
);
|
208
209
|
|
209
|
-
formElement
|
210
|
+
requestSubmit(formElement);
|
210
211
|
},
|
211
212
|
|
212
|
-
getValues: () =>
|
213
|
-
const formElement = get().formElement;
|
214
|
-
invariant(
|
215
|
-
formElement,
|
216
|
-
"Cannot find reference to form. This is probably a bug in remix-validated-form."
|
217
|
-
);
|
218
|
-
|
219
|
-
return new FormData(formElement);
|
220
|
-
},
|
213
|
+
getValues: () => new FormData(get().formElement ?? undefined),
|
221
214
|
|
222
215
|
resetFormElement: () => get().formElement?.reset(),
|
223
216
|
});
|
package/src/server.ts
CHANGED
package/vite.config.ts
CHANGED