remix-validated-form 4.5.4 → 4.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.4",
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
- formElement.requestSubmit();
210
+ requestSubmit(formElement);
210
211
  },
211
212
 
212
213
  getValues: () => new FormData(get().formElement ?? undefined),