Repository: react-materialize/react-materialize
Pull request #724 (2018-12-16 14:50:05)

3.0.0 remove input
remove input component in favour of TextInput, Select, etc


Patch:
diff --git a/examples/InputCheckbox.js b/examples/InputCheckbox.js
deleted file mode 100644
index efc6c3f..0000000
--- a/examples/InputCheckbox.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react';
-import Input from '../src/Input';
-import Row from '../src/Row';
-
-export default
-<Row>
-    <Input name='group1' type='checkbox' value='red' label='Red' />
-    <Input name='group1' type='checkbox' value='yellow' label='Yellow' defaultValue='checked' />
-    <Input name='group1' type='checkbox' value='green' label='Green' className='filled-in' defaultChecked='checked' />
-    <Input name='group1' type='checkbox' value='brown' label='Brown' disabled='disabled' />
-</Row>;
diff --git a/examples/InputDatePicker.js b/examples/InputDatePicker.js
deleted file mode 100644
index 1c31f40..0000000
--- a/examples/InputDatePicker.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import React from 'react';
-import Input from '../src/Input';
-import Row from '../src/Row';
-
-export default
-<Row>
-  <Input name='on' type='date' onChange={function(e, value) {}} />
-</Row>;
diff --git a/examples/InputFields.js b/examples/InputFields.js
deleted file mode 100644
index e2a77f4..0000000
--- a/examples/InputFields.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import React from 'react';
-import Input from '../src/Input';
-import Row from '../src/Row';
-
-export default
-<Row>
-    <Input placeholder="Placeholder" s={6} label="First Name" />
-    <Input s={6} label="Last Name" />
-    <Input s={12} label="disabled" defaultValue="I am not editable" disabled />
-    <Input type="password" label="password" s={12} />
-    <Input type="email" label="Email" s={12} />
-</Row>;
diff --git a/examples/InputFile.js b/examples/InputFile.js
deleted file mode 100644
index f733581..0000000
--- a/examples/InputFile.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import React from 'react';
-import Input from '../src/Input';
-import Row from '../src/Row';
-
-export default <Row>
-  <Input type="file" label="File" s={12} />
-</Row>;
diff --git a/examples/InputFiles.js b/examples/InputFiles.js
deleted file mode 100644
index 5f7e86d..0000000
--- a/examples/InputFiles.js
+++ /dev/null
@@ -1,7 +0,0 @@
-import React from 'react';
-import Input from '../src/Input';
-import Row from '../src/Row';
-
-export default <Row>
-  <Input type="file" label="File" s={12} multiple placeholder="Upload one or more files" />
-</Row>;
diff --git a/examples/InputRadio.js b/examples/InputRadio.js
deleted file mode 100644
index a3567e8..0000000
--- a/examples/InputRadio.js
+++ /dev/null
@@ -1,11 +0,0 @@
-import React from 'react';
-import Input from '../src/Input';
-import Row from '../src/Row';
-
-export default
-<Row>
-    <Input name='group1' type='radio' value='red' label='Red' />
-    <Input name='group1' type='radio' value='yellow' label='Yellow' />
-    <Input name='group1' type='radio' value='green' label='Green' className='with-gap' />
-    <Input name='group1' type='radio' value='brown' label='Brown' disabled='disabled' />
-</Row>;
diff --git a/examples/InputSwitch.js b/examples/InputSwitch.js
deleted file mode 100644
index 1f685d7..0000000
--- a/examples/InputSwitch.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import React from 'react';
-import Input from '../src/Input';
-import Row from '../src/Row';
-
-export default
-<Row>
-  <Input name='on' type='switch' value='1' />
-</Row>;
diff --git a/examples/InputTextarea.js b/examples/InputTextarea.js
deleted file mode 100644
index 6a1a8fe..0000000
--- a/examples/InputTextarea.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import React from 'react';
-import Input from '../src/Input';
-import Row from '../src/Row';
-
-export default
-<Row>
-  <Input type='textarea' />
-</Row>;
diff --git a/examples/InputTimePicker.js b/examples/InputTimePicker.js
deleted file mode 100644
index fa07cc5..0000000
--- a/examples/InputTimePicker.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import React from 'react';
-import Input from '../src/Input';
-import Row from '../src/Row';
-
-export default
-<Row>
-  <Input name='on' type='time' onChange={function(e, value) {}} />
-</Row>;
diff --git a/src/Input.js b/src/Input.js
deleted file mode 100644
index 41153d2..0000000
--- a/src/Input.js
+++ /dev/null
@@ -1,389 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import cx from 'classnames';
-import idgen from './idgen';
-import constants from './constants';
-import Icon from './Icon';
-
-class Input extends Component {
-  constructor(props) {
-    super(props);
-
-    this.state = {
-      value: props.value || props.defaultValue,
-      checked: !!props.checked
-    };
-
-    this._onChange = this._onChange.bind(this);
-    this.getMultipleValues = this.getMultipleValues.bind(this);
-    this.isSelect = this.isSelect.bind(this);
-  }
-
-  componentDidMount() {
-    if (this.isMaterialSelect()) {
-      $(this.selectInput).material_select();
-      $(this.selectInput).on('change', this._onChange);
-    }
-    if (this.isDatePicker) {
-      $(this.dateInput).pickadate(this.props.options);
-      $(this.dateInput).on('change', this._onChange);
-    }
-    if (this.isTimePicker) {
-      $(this.timeInput).pickatime(this.props.options);
-      $(this.timeInput).on('change', this._onChange);
-    }
-  }
-
-  componentDidUpdate() {
-    if (this.isMaterialSelect() && !this.props.multiple) {
-      $(this.selectInput).material_select();
-    }
-  }
-
-  componentWillReceiveProps(nextProps) {
-    if (
-      nextProps.type === 'checkbox' &&
-      this.state.checked !== nextProps.checked
-    ) {
-      this.setState({
-        checked: nextProps.checked
-      });
-    }
-    if (this.isMaterialSelect() && !this.props.multiple) {
-      this.setState(
-        {
-          value: nextProps.defaultValue
-        },
-        () => $(this.selectInput).material_select()
-      );
-    }
-  }
-
-  componentWillUnmount() {
-    if (this.isMaterialSelect()) {
-      $(this.selectInput).off('change', this._onChange);
-    }
-  }
-
-  getMultipleValues({ options }) {
-    if (!options) {
-      return;
-    }
-
-    return Array.from(options)
-      .filter(opt => opt.selected)
-      .map(opt => opt.value);
-  }
-
-  _onChange(e) {
-    const { onChange } = this.props;
-    var types = {
-      checkbox: e.target.checked,
-      radio: e.target.checked,
-      'select-multiple': this.getMultipleValues(e.target),
-      default: e.target.value
-    };
-    const value = types.hasOwnProperty(e.target.type)
-      ? types[e.target.type]
-      : types['default'];
-    if (onChange) {
-      onChange(e, value);
-    }
-
-    this.setState({ value, checked: e.target.checked });
-  }
-
-  render() {
-    const {
-      browserDefault,
-      children,
-      className,
-      labelClassName,
-      defaultValue,
-      error,
-      label,
-      multiple,
-      placeholder,
-      success,
-      s,
-      m,
-      l,
-      xl,
-      type,
-      validate,
-      onLabel,
-      offLabel,
-      inline,
-      ...other
-    } = this.props;
-    let sizes = { s, m, l, xl };
-    this._id = this._id || this.props.id || `input_${idgen()}`;
-    let classes = {
-      col: true,
-      inline: type !== 'checkbox' && type !== 'radio' && inline,
-      'input-field': type !== 'checkbox' && type !== 'radio' && type !== 'file',
-      'file-field': type === 'file'
-    };
-    constants.SIZES.forEach(size => {
-      classes[size + sizes[size]] = sizes[size];
-    });
-    let inputClasses = {
-      validate,
-      invalid: error,
-      valid: success,
-      'browser-default': browserDefault && this.isSelect()
-    };
-    let C, inputType;
-    switch (type) {
-      case 'textarea':
-        C = 'textarea';
-        inputClasses['materialize-textarea'] = true;
-        break;
-      case 'switch':
-        C = 'input';
-        inputType = 'checkbox';
-        break;
-      case 'file':
-        C = 'input';
-        inputClasses['file-path'] = true;
-        break;
-      default:
-        C = 'input';
-        inputType = type || 'text';
-    }
-    let labelClasses = {
-      active: this.state.value || this.isSelect() || placeholder
-    };
-
-    let htmlLabel =
-      label || inputType === 'radio' ? (
-        <label
-          className={cx(labelClasses, labelClassName)}
-          data-success={success}
-          data-error={error}
-          htmlFor={this._id}
-        >
-          {label}
-        </label>
-      ) : null;
-
-    if (this.isSelect()) {
-      let options =
-        placeholder && !defaultValue
-          ? [
-              <option disabled key={idgen()}>
-                {placeholder}
-              </option>
-            ]
-          : [];
-      options = options.concat(
-        React.Children.map(children, child =>
-          React.cloneElement(child, { key: child.props.value })
-        )
-      );
-
-      return (
-        <div className={cx(classes)}>
-          {this.renderIcon()}
-          {htmlLabel}
-          <select
-            {...other}
-            multiple={multiple}
-            id={this._id}
-            className={cx(className, inputClasses)}
-            ref={ref => (this.selectInput = ref)}
-            defaultValue={defaultValue}
-          >
-            {options}
-          </select>
-        </div>
-      );
-    } else if (type === 'date') {
-      this.isDatePicker = true;
-      delete other.options;
-
-      return (
-        <div className={cx(classes)}>
-          {this.renderIcon()}
-          <C
-            {...other}
-            className={cx(className, inputClasses)}
-            defaultValue={defaultValue}
-            id={this._id}
-            ref={ref => (this.dateInput = ref)}
-            placeholder={placeholder}
-            type="date"
-          />
-          {htmlLabel}
-        </div>
-      );
-    } else if (type === 'time') {
-      this.isTimePicker = true;
-      delete other.options;
-
-      return (
-        <div className={cx(classes)}>
-          {this.renderIcon()}
-          <C
-            {...other}
-            className={cx(className, inputClasses)}
-            defaultValue={defaultValue}
-            id={this._id}
-            ref={ref => (this.timeInput = ref)}
-            placeholder={placeholder}
-          />
-          {htmlLabel}
-        </div>
-      );
-    } else if (type === 'switch') {
-      return (
-        <div className="switch">
-          <label>
-            {offLabel || 'Off'}
-            <input {...other} onChange={this._onChange} type="checkbox" />
-            <span className="lever" />
-            {onLabel || 'On'}
-          </label>
-        </div>
-      );
-    } else if (type === 'file') {
-      return (
-        <div className={cx(classes)}>
-          <div className="btn">
-            <span>{label}</span>
-            <C type="file" multiple={multiple} {...other} />
-          </div>
-          <div className="file-path-wrapper">
-            <C
-              type="text"
-              className={cx(className, inputClasses)}
-              defaultValue={defaultValue}
-              id={this._id}
-              placeholder={placeholder}
-            />
-          </div>
-        </div>
-      );
-    } else {
-      let defaultValue =
-        inputType !== 'checkbox' && inputType !== 'radio'
-          ? this.state.value
-          : defaultValue;
-
-      if (inputType === 'checkbox' || inputType === 'radio') {
-        return (
-          <div className={cx(classes)}>
-            {this.renderIcon()}
-            <C
-              {...other}
-              className={cx(className, inputClasses)}
-              ref={ref => (this.input = ref)}
-              id={this._id}
-              checked={this.state.checked}
-              onChange={this._onChange}
-              placeholder={placeholder}
-              type={inputType}
-            />
-            {htmlLabel}
-          </div>
-        );
-      }
-
-      return (
-        <div className={cx(classes)}>
-          {this.renderIcon()}
-          <C
-            {...other}
-            className={cx(className, inputClasses)}
-            ref={ref => (this.input = ref)}
-            defaultValue={defaultValue}
-            id={this._id}
-            onChange={this._onChange}
-            placeholder={placeholder}
-            type={inputType}
-          />
-          {htmlLabel}
-        </div>
-      );
-    }
-  }
-
-  renderIcon() {
-    const { icon, children } = this.props;
-    if (icon) {
-      return <Icon className="prefix">{icon}</Icon>;
-    } else {
-      let icon = null;
-      if (React.Children.count(children) === 1 && !Array.isArray(children)) {
-        icon = React.Children.only(children);
-      }
-      return icon === null
-        ? null
-        : React.cloneElement(icon, { className: 'prefix' });
-    }
-  }
-
-  isSelect() {
-    return this.props.type === 'select';
-  }
-
-  isMaterialSelect() {
-    return (
-      this.props.type === 'select' &&
-      !this.props.browserDefault &&
-      typeof $ !== 'undefined'
-    );
-  }
-}
-
-Input.propTypes = {
-  /*
-   * Responsive size for Mobile Devices
-   */
-  s: PropTypes.number,
-  /*
-   * Responsive size for Tablet Devices
-   */
-  m: PropTypes.number,
-  /*
-   * Responsive size for Desktop Devices
-   */
-  l: PropTypes.number,
-  /**
-   *  Responsive size for Large Desktop Devices
-   */
-  xl: PropTypes.number,
-  inline: PropTypes.bool,
-  children: PropTypes.node,
-  className: PropTypes.string,
-  labelClassName: PropTypes.string,
-  label: PropTypes.node,
-  error: PropTypes.string,
-  success: PropTypes.string,
-  /**
-   * Input field type, e.g. select, checkbox, radio, text, tel, email, file
-   * @default 'text'
-   */
-  type: PropTypes.string,
-  defaultValue: PropTypes.any,
-  placeholder: PropTypes.string,
-  id: PropTypes.string,
-  icon: PropTypes.string,
-  name: PropTypes.string,
-  validate: PropTypes.bool,
-  multiple: PropTypes.bool,
-  browserDefault: PropTypes.bool,
-  checked: PropTypes.bool,
-  onLabel: PropTypes.string,
-  offLabel: PropTypes.string,
-  onChange: PropTypes.func,
-  options: PropTypes.any,
-  /**
-   * Value used to set a initial value
-   */
-  value: PropTypes.oneOfType([PropTypes.string, PropTypes.array])
-};
-
-Input.defaultProps = { type: 'text', checked: false };
-
-export default Input;
diff --git a/src/Select.js b/src/Select.js
deleted file mode 100644
index c5c0122..0000000
--- a/src/Select.js
+++ /dev/null
@@ -1,196 +0,0 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import cx from 'classnames';
-import idgen from './idgen';
-import constants from './constants';
-
-class Select extends Component {
-  constructor(props) {
-    super(props);
-
-    this.id = props.id || idgen();
-    this.handleChange = this.handleChange.bind(this);
-    this.state = { value: props.value };
-  }
-
-  handleChange(event) {
-    const { onChange } = this.props;
-    let value = event.target.value;
-
-    if (this.props.multiple) {
-      value = this.instance.getSelectedValues();
-    }
-
-    if (onChange) onChange(event);
-
-    this.setState({ value });
-  }
-
-  componentDidMount() {
-    if (typeof M !== 'undefined') {
-      this.instance = M.FormSelect.init(this._selectRef);
-    }
-  }
-
-  render() {
-    const {
-      s,
-      m,
-      l,
-      disabled,
-      noLayout,
-      browserDefault,
-      icon,
-      label,
-      selectClassName,
-      success,
-      error,
-      validate,
-      children,
-      multiple,
-      value,
-      type
-    } = this.props;
-
-    const sizes = { s, m, l };
-
-    let responsiveClasses;
-    if (!noLayout) {
-      responsiveClasses = { col: true };
-      constants.SIZES.forEach(size => {
-        responsiveClasses[size + sizes[size]] = sizes[size];
-      });
-    }
-
-    const wrapperClasses = cx('input-field', responsiveClasses);
-
-    const selectProps = {
-      type: 'select',
-      id: this.id,
-      value: this.state.value,
-      disabled,
-      multiple
-    };
-
-    const renderLabel = () =>
-      label && (
-        <label
-          data-success={success}
-          data-error={error}
-          htmlFor={selectProps.id}
-        >
-          {label}
-        </label>
-      );
-
-    const renderIcon = () =>
-      icon && <i className="material-icons prefix">{icon}</i>;
-
-    const renderOption = child =>
-      React.cloneElement(child, { key: child.props.value });
-
-    const renderOptions = () => React.Children.map(children, renderOption);
-
-    return (
-      <div className={wrapperClasses}>
-        {renderIcon()}
-        <select
-          value={this.state.value}
-          ref={el => {
-            this._selectRef = el;
-          }}
-          onChange={this.handleChange}
-          className={cx(
-            {
-              validate,
-              multiple,
-              ['browser-default']: browserDefault
-            },
-            selectClassName
-          )}
-          {...selectProps}
-        >
-          {renderOptions()}
-        </select>
-        {renderLabel()}
-      </div>
-    );
-  }
-}
-
-Select.propTypes = {
-  /*
-   * Use browser default styles
-   */
-  browserDefault: PropTypes.bool,
-  /*
-   * Strip away all layout classes such as col and sX
-   */
-  noLayout: PropTypes.bool,
-  /*
-   * Responsive size for Small
-   */
-  s: PropTypes.number,
-  /*
-   * Responsive size for Medium
-   */
-  m: PropTypes.number,
-  /*
-   * Responsive size for Large
-   */
-  l: PropTypes.number,
-  /*
-   * disabled input
-   */
-  disabled: PropTypes.bool,
-  /*
-   * override id
-   * @default idgen()
-   */
-  id: PropTypes.string,
-  /*
-   * prefix icon
-   */
-  icon: PropTypes.string,
-  /*
-   * label text
-   */
-  label: PropTypes.string,
-  /*
-   * Input initial value
-   */
-  value: PropTypes.string,
-  /*
-   * Add validate class to input
-   */
-  validate: PropTypes.bool,
-  /*
-   * Custom success message
-   */
-  success: PropTypes.string,
-  /*
-   * Custom error message
-   */
-  error: PropTypes.string,
-  /*
-   * Additional classes for input
-   */
-  selectClassName: PropTypes.string,
-  /*
-   * override type="text"
-   */
-  type: PropTypes.string,
-  /*
-   * onChange callback
-   */
-  onChange: PropTypes.func,
-  /*
-   * Render a multiple dropdown,
-   * use instance.getSelectedValues()
-   * to get array of selected values
-   */
-  multiple: PropTypes.bool,
-  children: PropTypes.any
-};
-
-export default Select;
diff --git a/src/TextInput.js b/src/TextInput.js
index 8c64784..c92e46a 100644
--- a/src/TextInput.js
+++ b/src/TextInput.js
@@ -7,16 +7,20 @@ import constants from './constants';
 class TextInput extends Component {
   constructor(props) {
     super(props);
+    this.state = {
+      value: ''
+    };
 
     this.id = props.id || idgen();
+    this.handleChange = this.handleChange.bind(this);
+  }
 
-    if (props.password) {
-      this.id = 'password';
-    }
+  handleChange(event) {
+    const { target: { value } } = event;
+    const { onChange } = this.props;
+    if (onChange) onChange(event);
 
-    if (props.email) {
-      this.id = 'email';
-    }
+    this.setState({ value });
   }
 
   componentDidUpdate(prevProps) {
@@ -41,8 +45,6 @@ class TextInput extends Component {
       inputClassName,
       success,
       error,
-      password,
-      email,
       validate,
       value,
       type
@@ -60,29 +62,17 @@ class TextInput extends Component {
 
     const wrapperClasses = cx('input-field', responsiveClasses);
 
-    let computedType;
-    if (type) {
-      computedType = type;
-    } else if (password) {
-      computedType = 'password';
-    } else if (email) {
-      computedType = 'email';
-    } else {
-      computedType = 'text';
-    }
-
     const inputProps = {
       placeholder,
-      type: computedType,
+      type: type || 'text',
       id: this.id,
-      defaultValue: value,
+      value: value || this.state.value,
       disabled
     };
 
     const renderLabel = () =>
       label && (
         <label
-          className={cx({ active: value || placeholder })}
           data-success={success}
           data-error={error}
           htmlFor={inputProps.id}
@@ -91,15 +81,6 @@ class TextInput extends Component {
         </label>
       );
 
-    const renderHelper = () =>
-      [error || success] && (
-        <span
-          className="helper-text"
-          data-error={error}
-          data-success={success}
-        />
-      );
-
     const renderIcon = () =>
       icon && <i className="material-icons prefix">{icon}</i>;
 
@@ -115,7 +96,6 @@ class TextInput extends Component {
           {...inputProps}
         />
         {renderLabel()}
-        {renderHelper()}
       </div>
     );
   }
@@ -190,15 +170,7 @@ TextInput.propTypes = {
   /*
    * onChange callback
    */
-  onChange: PropTypes.func,
-  /*
-   * password type
-   */
-  password: PropTypes.bool,
-  /*
-   * email type
-   */
-  email: PropTypes.bool
+  onChange: PropTypes.func
 };
 
 export default TextInput;
diff --git a/src/index.js b/src/index.js
index 721685e..5c96c26 100644
--- a/src/index.js
+++ b/src/index.js
@@ -18,7 +18,6 @@ import Divider from './Divider';
 import Dropdown from './Dropdown';
 import Footer from './Footer';
 import Icon from './Icon';
-import Input from './Input';
 import MediaBox from './MediaBox';
 import Modal from './Modal';
 import NavItem from './NavItem';
@@ -33,7 +32,6 @@ import SearchForm from './SearchForm';
 import Section from './Section';
 import SideNav from './SideNav';
 import SideNavItem from './SideNavItem';
-import Select from './Select';
 import Slide from './Slide';
 import Slider from './Slider';
 import Tab from './Tab';
@@ -64,7 +62,6 @@ export {
   Dropdown,
   Footer,
   Icon,
-  Input,
   MediaBox,
   Modal,
   NavItem,
@@ -79,7 +76,6 @@ export {
   Section,
   SideNav,
   SideNavItem,
-  Select,
   Slide,
   Slider,
   Tab,
diff --git a/stories/Checkbox.stories.js b/stories/Checkbox.stories.js
index 5b489bd..f162bb7 100644
--- a/stories/Checkbox.stories.js
+++ b/stories/Checkbox.stories.js
@@ -2,7 +2,7 @@ import React from 'react';
 import { storiesOf } from '@storybook/react';
 import Checkbox from '../src/Checkbox';
 
-const stories = storiesOf('components/Checkbox', module);
+const stories = storiesOf('javascript/Checkbox', module);
 
 stories.addParameters({
   info: {
diff --git a/stories/Select.stories.js b/stories/Select.stories.js
deleted file mode 100644
index 79eddec..0000000
--- a/stories/Select.stories.js
+++ /dev/null
@@ -1,53 +0,0 @@
-import React from 'react';
-import { storiesOf } from '@storybook/react';
-import Select from '../src/Select';
-
-const stories = storiesOf('components/Select', module);
-
-stories.addParameters({
-  info: {
-    text: `Select allows user input through specified options.`
-  }
-});
-
-stories.add('Default', () => (
-  <Select>
-    <option value="" disabled selected>Choose your option</option>
-    <option value="1">Option 1</option>
-    <option value="2">Option 2</option>
-    <option value="3">Option 3</option>
-  </Select>
-));
-
-stories.add('Multiple', () => (
-  <Select multiple>
-    <option value="" disabled selected>Choose your option</option>
-    <option value="1">Option 1</option>
-    <option value="2">Option 2</option>
-    <option value="3">Option 3</option>
-  </Select>
-));
-
-stories.add('Label', () => (
-  <Select label="Choose your option">
-    <option value="1">Option 1</option>
-    <option value="2" selected>Option 2</option>
-    <option value="3">Option 3</option>
-  </Select>
-));
-
-stories.add('Disabled', () => (
-  <Select disabled>
-    <option value="1">Option 1</option>
-    <option value="2" selected>Option 2</option>
-    <option value="3">Option 3</option>
-  </Select>
-));
-
-stories.add('Browser default', () => (
-  <Select browserDefault>
-    <option value="1">Option 1</option>
-    <option value="2" selected>Option 2</option>
-    <option value="3">Option 3</option>
-  </Select>
-));
diff --git a/stories/TextInput.stories.js b/stories/TextInput.stories.js
deleted file mode 100644
index d48974c..0000000
--- a/stories/TextInput.stories.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react';
-import { storiesOf } from '@storybook/react';
-import TextInput from '../src/TextInput';
-
-const stories = storiesOf('components/TextInput', module);
-
-stories.addParameters({
-  info: {
-    text: `Text fields allow user input. The border should light
-     up simply and clearly indicating which field the user is 
-     currently editing.
-     The validate prop leverages HTML5 validation and will add
-      a valid and invalid class accordingly. If you don't want 
-      the Green and Red validation states, just remove the validate prop.`
-  }
-});
-
-stories.add('Default', () => (
-  <TextInput />
-));
-
-stories.add('Label', () => (
-  <TextInput label="First Name" />
-));
-
-stories.add('Placeholder', () => (
-  <TextInput placeholder="First Name" />
-));
-
-stories.add('Predefined value', () => (
-  <TextInput value="John" />
-));
-
-stories.add('Disabled', () => (
-  <TextInput disabled value="John" />
-));
-
-stories.add('Password', () => (
-  <TextInput password label="Password" />
-));
-
-stories.add('Email validate', () => (
-  <TextInput email validate label="Email" />
-));
-
-stories.add('with custom error/success', () => (
-  <TextInput email validate label="Email" error="Wrong Email sir" success="Great" />
-));
-
-stories.add('with Icon', () => (
-  <TextInput icon="email" label="Email" />
-));


Test patch:
diff --git a/test/Input.spec.js b/test/Input.spec.js
deleted file mode 100644
index 7c5b4a1..0000000
--- a/test/Input.spec.js
+++ /dev/null
@@ -1,188 +0,0 @@
-import React from 'react';
-import { shallow, mount } from 'enzyme';
-import Input from '../src/Input';
-import Icon from '../src/Icon';
-import mocker from './helper/mocker';
-
-describe('<Input />', () => {
-  let wrapper;
-  const pickadateMock = jest.fn();
-  const pickatimeMock = jest.fn();
-  const selectMock = jest.fn();
-
-  const pickadateRestore = mocker('pickadate', pickadateMock);
-  const pickatimeRestore = mocker('pickatime', pickatimeMock);
-  const selectRestore = mocker('material_select', selectMock);
-
-  afterAll(() => {
-    pickadateRestore();
-    pickatimeRestore();
-    selectRestore();
-  });
-
-  test('renders', () => {
-    wrapper = shallow(<Input />);
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('text input', () => {
-    wrapper = shallow(<Input className="red" />);
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('input value', () => {
-    wrapper = shallow(<Input value="name" />);
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('label', () => {
-    wrapper = shallow(<Input label="Name" labelClassName="red" />);
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('textarea', () => {
-    wrapper = shallow(<Input type="textarea" />);
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('select', () => {
-    const values = [1, 2, 3, 4, 5];
-    wrapper = shallow(
-      <Input type="select">
-        {values.map(val => <option key={val} value={val} />)}
-      </Input>
-    );
-    expect(wrapper.instance().isSelect()).toBeTruthy();
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('renders an icon child with prefix class', () => {
-    wrapper = shallow(
-      <Input type="select" icon="weekend">
-        <option value="yes" />
-      </Input>
-    );
-    expect(wrapper.find(Icon).hasClass('prefix')).toEqual(true);
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('placeholder', () => {
-    wrapper = shallow(
-      <Input type="select" placeholder="Choose your option">
-        <option value="1">Option 1</option>
-        <option value="2">Option 2</option>
-        <option value="3">Option 3</option>
-      </Input>
-    );
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('multiple select', () => {
-    wrapper = shallow(
-      <Input type="select" multiple placeholder="Choose your option">
-        <option value="1">Option 1</option>
-        <option value="2">Option 2</option>
-        <option value="3">Option 3</option>
-      </Input>
-    );
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('switch', () => {
-    const offLabel = 'No';
-    const onLabel = 'Yes';
-    wrapper = shallow(
-      <Input type="switch" onLabel={onLabel} offLabel={offLabel} />
-    );
-    expect(wrapper).toMatchSnapshot();
-    expect(wrapper.find('label').text()).toContain(onLabel);
-    expect(wrapper.find('label').text()).toContain(offLabel);
-  });
-
-  test('radio', () => {
-    wrapper = shallow(
-      <Input name="group1" type="radio" value="yellow" label="Yellow" />
-    );
-    expect(wrapper).toMatchSnapshot();
-    expect(wrapper.find({ checked: false })).toHaveLength(1);
-  });
-
-  test('radio checked', () => {
-    wrapper = shallow(
-      <Input
-        name="group1"
-        type="radio"
-        value="yellow"
-        label="Yellow"
-        checked={false}
-      />
-    );
-    expect(wrapper).toMatchSnapshot();
-    expect(wrapper.find({ checked: false })).toHaveLength(1);
-  });
-
-  test('radio event', () => {
-    wrapper = shallow(
-      <Input name="group1" type="radio" value="yellow" label="Yellow" />
-    );
-
-    expect(wrapper).toMatchSnapshot();
-    wrapper
-      .find('input')
-      .simulate('change', { target: { type: 'radio', checked: true } });
-
-    expect(wrapper).toMatchSnapshot();
-    expect(wrapper.find({ checked: true })).toHaveLength(1);
-  });
-
-  test('radio onChange', () => {
-    const onChange = jest.fn();
-
-    wrapper = shallow(
-      <Input
-        name="group1"
-        type="radio"
-        value="yellow"
-        checked
-        label="Yellow"
-        onChange={onChange}
-      />
-    );
-
-    const event = { target: { type: 'radio', checked: false } };
-    expect(wrapper).toMatchSnapshot();
-    wrapper.find('input').simulate('change', event);
-    expect(wrapper).toMatchSnapshot();
-    expect(onChange).toHaveBeenCalledWith(event, false);
-  });
-
-  test('pickadate', () => {
-    const options = { one: 'two' };
-    wrapper = shallow(<Input type="date" options={options} />);
-
-    expect(pickadateMock).toHaveBeenCalledWith(options);
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('pickadate with icon', () => {
-    wrapper = shallow(
-      <Input type="date">
-        <Icon>today</Icon>
-      </Input>
-    );
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('pickatime', () => {
-    const options = { one: 'two' };
-    wrapper = mount(<Input type="time" options={options} />);
-
-    expect(pickatimeMock).toHaveBeenCalledWith(options);
-    expect(wrapper).toMatchSnapshot();
-  });
-
-  test('file input', () => {
-    wrapper = shallow(<Input type="file" label="Upload" multiple />);
-    expect(wrapper).toMatchSnapshot();
-  });
-});
diff --git a/test/Select.spec.js b/test/Select.spec.js
deleted file mode 100644
index a169c26..0000000
--- a/test/Select.spec.js
+++ /dev/null
@@ -1,98 +0,0 @@
-import React from 'react';
-import { shallow, mount } from 'enzyme';
-import Select from '../src/Select';
-import mocker from './helper/new-mocker';
-
-describe('<Select />', () => {
-  let wrapper;
-
-  test('handles layout classes', () => {
-    wrapper = shallow(<Select s={4} m={6} />);
-
-    expect(wrapper.hasClass('input-field')).toBeTruthy();
-    expect(wrapper.hasClass('col')).toBeTruthy();
-    expect(wrapper.hasClass('s4')).toBeTruthy();
-    expect(wrapper.hasClass('m6')).toBeTruthy();
-  });
-
-  test('handles removing layout classes', () => {
-    wrapper = shallow(<Select s={4} m={6} noLayout />);
-
-    expect(wrapper.hasClass('input-field')).toBeTruthy();
-    expect(wrapper.hasClass('col')).toBeFalsy();
-    expect(wrapper.hasClass('s4')).toBeFalsy();
-    expect(wrapper.hasClass('m6')).toBeFalsy();
-  });
-
-  test('renders browserDefault', () => {
-    wrapper = shallow(<Select browserDefault />);
-    expect(wrapper.find('select').hasClass('browser-default')).toBeTruthy();
-  });
-
-  test('renders label', () => {
-    wrapper = shallow(<Select label="Name" />);
-    expect(wrapper.find('label').text()).toEqual('Name');
-  });
-
-  test('handles validate', () => {
-    wrapper = shallow(<Select validate />);
-    expect(wrapper.find('select.validate')).toHaveLength(1);
-  });
-
-  test('handles selectClassName', () => {
-    wrapper = shallow(<Select validate selectClassName={'hello red'} />);
-    expect(wrapper.find('select.hello.red.validate')).toHaveLength(1);
-  });
-
-  test('calls onChange if provided', () => {
-    wrapper = shallow(<Select />);
-    wrapper.setState({ value: 'hello' });
-    expect(wrapper.find('select').prop('value')).toEqual('hello');
-  });
-
-  test('with icon', () => {
-    wrapper = shallow(<Select icon="cloud" />);
-    expect(wrapper.find('i.material-icons.prefix')).toHaveLength(1);
-  });
-
-  test('renders options', () => {
-    wrapper = shallow(
-      <Select>
-        <option value={1}>1</option>
-        <option value={2}>2</option>
-      </Select>
-    );
-
-    expect(wrapper.find('option')).toHaveLength(2);
-  });
-
-  test('renders multiple', () => {
-    wrapper = shallow(<Select multiple />);
-    expect(wrapper.find('select.multiple')).toHaveLength(1);
-  });
-
-  describe('initialises', () => {
-    const selectInitMock = jest.fn();
-    const selectInstanceDestroyMock = jest.fn();
-    const selectMock = {
-      init: (el, options) => {
-        selectInitMock(options);
-        return {
-          destroy: selectInstanceDestroyMock
-        };
-      }
-    };
-    const restore = mocker('FormSelect', selectMock);
-
-    beforeEach(() => {
-      selectInitMock.mockClear();
-      selectInstanceDestroyMock.mockClear();
-    });
-
-    test('calls FormSelect', () => {
-      mount(<Select />);
-
-      expect(selectInitMock).toHaveBeenCalledTimes(1);
-    });
-  });
-});
diff --git a/test/TextInput.spec.js b/test/TextInput.spec.js
index 8d4eea9..4a082d8 100644
--- a/test/TextInput.spec.js
+++ b/test/TextInput.spec.js
@@ -44,10 +44,16 @@ describe('<TextInput />', () => {
   });
 
   test('handles other types', () => {
-    wrapper = shallow(<TextInput password />);
+    wrapper = shallow(<TextInput type="password" />);
     expect(wrapper.find('input').prop('type')).toEqual('password');
   });
 
+  test('calls onChange if provided', () => {
+    wrapper = shallow(<TextInput />);
+    wrapper.setState({ value: 'hello' });
+    expect(wrapper.find('input').prop('value')).toEqual('hello');
+  });
+
   test('with icon', () => {
     wrapper = shallow(<TextInput icon="cloud" />);
     expect(wrapper.find('i.material-icons.prefix')).toHaveLength(1);
diff --git a/test/__snapshots__/Input.spec.js.snap b/test/__snapshots__/Input.spec.js.snap
deleted file mode 100644
index dea5947..0000000
--- a/test/__snapshots__/Input.spec.js.snap
+++ /dev/null
@@ -1,441 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`<Input /> file input 1`] = `
-<div
-  className="col file-field"
->
-  <div
-    className="btn"
-  >
-    <span>
-      Upload
-    </span>
-    <input
-      checked={false}
-      multiple={true}
-      type="file"
-    />
-  </div>
-  <div
-    className="file-path-wrapper"
-  >
-    <input
-      className="file-path"
-      id="input_mockId"
-      type="text"
-    />
-  </div>
-</div>
-`;
-
-exports[`<Input /> input value 1`] = `
-<div
-  className="col input-field"
->
-  <input
-    checked={false}
-    className=""
-    defaultValue="name"
-    id="input_mockId"
-    onChange={[Function]}
-    type="text"
-    value="name"
-  />
-</div>
-`;
-
-exports[`<Input /> label 1`] = `
-<div
-  className="col input-field"
->
-  <input
-    checked={false}
-    className=""
-    id="input_mockId"
-    onChange={[Function]}
-    type="text"
-  />
-  <label
-    className="red"
-    htmlFor="input_mockId"
-  >
-    Name
-  </label>
-</div>
-`;
-
-exports[`<Input /> multiple select 1`] = `
-<div
-  className="col input-field"
->
-  <select
-    checked={false}
-    className=""
-    id="input_mockId"
-    multiple={true}
-  >
-    <option
-      disabled={true}
-      key="mockId"
-    >
-      Choose your option
-    </option>
-    <option
-      key="1/.0"
-      value="1"
-    >
-      Option 1
-    </option>
-    <option
-      key="2/.1"
-      value="2"
-    >
-      Option 2
-    </option>
-    <option
-      key="3/.2"
-      value="3"
-    >
-      Option 3
-    </option>
-  </select>
-</div>
-`;
-
-exports[`<Input /> pickadate 1`] = `
-<div
-  className="col input-field"
->
-  <input
-    checked={false}
-    className=""
-    id="input_mockId"
-    type="date"
-  />
-</div>
-`;
-
-exports[`<Input /> pickadate with icon 1`] = `
-<div
-  className="col input-field"
->
-  <Icon
-    className="prefix"
-  >
-    today
-  </Icon>
-  <input
-    checked={false}
-    className=""
-    id="input_mockId"
-    type="date"
-  />
-</div>
-`;
-
-exports[`<Input /> pickatime 1`] = `
-<Input
-  checked={false}
-  options={
-    Object {
-      "one": "two",
-    }
-  }
-  type="time"
->
-  <div
-    className="col input-field"
-  >
-    <input
-      checked={false}
-      className=""
-      id="input_mockId"
-    />
-  </div>
-</Input>
-`;
-
-exports[`<Input /> placeholder 1`] = `
-<div
-  className="col input-field"
->
-  <select
-    checked={false}
-    className=""
-    id="input_mockId"
-  >
-    <option
-      disabled={true}
-      key="mockId"
-    >
-      Choose your option
-    </option>
-    <option
-      key="1/.0"
-      value="1"
-    >
-      Option 1
-    </option>
-    <option
-      key="2/.1"
-      value="2"
-    >
-      Option 2
-    </option>
-    <option
-      key="3/.2"
-      value="3"
-    >
-      Option 3
-    </option>
-  </select>
-</div>
-`;
-
-exports[`<Input /> radio 1`] = `
-<div
-  className="col"
->
-  <input
-    checked={false}
-    className=""
-    id="input_mockId"
-    name="group1"
-    onChange={[Function]}
-    type="radio"
-    value="yellow"
-  />
-  <label
-    className="active"
-    htmlFor="input_mockId"
-  >
-    Yellow
-  </label>
-</div>
-`;
-
-exports[`<Input /> radio checked 1`] = `
-<div
-  className="col"
->
-  <input
-    checked={false}
-    className=""
-    id="input_mockId"
-    name="group1"
-    onChange={[Function]}
-    type="radio"
-    value="yellow"
-  />
-  <label
-    className="active"
-    htmlFor="input_mockId"
-  >
-    Yellow
-  </label>
-</div>
-`;
-
-exports[`<Input /> radio event 1`] = `
-<div
-  className="col"
->
-  <input
-    checked={false}
-    className=""
-    id="input_mockId"
-    name="group1"
-    onChange={[Function]}
-    type="radio"
-    value="yellow"
-  />
-  <label
-    className="active"
-    htmlFor="input_mockId"
-  >
-    Yellow
-  </label>
-</div>
-`;
-
-exports[`<Input /> radio event 2`] = `
-<div
-  className="col"
->
-  <input
-    checked={true}
-    className=""
-    id="input_mockId"
-    name="group1"
-    onChange={[Function]}
-    type="radio"
-    value="yellow"
-  />
-  <label
-    className="active"
-    htmlFor="input_mockId"
-  >
-    Yellow
-  </label>
-</div>
-`;
-
-exports[`<Input /> radio onChange 1`] = `
-<div
-  className="col"
->
-  <input
-    checked={true}
-    className=""
-    id="input_mockId"
-    name="group1"
-    onChange={[Function]}
-    type="radio"
-    value="yellow"
-  />
-  <label
-    className="active"
-    htmlFor="input_mockId"
-  >
-    Yellow
-  </label>
-</div>
-`;
-
-exports[`<Input /> radio onChange 2`] = `
-<div
-  className="col"
->
-  <input
-    checked={false}
-    className=""
-    id="input_mockId"
-    name="group1"
-    onChange={[Function]}
-    type="radio"
-    value="yellow"
-  />
-  <label
-    className=""
-    htmlFor="input_mockId"
-  >
-    Yellow
-  </label>
-</div>
-`;
-
-exports[`<Input /> renders 1`] = `
-<div
-  className="col input-field"
->
-  <input
-    checked={false}
-    className=""
-    id="input_mockId"
-    onChange={[Function]}
-    type="text"
-  />
-</div>
-`;
-
-exports[`<Input /> renders an icon child with prefix class 1`] = `
-<div
-  className="col input-field"
->
-  <Icon
-    className="prefix"
-  >
-    weekend
-  </Icon>
-  <select
-    checked={false}
-    className=""
-    icon="weekend"
-    id="input_mockId"
-  >
-    <option
-      key="yes/.0"
-      value="yes"
-    />
-  </select>
-</div>
-`;
-
-exports[`<Input /> select 1`] = `
-<div
-  className="col input-field"
->
-  <select
-    checked={false}
-    className=""
-    id="input_mockId"
-  >
-    <option
-      key=".$1"
-      value={1}
-    />
-    <option
-      key=".$2"
-      value={2}
-    />
-    <option
-      key=".$3"
-      value={3}
-    />
-    <option
-      key=".$4"
-      value={4}
-    />
-    <option
-      key=".$5"
-      value={5}
-    />
-  </select>
-</div>
-`;
-
-exports[`<Input /> switch 1`] = `
-<div
-  className="switch"
->
-  <label>
-    No
-    <input
-      checked={false}
-      onChange={[Function]}
-      type="checkbox"
-    />
-    <span
-      className="lever"
-    />
-    Yes
-  </label>
-</div>
-`;
-
-exports[`<Input /> text input 1`] = `
-<div
-  className="col input-field"
->
-  <input
-    checked={false}
-    className="red"
-    id="input_mockId"
-    onChange={[Function]}
-    type="text"
-  />
-</div>
-`;
-
-exports[`<Input /> textarea 1`] = `
-<div
-  className="col input-field"
->
-  <textarea
-    checked={false}
-    className="materialize-textarea"
-    id="input_mockId"
-    onChange={[Function]}
-  />
-</div>
-`;