From 9534abffc86ad4dfb30755582da02e6dd69e90ea Mon Sep 17 00:00:00 2001 From: Dan Barber Date: Fri, 12 Oct 2018 14:28:44 -0400 Subject: [PATCH] Handle up/down arrow keys for selecting opponent --- assets/js/components/opponent-finder.js | 50 ++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/assets/js/components/opponent-finder.js b/assets/js/components/opponent-finder.js index 87703f0..1267e8f 100644 --- a/assets/js/components/opponent-finder.js +++ b/assets/js/components/opponent-finder.js @@ -17,11 +17,20 @@ class OpponentFinder extends React.Component { foundOpponents: [], selectedOpponent: "", selectedOpponentId: "", + focusedOpponent: null, }; + this.opponentResults = []; + this.debouncedSearch = _.debounce(this.search.bind(this), 250); } + componentDidUpdate() { + if (this.state.focusedOpponent !== null) { + this.opponentResults[this.state.focusedOpponent].focus(); + } + } + search() { if (this.state.queryString != "") { API.findOpponent(this.state.queryString) @@ -50,6 +59,37 @@ class OpponentFinder extends React.Component { } } + handleKeyPress(event) { + if (this.isKeyingDown(event)) { this.focusNextOpponent(); } + + if (this.isKeyingUp(event)) { this.focusPreviousOpponent(); } + } + + isKeyingDown(event) { + return event.key === "ArrowDown" || (event.key === "Tab" && !event.shiftKey); + } + + isKeyingUp(event) { + return event.key === "ArrowUp" || (event.key === "Tab" && event.shiftKey); + } + + focusNextOpponent() { + if (this.state.focusedOpponent === null) { + this.setState({ focusedOpponent: 0 }); + } else if (this.state.focusedOpponent < this.state.foundOpponents.length - 1) { + this.setState({ focusedOpponent: this.state.focusedOpponent + 1 }); + } + } + + focusPreviousOpponent() { + if (this.state.focusedOpponent > 0) { + this.setState({ focusedOpponent: this.state.focusedOpponent - 1 }); + } else { + this.setState({ focusedOpponent: null }); + this.queryStringInput.select(); + } + } + selectOpponent(event) { event.preventDefault(); @@ -63,15 +103,17 @@ class OpponentFinder extends React.Component { selectedOpponent, foundOpponents: [], queryString: selectedOpponent.name, + focusedOpponent: null, }); } renderOpponents() { - return _.map(this.state.foundOpponents, (opponent) => { + return _.map(this.state.foundOpponents, (opponent, index) => { return (
  • { this.opponentResults[index] = link; }} data-id={opponent.id} href="#" onClick={this.selectOpponent.bind(this)} @@ -95,10 +137,14 @@ class OpponentFinder extends React.Component { const { store, gameId } = this.props; return ( -
    +
    { this.queryStringInput = input; }} name="q" value={this.state.queryString} onChange={this.handleChange.bind(this)}