Skip to content

Commit 1db1baa

Browse files
fix: ant-package (#155)
* fix: resolved Mantine fieldConfig.description, mantine-zod advanced features Cypress test, Select not working fix, key props spread * added test wrapper to 'renders select field correctly' test * re added the conditional theme provider rendering * refined ant package, restored react package to previous * refactor(ant): improve implementation, fix bugs, and add tests * restore default ant autoform props * added changeset * added changeset version and changelog * commit deleted changeset * rename AutoFormProps of packages/ant/AutoForm in camelCase * ant package version 1.0.0 -> 1.1.0 * fix: ant package field focus on error * fix: select use proper enum value * remove date field comment * added changeset
1 parent c688ee8 commit 1db1baa

37 files changed

+1047
-642
lines changed

.changeset/lemon-pumpkins-walk.md

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
"@autoform/ant": minor
3+
---
4+
5+
### What the change is
6+
7+
- **Component:** Simplified logic, removed unnecessary context, and fixed date component bugs.
8+
- **React Integration:** Restored structure while keeping improvements; updated `AutoFormProps` to allow custom attributes.
9+
- **Testing:** Added Cypress tests (`ant-zod`) for validation.
10+
11+
### Why the change was made
12+
13+
- These changes refine implementation and fix existing issues.

apps/web/components/Ant.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ const Ant = () => {
1010
console.log(JSON.stringify(data, null, 2));
1111
}}
1212
// Ant Design Form Props
13-
AntFormProps={{
13+
antFormProps={{
1414
layout: "horizontal",
1515
className: "no-margin-form",
1616
onValuesChange: (e) => {
17-
// console.log("inputChange", e);
17+
console.log("inputChange", e);
1818
},
1919
// onFinish: (e) => {
2020
// console.log("onFinish", e);

apps/web/cypress/component/autoform/all.cy.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ import "./mui-yup/all.cy";
22
import "./mui-zod/all.cy";
33
import "./mantine-zod/all.cy";
44
import "./shadcn-zod/all.cy";
5+
import "./ant-zod/all.cy"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
import React from "react";
2+
import { AutoForm } from "@autoform/ant";
3+
import { ZodProvider, fieldConfig } from "@autoform/zod";
4+
import { z } from "zod";
5+
6+
describe("AutoForm Advanced Features Tests", () => {
7+
const advancedSchema = z.object({
8+
username: z
9+
.string()
10+
.min(3, "Username must be at least 3 characters")
11+
.superRefine(
12+
fieldConfig({
13+
description: "Choose a unique username",
14+
order: 1,
15+
inputProps: {
16+
placeholder: "Enter username",
17+
},
18+
})
19+
),
20+
password: z
21+
.string()
22+
.min(8, "Password must be at least 8 characters")
23+
.superRefine(
24+
fieldConfig({
25+
description: "Use a strong password",
26+
order: 2,
27+
inputProps: {
28+
type: "password",
29+
},
30+
})
31+
),
32+
favoriteColor: z.enum(["red", "green", "blue"]).superRefine(
33+
fieldConfig({
34+
fieldType: "select",
35+
order: 3,
36+
})
37+
),
38+
bio: z
39+
.string()
40+
.optional()
41+
.superRefine(
42+
fieldConfig({
43+
order: 4,
44+
})
45+
),
46+
});
47+
48+
const schemaProvider = new ZodProvider(advancedSchema);
49+
50+
it("renders fields in the correct order", () => {
51+
cy.mount(
52+
<AutoForm
53+
schema={schemaProvider}
54+
onSubmit={cy.stub().as("onSubmit")}
55+
withSubmit
56+
/>
57+
);
58+
59+
cy.get(".ant-form-item")
60+
.eq(0)
61+
.find("input")
62+
.should("have.attr", "name", "username");
63+
cy.get(".ant-form-item")
64+
.eq(1)
65+
.find("input")
66+
.should("have.attr", "name", "password");
67+
cy.get(".ant-form-item").eq(2).find(".ant-select").find(".ant-select-selection-search-input");
68+
cy.get(".ant-form-item")
69+
.eq(3)
70+
.find("input")
71+
.should("have.attr", "name", "bio");
72+
});
73+
74+
it("displays field descriptions", () => {
75+
cy.mount(
76+
<AutoForm
77+
schema={schemaProvider}
78+
onSubmit={cy.stub().as("onSubmit")}
79+
withSubmit
80+
/>
81+
);
82+
83+
cy.contains("Choose a unique username").should("be.visible");
84+
cy.contains("Use a strong password").should("be.visible");
85+
});
86+
87+
it("applies custom input props", () => {
88+
cy.mount(
89+
<AutoForm
90+
schema={schemaProvider}
91+
onSubmit={cy.stub().as("onSubmit")}
92+
withSubmit
93+
/>
94+
);
95+
96+
cy.get('input[name="username"]').should(
97+
"have.attr",
98+
"placeholder",
99+
"Enter username"
100+
);
101+
cy.get('input[name="password"]').should("have.attr", "type", "password");
102+
});
103+
104+
it("renders select field correctly", () => {
105+
cy.mount(
106+
<AutoForm
107+
schema={schemaProvider}
108+
onSubmit={cy.stub().as("onSubmit")}
109+
withSubmit
110+
/>
111+
);
112+
113+
cy.get('.ant-select[name*="favoriteColor"]').should("exist").click().find('input#favoriteColor').click();
114+
cy.get('.ant-select-item[title="red"]').should('exist');
115+
cy.get('.ant-select-item[title="green"]').should('exist');
116+
cy.get('.ant-select-item[title="blue"]').should('exist');
117+
118+
});
119+
120+
it("renders textarea field correctly", () => {
121+
cy.mount(
122+
<AutoForm
123+
schema={schemaProvider}
124+
onSubmit={cy.stub().as("onSubmit")}
125+
withSubmit
126+
/>
127+
);
128+
129+
cy.get('input[name="bio"]').should("exist");
130+
});
131+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import "./basic.cy";
2+
import "./arrays.cy";
3+
import "./subobjects.cy";
4+
import "./advanced-features.cy";
5+
import "./validation.cy";
6+
import "./controlled-form.cy";
7+
import "./ui-customization.cy";
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import React from "react";
2+
import { AutoForm } from "@autoform/ant";
3+
import { ZodProvider } from "@autoform/zod";
4+
import { z } from "zod";
5+
6+
describe("AutoForm Arrays Tests", () => {
7+
const arraySchema = z.object({
8+
tags: z.array(z.string()),
9+
friends: z.array(
10+
z.object({
11+
name: z.string(),
12+
age: z.coerce.number(),
13+
})
14+
),
15+
});
16+
17+
const schemaProvider = new ZodProvider(arraySchema);
18+
19+
it("renders array fields correctly", () => {
20+
cy.mount(
21+
<AutoForm
22+
schema={schemaProvider}
23+
onSubmit={cy.stub().as("onSubmit")}
24+
withSubmit
25+
/>
26+
);
27+
28+
cy.get('.ant-btn').eq(0)
29+
.should('exist')
30+
.within(() => {
31+
cy.get('span[aria-label="plus"]').should('exist');
32+
});
33+
});
34+
35+
it("allows adding and removing array items", () => {
36+
cy.mount(
37+
<AutoForm
38+
schema={schemaProvider}
39+
onSubmit={cy.stub().as("onSubmit")}
40+
withSubmit
41+
/>
42+
);
43+
44+
// Add tags
45+
cy.get('span[aria-label="plus"]').eq(0).click();
46+
cy.get('input[name="tags.0"]').type("tag1");
47+
cy.get('span[aria-label="plus"]').eq(0).click();
48+
cy.get('input[name="tags.1"]').type("tag2");
49+
50+
// Add friends
51+
cy.get('span[aria-label="plus"]').eq(1).click();
52+
cy.get('input[name="friends.0.name"]').type("Alice");
53+
cy.get('input[name="friends.0.age"]').type("25");
54+
cy.get('span[aria-label="plus"]').eq(1).click();
55+
cy.get('input[name="friends.1.name"]').type("Bob");
56+
cy.get('input[name="friends.1.age"]').type("30");
57+
58+
// Remove a tag and a friend
59+
cy.get('span[aria-label="delete"]').eq(0).click();
60+
cy.get('span[aria-label="delete"]').eq(1).click();
61+
62+
cy.get('button[type="submit"]').click();
63+
64+
cy.get("@onSubmit").should("have.been.calledOnce");
65+
cy.get("@onSubmit").should("have.been.calledWith", {
66+
tags: ["tag2"],
67+
friends: [{ name: "Bob", age: 30 }],
68+
});
69+
});
70+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React from "react";
2+
import { AutoForm } from "@autoform/ant";
3+
import { ZodProvider, fieldConfig } from "@autoform/zod";
4+
import { z } from "zod";
5+
6+
describe("AutoForm Basic Tests", () => {
7+
const basicSchema = z.object({
8+
name: z.string().min(2, "Name must be at least 2 characters"),
9+
age: z.coerce.number().min(18, "Must be at least 18 years old"),
10+
email: z.string().email("Invalid email address"),
11+
website: z.string().url("Invalid URL").optional(),
12+
birthdate: z.coerce.date(),
13+
isStudent: z.boolean(),
14+
});
15+
16+
const schemaProvider = new ZodProvider(basicSchema);
17+
18+
it("renders all field types correctly", () => {
19+
cy.mount(
20+
<AutoForm
21+
schema={schemaProvider}
22+
onSubmit={cy.stub().as("onSubmit")}
23+
withSubmit
24+
/>
25+
);
26+
27+
cy.get('input[name="name"]').should("exist");
28+
cy.get('input[name="age"]').should("have.class", "ant-input-number-input");
29+
cy.get('input[name="email"]').should("exist");
30+
cy.get('input[name="website"]').should("exist");
31+
cy.get('input[name="birthdate"]');
32+
cy.get('input[name="isStudent"]').should("have.class", "ant-checkbox-input");
33+
});
34+
35+
it("submits form with correct data types", () => {
36+
const onSubmit = cy.stub().as("onSubmit");
37+
cy.mount(
38+
<AutoForm schema={schemaProvider} onSubmit={onSubmit} withSubmit />
39+
);
40+
41+
cy.get('input[name="name"]').type("John Doe");
42+
cy.get('input[name="age"]').type("25");
43+
cy.get('input[name="email"]').type("[email protected]");
44+
cy.get('input[name="website"]').type("https://example.com");
45+
cy.get('input[name="birthdate"]').clear().type("1990-01-01");
46+
cy.get('input[name="isStudent"]').check();
47+
48+
cy.get('button[type="submit"]').click();
49+
50+
cy.get("@onSubmit").should("have.been.calledOnce");
51+
cy.get("@onSubmit").should("have.been.calledWith", {
52+
name: "John Doe",
53+
age: 25,
54+
55+
website: "https://example.com",
56+
birthdate: new Date("1990-01-01"),
57+
isStudent: true,
58+
});
59+
});
60+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import React, { useState } from "react";
2+
import { AutoForm } from "@autoform/ant";
3+
import { ZodProvider } from "@autoform/zod";
4+
import { z } from "zod";
5+
6+
const ControlledForm = () => {
7+
const [formValues, setFormValues] = useState({
8+
name: "John Doe",
9+
10+
});
11+
12+
const schema = z.object({
13+
name: z.string(),
14+
email: z.string().email(),
15+
});
16+
17+
const schemaProvider = new ZodProvider(schema);
18+
19+
return (
20+
<AutoForm
21+
schema={schemaProvider}
22+
onSubmit={cy.stub().as("onSubmit")}
23+
withSubmit
24+
values={formValues}
25+
onFormInit={(form) => {
26+
form.watch((data) => {
27+
setFormValues(data as typeof formValues);
28+
});
29+
}}
30+
/>
31+
);
32+
};
33+
34+
describe("AutoForm Controlled Form Tests", () => {
35+
it("renders with initial values", () => {
36+
cy.mount(<ControlledForm />);
37+
38+
cy.get('input[name="name"]').should("have.value", "John Doe");
39+
cy.get('input[name="email"]').should("have.value", "[email protected]");
40+
});
41+
42+
it("updates controlled values on input", () => {
43+
return; // TODO: controlled forms for mui are re-creating the element on every change, so this is not reliable
44+
45+
cy.mount(<ControlledForm />);
46+
47+
cy.get('input[name="name"]').clear().type("Jane Doe");
48+
cy.get('input[name="name"]').should("have.value", "Jane Doe");
49+
50+
cy.get('input[name="email"]').clear().type("[email protected]");
51+
cy.get('input[name="email"]').should("have.value", "[email protected]");
52+
});
53+
});

0 commit comments

Comments
 (0)