Skip to content

Commit e10daab

Browse files
authored
fix(input): resolve flicker on showCalendarByFocus (sumcumo#82)
* fix(input): resolve flicker on showCalendarByFocus * chore(input): resolve tests
1 parent 6b9600a commit e10daab

File tree

3 files changed

+105
-18
lines changed

3 files changed

+105
-18
lines changed

src/components/DateInput.vue

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ export default {
9292
const constructedDateUtils = makeDateUtils(this.useUtc)
9393
return {
9494
input: null,
95+
isFocusedUsed: false,
96+
isBlurred: false,
9597
typedDate: '',
9698
utils: constructedDateUtils,
9799
}
@@ -141,23 +143,16 @@ export default {
141143
this.$emit('clear-date')
142144
},
143145
/**
144-
* Submits a typed date if it's valid
146+
* submit typedDate and emit a blur event
145147
*/
146148
inputBlurred() {
149+
this.isBlurred = this.isOpen
147150
if (this.typeable) {
148-
const parsableDate = this.parseDate(this.input.value)
149-
const parsedDate = Date.parse(parsableDate)
150-
151-
if (Number.isNaN(parsedDate)) {
152-
this.clearDate()
153-
} else {
154-
this.input.value = this.formattedDate
155-
this.typedDate = ''
156-
this.$emit('typed-date', parsedDate)
157-
}
151+
this.submitTypedDate()
158152
}
159153
this.$emit('blur')
160154
this.$emit('close-calendar')
155+
this.isFocusedUsed = false
161156
},
162157
/**
163158
* Attempt to parse a typed date
@@ -191,21 +186,47 @@ export default {
191186
this.parser,
192187
)
193188
},
194-
toggleCalendar() {
195-
this.$emit(this.isOpen ? 'close-calendar' : 'show-calendar')
196-
},
197189
showCalendarByClick() {
198-
if (!this.showCalendarOnButtonClick) {
190+
const isFocusedUsed = this.showCalendarOnFocus && !this.isFocusedUsed
191+
192+
if (!this.showCalendarOnButtonClick && !isFocusedUsed) {
199193
this.toggleCalendar()
200194
}
195+
196+
if (this.showCalendarOnFocus) {
197+
this.isFocusedUsed = true
198+
}
201199
},
202200
showCalendarByFocus() {
203201
if (this.showCalendarOnFocus) {
204202
this.$emit('show-calendar')
205203
}
206204
205+
this.isBlurred = false
207206
this.$emit('focus')
208207
},
208+
/**
209+
* Submits a typed date if it's valid
210+
*/
211+
submitTypedDate() {
212+
const parsableDate = this.parseDate(this.input.value)
213+
const parsedDate = Date.parse(parsableDate)
214+
215+
if (Number.isNaN(parsedDate)) {
216+
this.clearDate()
217+
} else {
218+
this.input.value = this.formattedDate
219+
this.typedDate = ''
220+
this.$emit('typed-date', parsedDate)
221+
}
222+
},
223+
toggleCalendar() {
224+
if (!this.isOpen && this.isBlurred) {
225+
this.isBlurred = false
226+
return
227+
}
228+
this.$emit(this.isOpen ? 'close-calendar' : 'show-calendar')
229+
},
209230
},
210231
}
211232
</script>

test/unit/specs/DateInput/DateInput.spec.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,17 @@ describe('DateInput unmounted', () => {
1111

1212
describe('DateInput', () => {
1313
let wrapper
14-
15-
beforeEach(() => {
16-
wrapper = shallowMount(DateInput, {
14+
const createWrapper = () => {
15+
return shallowMount(DateInput, {
1716
propsData: {
1817
selectedDate: new Date(2018, 2, 24),
1918
format: 'dd MMM yyyy',
2019
translation: en,
2120
},
2221
})
22+
}
23+
beforeEach(() => {
24+
wrapper = createWrapper()
2325
})
2426

2527
afterEach(() => {
@@ -120,6 +122,12 @@ describe('DateInput', () => {
120122
expect(wrapper.emitted('close-calendar')).toBeTruthy()
121123
})
122124

125+
it('should open the calendar on click', async () => {
126+
wrapper.find('input').trigger('click')
127+
await wrapper.vm.$nextTick()
128+
expect(wrapper.emitted('show-calendar')).toBeTruthy()
129+
})
130+
123131
it('should open the calendar on focus', async () => {
124132
wrapper.find('input').trigger('focus')
125133
expect(wrapper.emitted('show-calendar')).toBeFalsy()

test/unit/specs/Datepicker/Datepicker.spec.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,64 @@ describe('Datepicker mounted', () => {
5050
input.trigger('focus')
5151
expect(wrapper.emitted().focus).toBeTruthy()
5252
})
53+
54+
it('should open the calendar with click on input when showCalendarOnFocus = true', async () => {
55+
await wrapper.setProps({
56+
showCalendarOnFocus: true,
57+
})
58+
const input = wrapper.find('input')
59+
60+
await input.trigger('focus')
61+
await input.trigger('click')
62+
await wrapper.vm.$nextTick()
63+
expect(wrapper.vm.isOpen).toBeTruthy()
64+
})
65+
66+
it('should toggle the calendar via the calendar button', async () => {
67+
await wrapper.setProps({
68+
calendarButton: true,
69+
})
70+
71+
const calendarButton = wrapper.find('span.vdp-datepicker__calendar-button')
72+
73+
await calendarButton.trigger('click')
74+
expect(wrapper.vm.isOpen).toBeTruthy()
75+
76+
await calendarButton.trigger('click')
77+
expect(wrapper.vm.isOpen).toBeFalsy()
78+
})
79+
80+
it('should toggle the calendar via the calendar button when showCalendarOnFocus = true', async () => {
81+
await wrapper.setProps({
82+
calendarButton: true,
83+
showCalendarOnFocus: true,
84+
})
85+
86+
const calendarButton = wrapper.find('span.vdp-datepicker__calendar-button')
87+
88+
await calendarButton.trigger('click')
89+
expect(wrapper.vm.isOpen).toBeTruthy()
90+
91+
await calendarButton.trigger('click')
92+
expect(wrapper.vm.isOpen).toBeFalsy()
93+
})
94+
95+
it('should close the calendar via the calendar button, despite input being focused', async () => {
96+
await wrapper.setProps({
97+
calendarButton: true,
98+
showCalendarOnFocus: true,
99+
})
100+
101+
const input = wrapper.find('input')
102+
const calendarButton = wrapper.find('span.vdp-datepicker__calendar-button')
103+
104+
await input.trigger('focus')
105+
expect(wrapper.vm.isOpen).toBeTruthy()
106+
107+
await input.trigger('blur')
108+
await calendarButton.trigger('click')
109+
expect(wrapper.vm.isOpen).toBeFalsy()
110+
})
53111
})
54112

55113
describe('Datepicker shallowMounted', () => {

0 commit comments

Comments
 (0)