Skip to content

Commit

Permalink
Fix tabbing behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
ericgio committed May 20, 2016
1 parent a3199cf commit 8650f16
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 20 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-typeahead",
"version": "0.4.0",
"version": "0.4.1",
"description": "React-based typeahead using the Bootstrap theme",
"main": "lib/index.js",
"directories": {
Expand Down
19 changes: 10 additions & 9 deletions src/TokenizerInput.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Token from './Token.react';

import cx from 'classnames';
import {findDOMNode} from 'react-dom';
import keyCode from './keyCode';
import {BACKSPACE, LEFT, RIGHT} from './keyCode';

/**
* TokenizerInput
Expand Down Expand Up @@ -40,14 +40,14 @@ const TokenizerInput = React.createClass({
<div
className={cx(
'bootstrap-tokenizer',
'form-control',
'clearfix',
'form-control',
{'focus': this.state.focused}
)}
disabled={disabled}
onClick={this._handleInputFocus}
onFocus={this._handleInputFocus}
tabIndex={disabled ? -1 : 0}>
tabIndex={-1}>
{selected.map(this._renderToken)}
<AutosizeInput
{...this.props}
Expand Down Expand Up @@ -86,16 +86,12 @@ const TokenizerInput = React.createClass({

_handleBlur(e) {
this.setState({focused: false});
this.props.onBlur();
},

_handleKeydown(e) {
switch (e.keyCode) {
case keyCode.LEFT:
case keyCode.RIGHT:
// TODO: Tab forward and backward through tokens when user clicks left
// or right arrow keys.
break;
case keyCode.BACKSPACE:
case BACKSPACE:
let inputNode = findDOMNode(this.refs.input);
if (
inputNode &&
Expand All @@ -108,6 +104,11 @@ const TokenizerInput = React.createClass({
sibling && sibling.focus();
}
break;
case LEFT:
case RIGHT:
// TODO: Tab forward and backward through tokens when user clicks left
// or right arrow keys.
break;
}

this.props.onKeyDown && this.props.onKeyDown(e);
Expand Down
11 changes: 7 additions & 4 deletions src/Typeahead.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import TypeaheadInput from './TypeaheadInput.react';
import TypeaheadMenu from './TypeaheadMenu.react';

import {find, head, isEmpty, isEqual, uniqueId} from 'lodash';
import {BACKSPACE, DOWN, ESC, RETURN, TAB, UP} from './keyCode';
import {BACKSPACE, DOWN, ESC, RETURN, UP} from './keyCode';
import listensToClickOutside from 'react-onclickoutside/decorator';

require('../css/Typeahead.css');
Expand Down Expand Up @@ -199,6 +199,7 @@ const Typeahead = React.createClass({
filteredOptions={filteredOptions}
labelKey={labelKey}
onAdd={this._handleAddOption}
onBlur={this._handleBlur}
onChange={this._handleTextChange}
onFocus={this._handleFocus}
onKeyDown={this._handleKeydown.bind(null, filteredOptions)}
Expand All @@ -212,6 +213,10 @@ const Typeahead = React.createClass({
);
},

_handleBlur() {
this._hideDropdown();
},

_handleFocus() {
this.setState({showMenu: true});
},
Expand All @@ -237,13 +242,11 @@ const Typeahead = React.createClass({
break;
case UP:
case DOWN:
case TAB:
// Prevent page from scrolling.
e.preventDefault();

// Increment or decrement index based on user keystroke.
activeIndex +=
e.keyCode === UP || (e.keyCode === TAB && e.shiftKey) ? -1 : 1;
activeIndex += e.keyCode === UP ? -1 : 1;

// If we've reached the end, go back to the beginning or vice-versa.
activeIndex = (activeIndex + options.length) % options.length;
Expand Down
18 changes: 12 additions & 6 deletions src/TypeaheadInput.react.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import React, {PropTypes} from 'react';

import cx from 'classnames';
import {head} from 'lodash';
import keyCode from './keyCode';
import {BACKSPACE, ESC, RIGHT, TAB} from './keyCode';
import listensToClickOutside from 'react-onclickoutside/decorator';

/**
Expand All @@ -30,13 +30,13 @@ const TypeaheadInput = React.createClass({
className={cx('bootstrap-typeahead-input', this.props.className)}
onClick={this._handleInputFocus}
onFocus={this._handleInputFocus}
style={{outline: 'none'}}
tabIndex={0}>
style={{outline: 'none'}}>
<input
{...this.props}
className={cx('bootstrap-typeahead-input-main', 'form-control', {
'has-selection': !this.props.selected,
})}
onBlur={this._handleBlur}
onKeyDown={this._handleKeydown}
ref="input"
style={{
Expand All @@ -60,6 +60,7 @@ const TypeaheadInput = React.createClass({
width: '100%',
zIndex: 0,
}}
tabIndex={-1}
value={this._getHintText()}
/>
</div>
Expand Down Expand Up @@ -89,6 +90,10 @@ const TypeaheadInput = React.createClass({
}
},

_handleBlur(e) {
this.props.onBlur();
},

/**
* If the containing parent div is focused or clicked, focus the input.
*/
Expand All @@ -100,16 +105,17 @@ const TypeaheadInput = React.createClass({
const {filteredOptions, onAdd, onRemove, selected} = this.props;

switch (e.keyCode) {
case keyCode.ESC:
case ESC:
case TAB:
this.refs.input.blur();
break;
case keyCode.RIGHT:
case RIGHT:
// Autocomplete the selection if there's a hint and no selection yet.
if (this._getHintText() && !selected) {
onAdd && onAdd(head(filteredOptions));
}
break;
case keyCode.BACKSPACE:
case BACKSPACE:
// Remove the selection if we start deleting it.
selected && onRemove && onRemove(selected);
break;
Expand Down

0 comments on commit 8650f16

Please sign in to comment.