-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(formst/SelectField): add new select field component with corresp…
…onding formik wrapper component (#104)
- Loading branch information
1 parent
5520b16
commit ac74e58
Showing
5 changed files
with
652 additions
and
4 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,237 @@ | ||
import { Form, Formik } from 'formik' | ||
import React from 'react' | ||
import { Button } from '../Button' | ||
import FormikSelectField from './NewFormikSelectField' | ||
|
||
const items = [ | ||
{ value: 'apple', label: 'Apple' }, | ||
{ value: 'banana', label: 'Banana' }, | ||
{ value: 'pear', label: 'Pear' }, | ||
{ value: 'watermelon', label: 'Watermelon' }, | ||
{ value: 'peach', label: 'Peach' }, | ||
{ value: 'mango', label: 'Mango' }, | ||
] | ||
|
||
export const Default = () => { | ||
return ( | ||
<Formik | ||
initialValues={{ | ||
fruit: undefined, | ||
}} | ||
onSubmit={async (values, { resetForm }) => { | ||
alert(`Form submitted with value: ${values.fruit}`) | ||
resetForm() | ||
}} | ||
> | ||
{({ values }) => { | ||
return ( | ||
<div className="flex flex-col gap-2"> | ||
<Form> | ||
<FormikSelectField | ||
name="fruit" | ||
items={items} | ||
label="Fruits" | ||
placeholder="Select a fruit" | ||
className={{ root: 'mb-2' }} | ||
/> | ||
<Button type="submit">Submit</Button> | ||
</Form> | ||
<div>Value: {values.fruit}</div> | ||
</div> | ||
) | ||
}} | ||
</Formik> | ||
) | ||
} | ||
|
||
export const Required = () => { | ||
return ( | ||
<Formik | ||
initialValues={{ | ||
fruit: undefined, | ||
}} | ||
onSubmit={async (values, { resetForm }) => { | ||
alert(`Form submitted with value: ${values.fruit}`) | ||
resetForm() | ||
}} | ||
> | ||
{({ values }) => { | ||
return ( | ||
<div className="flex flex-col gap-2"> | ||
<Form> | ||
<FormikSelectField | ||
required | ||
name="fruit" | ||
items={items} | ||
label="Fruits" | ||
placeholder="Select a fruit" | ||
className={{ root: 'mb-2' }} | ||
/> | ||
<Button type="submit">Submit</Button> | ||
</Form> | ||
<div>Value: {values.fruit}</div> | ||
</div> | ||
) | ||
}} | ||
</Formik> | ||
) | ||
} | ||
|
||
export const Disabled = () => { | ||
return ( | ||
<Formik | ||
initialValues={{ | ||
fruit: items[0].value, | ||
}} | ||
onSubmit={async (values, { resetForm }) => { | ||
alert(`Form submitted with value: ${values.fruit}`) | ||
resetForm() | ||
}} | ||
> | ||
{({ values }) => { | ||
return ( | ||
<div className="flex flex-col gap-2"> | ||
<Form> | ||
<FormikSelectField | ||
disabled | ||
name="fruit" | ||
items={items} | ||
label="Fruits" | ||
placeholder="Select a fruit" | ||
className={{ root: 'mb-2' }} | ||
/> | ||
<Button type="submit">Submit</Button> | ||
</Form> | ||
<div>Value: {values.fruit}</div> | ||
</div> | ||
) | ||
}} | ||
</Formik> | ||
) | ||
} | ||
|
||
export const LargeLabel = () => { | ||
return ( | ||
<Formik | ||
initialValues={{ | ||
fruit: undefined, | ||
}} | ||
onSubmit={async (values, { resetForm }) => { | ||
alert(`Form submitted with value: ${values.fruit}`) | ||
resetForm() | ||
}} | ||
> | ||
{({ values }) => { | ||
return ( | ||
<div className="flex flex-col gap-2"> | ||
<Form> | ||
<FormikSelectField | ||
name="fruit" | ||
items={items} | ||
label="Fruits" | ||
labelType="large" | ||
placeholder="Select a fruit" | ||
className={{ root: 'mb-2' }} | ||
/> | ||
<Button type="submit">Submit</Button> | ||
</Form> | ||
<div>Value: {values.fruit}</div> | ||
</div> | ||
) | ||
}} | ||
</Formik> | ||
) | ||
} | ||
|
||
export const Error = () => { | ||
return ( | ||
<Formik | ||
initialValues={{ | ||
fruit: undefined, | ||
}} | ||
onSubmit={async (values, { resetForm }) => { | ||
alert(`Form submitted with value: ${values.fruit}`) | ||
resetForm() | ||
}} | ||
> | ||
{({ values }) => { | ||
return ( | ||
<div className="flex flex-col gap-2"> | ||
<Form> | ||
<FormikSelectField | ||
name="fruit" | ||
items={items} | ||
label="Fruits" | ||
labelType="large" | ||
error="Error message" | ||
placeholder="Select a fruit" | ||
className={{ root: 'mb-2' }} | ||
/> | ||
<FormikSelectField | ||
name="fruit" | ||
items={items} | ||
label="Fruits" | ||
error="Error message" | ||
placeholder="Select a fruit" | ||
className={{ root: 'mb-2' }} | ||
/> | ||
<Button type="submit">Submit</Button> | ||
</Form> | ||
<div>Value: {values.fruit}</div> | ||
</div> | ||
) | ||
}} | ||
</Formik> | ||
) | ||
} | ||
|
||
export const Tooltip = () => { | ||
return ( | ||
<Formik | ||
initialValues={{ | ||
fruit: items[0].value, | ||
}} | ||
onSubmit={async (values, { resetForm }) => { | ||
alert(`Form submitted with value: ${values.fruit}`) | ||
resetForm() | ||
}} | ||
> | ||
{({ values }) => { | ||
return ( | ||
<div> | ||
<Form className="flex flex-col gap-3"> | ||
<FormikSelectField | ||
required | ||
name="fruit" | ||
label="Label" | ||
tooltip="Tooltip for this input" | ||
items={items} | ||
/> | ||
<FormikSelectField | ||
required | ||
name="fruit" | ||
label="Label" | ||
labelType="large" | ||
tooltip="Tooltip for this input" | ||
items={items} | ||
/> | ||
<FormikSelectField | ||
required | ||
name="fruit" | ||
label="Label" | ||
labelType="large" | ||
tooltip="Tooltip for this input" | ||
error="Error message" | ||
items={items} | ||
/> | ||
<Button type="submit" className={{ root: 'w-max' }}> | ||
Submit | ||
</Button> | ||
</Form> | ||
<div>Value: {values.fruit}</div> | ||
</div> | ||
) | ||
}} | ||
</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,95 @@ | ||
import { useField } from 'formik' | ||
import React from 'react' | ||
import { Item, SelectClassName } from '../Select' | ||
import SelectField from './SelectField' | ||
|
||
export interface FormikSelectFieldProps { | ||
id?: string | ||
data?: { | ||
cy?: string | ||
test?: string | ||
} | ||
name: string | ||
label?: string | ||
labelType?: 'small' | 'large' | ||
placeholder?: string | ||
tooltip?: string | React.ReactNode | ||
required?: boolean | ||
items: Item[] | ||
disabled?: boolean | ||
error?: string | ||
hideError?: boolean | ||
contentPosition?: 'item-aligned' | 'popper' | ||
className?: { | ||
root?: string | ||
label?: string | ||
error?: string | ||
tooltip?: string | ||
select?: SelectClassName | ||
} | ||
} | ||
|
||
/** | ||
* This component returns a select field that works as to be expected in a Formik environment. | ||
* State is managed by Formik through the name attribute. | ||
* | ||
* @param id - The id of the field. | ||
* @param data - The object of data attributes that can be used for testing (e.g. data-test or data-cy) | ||
* @param name - The name of the field. | ||
* @param label - The optional label is shown next to the field in the form. | ||
* @param labelType - The optional labelType can be used to change the size and position of the label according to pre-defined standards. | ||
* @param placeholder - The optional placeholder is shown when no value is selected / initialization with 'undefined' is chosen. | ||
* @param disabled - The optional disabled prop disables the select component. | ||
* @param error - The optional error message is shown next to the component. | ||
* @param hideError - Hide the error message below this component as is might be more appropriate to show it somewhere else. | ||
* @param contentPosition - The position of the content of the select component. Currently only 'item-aligned' and 'popper' are supported. | ||
* @param tooltip - The optional tooltip is shown on hover next to the label. | ||
* @param items - The array of items that should be available on the select component. | ||
* @param required - Indicate whether the field is required or not. | ||
* @param className - The optional className object allows you to override the default styling. | ||
* @returns Select component with formik state management. | ||
*/ | ||
export function FormikSelectField({ | ||
id, | ||
data, | ||
name, | ||
label, | ||
labelType = 'small', | ||
placeholder, | ||
tooltip, | ||
required = false, | ||
items, | ||
disabled = false, | ||
error, | ||
hideError = false, | ||
contentPosition = 'item-aligned', | ||
className, | ||
...props | ||
}: FormikSelectFieldProps) { | ||
const [field, meta, helpers] = useField(name) | ||
|
||
return ( | ||
<SelectField | ||
id={id} | ||
data={data} | ||
name={name} | ||
value={field.value} | ||
onChange={(newValue: string) => helpers.setValue(newValue)} | ||
onBlur={() => helpers.setTouched(true)} | ||
label={label} | ||
labelType={labelType} | ||
placeholder={placeholder} | ||
tooltip={tooltip} | ||
required={required} | ||
items={items} | ||
disabled={disabled} | ||
error={!!meta.error && meta.touched ? meta.error : error} | ||
hideError={hideError} | ||
contentPosition={contentPosition} | ||
className={className} | ||
{...props} | ||
/> | ||
) | ||
} | ||
|
||
export default FormikSelectField |
Oops, something went wrong.