Add support for textarea and custom inputs

This commit is contained in:
Kimmo Puputti 2017-06-06 16:24:03 +03:00
parent 390bdf8132
commit 39618f4561
2 changed files with 46 additions and 4 deletions

View file

@ -39,6 +39,14 @@ const FormComponent = props => {
label="Label for input with initial value"
component={InputField}
/>
<Field
name="textarea1"
type="textarea"
label="Label for textarea"
placeholder="Textarea placeholder..."
validate={required}
component={InputField}
/>
<Button type="submit" disabled={submitDisabled} style={buttonStyles}>Submit form</Button>
</form>
);

View file

@ -1,4 +1,5 @@
import React, { Component, PropTypes } from 'react';
import { omit } from 'lodash';
import classNames from 'classnames';
import css from './InputField.css';
@ -16,6 +17,7 @@ class InputField extends Component {
labelRootClassName,
inputRootClassName,
errorRootClassName,
inputComponent: InputComponent,
type,
label,
placeholder,
@ -23,7 +25,22 @@ class InputField extends Component {
input,
meta,
} = this.props;
const isCustom = type === 'custom';
const isTextarea = type === 'textarea';
if (!isCustom && InputComponent) {
throw new Error('inputComponent should only be given with type="custom" prop');
}
if (isCustom && !InputComponent) {
throw new Error('inputComponent prop required for custom inputs');
}
// Normal <input> component takes all the props, but the type prop
// is omitted from <textarea> and custom components.
const inputProps = { ...input, type, placeholder, autoFocus };
const inputPropsWithoutType = omit(inputProps, 'type');
const { valid, invalid, touched, error } = meta;
// Error message and input error styles are only shown if the
@ -38,10 +55,20 @@ class InputField extends Component {
});
const errorClasses = errorRootClassName || css.validationError;
let component;
if (isCustom) {
component = <InputComponent className={inputRootClassName} {...inputPropsWithoutType} />;
} else if (isTextarea) {
component = <textarea className={inputClasses} {...inputPropsWithoutType} />;
} else {
component = <input className={inputClasses} {...inputProps} />;
}
return (
<div className={classes}>
{label ? <label className={labelClasses} htmlFor={inputProps.name}>{label}</label> : null}
<input className={inputClasses} {...inputProps} />
{label ? <label className={labelClasses} htmlFor={input.name}>{label}</label> : null}
{component}
{hasError ? <p className={errorClasses}>{error}</p> : null}
</div>
);
@ -55,12 +82,14 @@ InputField.defaultProps = {
inputRootClassName: null,
errorRootClassName: null,
clearOnUnmount: false,
inputComponent: null,
type: null,
label: null,
placeholder: null,
autoFocus: false,
};
const { string, shape, bool, func } = PropTypes;
const { string, shape, bool, func, oneOfType } = PropTypes;
InputField.propTypes = {
// Allow passing in classes to subcomponents
@ -72,8 +101,13 @@ InputField.propTypes = {
clearOnUnmount: bool,
// If the type props is 'custom', this prop is used as the component
inputComponent: oneOfType([func, string]),
// 'custom', 'textarea', or something passed to an <input> element
type: string,
// Extra props passed to the underlying input component
type: string.isRequired,
label: string,
placeholder: string,
autoFocus: bool,