From 4aee6dd18cee6bcedfaa24fe21c2eeaec8dad801 Mon Sep 17 00:00:00 2001 From: bezany Date: Fri, 5 Feb 2021 13:22:48 +0300 Subject: [PATCH] feat: range on hover (#571) --- __test__/calendar-range.test.js | 34 +++++++++++++++++++++++++++++++++ src/calendar/calendar-panel.js | 4 ++++ src/calendar/calendar-range.js | 31 ++++++++++++++++++++++++++++-- src/calendar/table-date.vue | 4 ++++ src/style/index.scss | 3 ++- 5 files changed, 73 insertions(+), 3 deletions(-) diff --git a/__test__/calendar-range.test.js b/__test__/calendar-range.test.js index d45fb84..3882b3e 100644 --- a/__test__/calendar-range.test.js +++ b/__test__/calendar-range.test.js @@ -80,4 +80,38 @@ describe('CalendarRange', () => { expect(startPanel.vm.calendarMonth).toBe(9); expect(endPanel.vm.calendarMonth).toBe(11); }); + + it('feat: hover range', async () => { + wrapper = mount(CalendarRange, { + propsData: { + defaultValue: new Date(2019, 9, 1), + }, + }); + expect(wrapper.vm.calendars).toEqual([new Date(2019, 9, 1), new Date(2019, 10, 1)]); + const tds = wrapper.findAll('.mx-table-date td'); + await tds.at(2).trigger('click'); + await tds.at(60).trigger('mouseenter'); + + for (let i = 0; i < tds.length; i++) { + if (i > 2 && i < 60) { + expect(tds.at(i).classes()).toContain('hover-in-range'); + } else { + expect(tds.at(i).classes()).not.toContain('hover-in-range'); + } + } + + await tds.at(60).trigger('click'); + + // hover to back + await tds.at(60).trigger('click'); + await tds.at(2).trigger('mouseenter'); + + for (let i = 0; i < tds.length; i++) { + if (i > 2 && i < 60) { + expect(tds.at(i).classes()).toContain('hover-in-range'); + } else { + expect(tds.at(i).classes()).not.toContain('hover-in-range'); + } + } + }); }); diff --git a/src/calendar/calendar-panel.js b/src/calendar/calendar-panel.js index f9dec48..ad35293 100644 --- a/src/calendar/calendar-panel.js +++ b/src/calendar/calendar-panel.js @@ -163,6 +163,9 @@ export default { handleSelectDate(date) { this.emitDate(date, this.type === 'week' ? 'week' : 'date'); }, + handleMouseEnter(cell) { + this.$emit('mouseenter', cell); + }, getMonthCellDate(month) { return createDate(this.calendarYear, month); }, @@ -259,6 +262,7 @@ export default { onSelect={this.handleSelectDate} onChangepanel={this.handelPanelChange} onChangecalendar={this.handleCalendarChange} + onMouseenter={this.handleMouseEnter} /> ); }, diff --git a/src/calendar/calendar-range.js b/src/calendar/calendar-range.js index d4c3665..dbef51b 100644 --- a/src/calendar/calendar-range.js +++ b/src/calendar/calendar-range.js @@ -16,6 +16,7 @@ export default { return { innerValue: [], calendars: [], + hoveredValue: null, }; }, computed: { @@ -65,6 +66,12 @@ export default { this.innerValue = [date, new Date(NaN)]; } }, + handleCellMouseEnter(cell) { + this.hoveredValue = cell; + }, + handleRangeMouseLeave() { + this.hoveredValue = null; + }, emitDate(dates, type) { this.$emit('select', dates, type); }, @@ -101,13 +108,28 @@ export default { getRangeClasses(cellDate, currentDates, classnames) { const classes = [].concat(this.getClasses(cellDate, currentDates, classnames)); if ( - !/disabled|active|not-current-month/.test(classnames) && currentDates.length === 2 && + !/disabled|active|not-current-month/.test(classnames) && cellDate.getTime() > currentDates[0].getTime() && cellDate.getTime() < currentDates[1].getTime() ) { classes.push('in-range'); + } else if ( + currentDates.length === 1 && + this.hoveredValue && + !/disabled|active/.test(classnames) + ) { + let min = this.hoveredValue.getTime(); + let max = currentDates[0].getTime(); + + if (min > max) { + [min, max] = [max, min]; + } + if (cellDate.getTime() > min && cellDate.getTime() < max) { + classes.push('hover-in-range'); + } } + return classes; }, }, @@ -125,12 +147,17 @@ export default { const on = { select: this.handleSelect, 'update:calendar': index === 0 ? this.updateStartCalendar : this.updateEndCalendar, + mouseenter: this.handleCellMouseEnter, }; return ; }); const { prefixClass } = this; - return
{calendarRange}
; + return ( +
+ {calendarRange} +
+ ); }, }; diff --git a/src/calendar/table-date.vue b/src/calendar/table-date.vue index 039e8e2..220a0eb 100644 --- a/src/calendar/table-date.vue +++ b/src/calendar/table-date.vue @@ -47,6 +47,7 @@ class="cell" :class="getCellClasses(cell)" :title="getCellTitle(cell)" + @mouseenter="handleMouseEnter(cell)" >
{{ cell.getDate() }}
@@ -153,6 +154,9 @@ export default { handlePanelChange(panel) { this.$emit('changepanel', panel); }, + handleMouseEnter(cell) { + this.$emit('mouseenter', cell); + }, handleCellClick(evt) { let { target } = evt; if (target.tagName.toUpperCase() === 'DIV') { diff --git a/src/style/index.scss b/src/style/index.scss index 5461cd7..d2b1a79 100644 --- a/src/style/index.scss +++ b/src/style/index.scss @@ -201,7 +201,8 @@ color: $calendar-active-color; background-color: $calendar-active-background-color; } - &.in-range { + &.in-range, + &.hover-in-range { color: $calendar-in-range-color; background-color: $calendar-in-range-background-color; }