2
0
mirror of https://github.com/tenrok/vue2-datepicker.git synced 2026-06-23 13:00:35 +03:00

refactor: range on hover use provide

This commit is contained in:
mengxiong10
2021-02-05 18:25:38 +08:00
parent 4aee6dd18c
commit cc0b60509a
5 changed files with 61 additions and 44 deletions
+20 -14
View File
@@ -1,4 +1,5 @@
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { parse } from 'date-fns';
import CalendarRange from '../src/calendar/calendar-range'; import CalendarRange from '../src/calendar/calendar-range';
import CalendarPanel from '../src/calendar/calendar-panel'; import CalendarPanel from '../src/calendar/calendar-panel';
@@ -10,19 +11,25 @@ afterEach(() => {
describe('CalendarRange', () => { describe('CalendarRange', () => {
it('feat: correct classes', () => { it('feat: correct classes', () => {
const start = new Date(2019, 9, 30);
const end = new Date(2019, 10, 2);
wrapper = mount(CalendarRange, { wrapper = mount(CalendarRange, {
propsData: { propsData: {
value: [new Date(2019, 9, 30), new Date(2019, 10, 2)], value: [start, end],
}, },
}); });
const activeTds = wrapper.findAll('.mx-table-date .active'); const tds = wrapper.findAll('.mx-table-date td');
const rangeTds = wrapper.findAll('.mx-table-date .in-range');
expect(activeTds.length).toBe(2); for (let i = 0; i < tds.length; i++) {
expect(activeTds.at(0).text()).toBe('30'); const td = tds.at(i);
expect(activeTds.at(1).text()).toBe('2'); const { title } = td.element;
expect(rangeTds.length).toBe(2); const cell = parse(title, 'yyyy-MM-dd', new Date()).getTime();
expect(rangeTds.at(0).text()).toBe('31'); if (cell > start.getTime() && cell < end.getTime()) {
expect(rangeTds.at(1).text()).toBe('1'); expect(td.classes()).toContain('in-range');
} else {
expect(td.classes()).not.toContain('hover-in-range');
}
}
}); });
it('feat: click range', async () => { it('feat: click range', async () => {
@@ -87,13 +94,12 @@ describe('CalendarRange', () => {
defaultValue: new Date(2019, 9, 1), 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'); const tds = wrapper.findAll('.mx-table-date td');
await tds.at(2).trigger('click'); await tds.at(10).trigger('click');
await tds.at(60).trigger('mouseenter'); await tds.at(60).trigger('mouseenter');
for (let i = 0; i < tds.length; i++) { for (let i = 0; i < tds.length; i++) {
if (i > 2 && i < 60) { if (i > 10 && i < 60) {
expect(tds.at(i).classes()).toContain('hover-in-range'); expect(tds.at(i).classes()).toContain('hover-in-range');
} else { } else {
expect(tds.at(i).classes()).not.toContain('hover-in-range'); expect(tds.at(i).classes()).not.toContain('hover-in-range');
@@ -104,10 +110,10 @@ describe('CalendarRange', () => {
// hover to back // hover to back
await tds.at(60).trigger('click'); await tds.at(60).trigger('click');
await tds.at(2).trigger('mouseenter'); await tds.at(10).trigger('mouseenter');
for (let i = 0; i < tds.length; i++) { for (let i = 0; i < tds.length; i++) {
if (i > 2 && i < 60) { if (i > 10 && i < 60) {
expect(tds.at(i).classes()).toContain('hover-in-range'); expect(tds.at(i).classes()).toContain('hover-in-range');
} else { } else {
expect(tds.at(i).classes()).not.toContain('hover-in-range'); expect(tds.at(i).classes()).not.toContain('hover-in-range');
-4
View File
@@ -163,9 +163,6 @@ export default {
handleSelectDate(date) { handleSelectDate(date) {
this.emitDate(date, this.type === 'week' ? 'week' : 'date'); this.emitDate(date, this.type === 'week' ? 'week' : 'date');
}, },
handleMouseEnter(cell) {
this.$emit('mouseenter', cell);
},
getMonthCellDate(month) { getMonthCellDate(month) {
return createDate(this.calendarYear, month); return createDate(this.calendarYear, month);
}, },
@@ -262,7 +259,6 @@ export default {
onSelect={this.handleSelectDate} onSelect={this.handleSelectDate}
onChangepanel={this.handelPanelChange} onChangepanel={this.handelPanelChange}
onChangecalendar={this.handleCalendarChange} onChangecalendar={this.handleCalendarChange}
onMouseenter={this.handleMouseEnter}
/> />
); );
}, },
+25 -25
View File
@@ -4,6 +4,12 @@ import { getValidDate, isValidDate, isValidRangeDate, startOfMonth } from '../ut
export default { export default {
name: 'CalendarRange', name: 'CalendarRange',
components: { CalendarPanel }, components: { CalendarPanel },
provide() {
return {
onDateMouseEnter: this.onDateMouseEnter,
onDateMouseLeave: this.onDateMouseLeave,
};
},
inject: { inject: {
prefixClass: { prefixClass: {
default: 'mx', default: 'mx',
@@ -66,10 +72,10 @@ export default {
this.innerValue = [date, new Date(NaN)]; this.innerValue = [date, new Date(NaN)];
} }
}, },
handleCellMouseEnter(cell) { onDateMouseEnter(cell) {
this.hoveredValue = cell; this.hoveredValue = cell;
}, },
handleRangeMouseLeave() { onDateMouseLeave() {
this.hoveredValue = null; this.hoveredValue = null;
}, },
emitDate(dates, type) { emitDate(dates, type) {
@@ -107,27 +113,26 @@ export default {
}, },
getRangeClasses(cellDate, currentDates, classnames) { getRangeClasses(cellDate, currentDates, classnames) {
const classes = [].concat(this.getClasses(cellDate, currentDates, classnames)); const classes = [].concat(this.getClasses(cellDate, currentDates, classnames));
if (
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 (/disabled|active/.test(classnames)) return classes;
const inRange = (data, range, fn = v => v.getTime()) => {
const value = fn(data);
let [min, max] = range.map(fn);
if (min > max) { if (min > max) {
[min, max] = [max, min]; [min, max] = [max, min];
} }
if (cellDate.getTime() > min && cellDate.getTime() < max) { return value > min && value < max;
classes.push('hover-in-range'); };
} if (currentDates.length === 2 && inRange(cellDate, currentDates)) {
return classes.concat('in-range');
}
if (
currentDates.length === 1 &&
this.hoveredValue &&
inRange(cellDate, [currentDates[0], this.hoveredValue])
) {
return classes.concat('hover-in-range');
} }
return classes; return classes;
@@ -147,17 +152,12 @@ export default {
const on = { const on = {
select: this.handleSelect, select: this.handleSelect,
'update:calendar': index === 0 ? this.updateStartCalendar : this.updateEndCalendar, 'update:calendar': index === 0 ? this.updateStartCalendar : this.updateEndCalendar,
mouseenter: this.handleCellMouseEnter,
}; };
return <calendar-panel {...{ props, on }}></calendar-panel>; return <calendar-panel {...{ props, on }}></calendar-panel>;
}); });
const { prefixClass } = this; const { prefixClass } = this;
return ( return <div class={`${prefixClass}-range-wrapper`}>{calendarRange}</div>;
<div class={`${prefixClass}-range-wrapper`} onMouseleave={this.handleRangeMouseLeave}>
{calendarRange}
</div>
);
}, },
}; };
+15 -1
View File
@@ -48,6 +48,7 @@
:class="getCellClasses(cell)" :class="getCellClasses(cell)"
:title="getCellTitle(cell)" :title="getCellTitle(cell)"
@mouseenter="handleMouseEnter(cell)" @mouseenter="handleMouseEnter(cell)"
@mouseleave="handleMouseLeave(cell)"
> >
<div>{{ cell.getDate() }}</div> <div>{{ cell.getDate() }}</div>
</td> </td>
@@ -78,6 +79,12 @@ export default {
prefixClass: { prefixClass: {
default: 'mx', default: 'mx',
}, },
onDateMouseEnter: {
default: undefined,
},
onDateMouseLeave: {
default: undefined,
},
}, },
props: { props: {
calendar: { calendar: {
@@ -155,7 +162,14 @@ export default {
this.$emit('changepanel', panel); this.$emit('changepanel', panel);
}, },
handleMouseEnter(cell) { handleMouseEnter(cell) {
this.$emit('mouseenter', cell); if (typeof this.onDateMouseEnter === 'function') {
this.onDateMouseEnter(cell);
}
},
handleMouseLeave(cell) {
if (typeof this.onDateMouseLeave === 'function') {
this.onDateMouseLeave(cell);
}
}, },
handleCellClick(evt) { handleCellClick(evt) {
let { target } = evt; let { target } = evt;
+1
View File
@@ -270,6 +270,7 @@
} }
.cell.not-current-month { .cell.not-current-month {
color: #ccc; color: #ccc;
background: none; // cover the in-range style
} }
} }