-
Notifications
You must be signed in to change notification settings - Fork 60
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: upstream the FormikField component to make react-component's fi…
…elds and Formik easier to work with.
- Loading branch information
Showing
12 changed files
with
2,023 additions
and
1,818 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import React from "react"; | ||
import type { Meta, StoryObj } from "@storybook/react"; | ||
|
||
import FormikField from "./FormikField"; | ||
import Select from "../Select"; | ||
import { Formik } from "formik"; | ||
|
||
const meta: Meta<typeof FormikField> = { | ||
title: "FormikField", | ||
component: FormikField, | ||
tags: ["autodocs"], | ||
}; | ||
|
||
export default meta; | ||
|
||
type Story = StoryObj<typeof FormikField>; | ||
|
||
export const Default: Story = { | ||
render: () => ( | ||
<Formik initialValues={{ username: "" }} onSubmit={() => {}}> | ||
<FormikField name="username" label="Username" type="text" /> | ||
</Formik> | ||
), | ||
}; | ||
|
||
export const Fields: Story = { | ||
parameters: { | ||
docs: { | ||
description: { | ||
story: ` | ||
Any React Components input can be provided to FormikField (e.g. Input, Textarea or Select) or you may provide a custom component. | ||
Any additional props that need to be passed can be given to FormikField. | ||
`, | ||
}, | ||
}, | ||
}, | ||
render: () => ( | ||
<Formik initialValues={{ release: "" }} onSubmit={() => {}}> | ||
<FormikField | ||
component={Select} | ||
name="release" | ||
label="Release" | ||
options={[ | ||
{ value: "", disabled: true, label: "Select an option" }, | ||
{ value: "1", label: "Cosmic Cuttlefish" }, | ||
{ value: "2", label: "Bionic Beaver" }, | ||
{ value: "3", label: "Xenial Xerus" }, | ||
]} | ||
/> | ||
</Formik> | ||
), | ||
}; | ||
|
||
export const Errors: Story = { | ||
parameters: { | ||
docs: { | ||
description: { | ||
story: ` | ||
Formik parameters are passed to the field using Formik's \`useField\`. This means that validation and errors, state handlers etc. should all just work. | ||
`, | ||
}, | ||
}, | ||
}, | ||
render: () => ( | ||
<Formik | ||
initialErrors={{ username: "This username has already been taken." }} | ||
initialTouched={{ username: true }} | ||
initialValues={{ username: "" }} | ||
onSubmit={() => {}} | ||
> | ||
<FormikField name="username" label="Username" type="text" /> | ||
</Formik> | ||
), | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import React from "react"; | ||
import { render, screen } from "@testing-library/react"; | ||
import { Formik } from "formik"; | ||
|
||
import FormikField from "./FormikField"; | ||
|
||
describe("FormikField", () => { | ||
it("can set a different component", () => { | ||
const Component = () => <select />; | ||
render( | ||
<Formik initialValues={{}} onSubmit={jest.fn()}> | ||
<FormikField component={Component} name="username" /> | ||
</Formik> | ||
); | ||
|
||
expect(screen.getByRole("combobox")).toBeInTheDocument(); | ||
expect(screen.queryByRole("textbox")).not.toBeInTheDocument(); | ||
}); | ||
|
||
it("can pass errors", () => { | ||
render( | ||
<Formik | ||
initialErrors={{ username: "Uh oh!" }} | ||
initialTouched={{ username: true }} | ||
initialValues={{ username: "" }} | ||
onSubmit={jest.fn()} | ||
> | ||
<FormikField name="username" /> | ||
</Formik> | ||
); | ||
|
||
expect(screen.getByRole("textbox")).toHaveAccessibleErrorMessage( | ||
"Error: Uh oh!" | ||
); | ||
}); | ||
|
||
it("can hide the errors", () => { | ||
render( | ||
<Formik | ||
initialErrors={{ username: "Uh oh!" }} | ||
initialTouched={{ username: true }} | ||
initialValues={{ username: "" }} | ||
onSubmit={jest.fn()} | ||
> | ||
<FormikField displayError={false} name="username" /> | ||
</Formik> | ||
); | ||
|
||
expect(screen.getByRole("textbox")).not.toHaveAccessibleErrorMessage(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import React from "react"; | ||
import { useField } from "formik"; | ||
import { | ||
type ComponentProps, | ||
type ComponentType, | ||
type ElementType, | ||
type HTMLProps, | ||
} from "react"; | ||
import Input from "components/Input"; | ||
|
||
export type Props<C extends ElementType | ComponentType = typeof Input> = { | ||
/** | ||
* The component to display. Defaults to `Input`. | ||
*/ | ||
component?: C; | ||
/** | ||
* This can be used to hide errors returned by Formik. | ||
*/ | ||
displayError?: boolean; | ||
/** | ||
* The name of the field as given to Formik. | ||
*/ | ||
name: string; | ||
value?: HTMLProps<HTMLElement>["value"]; | ||
} & ComponentProps<C>; | ||
|
||
/** | ||
* This component makes it easier to use Vanilla form inputs with Formik. It | ||
* makes use of Formik's context to automatically map errors, values, states | ||
* etc. onto the provided field. | ||
*/ | ||
const FormikField = <C extends ElementType | ComponentType = typeof Input>({ | ||
component: Component = Input, | ||
displayError = true, | ||
name, | ||
value, | ||
label, | ||
...props | ||
}: Props<C>): JSX.Element => { | ||
const [field, meta] = useField({ name, type: props.type, value }); | ||
|
||
return ( | ||
<Component | ||
aria-label={label} | ||
error={meta.touched && displayError ? meta.error : null} | ||
label={label} | ||
{...field} | ||
{...props} | ||
/> | ||
); | ||
}; | ||
|
||
export default FormikField; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default, type Props as FormikFieldProps } from "./FormikField"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.