diff --git a/src/components/DateInput.vue b/src/components/DateInput.vue index a150102e..8803b493 100644 --- a/src/components/DateInput.vue +++ b/src/components/DateInput.vue @@ -92,6 +92,8 @@ export default { const constructedDateUtils = makeDateUtils(this.useUtc) return { input: null, + isFocusedUsed: false, + isBlurred: false, typedDate: '', utils: constructedDateUtils, } @@ -141,23 +143,16 @@ export default { this.$emit('clear-date') }, /** - * Submits a typed date if it's valid + * submit typedDate and emit a blur event */ inputBlurred() { + this.isBlurred = this.isOpen if (this.typeable) { - const parsableDate = this.parseDate(this.input.value) - const parsedDate = Date.parse(parsableDate) - - if (Number.isNaN(parsedDate)) { - this.clearDate() - } else { - this.input.value = this.formattedDate - this.typedDate = '' - this.$emit('typed-date', parsedDate) - } + this.submitTypedDate() } this.$emit('blur') this.$emit('close-calendar') + this.isFocusedUsed = false }, /** * Attempt to parse a typed date @@ -191,21 +186,47 @@ export default { this.parser, ) }, - toggleCalendar() { - this.$emit(this.isOpen ? 'close-calendar' : 'show-calendar') - }, showCalendarByClick() { - if (!this.showCalendarOnButtonClick) { + const isFocusedUsed = this.showCalendarOnFocus && !this.isFocusedUsed + + if (!this.showCalendarOnButtonClick && !isFocusedUsed) { this.toggleCalendar() } + + if (this.showCalendarOnFocus) { + this.isFocusedUsed = true + } }, showCalendarByFocus() { if (this.showCalendarOnFocus) { this.$emit('show-calendar') } + this.isBlurred = false this.$emit('focus') }, + /** + * Submits a typed date if it's valid + */ + submitTypedDate() { + const parsableDate = this.parseDate(this.input.value) + const parsedDate = Date.parse(parsableDate) + + if (Number.isNaN(parsedDate)) { + this.clearDate() + } else { + this.input.value = this.formattedDate + this.typedDate = '' + this.$emit('typed-date', parsedDate) + } + }, + toggleCalendar() { + if (!this.isOpen && this.isBlurred) { + this.isBlurred = false + return + } + this.$emit(this.isOpen ? 'close-calendar' : 'show-calendar') + }, }, } diff --git a/test/unit/specs/DateInput/DateInput.spec.js b/test/unit/specs/DateInput/DateInput.spec.js index 1ed586a1..f40c6c74 100755 --- a/test/unit/specs/DateInput/DateInput.spec.js +++ b/test/unit/specs/DateInput/DateInput.spec.js @@ -11,15 +11,17 @@ describe('DateInput unmounted', () => { describe('DateInput', () => { let wrapper - - beforeEach(() => { - wrapper = shallowMount(DateInput, { + const createWrapper = () => { + return shallowMount(DateInput, { propsData: { selectedDate: new Date(2018, 2, 24), format: 'dd MMM yyyy', translation: en, }, }) + } + beforeEach(() => { + wrapper = createWrapper() }) afterEach(() => { @@ -120,6 +122,12 @@ describe('DateInput', () => { expect(wrapper.emitted('close-calendar')).toBeTruthy() }) + it('should open the calendar on click', async () => { + wrapper.find('input').trigger('click') + await wrapper.vm.$nextTick() + expect(wrapper.emitted('show-calendar')).toBeTruthy() + }) + it('should open the calendar on focus', async () => { wrapper.find('input').trigger('focus') expect(wrapper.emitted('show-calendar')).toBeFalsy() diff --git a/test/unit/specs/Datepicker/Datepicker.spec.js b/test/unit/specs/Datepicker/Datepicker.spec.js index 33aba497..54a509c5 100755 --- a/test/unit/specs/Datepicker/Datepicker.spec.js +++ b/test/unit/specs/Datepicker/Datepicker.spec.js @@ -50,6 +50,64 @@ describe('Datepicker mounted', () => { input.trigger('focus') expect(wrapper.emitted().focus).toBeTruthy() }) + + it('should open the calendar with click on input when showCalendarOnFocus = true', async () => { + await wrapper.setProps({ + showCalendarOnFocus: true, + }) + const input = wrapper.find('input') + + await input.trigger('focus') + await input.trigger('click') + await wrapper.vm.$nextTick() + expect(wrapper.vm.isOpen).toBeTruthy() + }) + + it('should toggle the calendar via the calendar button', async () => { + await wrapper.setProps({ + calendarButton: true, + }) + + const calendarButton = wrapper.find('span.vdp-datepicker__calendar-button') + + await calendarButton.trigger('click') + expect(wrapper.vm.isOpen).toBeTruthy() + + await calendarButton.trigger('click') + expect(wrapper.vm.isOpen).toBeFalsy() + }) + + it('should toggle the calendar via the calendar button when showCalendarOnFocus = true', async () => { + await wrapper.setProps({ + calendarButton: true, + showCalendarOnFocus: true, + }) + + const calendarButton = wrapper.find('span.vdp-datepicker__calendar-button') + + await calendarButton.trigger('click') + expect(wrapper.vm.isOpen).toBeTruthy() + + await calendarButton.trigger('click') + expect(wrapper.vm.isOpen).toBeFalsy() + }) + + it('should close the calendar via the calendar button, despite input being focused', async () => { + await wrapper.setProps({ + calendarButton: true, + showCalendarOnFocus: true, + }) + + const input = wrapper.find('input') + const calendarButton = wrapper.find('span.vdp-datepicker__calendar-button') + + await input.trigger('focus') + expect(wrapper.vm.isOpen).toBeTruthy() + + await input.trigger('blur') + await calendarButton.trigger('click') + expect(wrapper.vm.isOpen).toBeFalsy() + }) }) describe('Datepicker shallowMounted', () => {