forked from canonical/react-components
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: upstream FormikField (canonical#1054)
- Loading branch information
Showing
13 changed files
with
2,041 additions
and
1,825 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
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,82 @@ | ||
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 = { | ||
args: { | ||
name: "username", | ||
label: "Username", | ||
type: "text", | ||
}, | ||
render: (args) => ( | ||
<Formik initialValues={{ username: "" }} onSubmit={() => {}}> | ||
<FormikField {...args} /> | ||
</Formik> | ||
), | ||
}; | ||
|
||
export const Fields: Story = { | ||
args: { | ||
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" }, | ||
], | ||
}, | ||
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: (args) => ( | ||
<Formik initialValues={{ release: "" }} onSubmit={() => {}}> | ||
<FormikField {...args} /> | ||
</Formik> | ||
), | ||
}; | ||
|
||
export const Errors: Story = { | ||
args: Default.args, | ||
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: (args) => ( | ||
<Formik | ||
initialErrors={{ username: "This username has already been taken." }} | ||
initialTouched={{ username: true }} | ||
initialValues={{ username: "" }} | ||
onSubmit={() => {}} | ||
> | ||
<FormikField {...args} /> | ||
</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,54 @@ | ||
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. | ||
* @default 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.