diff --git a/blocks/Button/Button.js b/blocks/Button/Button.js index 1615513..b1d2bc1 100644 --- a/blocks/Button/Button.js +++ b/blocks/Button/Button.js @@ -1,6 +1,6 @@ import {decl} from 'bem-react-core'; -import React from 'react'; -import ReactDom from 'react-dom'; +import React, {PropTypes} from 'React'; +import Focusable from '../Focusable/Focusable'; import warning from 'warning'; import ButtonText from 'e:Text'; @@ -41,18 +41,6 @@ export default decl({ this.setState(newState); }, - didMount() { - this.state.focused? - this._focus() : - this._blur(); - }, - - didUpdate() { - this.state.focused? - this._focus() : - this._blur(); - }, - mods({ disabled, checked }) { const { focused, hovered, pressed } = this.state; return { @@ -79,8 +67,6 @@ export default decl({ if(!disabled) { res = { ...res, - onFocus : this._onFocus, - onBlur : this._onBlur, onMouseEnter : this._onMouseEnter, onMouseLeave : this._onMouseLeave, onMouseDown : this._onMouseDown, @@ -101,6 +87,14 @@ export default decl({ return res; }, + render() { + return ( + + { this.__base.apply(this, arguments) } + + ); + }, + content({ children, icon, text }) { if(children) return children; const content = []; @@ -176,25 +170,15 @@ export default decl({ _onClick() { this.props.onClick(); - }, - - _focus() { - const domNode = ReactDom.findDOMNode(this); - document.activeElement !== domNode && domNode.focus(); - }, - - _blur() { - const domNode = ReactDom.findDOMNode(this); - document.activeElement === domNode && domNode.blur(); } }, { propTypes : { - type : React.PropTypes.oneOf([undefined, 'link']), - disabled : React.PropTypes.bool, - focused : React.PropTypes.bool, - onClick : React.PropTypes.func, - onFocusChange : React.PropTypes.func, - onCheckChange : React.PropTypes.func + type : PropTypes.oneOf([undefined, 'link']), + disabled : PropTypes.bool, + focused : PropTypes.bool, + onClick : PropTypes.func, + onFocusChange : PropTypes.func, + onCheckChange : PropTypes.func }, defaultProps : { diff --git a/blocks/Focusable/Focusable.js b/blocks/Focusable/Focusable.js new file mode 100644 index 0000000..6712bd1 --- /dev/null +++ b/blocks/Focusable/Focusable.js @@ -0,0 +1,39 @@ +import React, {Component, cloneElement, PropTypes} from 'react'; +import {findDOMNode} from 'react-dom'; + +export default class Focusable extends Component { + render() { + const { children, onFocus, onBlur } = this.props; + return React.cloneElement(children, { onFocus, onBlur }); + } + + componentDidMount() { + this.props.focused? + this._focus() : + this._blur(); + } + + componentDidUpdate() { + this.props.focused? + this._focus() : + this._blur(); + } + + _focus() { + const domNode = findDOMNode(this); + document.activeElement !== domNode && domNode.focus(); + } + + _blur() { + const domNode = findDOMNode(this); + document.activeElement === domNode && domNode.blur(); + } +} + +Focusable.propTypes = { + focused : PropTypes.bool, + onFocus : PropTypes.func, + onBlur : PropTypes.func +}; + + diff --git a/blocks/Link/Link.js b/blocks/Link/Link.js index d198ab7..7c064b7 100644 --- a/blocks/Link/Link.js +++ b/blocks/Link/Link.js @@ -1,6 +1,6 @@ import {decl} from 'bem-react-core'; -import React from 'react'; -import ReactDom from 'react-dom'; +import React, {PropTypes} from 'React'; +import Focusable from '../Focusable/Focusable'; import warning from 'warning'; export default decl({ @@ -30,18 +30,6 @@ export default decl({ this.setState(newState); }, - didMount() { - this.state.focused? - this._focus() : - this._blur(); - }, - - didUpdate() { - this.state.focused? - this._focus() : - this._blur(); - }, - mods({ disabled }) { const { focused, hovered } = this.state; return { @@ -72,8 +60,6 @@ export default decl({ res = { ...res, onClick : this._onClick, - onFocus : this._onFocus, - onBlur : this._onBlur, onMouseEnter : this._onMouseEnter, onMouseLeave : this._onMouseLeave }; @@ -84,6 +70,14 @@ export default decl({ return res; }, + render() { + return ( + + { this.__base.apply(this, arguments) } + + ); + }, + _onClick(e) { this.props.onClick(e); }, @@ -106,23 +100,13 @@ export default decl({ _onMouseLeave() { this.setState({ hovered : false }); - }, - - _focus() { - const domNode = ReactDom.findDOMNode(this); - document.activeElement !== domNode && domNode.focus(); - }, - - _blur() { - const domNode = ReactDom.findDOMNode(this); - document.activeElement === domNode && domNode.blur(); } }, { propTypes : { - disabled : React.PropTypes.bool, - focused : React.PropTypes.bool, - onClick : React.PropTypes.func, - onFocusChange : React.PropTypes.func + disabled : PropTypes.bool, + focused : PropTypes.bool, + onClick : PropTypes.func, + onFocusChange : PropTypes.func }, defaultProps : { diff --git a/blocks/Link/Link.tests/simple.js b/blocks/Link/Link.tests/simple.js index 77b2758..de088d3 100644 --- a/blocks/Link/Link.tests/simple.js +++ b/blocks/Link/Link.tests/simple.js @@ -21,9 +21,7 @@ class App extends React.Component { onClick={() => console.log('click!')} >link
- { this.setState({ linkFocused }); console.log('focusChange! ' + linkFocused); }} - onClick={() => console.log('click!')} + console.log('click!')} >link
link disabled diff --git a/blocks/TextInput/Control/TextInput-Control.js b/blocks/TextInput/Control/TextInput-Control.js index 4ce3870..a34265c 100644 --- a/blocks/TextInput/Control/TextInput-Control.js +++ b/blocks/TextInput/Control/TextInput-Control.js @@ -1,5 +1,6 @@ import {decl} from 'bem-react-core'; -import ReactDom from 'react-dom'; +import React from 'React'; +import Focusable from '../../Focusable/Focusable'; export default decl({ block : 'TextInput', @@ -12,18 +13,6 @@ export default decl({ this._onBlur = this._onBlur.bind(this); }, - didMount() { - this.props.focused? - this._focus() : - this._blur(); - }, - - didUpdate() { - this.props.focused? - this._focus() : - this._blur(); - }, - tag : 'input', attrs({ id, name, maxLength, tabIndex, placeholder, autoComplete, type, value, disabled }) { @@ -36,17 +25,23 @@ export default decl({ type, value, disabled, - onChange : this._onChange, - onBlur : this._onBlur + onChange : this._onChange }; autoComplete === false && (res.autoComplete = 'off'); - disabled || (res.onFocus = this._onFocus); - return res; }, + render() { + const { focused, onFocus, onBlur } = this.props; + return ( + + { this.__base.apply(this, arguments) } + + ); + }, + _onChange({ target }) { this.props.onChange(target.value); }, @@ -57,15 +52,5 @@ export default decl({ _onBlur() { this.props.onFocusChange(false); - }, - - _focus() { - const domNode = ReactDom.findDOMNode(this); - document.activeElement !== domNode && domNode.focus(); - }, - - _blur() { - const domNode = ReactDom.findDOMNode(this); - document.activeElement === domNode && domNode.blur(); } }); diff --git a/blocks/TextInput/TextInput.js b/blocks/TextInput/TextInput.js index 40d30b1..f996085 100644 --- a/blocks/TextInput/TextInput.js +++ b/blocks/TextInput/TextInput.js @@ -1,5 +1,5 @@ import Bem, {decl} from 'bem-react-core'; -import React from 'react'; +import React, {PropTypes} from 'React'; import warning from 'warning'; import TextInputControl from 'e:Control'; import 'e:Clear'; @@ -63,19 +63,19 @@ export default decl({ } }, { propTypes : { - id : React.PropTypes.string, - name : React.PropTypes.string, - value : React.PropTypes.any, - type : React.PropTypes.oneOf(['text', 'password', 'search']), - maxLength : React.PropTypes.number, - tabIndex : React.PropTypes.number, - placeholder : React.PropTypes.string, - autoComplete : React.PropTypes.bool, - hasClear : React.PropTypes.bool, - disabled : React.PropTypes.bool, - focused : React.PropTypes.bool, - onFocusChange : React.PropTypes.func, - onChange : React.PropTypes.func + id : PropTypes.string, + name : PropTypes.string, + value : PropTypes.any, + type : PropTypes.oneOf(['text', 'password', 'search']), + maxLength : PropTypes.number, + tabIndex : PropTypes.number, + placeholder : PropTypes.string, + autoComplete : PropTypes.bool, + hasClear : PropTypes.bool, + disabled : PropTypes.bool, + focused : PropTypes.bool, + onFocusChange : PropTypes.func, + onChange : PropTypes.func }, defaultProps : { diff --git a/package.json b/package.json index 987928d..67f531d 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "vow-fs": "^0.3.5", "webpack": "^1.13.1", "webpack-dev-server": "^1.14.1", - "webpack-bem-loader": "^0.0.1" + "webpack-bem-loader": "^0.0.2" }, "scripts": { "build": "webpack --config=webpack.config.js",