From 73066ab4e4587e2b99a17624d274f6ad6732b913 Mon Sep 17 00:00:00 2001 From: Bart Peeters Date: Sun, 7 Jan 2018 15:21:37 +0100 Subject: [PATCH] add back focus test. Another solution to fixing firefox bug using the onFocus of the overlay to always make the DaypickerInput focused, but do we wanth this? --- src/DayPickerInput.js | 64 ++++++++++++++++------------------- test/daypickerinput/events.js | 13 +++++++ 2 files changed, 43 insertions(+), 34 deletions(-) diff --git a/src/DayPickerInput.js b/src/DayPickerInput.js index 9d48fe6747..3f6dff621d 100644 --- a/src/DayPickerInput.js +++ b/src/DayPickerInput.js @@ -114,7 +114,6 @@ export default class DayPickerInput extends React.Component { this.state.showOverlay = props.showOverlay; this.hideAfterDayClick = this.hideAfterDayClick.bind(this); - this.handleContainerMouseDown = this.handleContainerMouseDown.bind(this); this.handleInputClick = this.handleInputClick.bind(this); this.handleInputFocus = this.handleInputFocus.bind(this); this.handleInputBlur = this.handleInputBlur.bind(this); @@ -123,6 +122,7 @@ export default class DayPickerInput extends React.Component { this.handleInputKeyUp = this.handleInputKeyUp.bind(this); this.handleDayClick = this.handleDayClick.bind(this); this.handleMonthChange = this.handleMonthChange.bind(this); + this.handleOverlayFocus = this.handleOverlayFocus.bind(this); } componentWillReceiveProps(nextProps) { @@ -203,7 +203,7 @@ export default class DayPickerInput extends React.Component { input = null; daypicker = null; - clickedInside = false; + overlayNode = null; clickTimeout = null; hideTimeout = null; @@ -265,15 +265,6 @@ export default class DayPickerInput extends React.Component { this.hideTimeout = setTimeout(() => this.hideDayPicker(), HIDE_TIMEOUT); } - handleContainerMouseDown() { - this.clickedInside = true; - // The input's onBlur method is called from a queue right after the onMouseDown event. - // setTimeout adds another callback in the queue, which is called after the onBlur event. - this.clickTimeout = setTimeout(() => { - this.clickedInside = false; - }, 0); - } - handleInputClick(e) { this.showDayPicker(); if (this.props.inputProps.onClick) { @@ -291,19 +282,23 @@ export default class DayPickerInput extends React.Component { } handleInputBlur(e) { - if (this.clickedInside) { - this.showDayPicker(); - // Force input's focus if blur event was caused by clicking inside the overlay - this.blurTimeout = setTimeout(() => this.input.focus(), 0); - } else { - this.hideDayPicker(); - } + this.setState({ + showOverlay: this.overlayNode && this.overlayNode.contains(e.relatedTarget), + }); if (this.props.inputProps.onBlur) { e.persist(); this.props.inputProps.onBlur(e); } } + handleOverlayFocus(e) { + // do we want to always keep the input focused when clicking inside the overlay? + // what if we have a custom overlay that contains an input? this is now unusable... + // console.log(e.target.getAttribute('tabindex'), e.target.nodeName); + e.preventDefault(); + this.input.focus(); + } + handleInputChange(e) { const { dayPickerProps, @@ -438,22 +433,24 @@ export default class DayPickerInput extends React.Component { } const Overlay = this.props.overlayComponent; return ( - - (this.daypicker = el)} - onTodayButtonClick={onTodayButtonClick} - {...dayPickerProps} + this.overlayNode = el}> + - + selectedDay={selectedDay} + input={this.input} + > + (this.daypicker = el)} + onTodayButtonClick={onTodayButtonClick} + {...dayPickerProps} + month={this.state.month} + selectedDays={selectedDay} + onDayClick={this.handleDayClick} + onMonthChange={this.handleMonthChange} + /> + + ); } @@ -462,7 +459,6 @@ export default class DayPickerInput extends React.Component { return (
(this.input = el)} diff --git a/test/daypickerinput/events.js b/test/daypickerinput/events.js index cec55f8de1..7c3728adb7 100644 --- a/test/daypickerinput/events.js +++ b/test/daypickerinput/events.js @@ -52,6 +52,19 @@ describe('DayPickerInput', () => { wrapper.find('input').simulate('blur'); expect(onBlur).toHaveBeenCalledTimes(1); }); + + it('should focus the input if blur after clicking the overlay', done => { + const wrapper = mount(); + wrapper.find('.DayPickerInput').simulate('mousedown'); + const instance = wrapper.instance(); + expect(instance.clickedInside).toBe(true); + expect(instance.clickTimeout).not.toBeNull(); + wrapper.find('input').simulate('blur'); + setTimeout(() => { + expect(document.activeElement).toEqual(instance.input); + done(); + }, 1); + }); }); describe('change', () => {