Automated inputs and forms
This is a new (as of Jan 2017) set of input/form components.
import {
Checkbox,
Password,
Email,
Zipcode,
PhoneNumber,
Form,
Input,
InputWithLabel,
TextField,
Select
} from '@eaze/input'
Motivation
We need a set of controlled inputs and forms that allow for autocompletion in mobile and enough built-in management that forms come with the following:
- Field-level errors
- Float labels
- Self-managed submit buttons that correctly trigger the
Go
on Safari mobile keyboards and manage their disabled states
Changes
Changes from old inputs (made by @ghigo):
- Form state is now in React state, not in Redux
- Inputs are not copied using React's
cloneElement
, so they are safe to modify after construction - Inputs self-register and update through React's context methods
- Because the inputs require the context methods, these inputs are not usable outside of the
Form
component
How to use
Here are some examples of how to use/create the new inputs and forms.
Creating a Form
Example:
<Form
onSubmit={this.onSubmit}
submitText={'Sign up'}
includeButton={false}
>
<EmailInput
name='email'
placeholder='Email'
eagerValidate
required
/>
<div className={style.buttons}>
// Use FormButton when making custom form buttons
// This consumes EazeButton and overwrites props with
// the correct props taken in through React `context` methods
<FormButton
buttonProps={{
loading: this.props.loading,
title: 'Sign up',
type: buttonTypes.PRIMARY
}}
/>
<div className={style.border}>
<Border />
</div>
<div className={style.logIn}>
Already have an account?
<div className={style.logInButton}>
<FormButton
buttonProps={{
title: 'Log In',
type: buttonTypes.TERTIARY
}}
/>
</div>
</div>
</div>
</Form>
Creating a new input
Inputs self-register through context methods. Required methods/properties for a new higher-level input include the following:
<Component>.contextTypes
: Must include #register and #onChange context methods to be used in the constructor and when the input updates.- Validators: in the constructor, make a
this.validators
array of functions that are used by the consumed Input #componentDidMount
: Must register using the this.context.register
function#onChange
: Must make a function that takes the input
's change event and abstracts its value into the context.onChange
method
Generally you'll want to consume and use InputWithLabel
, as that comes with float labels.
Example:
import React from 'react'
import PropTypes from 'prop-types'
import zip from 'zippo'
import InputWithLabel from './input-with-label'
class Zipcode extends React.Component {
constructor () {
super()
this.onChange = this.onChange.bind(this)
this.validators = [
(value) => {
if (!this.props.required) return null
if (!value) return 'Zipcode is required.'
},
(value) => {
if (!value) return null
return zip.validate(value) ? null : 'Please enter a valid zipcode'
}
]
}
onChange (e) {
this.context.onChange(this.props.name, e.target.value, this.wrapper.inputContainer.isValid())
}
componentDidMount () {
this.context.register(this.props.name, this.props.initialValue)
}
parser (value) {
return zip.parse(value || '')
}
render () {
return (
<InputWithLabel
{...this.props}
name={this.props.name}
type='phone'
parser={this.parser}
validators={this.validators}
onChange={this.onChange}
ref={(wrapper) => { this.wrapper = wrapper }}
eagerValidate
/>
)
}
}
Zipcode.contextTypes = {
onChange: PropTypes.func,
register: PropTypes.func
}
export default Zipcode
Where is @eaze/input used?
Disclaimer: This is not a complete list