From 2d40cac61c6c8582bf46a1396ca759c0e57d3882 Mon Sep 17 00:00:00 2001 From: MrWook Date: Tue, 2 Feb 2021 08:09:36 +0100 Subject: [PATCH 1/2] fix(input): resolve flicker on showCalendarByFocus --- src/components/DateInput.vue | 39 +++++++++++++------ test/unit/specs/DateInput/DateInput.spec.js | 14 +++++-- test/unit/specs/Datepicker/Datepicker.spec.js | 14 +++++++ 3 files changed, 52 insertions(+), 15 deletions(-) diff --git a/src/components/DateInput.vue b/src/components/DateInput.vue index a150102e..f78efc7e 100644 --- a/src/components/DateInput.vue +++ b/src/components/DateInput.vue @@ -92,6 +92,7 @@ export default { const constructedDateUtils = makeDateUtils(this.useUtc) return { input: null, + isFocusedUsed: false, typedDate: '', utils: constructedDateUtils, } @@ -141,23 +142,15 @@ export default { this.$emit('clear-date') }, /** - * Submits a typed date if it's valid + * submit typedDate and emit a blur event */ inputBlurred() { 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 @@ -195,9 +188,16 @@ export default { this.$emit(this.isOpen ? 'close-calendar' : 'show-calendar') }, showCalendarByClick() { - if (!this.showCalendarOnButtonClick) { + const isFocusedUsed = + !this.showCalendarOnFocus || + (this.showCalendarOnFocus && !this.isFocusedUsed) + if (!this.showCalendarOnButtonClick && !isFocusedUsed) { this.toggleCalendar() } + + if (this.showCalendarOnFocus) { + this.isFocusedUsed = true + } }, showCalendarByFocus() { if (this.showCalendarOnFocus) { @@ -206,6 +206,21 @@ export default { 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) + } + }, }, } 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..06706b00 100755 --- a/test/unit/specs/Datepicker/Datepicker.spec.js +++ b/test/unit/specs/Datepicker/Datepicker.spec.js @@ -50,6 +50,20 @@ describe('Datepicker mounted', () => { input.trigger('focus') expect(wrapper.emitted().focus).toBeTruthy() }) + + it('should open the calendar with click on input with showCalendarOnFocus', async () => { + wrapper.setProps({ + showCalendarOnFocus: true, + }) + await wrapper.vm.$nextTick() + wrapper.find('input').trigger('focus') + await wrapper.vm.$nextTick() + wrapper.find('input').trigger('click') + await wrapper.vm.$nextTick() + wrapper.find('input').trigger('FUCK') + expect(wrapper.emitted('opened')).toBeTruthy() + expect(wrapper.emitted('closed')).toBeFalsy() + }) }) describe('Datepicker shallowMounted', () => { From be4cfe015b59d4cbcd666f5226380b767a9a7e1c Mon Sep 17 00:00:00 2001 From: MrWook Date: Wed, 3 Feb 2021 08:10:38 +0100 Subject: [PATCH 2/2] chore(input): resolve tests --- src/components/DateInput.vue | 18 ++++-- test/unit/specs/Datepicker/Datepicker.spec.js | 62 ++++++++++++++++--- 2 files changed, 65 insertions(+), 15 deletions(-) diff --git a/src/components/DateInput.vue b/src/components/DateInput.vue index f78efc7e..8803b493 100644 --- a/src/components/DateInput.vue +++ b/src/components/DateInput.vue @@ -93,6 +93,7 @@ export default { return { input: null, isFocusedUsed: false, + isBlurred: false, typedDate: '', utils: constructedDateUtils, } @@ -145,6 +146,7 @@ export default { * submit typedDate and emit a blur event */ inputBlurred() { + this.isBlurred = this.isOpen if (this.typeable) { this.submitTypedDate() } @@ -184,13 +186,9 @@ export default { this.parser, ) }, - toggleCalendar() { - this.$emit(this.isOpen ? 'close-calendar' : 'show-calendar') - }, showCalendarByClick() { - const isFocusedUsed = - !this.showCalendarOnFocus || - (this.showCalendarOnFocus && !this.isFocusedUsed) + const isFocusedUsed = this.showCalendarOnFocus && !this.isFocusedUsed + if (!this.showCalendarOnButtonClick && !isFocusedUsed) { this.toggleCalendar() } @@ -204,6 +202,7 @@ export default { this.$emit('show-calendar') } + this.isBlurred = false this.$emit('focus') }, /** @@ -221,6 +220,13 @@ export default { 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/Datepicker/Datepicker.spec.js b/test/unit/specs/Datepicker/Datepicker.spec.js index 06706b00..54a509c5 100755 --- a/test/unit/specs/Datepicker/Datepicker.spec.js +++ b/test/unit/specs/Datepicker/Datepicker.spec.js @@ -51,18 +51,62 @@ describe('Datepicker mounted', () => { expect(wrapper.emitted().focus).toBeTruthy() }) - it('should open the calendar with click on input with showCalendarOnFocus', async () => { - wrapper.setProps({ + 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() - wrapper.find('input').trigger('focus') - await wrapper.vm.$nextTick() - wrapper.find('input').trigger('click') - await wrapper.vm.$nextTick() - wrapper.find('input').trigger('FUCK') - expect(wrapper.emitted('opened')).toBeTruthy() - expect(wrapper.emitted('closed')).toBeFalsy() + 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() }) })