diff options
author | Noah Loomans <noahloomans@gmail.com> | 2017-12-13 15:53:19 +0100 |
---|---|---|
committer | Noah Loomans <noahloomans@gmail.com> | 2017-12-13 15:53:19 +0100 |
commit | 503ab5c66ab524dfe36aed84a01899cd07ed2bc5 (patch) | |
tree | 68f3461d561ddc6a8e83898916aba06c193e6ffa /src/client/react/components | |
parent | fe27a0819a60caaa69b059f0c86d95ab0c4084b7 (diff) |
Allow selection of result using keyboard
Diffstat (limited to 'src/client/react/components')
-rw-r--r-- | src/client/react/components/container/Results.jsx | 15 | ||||
-rw-r--r-- | src/client/react/components/container/Search.jsx | 20 | ||||
-rw-r--r-- | src/client/react/components/presentational/Result.jsx | 10 |
3 files changed, 39 insertions, 6 deletions
diff --git a/src/client/react/components/container/Results.jsx b/src/client/react/components/container/Results.jsx index 1c38c8b..9be2639 100644 --- a/src/client/react/components/container/Results.jsx +++ b/src/client/react/components/container/Results.jsx @@ -4,14 +4,14 @@ import { connect } from 'react-redux'; import classnames from 'classnames'; import Result from '../presentational/Result'; -const Results = (({ results }) => ( +const Results = (({ results, selectedResult }) => ( <div className={classnames('search__results', { 'search__results--has-results': results.length > 0, })} > {results.map(user => ( - <Result key={user.value} user={user} /> + <Result key={user.value} user={user} selected={user === selectedResult} /> ))} </div> )); @@ -19,12 +19,21 @@ const Results = (({ results }) => ( Results.propTypes = { results: PropTypes.arrayOf(PropTypes.shape({ type: PropTypes.string, - value: PropTypes.value, + value: PropTypes.string, })).isRequired, + selectedResult: PropTypes.shape({ + type: PropTypes.string, + value: PropTypes.string, + }), +}; + +Results.defaultProps = { + selectedResult: null, }; const mapStateToProps = state => ({ results: state.search.results, + selectedResult: state.search.selectedResult, }); export default connect(mapStateToProps)(Results); diff --git a/src/client/react/components/container/Search.jsx b/src/client/react/components/container/Search.jsx index 7e33e84..50917dd 100644 --- a/src/client/react/components/container/Search.jsx +++ b/src/client/react/components/container/Search.jsx @@ -5,7 +5,7 @@ import classnames from 'classnames'; import SearchIcon from 'react-icons/lib/md/search'; -import { inputChange } from '../../actions/search'; +import { inputChange, changeSelectedResult } from '../../actions/search'; import Results from './Results'; import IconFromUserType from '../presentational/IconFromUserType'; @@ -25,6 +25,7 @@ class Search extends React.Component { this.onFocus = this.onFocus.bind(this); this.onBlur = this.onBlur.bind(this); + this.onKeyDown = this.onKeyDown.bind(this); } onFocus() { @@ -39,6 +40,22 @@ class Search extends React.Component { }); } + onKeyDown(event) { + if (event.key === 'ArrowUp' || event.key === 'ArrowDown') { + event.preventDefault(); + switch (event.key) { + case 'ArrowUp': + this.props.dispatch(changeSelectedResult(-1)); + break; + case 'ArrowDown': + this.props.dispatch(changeSelectedResult(+1)); + break; + default: + throw new Error('This should never happen... pls?'); + } + } + } + render() { const { value, @@ -63,6 +80,7 @@ class Search extends React.Component { <input id="search__input" onChange={event => dispatch(inputChange(event.target.value))} + onKeyDown={this.onKeyDown} value={value} placeholder="Zoeken" onFocus={this.onFocus} diff --git a/src/client/react/components/presentational/Result.jsx b/src/client/react/components/presentational/Result.jsx index a4a0b8e..80f65d4 100644 --- a/src/client/react/components/presentational/Result.jsx +++ b/src/client/react/components/presentational/Result.jsx @@ -1,10 +1,15 @@ import React from 'react'; import PropTypes from 'prop-types'; +import classnames from 'classnames'; import IconFromUserType from './IconFromUserType'; -const Result = ({ user }) => ( - <div className="search__result"> +const Result = ({ user, selected }) => ( + <div + className={classnames('search__result', { + 'search__result--selected': selected, + })} + > <div className="search__icon-wrapper"><IconFromUserType userType={user.type} /></div> <div className="search__result__text">{user.value}</div> </div> @@ -15,6 +20,7 @@ Result.propTypes = { value: PropTypes.string.isRequired, type: PropTypes.string.isRequired, }).isRequired, + selected: PropTypes.bool.isRequired, }; export default Result; |