remix-validated-form 4.5.4 → 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 -8
- package/browser/internal/logic/requestSubmit.d.ts +5 -0
- package/browser/internal/logic/requestSubmit.js +41 -0
- package/browser/internal/state/createFormStore.js +2 -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 +447 -345
- 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/dist/types/internal/logic/requestSubmit.d.ts +5 -0
- package/package.json +2 -1
- package/src/internal/logic/requestSubmit.test.tsx +24 -0
- package/src/internal/logic/requestSubmit.ts +103 -0
- package/src/internal/state/createFormStore.ts +2 -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/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",
|
@@ -38,6 +38,7 @@
|
|
38
38
|
},
|
39
39
|
"devDependencies": {
|
40
40
|
"@remix-run/react": "^1.6.5",
|
41
|
+
"@testing-library/react": "^13.3.0",
|
41
42
|
"@types/lodash": "^4.14.178",
|
42
43
|
"@types/react": "^18.0.9",
|
43
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,7 +207,7 @@ const createFormState = (
|
|
206
207
|
"Cannot find reference to form. This is probably a bug in remix-validated-form."
|
207
208
|
);
|
208
209
|
|
209
|
-
|
210
|
+
requestSubmit(formElement);
|
210
211
|
},
|
211
212
|
|
212
213
|
getValues: () => new FormData(get().formElement ?? undefined),
|