Skip to content

Commit

Permalink
feat(text-field): Sync inputComponent when component is updated (#848)
Browse files Browse the repository at this point in the history
  • Loading branch information
태재영 authored and Matt Goo committed May 6, 2019
1 parent 1c10eb3 commit 2b954fa
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 8 deletions.
7 changes: 6 additions & 1 deletion packages/text-field/Input.tsx
Expand Up @@ -29,7 +29,7 @@ export interface InputProps<T extends HTMLElement = HTMLInputElement> {
isValid?: boolean;
foundation?: MDCTextFieldFoundation;
handleValueChange?: (value: string | number | string[] | undefined, cb: () => void) => void;
ref?: (inputInstance: Input<T>) => void,
syncInput?: (inputInstance: Input<T>) => void,
onBlur?: Pick<React.HTMLProps<T>, 'onBlur'>;
onChange?: Pick<React.HTMLProps<T>, 'onChange'>;
onFocus?: Pick<React.HTMLProps<T>, 'onFocus'>;
Expand Down Expand Up @@ -81,6 +81,7 @@ export default class Input<T extends HTMLElement = HTMLInputElement> extends Rea
componentDidMount() {
const {
id,
syncInput,
disabled,
value,
setInputId,
Expand All @@ -89,6 +90,9 @@ export default class Input<T extends HTMLElement = HTMLInputElement> extends Rea
foundation,
isValid,
} = this.props;
if (syncInput) {
syncInput(this);
}
if (setInputId && id) {
setInputId(id!);
}
Expand Down Expand Up @@ -257,6 +261,7 @@ export default class Input<T extends HTMLElement = HTMLInputElement> extends Rea
/* eslint-disable no-unused-vars */
className,
foundation,
syncInput,
isValid,
value,
handleFocusChange,
Expand Down
9 changes: 2 additions & 7 deletions packages/text-field/index.tsx
Expand Up @@ -275,18 +275,13 @@ class TextField<T extends HTMLElement = HTMLInputElement> extends React.Componen
inputProps(child: React.ReactElement<InputProps<T>>) {
// ref does exist on React.ReactElement<InputProps<T>>
// @ts-ignore
const {props, ref} = child;
const {props} = child;
return Object.assign({}, props, {
foundation: this.state.foundation,
handleFocusChange: (isFocused: boolean) => this.setState({isFocused}),
setDisabled: (disabled: boolean) => this.setState({disabled}),
setInputId: (id: string) => this.setState({inputId: id}),
ref: (input: Input<T>) => {
if (typeof ref === 'function') {
ref(input);
}
this.inputComponent_ = input;
},
syncInput: (input: Input<T>) => (this.inputComponent_ = input),
inputType: this.props.textarea ? 'textarea' : 'input',
});
}
Expand Down
18 changes: 18 additions & 0 deletions test/unit/text-field/index.test.tsx
Expand Up @@ -696,3 +696,21 @@ test('Useless test for code coverage', () => {
wrapper.instance().adapter.registerInputInteractionHandler(temp, temp);
wrapper.instance().adapter.deregisterInputInteractionHandler(temp, temp);
});

test('Input component sync test in TextField', () => {
class TestComponent extends React.Component {
state = {
disabled: false,
};
render() {
return <TextField>
<Input disabled={this.state.disabled} />
</TextField>;
}
}
const wrapper = mount<TestComponent>(<TestComponent/>);
// If inputComponent is null and disabled is true,
// setDisabled called #inputAdapter.getNativeInput
// and throw error because there is no inputComponent
assert.doesNotThrow(() => wrapper.instance().setState({disabled: true}));
});

0 comments on commit 2b954fa

Please sign in to comment.