Skip to content

Commit

Permalink
fix(DatePicker): improve keyboard navigation (#4101)
Browse files Browse the repository at this point in the history
This change works around two problems in Flatpickr's range plugin,
where:

* Entering start date, entering end date, and then hitting enter yields
  wrong date (flatpickr/flatpickr#1942)
* Left/right arrow keys while entering end date does not work
  (flatpickr/flatpickr#1943)

Note: The default date format of Carbon `<DatePicker>` (`01/01/1970`
for English) is different from Flatpickr's default one (`1970-01-01`).
That said, to test if flatpickr/flatpickr#1942 is fixed, Carbon's date
format should be used.
  • Loading branch information
asudoh authored and dakahn committed Sep 27, 2019
1 parent d9e0987 commit 40da1fa
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
5 changes: 5 additions & 0 deletions packages/react/src/components/DatePicker/DatePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import l10n from 'flatpickr/dist/l10n/index';
import rangePlugin from 'flatpickr/dist/plugins/rangePlugin';
import { settings } from 'carbon-components';
import DatePickerInput from '../DatePickerInput';
import carbonFlatpickrFixEventsPlugin from './plugins/fixEventsPlugin';
import { match, keys } from '../../internal/keyboard';

const { prefix } = settings;
Expand Down Expand Up @@ -356,6 +357,10 @@ export default class DatePicker extends Component {
selectorFlatpickrCurrentMonth: '.cur-month',
classFlatpickrCurrentMonth: 'cur-month',
}),
carbonFlatpickrFixEventsPlugin({
inputFrom: this.inputField,
inputTo: this.toInputField,
}),
],
clickOpens: true,
nextArrow: this.rightArrowHTML(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* Copyright IBM Corp. 2016, 2018
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/

import { match, keys } from '../../../internal/keyboard';

/**
* @param {object} config Plugin configuration.
* @returns {Plugin} A Flatpickr plugin to fix Flatpickr's behavior of certain events.
*/
export default config => fp => {
/**
* Handles `keydown` event.
*/
const handleKeydown = event => {
const { inputFrom, inputTo } = config;
const { target } = event;
if (inputFrom === target || inputTo === target) {
if (match(event, keys.Enter)) {
// Makes sure the hitting enter key picks up pending values of both `<input>`
// Workaround for: https://github.com/flatpickr/flatpickr/issues/1942
fp.setDate(
[inputFrom.value, inputTo && inputTo.value],
true,
fp.config.dateFormat
);
event.stopPropagation();
} else if (
match(event, keys.ArrowLeft) ||
match(event, keys.ArrowRight)
) {
// Prevents Flatpickr code from canceling the event if left/right arrow keys are hit on `<input>`,
// so user can move the keyboard cursor for editing dates
// Workaround for: https://github.com/flatpickr/flatpickr/issues/1943
event.stopPropagation();
}
}
};

/**
* Releases event listeners used in this Flatpickr plugin.
*/
const release = () => {
const { inputFrom, inputTo } = config;
if (inputTo) {
inputTo.removeEventListener('keydown', handleKeydown, true);
}
inputFrom.removeEventListener('keydown', handleKeydown, true);
};

/**
* Sets up event listeners used for this Flatpickr plugin.
*/
const init = () => {
release();
const { inputFrom, inputTo } = config;
inputFrom.addEventListener('keydown', handleKeydown, true);
if (inputTo) {
inputTo.addEventListener('keydown', handleKeydown, true);
}
};

/**
* Registers this Flatpickr plugin.
*/
const register = () => {
fp.loadedPlugins.push('carbonFlatpickrFixEventsPlugin');
};

return {
onReady: [register, init],
onDestroy: [release],
};
};

0 comments on commit 40da1fa

Please sign in to comment.