@eaze/input
v4.0.1
Published
React components:
Downloads
21
Readme
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
// define an onSubmit, which will receive an object with
// keys equal to the `name` supplied to each input
// ex: {email: { value: '[email protected]', valid: true }, password: { value: '123', valid: false }}
onSubmit={this.onSubmit}
// This submit text will appear on the submit button
// automatically included with and managed by the form
// unless you set the `includeButton` prop to false,
// in which case you'll have to supply your own button.
submitText={'Sign up'}
// `includeButton` defaults to true.
// If you set it to false, supply your own buttons, as in this example
includeButton={false}
>
// A higher level component that consumes `./input-with-label.js`
<EmailInput
name='email'
placeholder='Email'
eagerValidate
required
/>
// ... Other inputs like EmailInput
// Because we declared `includeButton` prop as false, we set buttons here
<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 thethis.context.register
function#onChange
: Must make a function that takes theinput
's change event and abstracts its value into thecontext.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 array should have functions that either return null when there are no errors
// and return strings of error messages when there are errors
this.validators = [
// check for null if required
(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)
}
// if you want to provide a parser to be used by Input, define it here and pass it down.
// Make it a function that takes and returns a string.
parser (value) {
return zip.parse(value || '')
}
render () {
// Use phone type input to force number keyboard on mobile devices
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
- eaze.com
- signup
- login
- profile