diff --git a/src/components/BirthdayInput/BirthdayInput.example.js b/src/components/BirthdayInput/BirthdayInput.example.js index 9fc4d7d4..0ac1acc1 100644 --- a/src/components/BirthdayInput/BirthdayInput.example.js +++ b/src/components/BirthdayInput/BirthdayInput.example.js @@ -1,30 +1,26 @@ /* eslint-disable no-console */ -import React, { Component } from 'react'; +import React from 'react'; import { Field, reduxForm } from 'redux-form'; import * as validators from '../../util/validators'; -import { enhancedField } from '../../util/forms'; +import { InputField } from '../../components'; import BirthdayInput from './BirthdayInput'; -class FormComponent extends Component { - constructor(props) { - super(props); - this.EnhancedBirthdayInput = enhancedField(BirthdayInput); - } - render() { - const required = validators.required('A valid date is required'); - return ( -
- - - ); - } -} +const FormComponent = () => { + const required = validators.required('A valid date is required'); + return ( +
+ + + ); +}; const Form = reduxForm({ form: 'Styleguide.BirthdayInput.Form', diff --git a/src/components/BirthdayInput/BirthdayInput.js b/src/components/BirthdayInput/BirthdayInput.js index 3f26e2ef..bc0a5fb5 100644 --- a/src/components/BirthdayInput/BirthdayInput.js +++ b/src/components/BirthdayInput/BirthdayInput.js @@ -85,14 +85,14 @@ class BirthdayInput extends Component { this.handleSelectChange = this.handleSelectChange.bind(this); } componentWillMount() { - const value = this.props.input.value; + const value = this.props.value; if (value instanceof Date) { this.setState({ selected: selectedFromDate(value) }); } } componentWillReceiveProps(newProps) { - const oldValue = this.props.input.value; - const newValue = newProps.input.value; + const oldValue = this.props.value; + const newValue = newProps.value; const valueChanged = oldValue !== newValue; if (valueChanged && newValue instanceof Date) { this.setState({ selected: selectedFromDate(newValue) }); @@ -103,13 +103,13 @@ class BirthdayInput extends Component { } handleSelectFocus() { window.clearTimeout(this.blurTimeoutId); - this.props.input.onFocus(); + this.props.onFocus(); } handleSelectBlur() { window.clearTimeout(this.blurTimeoutId); this.blurTimeoutId = window.setTimeout( () => { - this.props.input.onBlur(); + this.props.onBlur(); }, BLUR_TIMEOUT ); @@ -117,18 +117,18 @@ class BirthdayInput extends Component { handleSelectChange(type, value) { this.setState(prevState => { const selected = { ...prevState.selected, [type]: parseNum(value) }; - this.props.input.onChange(dateFromSelected(selected)); + this.props.onChange(dateFromSelected(selected)); return { selected }; }); } render() { - const { className } = this.props; + const { rootClassName, className } = this.props; const selectedValue = n => { return typeof n === 'number' ? n : ''; }; - const classes = classNames(css.root, className); + const classes = classNames(rootClassName || css.root, className); return (
@@ -167,19 +167,21 @@ class BirthdayInput extends Component { } } -BirthdayInput.defaultProps = { className: '' }; +BirthdayInput.defaultProps = { + rootClassName: null, + className: null, + value: null, +}; -const { string, shape, instanceOf, func } = PropTypes; +const { string, instanceOf, func } = PropTypes; BirthdayInput.propTypes = { + rootClassName: string, className: string, - input: shape({ - name: string.isRequired, - value: instanceOf(Date), - onChange: func.isRequired, - onFocus: func.isRequired, - onBlur: func.isRequired, - }).isRequired, + value: instanceOf(Date), + onChange: func.isRequired, + onFocus: func.isRequired, + onBlur: func.isRequired, }; export default BirthdayInput; diff --git a/src/components/InputField/InputField.css b/src/components/InputField/InputField.css index e1056930..5546ae12 100644 --- a/src/components/InputField/InputField.css +++ b/src/components/InputField/InputField.css @@ -1,10 +1,10 @@ @import '../../marketplace.css'; .root { - margin-top: calc(6 * var(--spacingUnit)); + margin-top: calc(4 * var(--spacingUnit)); @media (--desktopViewport) { - margin-top: calc(6 * var(--spacingUnitDesktop)); + margin-top: calc(4 * var(--spacingUnitDesktop)); } } diff --git a/src/components/InputField/InputField.example.js b/src/components/InputField/InputField.example.js index 021f984a..9c5343b9 100644 --- a/src/components/InputField/InputField.example.js +++ b/src/components/InputField/InputField.example.js @@ -39,6 +39,14 @@ const FormComponent = props => { label="Label for input with initial value" component={InputField} /> + ); diff --git a/src/components/InputField/InputField.js b/src/components/InputField/InputField.js index 58ec3895..452d7297 100644 --- a/src/components/InputField/InputField.js +++ b/src/components/InputField/InputField.js @@ -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,29 +25,50 @@ 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 component takes all the props, but the type prop + // is omitted from