2020-07-29 10:04:09 +02:00
|
|
|
import React, { FormEvent, ChangeEvent, ReactElement, ReactNode } from 'react'
|
2020-06-30 12:56:50 +02:00
|
|
|
import InputElement from './InputElement'
|
|
|
|
import Help from './Help'
|
|
|
|
import Label from './Label'
|
|
|
|
import styles from './index.module.css'
|
2020-10-16 09:36:21 +02:00
|
|
|
import { ErrorMessage, FieldInputProps } from 'formik'
|
2020-07-17 21:21:27 +02:00
|
|
|
import classNames from 'classnames/bind'
|
|
|
|
|
|
|
|
const cx = classNames.bind(styles)
|
2020-06-30 12:56:50 +02:00
|
|
|
|
|
|
|
export interface InputProps {
|
|
|
|
name: string
|
2020-09-21 14:23:04 +02:00
|
|
|
label?: string | ReactNode
|
2020-06-30 12:56:50 +02:00
|
|
|
placeholder?: string
|
|
|
|
required?: boolean
|
|
|
|
help?: string
|
|
|
|
tag?: string
|
|
|
|
type?: string
|
|
|
|
options?: string[]
|
2020-11-16 16:21:15 +01:00
|
|
|
sortOptions?: boolean
|
2020-06-30 12:56:50 +02:00
|
|
|
additionalComponent?: ReactElement
|
|
|
|
value?: string
|
|
|
|
onChange?(
|
|
|
|
e:
|
|
|
|
| FormEvent<HTMLInputElement>
|
|
|
|
| ChangeEvent<HTMLInputElement>
|
|
|
|
| ChangeEvent<HTMLSelectElement>
|
|
|
|
| ChangeEvent<HTMLTextAreaElement>
|
|
|
|
): void
|
2021-07-06 13:55:10 +02:00
|
|
|
onKeyPress?(
|
|
|
|
e:
|
|
|
|
| React.KeyboardEvent<HTMLInputElement>
|
|
|
|
| React.KeyboardEvent<HTMLInputElement>
|
|
|
|
| React.KeyboardEvent<HTMLSelectElement>
|
|
|
|
| React.KeyboardEvent<HTMLTextAreaElement>
|
|
|
|
): void
|
2020-06-30 12:56:50 +02:00
|
|
|
rows?: number
|
|
|
|
multiple?: boolean
|
|
|
|
pattern?: string
|
|
|
|
min?: string
|
2020-09-16 11:57:02 +02:00
|
|
|
max?: string
|
2020-06-30 12:56:50 +02:00
|
|
|
disabled?: boolean
|
2020-07-29 10:04:09 +02:00
|
|
|
readOnly?: boolean
|
2020-10-16 09:36:21 +02:00
|
|
|
field?: FieldInputProps<any>
|
2020-07-17 15:06:28 +02:00
|
|
|
form?: any
|
2020-10-06 23:16:08 +02:00
|
|
|
prefix?: string | ReactElement
|
|
|
|
postfix?: string | ReactElement
|
2020-07-29 10:04:09 +02:00
|
|
|
step?: string
|
2020-09-10 12:20:40 +02:00
|
|
|
defaultChecked?: boolean
|
2020-11-16 16:21:15 +01:00
|
|
|
size?: 'mini' | 'small' | 'large' | 'default'
|
2021-03-25 08:34:07 +01:00
|
|
|
className?: string
|
2021-07-06 13:55:10 +02:00
|
|
|
divClassName?: string
|
2020-06-30 12:56:50 +02:00
|
|
|
}
|
|
|
|
|
2020-07-13 14:11:22 +02:00
|
|
|
export default function Input(props: Partial<InputProps>): ReactElement {
|
2020-12-10 14:30:40 +01:00
|
|
|
const { label, help, additionalComponent, size, field } = props
|
2020-06-30 12:56:50 +02:00
|
|
|
|
2020-07-17 21:21:27 +02:00
|
|
|
const hasError =
|
2020-09-21 14:23:04 +02:00
|
|
|
props.form?.touched[field.name] && props.form?.errors[field.name]
|
2020-07-17 21:21:27 +02:00
|
|
|
|
2021-07-06 13:55:10 +02:00
|
|
|
const styleClasses = cx(
|
|
|
|
{
|
|
|
|
field: true,
|
|
|
|
hasError: hasError
|
|
|
|
},
|
|
|
|
props.divClassName
|
|
|
|
)
|
2020-07-17 21:21:27 +02:00
|
|
|
|
2020-06-30 12:56:50 +02:00
|
|
|
return (
|
2020-07-17 13:19:38 +02:00
|
|
|
<div
|
2020-07-17 21:21:27 +02:00
|
|
|
className={styleClasses}
|
2020-09-10 22:22:16 +02:00
|
|
|
data-is-submitting={props.form?.isSubmitting ? true : null}
|
2020-07-17 13:19:38 +02:00
|
|
|
>
|
2020-12-10 14:30:40 +01:00
|
|
|
<Label htmlFor={props.name} required={props.required}>
|
2020-06-30 12:56:50 +02:00
|
|
|
{label}
|
|
|
|
</Label>
|
2020-10-31 00:55:00 +01:00
|
|
|
<InputElement size={size} {...field} {...props} />
|
2020-06-30 12:56:50 +02:00
|
|
|
|
2020-11-10 13:52:02 +01:00
|
|
|
{field && hasError && (
|
2020-07-13 14:24:41 +02:00
|
|
|
<div className={styles.error}>
|
|
|
|
<ErrorMessage name={field.name} />
|
|
|
|
</div>
|
|
|
|
)}
|
2020-07-13 14:11:22 +02:00
|
|
|
|
2020-06-30 12:56:50 +02:00
|
|
|
{help && <Help>{help}</Help>}
|
|
|
|
{additionalComponent && additionalComponent}
|
|
|
|
</div>
|
|
|
|
)
|
|
|
|
}
|