Skip to content

Commit

Permalink
Added ability to navigate calendar with keyboard
Browse files Browse the repository at this point in the history
  • Loading branch information
ro-savage committed Aug 11, 2016
1 parent f518bc0 commit ad2a8e8
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 4 deletions.
29 changes: 29 additions & 0 deletions components/date_picker/Calendar.js
Expand Up @@ -11,6 +11,7 @@ const factory = (IconButton) => {
class Calendar extends Component {
static propTypes = {
display: PropTypes.oneOf(['months', 'years']),
handleSelect: PropTypes.func,
locale: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.object
Expand Down Expand Up @@ -39,12 +40,20 @@ const factory = (IconButton) => {
viewDate: this.props.selectedDate
};

componentWillMount () {
document.body.addEventListener('keydown', this.handleKeys);
}

componentDidUpdate () {
if (this.refs.activeYear) {
this.scrollToActive();
}
}

componentWillUnmount () {
document.body.removeEventListener('keydown', this.handleKeys);
}

scrollToActive () {
this.refs.years.scrollTop = this.refs.activeYear.offsetTop
- this.refs.years.offsetHeight / 2
Expand All @@ -62,6 +71,26 @@ const factory = (IconButton) => {
this.props.onChange(viewDate, false);
};

handleKeys = (e) => {
const { selectedDate } = this.props;

if (e.which === 37 || e.which === 38 || e.which === 39 || e.which === 40 || e.which === 13) e.preventDefault();

switch (e.which) {
case 13: this.props.handleSelect(); break; // enter
case 37: this.handleDayArrowKey(time.addDays(selectedDate, -1)); break; // left
case 38: this.handleDayArrowKey(time.addDays(selectedDate, -7)); break; // up
case 39: this.handleDayArrowKey(time.addDays(selectedDate, 1)); break; // right
case 40: this.handleDayArrowKey(time.addDays(selectedDate, 7)); break; // down
default: break;
}
}

handleDayArrowKey = (date) => {
this.setState({ viewDate: date });
this.props.onChange(date, false);
}

changeViewMonth = (event) => {
const direction = event.target.id;
this.setState({
Expand Down
4 changes: 2 additions & 2 deletions components/date_picker/DatePicker.js
Expand Up @@ -130,8 +130,8 @@ const factory = (Input, DatePickerDialog) => {
minDate={minDate}
name={this.props.name}
onDismiss={this.handleDismiss}
onEscKeyDown={onEscKeyDown}
onOverlayClick={onOverlayClick}
onEscKeyDown={onEscKeyDown || this.handleDismiss}
onOverlayClick={onOverlayClick || this.handleDismiss}
onSelect={this.handleSelect}
sundayFirstDayOfWeek={sundayFirstDayOfWeek}
theme={this.props.theme}
Expand Down
1 change: 1 addition & 0 deletions components/date_picker/DatePickerDialog.js
Expand Up @@ -116,6 +116,7 @@ const factory = (Dialog, Calendar) => {
<div className={theme.calendarWrapper}>
<Calendar
display={this.state.display}
handleSelect={this.handleSelect}
maxDate={this.props.maxDate}
minDate={this.props.minDate}
onChange={this.handleNewDate}
Expand Down
34 changes: 34 additions & 0 deletions lib/date_picker/Calendar.js
Expand Up @@ -62,6 +62,29 @@ var factory = function factory(IconButton) {
var viewDate = _time2.default.setYear(_this.props.selectedDate, year);
_this.setState({ viewDate: viewDate });
_this.props.onChange(viewDate, false);
}, _this.handleKeys = function (e) {
var selectedDate = _this.props.selectedDate;


if (e.which === 37 || e.which === 38 || e.which === 39 || e.which === 40 || e.which === 13) e.preventDefault();

switch (e.which) {
case 13:
_this.props.handleSelect();break; // enter
case 37:
_this.handleDayArrowKey(_time2.default.addDays(selectedDate, -1));break; // left
case 38:
_this.handleDayArrowKey(_time2.default.addDays(selectedDate, -7));break; // up
case 39:
_this.handleDayArrowKey(_time2.default.addDays(selectedDate, 1));break; // right
case 40:
_this.handleDayArrowKey(_time2.default.addDays(selectedDate, 7));break; // down
default:
break;
}
}, _this.handleDayArrowKey = function (date) {
_this.setState({ viewDate: date });
_this.props.onChange(date, false);
}, _this.changeViewMonth = function (event) {
var direction = event.target.id;
_this.setState({
Expand All @@ -72,12 +95,22 @@ var factory = function factory(IconButton) {
}

_createClass(Calendar, [{
key: 'componentWillMount',
value: function componentWillMount() {
document.body.addEventListener('keydown', this.handleKeys);
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate() {
if (this.refs.activeYear) {
this.scrollToActive();
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
document.body.removeEventListener('keydown', this.handleKeys);
}
}, {
key: 'scrollToActive',
value: function scrollToActive() {
Expand Down Expand Up @@ -147,6 +180,7 @@ var factory = function factory(IconButton) {

Calendar.propTypes = {
display: _react.PropTypes.oneOf(['months', 'years']),
handleSelect: _react.PropTypes.func,
locale: _react2.default.PropTypes.oneOfType([_react2.default.PropTypes.string, _react2.default.PropTypes.object]),
maxDate: _react.PropTypes.object,
minDate: _react.PropTypes.object,
Expand Down
4 changes: 2 additions & 2 deletions lib/date_picker/DatePicker.js
Expand Up @@ -157,8 +157,8 @@ var factory = function factory(Input, DatePickerDialog) {
minDate: minDate,
name: this.props.name,
onDismiss: this.handleDismiss,
onEscKeyDown: onEscKeyDown,
onOverlayClick: onOverlayClick,
onEscKeyDown: onEscKeyDown || this.handleDismiss,
onOverlayClick: onOverlayClick || this.handleDismiss,
onSelect: this.handleSelect,
sundayFirstDayOfWeek: sundayFirstDayOfWeek,
theme: this.props.theme,
Expand Down
1 change: 1 addition & 0 deletions lib/date_picker/DatePickerDialog.js
Expand Up @@ -123,6 +123,7 @@ var factory = function factory(Dialog, Calendar) {
{ className: theme.calendarWrapper },
_react2.default.createElement(Calendar, {
display: this.state.display,
handleSelect: this.handleSelect,
maxDate: this.props.maxDate,
minDate: this.props.minDate,
onChange: this.handleNewDate,
Expand Down

0 comments on commit ad2a8e8

Please sign in to comment.