diff --git a/src/forms/TextInput.jsx b/src/forms/TextInput.jsx
index 366398f72..c43bd4f90 100644
--- a/src/forms/TextInput.jsx
+++ b/src/forms/TextInput.jsx
@@ -5,80 +5,66 @@ import cx from 'classnames';
/**
* @module TextInput
*/
-class TextInput extends React.Component {
+const TextInput = (props) => {
- constructor(props) {
- super(props);
- this.state = {
- value: props.value || '',
- };
- this.onChange = this.onChange.bind(this);
- }
+ const {
+ name,
+ value,
+ label,
+ labelClassName,
+ className,
+ children,
+ error,
+ placeholder,
+ required,
+ id,
+ onChange,
+ isSearch,
+ maxLength,
+ pattern,
+ disabled,
+ ...other
+ } = props;
- onChange(e) {
- this.setState({ value: e.target.value });
- if (this.props.onChange) {
- this.props.onChange(e);
- }
- }
+ const classNames = cx(
+ { 'field--error': error },
+ className
+ );
- render() {
- const {
- name,
- value, // eslint-disable-line no-unused-vars
- label,
- labelClassName,
- className,
- children,
- error,
- placeholder,
- required,
- id,
- onChange, // eslint-disable-line no-unused-vars
- isSearch,
- maxLength,
- pattern,
- disabled
- } = this.props;
+ const labelClassNames = cx(
+ 'label--field',
+ { required, disabled },
+ labelClassName
+ );
- const classNames = cx(
- { 'field--error': error },
- className
- );
+ return (
+
+ {label &&
+
+ }
+
- const labelClassNames = cx(
- 'label--field',
- { required, disabled },
- labelClassName
- );
+ { maxLength &&
{value.length} / {maxLength}
}
- return (
-
- {label &&
-
- }
-
-
- { this.props.maxLength &&
{this.state.value.length} / {this.props.maxLength}
}
-
- { error &&
{error}
}
- {children}
-
- );
- }
-}
+ { error &&
{error}
}
+ {children}
+
+ );
+};
TextInput.propTypes = {
name: PropTypes.string.isRequired,
diff --git a/src/forms/textInput.test.jsx b/src/forms/textInput.test.jsx
index d016644f4..5baa4aec8 100644
--- a/src/forms/textInput.test.jsx
+++ b/src/forms/textInput.test.jsx
@@ -1,5 +1,6 @@
import React from 'react';
import TestUtils from 'react-addons-test-utils';
+import { TestWrapper } from '../utils/testUtils';
import TextInput from './TextInput';
describe('TextInput', function() {
@@ -21,12 +22,14 @@ describe('TextInput', function() {
required: true,
};
textInputComponent = TestUtils.renderIntoDocument(
-
+
+
+
);
inputEl = TestUtils.findRenderedDOMComponentWithTag(textInputComponent, 'input');
@@ -57,12 +60,14 @@ describe('TextInput', function() {
it('should have input type search if `isSearch` is set to true', () => {
textInputComponent = TestUtils.renderIntoDocument(
-
+
+
+
);
inputEl = TestUtils.findRenderedDOMComponentWithTag(textInputComponent, 'input');
@@ -72,12 +77,14 @@ describe('TextInput', function() {
it('should have a disabled attribute when specified', () => {
textInputComponent = TestUtils.renderIntoDocument(
-
+
+
+
);
inputEl = TestUtils.findRenderedDOMComponentWithTag(textInputComponent, 'input');
@@ -102,43 +109,17 @@ describe('TextInput', function() {
expect(inputEl.getAttribute('maxLength')).toEqual(MAX_LEN);
});
- it('should set its value on input change', function() {
- const newValue = `${VALUE}r`;
- expect(inputEl.value).toEqual(VALUE);
- TestUtils.Simulate.change(inputEl, { target: { value: newValue } });
- expect(inputEl.value).toEqual(newValue);
- });
-
- it('should call onChange and setState with input change', function() {
- const newValue = `${VALUE}r`;
- const changeSpy = spyOn(TextInput.prototype, 'onChange').and.callThrough();
- const stateSpy = spyOn(TextInput.prototype, 'setState').and.callThrough();
-
- const boundComponent = TestUtils.renderIntoDocument(
-
- );
-
- inputEl = TestUtils.findRenderedDOMComponentWithTag(boundComponent, 'input');
- TestUtils.Simulate.change(inputEl, { target: { value: newValue } });
-
- expect(changeSpy).toHaveBeenCalled();
- expect(stateSpy).toHaveBeenCalledWith({ value: newValue });
- });
-
it('should call onChange `props` function when input is changed', () => {
const newValue = `${VALUE}r`;
const boundComponent = TestUtils.renderIntoDocument(
-
+
+
+
);
inputEl = TestUtils.findRenderedDOMComponentWithTag(boundComponent, 'input');
TestUtils.Simulate.change(inputEl, { target: { value: newValue } });
diff --git a/src/utils/testUtils.js b/src/utils/testUtils.js
index d5085b98e..d5e97b3cd 100644
--- a/src/utils/testUtils.js
+++ b/src/utils/testUtils.js
@@ -1,4 +1,5 @@
import React from 'react';
+import createReactClass from 'create-react-class';
import TestUtils from 'react-addons-test-utils';
export const variantTest = (FoundationComponent, className, variants) => {
@@ -32,3 +33,13 @@ export const hasRoleAttribute = (el, roleName) => {
export const componentHasProperty = (component, prop, value) => {
expect(component && component.props && component.props[prop] === value).toBe(true);
};
+
+// Note: functional components need to be
+// wrapped it in a stateful component to use TestUtils effectively
+export const TestWrapper = createReactClass({
+ render: function() {
+ return (
+ {this.props.children}
+ );
+ }
+});
diff --git a/yarn.lock b/yarn.lock
index 1b3deddc9..51df245c1 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3685,14 +3685,14 @@ js-tokens@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
-js-yaml@3.6.1, js-yaml@^3.4.3, js-yaml@^3.5.1:
+js-yaml@3.6.1, js-yaml@^3.5.1:
version "3.6.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.6.1.tgz#6e5fe67d8b205ce4d22fad05b7781e8dadcc4b30"
dependencies:
argparse "^1.0.7"
esprima "^2.6.0"
-js-yaml@^3.7.0, js-yaml@~3.7.0:
+js-yaml@^3.4.3, js-yaml@^3.7.0, js-yaml@~3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80"
dependencies: