remix-validated-form 0.0.2 → 1.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/.eslintcache +1 -0
- package/README.md +180 -1
- package/browser/ValidatedForm.d.ts +11 -0
- package/browser/ValidatedForm.js +69 -0
- package/browser/hooks.d.ts +8 -0
- package/browser/hooks.js +17 -0
- package/{src/index.ts → browser/index.d.ts} +0 -0
- package/browser/index.js +5 -0
- package/browser/internal/formContext.d.ts +13 -0
- package/browser/internal/formContext.js +7 -0
- package/browser/internal/util.d.ts +3 -0
- package/browser/internal/util.js +19 -0
- package/browser/server.d.ts +2 -0
- package/browser/server.js +2 -0
- package/browser/validation/types.d.ts +15 -0
- package/browser/validation/types.js +1 -0
- package/browser/validation/validation.test.d.ts +1 -0
- package/browser/validation/validation.test.js +120 -0
- package/browser/validation/withYup.d.ts +3 -0
- package/browser/validation/withYup.js +34 -0
- package/browser/validation/withZod.d.ts +3 -0
- package/browser/validation/withZod.js +35 -0
- package/build/ValidatedForm.d.ts +11 -0
- package/build/ValidatedForm.js +76 -0
- package/build/hooks.d.ts +8 -0
- package/build/hooks.js +23 -0
- package/build/index.d.ts +5 -0
- package/build/index.js +17 -0
- package/build/internal/formContext.d.ts +13 -0
- package/build/internal/formContext.js +10 -0
- package/build/internal/util.d.ts +3 -0
- package/build/internal/util.js +24 -0
- package/build/server.d.ts +2 -0
- package/build/server.js +6 -0
- package/build/validation/types.d.ts +15 -0
- package/build/validation/types.js +2 -0
- package/build/validation/validation.test.d.ts +1 -0
- package/build/validation/validation.test.js +141 -0
- package/build/validation/withYup.d.ts +3 -0
- package/build/validation/withYup.js +38 -0
- package/build/validation/withZod.d.ts +3 -0
- package/build/validation/withZod.js +39 -0
- package/package.json +7 -2
- package/.eslintrc.js +0 -46
- package/.github/workflows/test.yml +0 -35
- package/.husky/pre-commit +0 -4
- package/src/ValidatedForm.tsx +0 -130
- package/src/hooks.ts +0 -27
- package/src/internal/formContext.ts +0 -18
- package/src/internal/util.ts +0 -23
- package/src/server.ts +0 -5
- package/src/validation/types.ts +0 -12
- package/src/validation/validation.test.ts +0 -76
- package/src/validation/withYup.ts +0 -37
- package/test-app/README.md +0 -53
- package/test-app/app/components/Input.tsx +0 -24
- package/test-app/app/components/SubmitButton.tsx +0 -18
- package/test-app/app/entry.client.tsx +0 -4
- package/test-app/app/entry.server.tsx +0 -21
- package/test-app/app/root.tsx +0 -246
- package/test-app/app/routes/default-values.tsx +0 -34
- package/test-app/app/routes/index.tsx +0 -100
- package/test-app/app/routes/noscript.tsx +0 -10
- package/test-app/app/routes/submission.alt.tsx +0 -6
- package/test-app/app/routes/submission.fetcher.tsx +0 -6
- package/test-app/app/routes/submission.tsx +0 -47
- package/test-app/app/routes/validation.tsx +0 -40
- package/test-app/app/styles/dark.css +0 -7
- package/test-app/app/styles/demos/about.css +0 -26
- package/test-app/app/styles/demos/remix.css +0 -120
- package/test-app/app/styles/global.css +0 -98
- package/test-app/cypress/fixtures/example.json +0 -5
- package/test-app/cypress/integration/default-values.ts +0 -15
- package/test-app/cypress/integration/sanity.ts +0 -19
- package/test-app/cypress/integration/submission.ts +0 -26
- package/test-app/cypress/integration/validation.ts +0 -70
- package/test-app/cypress/plugins/config.ts +0 -38
- package/test-app/cypress/plugins/index.ts +0 -9
- package/test-app/cypress/support/commands/index.ts +0 -13
- package/test-app/cypress/support/commands/types.d.ts +0 -11
- package/test-app/cypress/support/index.ts +0 -20
- package/test-app/cypress/tsconfig.json +0 -11
- package/test-app/cypress.json +0 -3
- package/test-app/package-lock.json +0 -11675
- package/test-app/package.json +0 -40
- package/test-app/public/favicon.ico +0 -0
- package/test-app/remix.config.js +0 -10
- package/test-app/remix.env.d.ts +0 -2
- package/test-app/tsconfig.json +0 -18
- package/tsconfig.json +0 -15
@@ -1,98 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* You can just delete everything here or keep whatever you like, it's just a
|
3
|
-
* quick baseline!
|
4
|
-
*/
|
5
|
-
:root {
|
6
|
-
--color-foreground: hsl(0, 0%, 7%);
|
7
|
-
--color-background: hsl(0, 0%, 100%);
|
8
|
-
--color-links: hsl(213, 100%, 52%);
|
9
|
-
--color-links-hover: hsl(213, 100%, 43%);
|
10
|
-
--color-border: hsl(0, 0%, 82%);
|
11
|
-
--font-body: -apple-system, "Segoe UI", Helvetica Neue, Helvetica, Roboto,
|
12
|
-
Arial, sans-serif, system-ui, "Apple Color Emoji", "Segoe UI Emoji";
|
13
|
-
}
|
14
|
-
|
15
|
-
html {
|
16
|
-
box-sizing: border-box;
|
17
|
-
}
|
18
|
-
|
19
|
-
*,
|
20
|
-
*::before,
|
21
|
-
*::after {
|
22
|
-
box-sizing: inherit;
|
23
|
-
}
|
24
|
-
|
25
|
-
:-moz-focusring {
|
26
|
-
outline: auto;
|
27
|
-
}
|
28
|
-
|
29
|
-
:focus {
|
30
|
-
outline: var(--color-links) solid 2px;
|
31
|
-
outline-offset: 2px;
|
32
|
-
}
|
33
|
-
|
34
|
-
html,
|
35
|
-
body {
|
36
|
-
padding: 0;
|
37
|
-
margin: 0;
|
38
|
-
background-color: var(--color-background);
|
39
|
-
color: var(--color-foreground);
|
40
|
-
}
|
41
|
-
|
42
|
-
body {
|
43
|
-
font-family: var(--font-body);
|
44
|
-
line-height: 1.5;
|
45
|
-
}
|
46
|
-
|
47
|
-
a {
|
48
|
-
color: var(--color-links);
|
49
|
-
text-decoration: none;
|
50
|
-
}
|
51
|
-
|
52
|
-
a:hover {
|
53
|
-
color: var(--color-links-hover);
|
54
|
-
text-decoration: underline;
|
55
|
-
}
|
56
|
-
|
57
|
-
hr {
|
58
|
-
display: block;
|
59
|
-
height: 1px;
|
60
|
-
border: 0;
|
61
|
-
background-color: var(--color-border);
|
62
|
-
margin-top: 2rem;
|
63
|
-
margin-bottom: 2rem;
|
64
|
-
}
|
65
|
-
|
66
|
-
input:where([type="text"]),
|
67
|
-
input:where([type="search"]) {
|
68
|
-
display: block;
|
69
|
-
border: 1px solid var(--color-border);
|
70
|
-
width: 100%;
|
71
|
-
font: inherit;
|
72
|
-
line-height: 1;
|
73
|
-
height: calc(1ch + 1.5em);
|
74
|
-
padding-right: 0.5em;
|
75
|
-
padding-left: 0.5em;
|
76
|
-
background-color: hsl(0 0% 100% / 20%);
|
77
|
-
color: var(--color-foreground);
|
78
|
-
}
|
79
|
-
|
80
|
-
.sr-only {
|
81
|
-
position: absolute;
|
82
|
-
width: 1px;
|
83
|
-
height: 1px;
|
84
|
-
padding: 0;
|
85
|
-
margin: -1px;
|
86
|
-
overflow: hidden;
|
87
|
-
clip: rect(0, 0, 0, 0);
|
88
|
-
white-space: nowrap;
|
89
|
-
border-width: 0;
|
90
|
-
}
|
91
|
-
|
92
|
-
.container {
|
93
|
-
--gutter: 16px;
|
94
|
-
width: 1024px;
|
95
|
-
max-width: calc(100% - var(--gutter) * 2);
|
96
|
-
margin-right: auto;
|
97
|
-
margin-left: auto;
|
98
|
-
}
|
@@ -1,15 +0,0 @@
|
|
1
|
-
describe("Validation", () => {
|
2
|
-
it("should propagate default values to inputs", () => {
|
3
|
-
cy.visit("/default-values");
|
4
|
-
cy.findByLabelText("First Name").should("have.value", "Jane");
|
5
|
-
cy.findByLabelText("Last Name").should("have.value", "Doe");
|
6
|
-
cy.findByLabelText("Email").should("have.value", "jane.doe@example.com");
|
7
|
-
});
|
8
|
-
|
9
|
-
it("should propagate default values to inputs without JS", () => {
|
10
|
-
cy.visitWithoutJs("/default-values");
|
11
|
-
cy.findByLabelText("First Name").should("have.value", "Jane");
|
12
|
-
cy.findByLabelText("Last Name").should("have.value", "Doe");
|
13
|
-
cy.findByLabelText("Email").should("have.value", "jane.doe@example.com");
|
14
|
-
});
|
15
|
-
});
|
@@ -1,19 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* Some tests just to verify that the test utils in the app actually behave as assumed by other tests
|
3
|
-
*/
|
4
|
-
|
5
|
-
describe("Sanity", () => {
|
6
|
-
describe("Visiting without JS", () => {
|
7
|
-
it("should not show a noscript message when javascript enabled", () => {
|
8
|
-
cy.visit("/noscript");
|
9
|
-
cy.findByText("Is JS turned on?").should("exist");
|
10
|
-
cy.findByText("JS is turned off").should("not.exist");
|
11
|
-
});
|
12
|
-
|
13
|
-
it("should show a noscript message when javascript disabled", () => {
|
14
|
-
cy.visitWithoutJs("/noscript");
|
15
|
-
cy.findByText("Is JS turned on?").should("exist");
|
16
|
-
cy.findByText("JS is turned off").should("exist");
|
17
|
-
});
|
18
|
-
});
|
19
|
-
});
|
@@ -1,26 +0,0 @@
|
|
1
|
-
describe("Validation", () => {
|
2
|
-
it("should show the loading state for the correct submit button", () => {
|
3
|
-
cy.visit("/submission");
|
4
|
-
cy.findByText("Submit main form").click();
|
5
|
-
cy.findByText("Submitting alt form").should("not.exist");
|
6
|
-
cy.findByText("Submitting fetcher form").should("not.exist");
|
7
|
-
// if we check the one we're expecting last, then the test will correctly fail if the other buttons are in a loading state
|
8
|
-
cy.findByText("Submitting main form").should("exist");
|
9
|
-
|
10
|
-
cy.findByText("Submitting main form").should("not.exist");
|
11
|
-
|
12
|
-
cy.findByText("Submit alt form").click();
|
13
|
-
cy.findByText("Submitting main form").should("not.exist");
|
14
|
-
cy.findByText("Submitting fetcher form").should("not.exist");
|
15
|
-
cy.findByText("Submitting alt form").should("exist");
|
16
|
-
|
17
|
-
cy.findByText("Submitting alt form").should("not.exist");
|
18
|
-
|
19
|
-
cy.findByText("Submit fetcher form").click();
|
20
|
-
cy.findByText("Submitting alt form").should("not.exist");
|
21
|
-
cy.findByText("Submitting main form").should("not.exist");
|
22
|
-
cy.findByText("Submitting fetcher form").should("exist");
|
23
|
-
|
24
|
-
cy.findByText("Submitting fetcher form").should("not.exist");
|
25
|
-
});
|
26
|
-
});
|
@@ -1,70 +0,0 @@
|
|
1
|
-
describe("Validation", () => {
|
2
|
-
it("should support validating individual fields", () => {
|
3
|
-
cy.visit("/validation");
|
4
|
-
|
5
|
-
cy.findByLabelText("First Name").focus().blur();
|
6
|
-
cy.findByText("First Name is a required field").should("exist");
|
7
|
-
cy.findByLabelText("First Name").type("John");
|
8
|
-
cy.findByText("First Name is a required field").should("not.exist");
|
9
|
-
|
10
|
-
cy.findByLabelText("Last Name").focus().blur();
|
11
|
-
cy.findByText("Last Name is a required field").should("exist");
|
12
|
-
cy.findByLabelText("Last Name").type("Doe");
|
13
|
-
cy.findByText("Last Name is a required field").should("not.exist");
|
14
|
-
|
15
|
-
cy.findByLabelText("Email").focus().blur();
|
16
|
-
cy.findByText("Email is a required field").should("exist");
|
17
|
-
cy.findByLabelText("Email").type("not an email");
|
18
|
-
cy.findByLabelText("Email").blur();
|
19
|
-
cy.findByText("Email must be a valid email").should("exist");
|
20
|
-
|
21
|
-
cy.findByLabelText("Email").clear().type("an.email@example.com").blur();
|
22
|
-
cy.findByText("Email must be a valid email").should("not.exist");
|
23
|
-
|
24
|
-
cy.findByText("Email is a required field").should("not.exist");
|
25
|
-
cy.findByText("Last Name is a required field").should("not.exist");
|
26
|
-
cy.findByText("First Name is a required field").should("not.exist");
|
27
|
-
|
28
|
-
cy.findByText("Submit").click();
|
29
|
-
cy.findByText("Submitted for John Doe!").should("exist");
|
30
|
-
});
|
31
|
-
|
32
|
-
it("should validate the whole form at once when submit clicked", () => {
|
33
|
-
cy.visit("/validation");
|
34
|
-
|
35
|
-
cy.findByText("Submit").click();
|
36
|
-
|
37
|
-
cy.findByText("Email is a required field").should("exist");
|
38
|
-
cy.findByText("Last Name is a required field").should("exist");
|
39
|
-
cy.findByText("First Name is a required field").should("exist");
|
40
|
-
|
41
|
-
cy.findByLabelText("First Name").type("John");
|
42
|
-
cy.findByText("First Name is a required field").should("not.exist");
|
43
|
-
|
44
|
-
cy.findByLabelText("Last Name").type("Doe");
|
45
|
-
cy.findByText("Last Name is a required field").should("not.exist");
|
46
|
-
|
47
|
-
cy.findByLabelText("Email").type("an.email@example.com").blur();
|
48
|
-
cy.findByText("Email is a required field").should("not.exist");
|
49
|
-
|
50
|
-
cy.findByText("Submit").click();
|
51
|
-
cy.findByText("Submitted for John Doe!").should("exist");
|
52
|
-
});
|
53
|
-
|
54
|
-
it("should show validation errors even with JS disabled", () => {
|
55
|
-
cy.visitWithoutJs("/validation");
|
56
|
-
|
57
|
-
cy.findByText("Submit").click();
|
58
|
-
|
59
|
-
cy.findByText("Email is a required field").should("exist");
|
60
|
-
cy.findByText("Last Name is a required field").should("exist");
|
61
|
-
cy.findByText("First Name is a required field").should("exist");
|
62
|
-
|
63
|
-
cy.findByLabelText("First Name").type("John");
|
64
|
-
cy.findByLabelText("Last Name").type("Doe");
|
65
|
-
cy.findByLabelText("Email").type("an.email@example.com").blur();
|
66
|
-
|
67
|
-
cy.findByText("Submit").click();
|
68
|
-
cy.findByText("Submitted for John Doe!").should("exist");
|
69
|
-
});
|
70
|
-
});
|
@@ -1,38 +0,0 @@
|
|
1
|
-
// Plugin taken from Kent C Dodds' remix app
|
2
|
-
export default (
|
3
|
-
on: Cypress.PluginEvents,
|
4
|
-
config: Cypress.PluginConfigOptions
|
5
|
-
) => {
|
6
|
-
const port = process.env.PORT ?? "3000";
|
7
|
-
const configOverrides: Partial<Cypress.PluginConfigOptions> = {
|
8
|
-
baseUrl: `http://localhost:${port}`,
|
9
|
-
viewportWidth: 1030,
|
10
|
-
viewportHeight: 800,
|
11
|
-
integrationFolder: "cypress/integration",
|
12
|
-
video: !process.env.CI,
|
13
|
-
screenshotOnRunFailure: !process.env.CI,
|
14
|
-
};
|
15
|
-
Object.assign(config, configOverrides);
|
16
|
-
|
17
|
-
on("before:browser:launch", (browser, options) => {
|
18
|
-
if (browser.name === "chrome") {
|
19
|
-
options.args.push(
|
20
|
-
"--no-sandbox",
|
21
|
-
"--allow-file-access-from-files",
|
22
|
-
"--use-fake-ui-for-media-stream",
|
23
|
-
"--use-fake-device-for-media-stream",
|
24
|
-
"--use-file-for-fake-audio-capture=cypress/fixtures/sample.wav"
|
25
|
-
);
|
26
|
-
}
|
27
|
-
return options;
|
28
|
-
});
|
29
|
-
|
30
|
-
on("task", {
|
31
|
-
log(message) {
|
32
|
-
console.log(message);
|
33
|
-
return null;
|
34
|
-
},
|
35
|
-
});
|
36
|
-
|
37
|
-
return config;
|
38
|
-
};
|
@@ -1,13 +0,0 @@
|
|
1
|
-
import "@testing-library/cypress/add-commands";
|
2
|
-
|
3
|
-
Cypress.Commands.add("visitWithoutJs", (url) => {
|
4
|
-
const parentDocument = (cy as any).state("window").parent.document;
|
5
|
-
const iframe = parentDocument.querySelector(".iframes-container iframe");
|
6
|
-
if (false !== Cypress.config("chromeWebSecurity")) {
|
7
|
-
throw new TypeError(
|
8
|
-
"When you disable script you also have to set 'chromeWebSecurity' in your config to 'false'"
|
9
|
-
);
|
10
|
-
}
|
11
|
-
iframe.sandbox = "allow-forms";
|
12
|
-
return cy.visit(url);
|
13
|
-
});
|
@@ -1,20 +0,0 @@
|
|
1
|
-
// ***********************************************************
|
2
|
-
// This example support/index.js is processed and
|
3
|
-
// loaded automatically before your test files.
|
4
|
-
//
|
5
|
-
// This is a great place to put global configuration and
|
6
|
-
// behavior that modifies Cypress.
|
7
|
-
//
|
8
|
-
// You can change the location of this file or turn off
|
9
|
-
// automatically serving support files with the
|
10
|
-
// 'supportFile' configuration option.
|
11
|
-
//
|
12
|
-
// You can read more here:
|
13
|
-
// https://on.cypress.io/configuration
|
14
|
-
// ***********************************************************
|
15
|
-
|
16
|
-
// Import commands.js using ES2015 syntax:
|
17
|
-
import "./commands";
|
18
|
-
|
19
|
-
// Alternatively you can use CommonJS syntax:
|
20
|
-
// require('./commands')
|
package/test-app/cypress.json
DELETED