From 79f6ac6e47346242b5d9f01586ca1203e0313045 Mon Sep 17 00:00:00 2001 From: Olivier Tassinari Date: Sat, 9 Jun 2018 20:12:37 +0200 Subject: [PATCH] [TextField] Bind the focus/blur explicitly --- .size-limit.js | 2 +- .../demos/selection-controls/SwitchLabels.js | 5 --- .../src/FormControl/FormControl.js | 23 ++----------- .../src/FormControl/FormControl.test.js | 30 ++++------------- packages/material-ui/src/Input/Input.js | 12 ++++++- .../material-ui/src/internal/SwitchBase.js | 32 +++++++++++++++++++ 6 files changed, 53 insertions(+), 51 deletions(-) diff --git a/.size-limit.js b/.size-limit.js index abd3066a57eddc..754a3fc35e0fdd 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -27,7 +27,7 @@ module.exports = [ name: 'The size of all the modules of material-ui.', webpack: true, path: 'packages/material-ui/build/index.js', - limit: '94.7 KB', + limit: '94.8 KB', }, { name: 'The main bundle of the docs', diff --git a/docs/src/pages/demos/selection-controls/SwitchLabels.js b/docs/src/pages/demos/selection-controls/SwitchLabels.js index 98ef11d9fe7e14..b7bbece9a44e35 100644 --- a/docs/src/pages/demos/selection-controls/SwitchLabels.js +++ b/docs/src/pages/demos/selection-controls/SwitchLabels.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import FormGroup from '@material-ui/core/FormGroup'; import FormControlLabel from '@material-ui/core/FormControlLabel'; import Switch from '@material-ui/core/Switch'; @@ -46,8 +45,4 @@ class SwitchLabels extends React.Component { } } -SwitchLabels.propTypes = { - classes: PropTypes.object.isRequired, -}; - export default SwitchLabels; diff --git a/packages/material-ui/src/FormControl/FormControl.js b/packages/material-ui/src/FormControl/FormControl.js index 5b52883a9429ab..5906625458e337 100644 --- a/packages/material-ui/src/FormControl/FormControl.js +++ b/packages/material-ui/src/FormControl/FormControl.js @@ -93,20 +93,11 @@ class FormControl extends React.Component { }; } - handleFocus = event => { - if (this.props.onFocus) { - this.props.onFocus(event); - } + handleFocus = () => { this.setState(state => (!state.focused ? { focused: true } : null)); }; - handleBlur = event => { - // The event might be undefined. - // For instance, a child component might call this hook - // when an input is disabled but still having the focus. - if (this.props.onBlur && event) { - this.props.onBlur(event); - } + handleBlur = () => { this.setState(state => (state.focused ? { focused: false } : null)); }; @@ -146,8 +137,6 @@ class FormControl extends React.Component { className, )} {...other} - onFocus={this.handleFocus} - onBlur={this.handleBlur} /> ); } @@ -188,14 +177,6 @@ FormControl.propTypes = { * If `dense` or `normal`, will adjust vertical spacing of this and contained components. */ margin: PropTypes.oneOf(['none', 'dense', 'normal']), - /** - * @ignore - */ - onBlur: PropTypes.func, - /** - * @ignore - */ - onFocus: PropTypes.func, /** * If `true`, the label will indicate that the input is required. */ diff --git a/packages/material-ui/src/FormControl/FormControl.test.js b/packages/material-ui/src/FormControl/FormControl.test.js index 3df51846011994..72854ca18d720b 100644 --- a/packages/material-ui/src/FormControl/FormControl.test.js +++ b/packages/material-ui/src/FormControl/FormControl.test.js @@ -1,5 +1,4 @@ import React from 'react'; -import { spy } from 'sinon'; import { assert } from 'chai'; import { createShallow, getClasses } from '../test-utils'; import Input from '../Input'; @@ -223,38 +222,23 @@ describe('', () => { describe('handleFocus', () => { it('should set the focused state', () => { - assert.strictEqual(wrapper.state('focused'), false); + assert.strictEqual(wrapper.state().focused, false); muiFormControlContext.onFocus(); - assert.strictEqual(wrapper.state('focused'), true); + assert.strictEqual(wrapper.state().focused, true); muiFormControlContext.onFocus(); - assert.strictEqual(wrapper.state('focused'), true); - }); - - it('should be able to use a onFocus property', () => { - const handleFocus = spy(); - wrapper.setProps({ onFocus: handleFocus }); - muiFormControlContext.onFocus(); - assert.strictEqual(handleFocus.callCount, 1); + assert.strictEqual(wrapper.state().focused, true); }); }); describe('handleBlur', () => { it('should clear the focused state', () => { - assert.strictEqual(wrapper.state('focused'), false); + assert.strictEqual(wrapper.state().focused, false); muiFormControlContext.onFocus(); - assert.strictEqual(wrapper.state('focused'), true); + assert.strictEqual(wrapper.state().focused, true); muiFormControlContext.onBlur(); - assert.strictEqual(wrapper.state('focused'), false); + assert.strictEqual(wrapper.state().focused, false); muiFormControlContext.onBlur(); - assert.strictEqual(wrapper.state('focused'), false); - }); - - it('should be able to use a onBlur property', () => { - const handleBlur = spy(); - wrapper.setProps({ onBlur: handleBlur }); - muiFormControlContext.onFocus(); - muiFormControlContext.onBlur({}); - assert.strictEqual(handleBlur.callCount, 1); + assert.strictEqual(wrapper.state().focused, false); }); }); }); diff --git a/packages/material-ui/src/Input/Input.js b/packages/material-ui/src/Input/Input.js index 074a8b42aa5bfe..4ebb8be556ca1d 100644 --- a/packages/material-ui/src/Input/Input.js +++ b/packages/material-ui/src/Input/Input.js @@ -289,7 +289,7 @@ class Input extends React.Component { input = null; // Holds the input reference handleFocus = event => { - // Fix an bug with IE11 where the focus/blur events are triggered + // Fix a bug with IE11 where the focus/blur events are triggered // while the input is disabled. if (formControlState(this.props, this.context).disabled) { event.stopPropagation(); @@ -300,6 +300,11 @@ class Input extends React.Component { if (this.props.onFocus) { this.props.onFocus(event); } + + const { muiFormControl } = this.context; + if (muiFormControl && muiFormControl.onFocus) { + muiFormControl.onFocus(event); + } }; handleBlur = event => { @@ -307,6 +312,11 @@ class Input extends React.Component { if (this.props.onBlur) { this.props.onBlur(event); } + + const { muiFormControl } = this.context; + if (muiFormControl && muiFormControl.onBlur) { + muiFormControl.onBlur(event); + } }; handleChange = event => { diff --git a/packages/material-ui/src/internal/SwitchBase.js b/packages/material-ui/src/internal/SwitchBase.js index 4298908c932121..df6522030cf93e 100644 --- a/packages/material-ui/src/internal/SwitchBase.js +++ b/packages/material-ui/src/internal/SwitchBase.js @@ -47,6 +47,28 @@ class SwitchBase extends React.Component { input = null; isControlled = null; + handleFocus = event => { + if (this.props.onFocus) { + this.props.onFocus(event); + } + + const { muiFormControl } = this.context; + if (muiFormControl && muiFormControl.onFocus) { + muiFormControl.onFocus(event); + } + }; + + handleBlur = event => { + if (this.props.onBlur) { + this.props.onBlur(event); + } + + const { muiFormControl } = this.context; + if (muiFormControl && muiFormControl.onBlur) { + muiFormControl.onBlur(event); + } + }; + handleInputChange = event => { const checked = event.target.checked; @@ -105,6 +127,8 @@ class SwitchBase extends React.Component { disabled={disabled} tabIndex={null} role={undefined} + onFocus={this.handleFocus} + onBlur={this.handleBlur} {...other} > {checked ? checkedIcon : icon} @@ -186,6 +210,10 @@ SwitchBase.propTypes = { * @ignore */ name: PropTypes.string, + /** + * @ignore + */ + onBlur: PropTypes.func, /** * Callback fired when the state is changed. * @@ -194,6 +222,10 @@ SwitchBase.propTypes = { * @param {boolean} checked The `checked` value of the switch */ onChange: PropTypes.func, + /** + * @ignore + */ + onFocus: PropTypes.func, /** * @ignore */