Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SelectField] Keyboard navigation support #3583

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 39 additions & 18 deletions src/DropDownMenu/DropDownMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand All @@ -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.
*/
Expand All @@ -107,6 +115,7 @@ const DropDownMenu = React.createClass({
disabled: false,
openImmediately: false,
maxHeight: 500,
tabIndex: 0,
};
},

Expand Down Expand Up @@ -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')) {
Expand All @@ -235,26 +232,46 @@ const DropDownMenu = React.createClass({
}
},

handleKeyDown(event) {
switch (event.keyCode) {
case 13:
case 32:
case 40:
event.preventDefault();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use keycode here? (https://github.com/timoxley/keycode)

It was added to other components recently.

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() {
const {
autoWidth,
children,
className,
disabled,
iconStyle,
labelStyle,
listStyle,
Expand All @@ -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) => {
Expand All @@ -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) {
Expand All @@ -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))}
>
<ClearFix style={styles.control} onTouchTap={this.handleTouchTapControl}>
Expand Down
7 changes: 7 additions & 0 deletions src/SelectField/SelectField.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,11 @@ const SelectField = React.createClass({
});
},

handleRequestClose() {
const el = this.refs.field._getInputNode();
el.focus();
},

render() {
const {
autoWidth,
Expand Down Expand Up @@ -198,6 +203,7 @@ const SelectField = React.createClass({
return (
<TextField
style={style}
ref="field"
floatingLabelText={floatingLabelText}
floatingLabelStyle={floatingLabelStyle}
hintStyle={hintStyle}
Expand All @@ -219,6 +225,7 @@ const SelectField = React.createClass({
underlineStyle={styles.hideDropDownUnderline}
autoWidth={autoWidth}
value={value}
onRequestClose={this.handleRequestClose}
onChange={onChange}
{...other}
>
Expand Down
2 changes: 1 addition & 1 deletion src/date-picker/date-picker-inline.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class DatePickerInline extends React.Component {

state = {
anchorEl: null,
}
};

componentWillReceiveProps(nextProps) {
if (nextProps.open) {
Expand Down