Skip to content

Commit

Permalink
fix(text-field): put foundation on state and do render input unless f…
Browse files Browse the repository at this point in the history
…oundation is present (#353)
  • Loading branch information
Matt Goo authored Oct 30, 2018
1 parent 36469f7 commit 2cb5d64
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 88 deletions.
26 changes: 13 additions & 13 deletions packages/text-field/Input.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,18 @@ export default class Input extends React.Component {
state = {wasUserTriggeredChange: false};

componentDidMount() {
if (this.props.id) {
this.props.setInputId(this.props.id);
const {
id, disabled, value, setInputId, setDisabled, handleValueChange, foundation,
} = this.props;

if (id) {
setInputId(id);
}
if (this.props.disabled) {
this.props.setDisabled(true);
if (disabled) {
setDisabled(true);
}
if (value) {
handleValueChange(value, () => foundation.setValue(value));
}
}

Expand All @@ -61,15 +68,6 @@ export default class Input extends React.Component {
setInputId(id);
}

// this should be in the componentDidMount, but foundation is not created
// at that time.
// Will fix this in
// https://github.com/material-components/material-components-web-react/pull/353/files
if (value && foundation !== prevProps.foundation) {
handleValueChange(value, () => foundation.setValue(value));
return;
}

if (value !== prevProps.value) {
handleValueChange(value, () => {
// only call #foundation.setValue on programatic changes;
Expand Down Expand Up @@ -193,6 +191,7 @@ Input.propTypes = {
deactivateFocus: PropTypes.func,
autoCompleteFocus: PropTypes.func,
setDisabled: PropTypes.func,
setValue: PropTypes.func,
setTransformOrigin: PropTypes.func,
handleValidationAttributeMutation_: PropTypes.func,
}),
Expand Down Expand Up @@ -222,6 +221,7 @@ Input.defaultProps = {
autoCompleteFocus: () => {},
setDisabled: () => {},
setTransformOrigin: () => {},
setValue: () => {},
handleValidationAttributeMutation_: () => {},
},
handleValueChange: () => {},
Expand Down
24 changes: 13 additions & 11 deletions packages/text-field/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ import LineRipple from '@material/react-line-ripple';
import NotchedOutline from '@material/react-notched-outline';

class TextField extends React.Component {

foundation_ = null;

constructor(props) {
super(props);
this.floatingLabelElement = React.createRef();
Expand Down Expand Up @@ -65,19 +62,24 @@ class TextField extends React.Component {
// helper text state
showHelperTextToScreenReader: false,
isValid: true,

// foundation is on state,
// so that the Input renders after this component
foundation: null,
};
}

componentDidMount() {
const foundationMap = {
helperText: this.helperTextAdapter,
};
this.foundation_ = new MDCTextFieldFoundation(this.adapter, foundationMap);
this.foundation_.init();
const foundation = new MDCTextFieldFoundation(this.adapter, foundationMap);
this.setState({foundation});
foundation.init();
}

componentWillUnmount() {
this.foundation_.destroy();
this.state.foundation.destroy();
}

/**
Expand Down Expand Up @@ -223,7 +225,7 @@ class TextField extends React.Component {

inputProps(props) {
return Object.assign({}, props, {
foundation: this.foundation_,
foundation: this.state.foundation,
handleFocusChange: (isFocused) => this.setState({isFocused}),
handleValueChange: (value, cb) => this.setState({value}, cb),
setDisabled: (disabled) => this.setState({disabled}),
Expand All @@ -247,17 +249,17 @@ class TextField extends React.Component {
trailingIcon,
textarea,
} = this.props;

const {foundation} = this.state;
const textField = (
<div
{...this.otherProps}
className={this.classes}
onClick={() => this.foundation_ && this.foundation_.handleTextFieldInteraction()}
onKeyDown={() => this.foundation_ && this.foundation_.handleTextFieldInteraction()}
onClick={() => foundation && foundation.handleTextFieldInteraction()}
onKeyDown={() => foundation && foundation.handleTextFieldInteraction()}
key='text-field-container'
>
{leadingIcon ? this.renderIcon(leadingIcon) : null}
{this.renderInput()}
{foundation ? this.renderInput() : null}
{label && !fullWidth ? this.renderLabel() : null}
{outlined ? this.renderNotchedOutline() : null}
{!fullWidth && !textarea && !outlined ? this.renderLineRipple() : null}
Expand Down
21 changes: 10 additions & 11 deletions test/unit/text-field/Input.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ test('#componentDidMount should not call any method if disabled and id do not ex
td.verify(setDisabled(td.matchers.isA(Boolean)), {times: 0});
});

test('#componentDidMount calls props.handleValueChange when the foundation initializes with a value', () => {
const handleValueChange = td.func();
const value = 'test value';
shallow(<Input
value={value}
handleValueChange={handleValueChange}
/>);
td.verify(handleValueChange(value, td.matchers.isA(Function)), {times: 1});
});

test('change to minLength calls handleValidationAttributeChange', () => {
const handleValidationAttributeChange = td.func();
const wrapper = shallow(<Input foundation={{handleValidationAttributeChange}} />);
Expand Down Expand Up @@ -144,17 +154,6 @@ test('#componentDidUpdate calls handleValueChange when the foundation initialize
td.verify(handleValueChange('test value', td.matchers.isA(Function)), {times: 1});
});

test('#componentDidUpdate calls setValue when the foundation initializes with a value', () => {
const setValue = td.func();
const handleValueChange = (value, cb) => {
cb(value);
};
const wrapper = shallow(<Input value='test value' handleValueChange={handleValueChange} />);

wrapper.setProps({foundation: {setValue}});
td.verify(setValue('test value'), {times: 1});
});

test('props.handleValueChange() is called if this.props.value updates', () => {
const handleValueChange = td.func();
const wrapper = shallow(<Input handleValueChange={handleValueChange} />);
Expand Down
Loading

0 comments on commit 2cb5d64

Please sign in to comment.