Skip to content

Commit

Permalink
Flow type elements in event handlers instead of instanceof checks
Browse files Browse the repository at this point in the history
  • Loading branch information
jennyscript committed Aug 11, 2018
1 parent fe93cab commit 96e3ca2
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 74 deletions.
12 changes: 8 additions & 4 deletions docs/src/TextArea.doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,24 @@ card(
},
{
name: 'onBlur',
type: '({ event: SyntheticFocusEvent<>, value: string }) => void',
type:
'({ event: SyntheticFocusEvent<HTMLTextAreaElement>, value: string }) => void',
},
{
name: 'onChange',
type: '({ event: SyntheticInputEvent<>, value: string }) => void',
type:
'({ event: SyntheticInputEvent<HTMLTextAreaElement>, value: string }) => void',
required: true,
},
{
name: 'onFocus',
type: '({ event: SyntheticFocusEvent<>, value: string }) => void',
type:
'({ event: SyntheticFocusEvent<HTMLTextAreaElement>, value: string }) => void',
},
{
name: 'onKeyDown',
type: '({ event: SyntheticKeyboardEvent<>, value: string }) => void',
type:
'({ event: SyntheticKeyboardEvent<HTMLTextAreaElement>, value: string }) => void',
},
{
name: 'placeholder',
Expand Down
12 changes: 8 additions & 4 deletions docs/src/TextField.doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,24 @@ card(
},
{
name: 'onBlur',
type: '({ event: SyntheticFocusEvent<>, value: string }) => void',
type:
'({ event: SyntheticFocusEvent<HTMLInputElement>, value: string }) => void',
},
{
name: 'onChange',
type: '({ event: SyntheticInputEvent<>, value: string }) => void',
type:
'({ event: SyntheticInputEvent<HTMLInputElement>, value: string }) => void',
required: true,
},
{
name: 'onFocus',
type: '({ event: SyntheticFocusEvent<>, value: string }) => void',
type:
'({ event: SyntheticFocusEvent<HTMLInputElement>, value: string }) => void',
},
{
name: 'onKeyDown',
type: '({ event: SyntheticKeyboardEvent<>, value: string }) => void',
type:
'({ event: SyntheticKeyboardEvent<HTMLInputElement>, value: string }) => void',
},
{
name: 'placeholder',
Expand Down
54 changes: 32 additions & 22 deletions packages/gestalt/src/TextArea.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,22 @@ type Props = {|
id: string,
idealErrorDirection?: 'up' | 'right' | 'down' | 'left' /* default: right */,
name?: string,
onBlur?: ({ event: SyntheticFocusEvent<>, value: string }) => void,
onChange: ({ event: SyntheticInputEvent<>, value: string }) => void,
onFocus?: ({ event: SyntheticFocusEvent<>, value: string }) => void,
onKeyDown?: ({ event: SyntheticKeyboardEvent<>, value: string }) => void,
onBlur?: ({
event: SyntheticFocusEvent<HTMLTextAreaElement>,
value: string,
}) => void,
onChange: ({
event: SyntheticInputEvent<HTMLTextAreaElement>,
value: string,
}) => void,
onFocus?: ({
event: SyntheticFocusEvent<HTMLTextAreaElement>,
value: string,
}) => void,
onKeyDown?: ({
event: SyntheticKeyboardEvent<HTMLTextAreaElement>,
value: string,
}) => void,
placeholder?: string,
rows?: number /* default: 3 */,
value?: string,
Expand Down Expand Up @@ -70,48 +82,46 @@ export default class TextArea extends React.Component<Props, State> {
return null;
}

handleChange = (event: SyntheticInputEvent<>) => {
if (event.target instanceof HTMLTextAreaElement) {
this.props.onChange({
event,
value: event.target.value,
});
handleChange = (event: SyntheticInputEvent<HTMLTextAreaElement>) => {
this.props.onChange({
event,
value: event.currentTarget.value,
});

if (this.props.errorMessage) {
this.setState({ errorIsOpen: true });
}
if (this.props.errorMessage) {
this.setState({ errorIsOpen: true });
}
};

handleBlur = (event: SyntheticFocusEvent<>) => {
handleBlur = (event: SyntheticFocusEvent<HTMLTextAreaElement>) => {
if (this.props.errorMessage) {
this.setState({ errorIsOpen: false });
}
if (event.target instanceof HTMLTextAreaElement && this.props.onBlur) {
if (this.props.onBlur) {
this.props.onBlur({
event,
value: event.target.value,
value: event.currentTarget.value,
});
}
};

handleFocus = (event: SyntheticFocusEvent<>) => {
handleFocus = (event: SyntheticFocusEvent<HTMLTextAreaElement>) => {
if (this.props.errorMessage) {
this.setState({ errorIsOpen: true });
}
if (event.target instanceof HTMLTextAreaElement && this.props.onFocus) {
if (this.props.onFocus) {
this.props.onFocus({
event,
value: event.target.value,
value: event.currentTarget.value,
});
}
};

handleKeyDown = (event: SyntheticKeyboardEvent<>) => {
if (event.target instanceof HTMLTextAreaElement && this.props.onKeyDown) {
handleKeyDown = (event: SyntheticKeyboardEvent<HTMLTextAreaElement>) => {
if (this.props.onKeyDown) {
this.props.onKeyDown({
event,
value: event.target.value,
value: event.currentTarget.value,
});
}
};
Expand Down
22 changes: 10 additions & 12 deletions packages/gestalt/src/TextArea.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import TextArea from './TextArea.js';
import Flyout from './Flyout.js';

describe('TextArea', () => {
beforeAll(() => {
// Mock this out for the instanceof checks in event handlers
global.HTMLTextAreaElement = Object;
});
it('Renders a Flyout if an error message is passed in', () => {
const wrapper = shallow(
<TextArea errorMessage="test" id="test" onChange={jest.fn()} />
Expand Down Expand Up @@ -91,9 +87,11 @@ describe('TextArea', () => {
const tree = shallow(
<TextArea id="test" onBlur={mockBlur} onChange={jest.fn()} />
);
tree.find('textarea').simulate('blur', { target: { value: 'fake value' } });
tree
.find('textarea')
.simulate('blur', { currentTarget: { value: 'fake value' } });
expect(mockBlur).toHaveBeenCalledWith({
event: { target: { value: 'fake value' } },
event: { currentTarget: { value: 'fake value' } },
value: 'fake value',
});
});
Expand All @@ -103,9 +101,9 @@ describe('TextArea', () => {
const tree = shallow(<TextArea id="test" onChange={mockChange} />);
tree
.find('textarea')
.simulate('change', { target: { value: 'fake value' } });
.simulate('change', { currentTarget: { value: 'fake value' } });
expect(mockChange).toHaveBeenCalledWith({
event: { target: { value: 'fake value' } },
event: { currentTarget: { value: 'fake value' } },
value: 'fake value',
});
});
Expand All @@ -117,9 +115,9 @@ describe('TextArea', () => {
);
tree
.find('textarea')
.simulate('focus', { target: { value: 'fake value' } });
.simulate('focus', { currentTarget: { value: 'fake value' } });
expect(mockFocus).toHaveBeenCalledWith({
event: { target: { value: 'fake value' } },
event: { currentTarget: { value: 'fake value' } },
value: 'fake value',
});
});
Expand All @@ -131,9 +129,9 @@ describe('TextArea', () => {
);
tree
.find('textarea')
.simulate('keyDown', { target: { value: 'fake value' } });
.simulate('keyDown', { currentTarget: { value: 'fake value' } });
expect(mockKeyDown).toHaveBeenCalledWith({
event: { target: { value: 'fake value' } },
event: { currentTarget: { value: 'fake value' } },
value: 'fake value',
});
});
Expand Down
50 changes: 30 additions & 20 deletions packages/gestalt/src/TextField.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,22 @@ type Props = {|
id: string,
idealErrorDirection?: 'up' | 'right' | 'down' | 'left' /* default: right */,
name?: string,
onBlur?: ({ event: SyntheticFocusEvent<>, value: string }) => void,
onChange: ({ event: SyntheticInputEvent<>, value: string }) => void,
onFocus?: ({ event: SyntheticFocusEvent<>, value: string }) => void,
onKeyDown?: ({ event: SyntheticKeyboardEvent<>, value: string }) => void,
onBlur?: ({
event: SyntheticFocusEvent<HTMLInputElement>,
value: string,
}) => void,
onChange: ({
event: SyntheticInputEvent<HTMLInputElement>,
value: string,
}) => void,
onFocus?: ({
event: SyntheticFocusEvent<HTMLInputElement>,
value: string,
}) => void,
onKeyDown?: ({
event: SyntheticKeyboardEvent<HTMLInputElement>,
value: string,
}) => void,
placeholder?: string,
type?: 'date' | 'email' | 'number' | 'password' | 'text' | 'url',
value?: string,
Expand Down Expand Up @@ -84,44 +96,42 @@ export default class TextField extends React.Component<Props, State> {
return null;
}

handleChange = (event: SyntheticInputEvent<>) => {
if (event.target instanceof HTMLInputElement) {
this.props.onChange({
event,
value: event.target.value,
});
}
handleChange = (event: SyntheticInputEvent<HTMLInputElement>) => {
this.props.onChange({
event,
value: event.currentTarget.value,
});
};

handleBlur = (event: SyntheticFocusEvent<>) => {
handleBlur = (event: SyntheticFocusEvent<HTMLInputElement>) => {
if (this.props.errorMessage) {
this.setState({ errorIsOpen: false });
}
if (event.target instanceof HTMLInputElement && this.props.onBlur) {
if (this.props.onBlur) {
this.props.onBlur({
event,
value: event.target.value,
value: event.currentTarget.value,
});
}
};

handleFocus = (event: SyntheticFocusEvent<>) => {
handleFocus = (event: SyntheticFocusEvent<HTMLInputElement>) => {
if (this.props.errorMessage) {
this.setState({ errorIsOpen: true });
}
if (event.target instanceof HTMLInputElement && this.props.onFocus) {
if (this.props.onFocus) {
this.props.onFocus({
event,
value: event.target.value,
value: event.currentTarget.value,
});
}
};

handleKeyDown = (event: SyntheticKeyboardEvent<>) => {
if (event.target instanceof HTMLInputElement && this.props.onKeyDown) {
handleKeyDown = (event: SyntheticKeyboardEvent<HTMLInputElement>) => {
if (this.props.onKeyDown) {
this.props.onKeyDown({
event,
value: event.target.value,
value: event.currentTarget.value,
});
}
};
Expand Down
28 changes: 16 additions & 12 deletions packages/gestalt/src/TextField.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ import TextField from './TextField.js';
import Flyout from './Flyout.js';

describe('TextField', () => {
beforeAll(() => {
// Mock this out for the instanceof checks in event handlers
global.HTMLInputElement = Object;
});
it('Renders a Flyout if an error message is passed in', () => {
const wrapper = shallow(
<TextField errorMessage="test" id="test" onChange={jest.fn()} />
Expand Down Expand Up @@ -124,19 +120,23 @@ describe('TextField', () => {
const tree = shallow(
<TextField id="test" onBlur={mockBlur} onChange={jest.fn()} />
);
tree.find('input').simulate('blur', { target: { value: 'fake value' } });
tree
.find('input')
.simulate('blur', { currentTarget: { value: 'fake value' } });
expect(mockBlur).toHaveBeenCalledWith({
event: { target: { value: 'fake value' } },
event: { currentTarget: { value: 'fake value' } },
value: 'fake value',
});
});

it('handles change events', () => {
const mockChange = jest.fn();
const tree = shallow(<TextField id="test" onChange={mockChange} />);
tree.find('input').simulate('change', { target: { value: 'fake value' } });
tree
.find('input')
.simulate('change', { currentTarget: { value: 'fake value' } });
expect(mockChange).toHaveBeenCalledWith({
event: { target: { value: 'fake value' } },
event: { currentTarget: { value: 'fake value' } },
value: 'fake value',
});
});
Expand All @@ -146,9 +146,11 @@ describe('TextField', () => {
const tree = shallow(
<TextField id="test" onChange={jest.fn()} onFocus={mockFocus} />
);
tree.find('input').simulate('focus', { target: { value: 'fake value' } });
tree
.find('input')
.simulate('focus', { currentTarget: { value: 'fake value' } });
expect(mockFocus).toHaveBeenCalledWith({
event: { target: { value: 'fake value' } },
event: { currentTarget: { value: 'fake value' } },
value: 'fake value',
});
});
Expand All @@ -158,9 +160,11 @@ describe('TextField', () => {
const tree = shallow(
<TextField id="test" onChange={jest.fn()} onKeyDown={mockKeyDown} />
);
tree.find('input').simulate('keyDown', { target: { value: 'fake value' } });
tree
.find('input')
.simulate('keyDown', { currentTarget: { value: 'fake value' } });
expect(mockKeyDown).toHaveBeenCalledWith({
event: { target: { value: 'fake value' } },
event: { currentTarget: { value: 'fake value' } },
value: 'fake value',
});
});
Expand Down

0 comments on commit 96e3ca2

Please sign in to comment.