1
0
mirror of https://github.com/oceanprotocol/commons.git synced 2023-03-15 18:03:00 +01:00
commons/client/src/components/atoms/Form/Input.tsx

228 lines
7.6 KiB
TypeScript
Raw Normal View History

2019-01-24 15:42:10 +01:00
import cx from 'classnames'
2019-03-29 19:44:58 +01:00
import React, { PureComponent, FormEvent, ChangeEvent } from 'react'
2019-02-08 11:18:42 +01:00
import slugify from 'slugify'
2019-03-29 15:05:38 +01:00
import DatePicker from 'react-datepicker'
2019-01-24 15:42:10 +01:00
import { ReactComponent as SearchIcon } from '../../../img/search.svg'
import Help from './Help'
2019-01-24 14:52:50 +01:00
import Label from './Label'
import Row from './Row'
2019-02-08 15:37:22 +01:00
import InputGroup from './InputGroup'
2019-03-29 15:05:38 +01:00
import styles from './Input.module.scss'
2019-01-23 17:37:20 +01:00
2019-02-07 11:28:04 +01:00
interface InputProps {
2019-01-23 17:37:20 +01:00
name: string
label: string
placeholder?: string
2019-01-23 17:37:20 +01:00
required?: boolean
help?: string
tag?: string
type?: string
2019-02-08 11:18:42 +01:00
options?: string[]
2019-02-08 15:37:22 +01:00
additionalComponent?: any
value?: string
2019-03-29 19:44:58 +01:00
onChange?(
event:
| FormEvent<HTMLInputElement>
| ChangeEvent<HTMLInputElement>
| ChangeEvent<HTMLSelectElement>
| ChangeEvent<HTMLTextAreaElement>
): void
rows?: number
2019-02-08 15:37:22 +01:00
group?: any
2019-02-12 14:07:22 +01:00
multiple?: boolean
2019-01-23 17:37:20 +01:00
}
2019-02-07 11:28:04 +01:00
interface InputState {
2019-01-23 17:37:20 +01:00
isFocused: boolean
2019-04-05 16:41:29 +02:00
dateCreated?: Date
2019-01-23 17:37:20 +01:00
}
2019-02-07 11:28:04 +01:00
export default class Input extends PureComponent<InputProps, InputState> {
2019-03-29 19:44:58 +01:00
public state: InputState = {
isFocused: false,
2019-04-05 16:41:29 +02:00
dateCreated: new Date()
2019-03-29 19:44:58 +01:00
}
2019-01-23 17:37:20 +01:00
public inputWrapClasses() {
if (this.props.type === 'search') {
return styles.inputWrapSearch
2019-01-23 17:37:20 +01:00
} else if (this.props.type === 'search' && this.state.isFocused) {
2019-01-24 15:42:10 +01:00
return cx(styles.inputWrapSearch, styles.isFocused)
2019-01-23 17:37:20 +01:00
} else if (this.state.isFocused && this.props.type !== 'search') {
2019-01-24 15:42:10 +01:00
return cx(styles.inputWrap, styles.isFocused)
2019-01-23 17:37:20 +01:00
} else {
return styles.inputWrap
2019-01-23 17:37:20 +01:00
}
}
public toggleFocus = () => {
this.setState({ isFocused: !this.state.isFocused })
2019-01-23 17:37:20 +01:00
}
2019-04-01 13:49:25 +02:00
private handleDateChange = (date: Date) => {
2019-04-30 19:19:28 +02:00
this.setState({ dateCreated: date })
2019-04-05 16:14:26 +02:00
const event = {
currentTarget: {
2019-04-05 16:41:29 +02:00
name: 'dateCreated',
2019-04-05 16:14:26 +02:00
value: date
}
}
2019-04-15 23:30:35 +02:00
this.props.onChange!(event as any) // eslint-disable-line @typescript-eslint/no-non-null-assertion
2019-03-29 15:05:38 +01:00
}
2019-02-11 12:28:03 +01:00
public InputComponent = () => {
2019-02-21 15:05:12 +01:00
const {
type,
options,
group,
name,
required,
onChange,
2019-05-10 12:30:31 +02:00
value
2019-02-21 15:05:12 +01:00
} = this.props
2019-02-11 12:53:19 +01:00
const wrapClass = this.inputWrapClasses()
2019-02-11 12:28:03 +01:00
2019-03-29 15:05:38 +01:00
switch (type) {
case 'select':
return (
<div className={wrapClass}>
<select
id={name}
className={styles.select}
name={name}
required={required}
onFocus={this.toggleFocus}
onBlur={this.toggleFocus}
onChange={onChange}
value={value}
>
<option value="">---</option>
{options &&
options
.sort((a, b) => a.localeCompare(b))
.map((option: string, index: number) => (
<option key={index} value={option}>
2019-03-29 15:05:38 +01:00
{option}
</option>
))}
</select>
</div>
)
case 'textarea':
return (
<div className={wrapClass}>
<textarea
id={name}
className={styles.input}
onFocus={this.toggleFocus}
onBlur={this.toggleFocus}
2019-05-10 12:30:31 +02:00
{...this.props}
2019-03-29 15:05:38 +01:00
/>
</div>
)
case 'radio':
case 'checkbox':
return (
<div className={styles.radioGroup}>
2019-02-11 12:28:03 +01:00
{options &&
2019-03-29 15:05:38 +01:00
options.map((option: string, index: number) => (
<div className={styles.radioWrap} key={index}>
<input
className={styles.radio}
id={slugify(option, {
lower: true
})}
type={type}
name={name}
2019-03-04 17:50:24 +01:00
value={slugify(option, {
lower: true
})}
2019-03-29 15:05:38 +01:00
/>
<label
className={styles.radioLabel}
htmlFor={slugify(option, {
lower: true
})}
2019-03-04 17:50:24 +01:00
>
{option}
2019-03-29 15:05:38 +01:00
</label>
</div>
))}
</div>
)
case 'date':
return (
<div className={wrapClass}>
<DatePicker
2019-04-05 16:41:29 +02:00
selected={this.state.dateCreated}
2019-03-29 15:05:38 +01:00
onChange={this.handleDateChange}
className={styles.input}
onFocus={this.toggleFocus}
onBlur={this.toggleFocus}
2019-04-01 13:49:25 +02:00
id={name}
name={name}
2019-03-29 15:05:38 +01:00
/>
</div>
)
2019-04-23 13:02:47 +02:00
default:
return (
<div className={wrapClass}>
{group ? (
<InputGroup>
<input
id={name}
2019-04-30 19:19:28 +02:00
type={type || 'text'}
2019-04-23 13:02:47 +02:00
className={styles.input}
onFocus={this.toggleFocus}
onBlur={this.toggleFocus}
{...this.props}
/>
{group}
</InputGroup>
) : (
<input
id={name}
2019-04-30 19:19:28 +02:00
type={type || 'text'}
2019-04-23 13:02:47 +02:00
className={styles.input}
onFocus={this.toggleFocus}
onBlur={this.toggleFocus}
{...this.props}
/>
)}
{type === 'search' && <SearchIcon />}
</div>
)
2019-02-07 17:03:37 +01:00
}
}
2019-01-23 17:37:20 +01:00
public render() {
2019-02-12 14:07:22 +01:00
const {
name,
label,
required,
help,
additionalComponent,
multiple
} = this.props
2019-01-23 17:37:20 +01:00
return (
2019-01-24 14:52:50 +01:00
<Row>
<Label htmlFor={name} required={required}>
2019-01-23 17:37:20 +01:00
{label}
2019-01-24 14:52:50 +01:00
</Label>
2019-01-29 10:53:46 +01:00
2019-02-11 12:28:03 +01:00
<this.InputComponent />
2019-01-29 10:53:46 +01:00
{help && <Help>{help}</Help>}
2019-01-23 17:37:20 +01:00
2019-02-12 14:07:22 +01:00
{multiple && 'hello'}
2019-01-23 17:37:20 +01:00
{additionalComponent && additionalComponent}
2019-01-24 14:52:50 +01:00
</Row>
2019-01-23 17:37:20 +01:00
)
}
}