diff --git a/src/DropDownMenu/DropDownMenu.jsx b/src/DropDownMenu/DropDownMenu.jsx index d92b5bab6098d4..ecd23fc25e8b17 100644 --- a/src/DropDownMenu/DropDownMenu.jsx +++ b/src/DropDownMenu/DropDownMenu.jsx @@ -71,6 +71,11 @@ const DropDownMenu = React.createClass({ */ onChange: React.PropTypes.func, + /** + * Fired when the dropdown is closed + */ + onRequestClose: React.PropTypes.func, + /** * Set to true to have the `DropDownMenu` automatically open on mount. */ @@ -80,7 +85,10 @@ const DropDownMenu = React.createClass({ * Override the inline-styles of the root element. */ style: React.PropTypes.object, - + /** + * Used for keyboard navigation + */ + tabIndex: React.PropTypes.number, /** * Overrides the inline-styles of the underline. */ @@ -107,6 +115,7 @@ const DropDownMenu = React.createClass({ disabled: false, openImmediately: false, maxHeight: 500, + tabIndex: 0, }; }, @@ -203,21 +212,9 @@ const DropDownMenu = React.createClass({ * need it in order to work. That will be addressed later. */ getInputNode() { - const root = this.refs.root; - - root.focus = () => { - if (!this.props.disabled) { - this.setState({ - open: !this.state.open, - anchorEl: this.refs.root, - }); - } - }; - - return root; + return this.refs.root; }, - _setWidth() { const el = this.refs.root; if (!this.props.style || !this.props.style.hasOwnProperty('width')) { @@ -235,19 +232,38 @@ const DropDownMenu = React.createClass({ } }, + handleKeyDown(event) { + switch (event.keyCode) { + case 13: + case 32: + case 40: + event.preventDefault(); + if (!this.props.disabled) { + this.setState({ + open: !this.state.open, + anchorEl: this.refs.root, + }); + } + } + }, + _onMenuItemTouchTap(key, payload, event) { this.props.onChange(event, key, payload); this.setState({ open: false, - }); + }, this.handleRequestCloseMenu); }, handleRequestCloseMenu() { + const {onRequestClose} = this.props; + const onRequestCloseCallback = (!onRequestClose ? null : + () => onRequestClose('menuClosed')); + this.setState({ open: false, anchorEl: null, - }); + }, onRequestCloseCallback); }, render() { @@ -255,6 +271,7 @@ const DropDownMenu = React.createClass({ autoWidth, children, className, + disabled, iconStyle, labelStyle, listStyle, @@ -277,6 +294,7 @@ const DropDownMenu = React.createClass({ } = muiTheme; const styles = this.getStyles(); + const tabIndex = disabled ? -1 : this.props.tabIndex; let displayValue = ''; React.Children.forEach(children, (child) => { @@ -286,11 +304,11 @@ const DropDownMenu = React.createClass({ } }); - const menuItemElements = React.Children.map(children, (child, index) => { + const menuItemElements = (open ? React.Children.map(children, (child, index) => { return React.cloneElement(child, { onTouchTap: this._onMenuItemTouchTap.bind(this, index, child.props.value), }); - }); + }) : null); let popoverStyle; if (anchorEl && !autoWidth) { @@ -302,6 +320,9 @@ const DropDownMenu = React.createClass({ {...other} ref="root" className={className} + disabled={disabled} + onKeyDown={this.handleKeyDown} + tabIndex={tabIndex} style={prepareStyles(Object.assign({}, styles.root, open && styles.rootWhenOpen, style))} > diff --git a/src/SelectField/SelectField.jsx b/src/SelectField/SelectField.jsx index 7933ca82581ed7..e14441742809a9 100644 --- a/src/SelectField/SelectField.jsx +++ b/src/SelectField/SelectField.jsx @@ -167,6 +167,11 @@ const SelectField = React.createClass({ }); }, + handleRequestClose() { + const el = this.refs.field._getInputNode(); + el.focus(); + }, + render() { const { autoWidth, @@ -198,6 +203,7 @@ const SelectField = React.createClass({ return ( diff --git a/src/date-picker/date-picker-inline.jsx b/src/date-picker/date-picker-inline.jsx index 898a229e727689..2282f9d793ec20 100644 --- a/src/date-picker/date-picker-inline.jsx +++ b/src/date-picker/date-picker-inline.jsx @@ -29,7 +29,7 @@ class DatePickerInline extends React.Component { state = { anchorEl: null, - } + }; componentWillReceiveProps(nextProps) { if (nextProps.open) {