Skip to content

Commit

Permalink
Add support for formprops
Browse files Browse the repository at this point in the history
  • Loading branch information
vantezzen committed Oct 22, 2024
1 parent 2ce46ce commit 0ccca22
Show file tree
Hide file tree
Showing 13 changed files with 249 additions and 36 deletions.
4 changes: 4 additions & 0 deletions apps/docs/pages/docs/react/api.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,7 @@ Additional, custom form components can be passed to the `formComponents` prop. T
## uiComponents: Partial\<AutoFormUIComponents>

Override the default UI components with custom components. This allows you to customize the look and feel of the form.

## formProps?: React.ComponentProps\<'form'>

The `formProps` prop allows you to pass additional props directly to the underlying form element. This can be useful for adding custom attributes, event handlers, or other properties to the form.
21 changes: 21 additions & 0 deletions apps/docs/pages/docs/react/customization.md
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,24 @@ You can also override the default UI components with custom components. This all
}}
/>
```

## Form element customization

In addition to overriding UI components, you can also customize the form element itself using the `formProps` prop:

```tsx
<AutoForm
schema={schemaProvider}
onSubmit={handleSubmit}
formProps={{
className: "my-custom-form",
"data-testid": "user-form",
noValidate: true,
onTouchStart: (e) => {
console.log("onTouchStart", e);
},
}}
/>
```

This allows you to add custom classes, data attributes, or other properties directly to the form element.
19 changes: 19 additions & 0 deletions apps/docs/pages/docs/react/getting-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,25 @@ const [values, setValues] = useState({});

This allows you to access form methods and state from the parent component. You can use the `onFormInit` prop independent of controlled forms to access the form instance.

## Passing props to the form element

You can pass additional props to the underlying form element using the `formProps` prop:

```tsx
<AutoForm
schema={schemaProvider}
onSubmit={handleSubmit}
formProps={{
className: "my-custom-form-class",
onKeyDown: (e) => {
if (e.key === "Enter") e.preventDefault();
},
}}
/>
```

This allows you to customize the form element's attributes and behavior as needed.

## Submitting the form

You can use the `withSubmit` prop to automatically add a submit button to the form.
Expand Down
57 changes: 57 additions & 0 deletions apps/web/cypress/component/autoform/mantine-zod/form-props.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from "react";
import { AutoForm } from "@autoform/mantine";
import { ZodProvider } from "@autoform/zod";
import { z } from "zod";
import { TestWrapper } from "./utils";

describe("AutoForm Form Props Tests (Mantine)", () => {
const schema = z.object({
name: z.string(),
});

const schemaProvider = new ZodProvider(schema);

it("applies custom form props", () => {
cy.mount(
<TestWrapper>
<AutoForm
schema={schemaProvider}
onSubmit={cy.stub().as("onSubmit")}
withSubmit
formProps={{
className: "custom-form-class",
"data-testid": "custom-form",
onKeyDown: cy.stub().as("onKeyDown"),
}}
/>
</TestWrapper>
);

cy.get("form")
.should("have.class", "custom-form-class")
.and("have.attr", "data-testid", "custom-form");

cy.get('input[name="name"]').type("{enter}");
cy.get("@onKeyDown").should("have.been.called");
});

it("prevents form submission on enter key", () => {
cy.mount(
<TestWrapper>
<AutoForm
schema={schemaProvider}
onSubmit={cy.stub().as("onSubmit")}
withSubmit
formProps={{
onKeyDown: (e) => {
if (e.key === "Enter") e.preventDefault();
},
}}
/>
</TestWrapper>
);

cy.get('input[name="name"]').type("John Doe{enter}");
cy.get("@onSubmit").should("not.have.been.called");
});
});
52 changes: 52 additions & 0 deletions apps/web/cypress/component/autoform/mui-zod/form-props.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from "react";
import { AutoForm } from "@autoform/mui";
import { ZodProvider } from "@autoform/zod";
import { z } from "zod";

describe("AutoForm Form Props Tests (MUI)", () => {
const schema = z.object({
name: z.string(),
});

const schemaProvider = new ZodProvider(schema);

it("applies custom form props", () => {
cy.mount(
<AutoForm
schema={schemaProvider}
onSubmit={cy.stub().as("onSubmit")}
withSubmit
formProps={{
className: "custom-form-class",
"data-testid": "custom-form",
onKeyDown: cy.stub().as("onKeyDown"),
}}
/>
);

cy.get("form")
.should("have.class", "custom-form-class")
.and("have.attr", "data-testid", "custom-form");

cy.get('input[name="name"]').type("{enter}");
cy.get("@onKeyDown").should("have.been.called");
});

it("prevents form submission on enter key", () => {
cy.mount(
<AutoForm
schema={schemaProvider}
onSubmit={cy.stub().as("onSubmit")}
withSubmit
formProps={{
onKeyDown: (e) => {
if (e.key === "Enter") e.preventDefault();
},
}}
/>
);

cy.get('input[name="name"]').type("John Doe{enter}");
cy.get("@onSubmit").should("not.have.been.called");
});
});
57 changes: 57 additions & 0 deletions apps/web/cypress/component/autoform/shadcn-zod/form-props.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from "react";
import { AutoForm } from "@autoform/shadcn/components/ui/autoform/AutoForm";
import { ZodProvider } from "@autoform/zod";
import { z } from "zod";
import { TestWrapper } from "./utils";

describe("AutoForm Form Props Tests (shadcn)", () => {
const schema = z.object({
name: z.string(),
});

const schemaProvider = new ZodProvider(schema);

it("applies custom form props", () => {
cy.mount(
<TestWrapper>
<AutoForm
schema={schemaProvider}
onSubmit={cy.stub().as("onSubmit")}
withSubmit
formProps={{
className: "custom-form-class",
"data-testid": "custom-form",
onKeyDown: cy.stub().as("onKeyDown"),
}}
/>
</TestWrapper>
);

cy.get("form")
.should("have.class", "custom-form-class")
.and("have.attr", "data-testid", "custom-form");

cy.get('input[name="name"]').type("{enter}");
cy.get("@onKeyDown").should("have.been.called");
});

it("prevents form submission on enter key", () => {
cy.mount(
<TestWrapper>
<AutoForm
schema={schemaProvider}
onSubmit={cy.stub().as("onSubmit")}
withSubmit
formProps={{
onKeyDown: (e) => {
if (e.key === "Enter") e.preventDefault();
},
}}
/>
</TestWrapper>
);

cy.get('input[name="name"]').type("John Doe{enter}");
cy.get("@onSubmit").should("not.have.been.called");
});
});
22 changes: 11 additions & 11 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 7 additions & 6 deletions packages/mantine/src/components/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
import React from "react";
import { Box } from "@mantine/core";

export const Form: React.FC<{
onSubmit: (e: React.FormEvent) => void;
children: React.ReactNode;
}> = ({ onSubmit, children }) => {
export const Form = React.forwardRef<
HTMLFormElement,
React.ComponentProps<"form">
>(({ children, ...props }, ref) => {
return (
<Box
component="form"
onSubmit={onSubmit}
style={{
display: "flex",
flexDirection: "column",
gap: 15,
}}
ref={ref}
{...props}
>
{children}
</Box>
);
};
});
12 changes: 6 additions & 6 deletions packages/mui/src/components/Form.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import React from "react";
import Box from "@mui/material/Box";

export const Form: React.FC<{
onSubmit: (e: React.FormEvent) => void;
children: React.ReactNode;
}> = ({ onSubmit, children }) => {
export const Form = React.forwardRef<
HTMLFormElement,
React.ComponentProps<"form">
>(({ children, ...props }, ref) => {
return (
<Box component="form" onSubmit={onSubmit} noValidate autoComplete="off">
<Box component="form" ref={ref} noValidate autoComplete="off" {...props}>
{children}
</Box>
);
};
});
Loading

0 comments on commit 0ccca22

Please sign in to comment.