diff --git a/package.json b/package.json index 9f8816b25..c5971dec9 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "devDependencies": { "@ls-lint/ls-lint": "^1.8.0", "@vant/cli": "^2.4.0", + "prettier": "^2.0.2", "vue": "^2.6.11", "vue-template-compiler": "^2.6.11" }, diff --git a/src/calendar/index.js b/src/calendar/index.js index 76c4147a4..4d2b4fd2f 100644 --- a/src/calendar/index.js +++ b/src/calendar/index.js @@ -7,10 +7,11 @@ import { copyDates, getNextDay, compareDay, + ROW_HEIGHT, + calcDateNum, compareMonth, createComponent, - calcDateNum, - ROW_HEIGHT, + getDayByOffset, } from './utils'; // Components @@ -294,26 +295,36 @@ export default createComponent({ }, select(date, complete) { - this.currentDate = date; - this.$emit('select', copyDates(this.currentDate)); + const emit = (date) => { + this.currentDate = date; + this.$emit('select', copyDates(this.currentDate)); + }; if (complete && this.type === 'range') { - const valid = this.checkRange(); + const valid = this.checkRange(date); if (!valid) { + // auto selected to max range if showConfirm + if (this.showConfirm) { + emit([date[0], getDayByOffset(date[0], this.maxRange - 1)]); + } else { + emit(date); + } return; } } + emit(date); + if (complete && !this.showConfirm) { this.onConfirm(); } }, - checkRange() { - const { maxRange, currentDate, rangePrompt } = this; + checkRange(date) { + const { maxRange, rangePrompt } = this; - if (maxRange && calcDateNum(currentDate) > maxRange) { + if (maxRange && calcDateNum(date) > maxRange) { Toast(rangePrompt || t('rangePrompt', maxRange)); return false; } @@ -322,10 +333,6 @@ export default createComponent({ }, onConfirm() { - if (this.type === 'range' && !this.checkRange()) { - return; - } - this.$emit('confirm', copyDates(this.currentDate)); }, diff --git a/src/calendar/test/index.spec.js b/src/calendar/test/index.spec.js index ca4ba49ee..9a3f70dfe 100644 --- a/src/calendar/test/index.spec.js +++ b/src/calendar/test/index.spec.js @@ -1,26 +1,14 @@ import Calendar from '..'; import { mount, later } from '../../../test'; import { getNextDay } from '../utils'; - -const now = new Date(); -const minDate = new Date(2010, 0, 10); -const maxDate = new Date(2010, 0, 20); - -function formatDate(date) { - if (date) { - return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`; - } - - return ''; -} - -function formatRange([start, end]) { - return `${formatDate(start)}-${formatDate(end)}`; -} - -function formatMultiple(dates) { - return dates.map(formatDate).join(','); -} +import { + now, + minDate, + maxDate, + formatDate, + formatRange, + formatMultiple, +} from './utils'; test('select event when type is single', async () => { const wrapper = mount(Calendar, { diff --git a/src/calendar/test/prop.spec.js b/src/calendar/test/prop.spec.js index 8bbf7d801..02bedf27c 100644 --- a/src/calendar/test/prop.spec.js +++ b/src/calendar/test/prop.spec.js @@ -1,16 +1,39 @@ import Calendar from '..'; import { mount, later } from '../../../test'; +import { minDate, maxDate, formatRange } from './utils'; -const minDate = new Date(2010, 0, 10); -const maxDate = new Date(2010, 0, 20); - -test('max-range prop', async () => { +test('max-range prop when showConfirm is false', async () => { const wrapper = mount(Calendar, { propsData: { type: 'range', minDate, maxDate, - maxRange: 1, + maxRange: 3, + poppable: false, + showConfirm: false, + }, + }); + + await later(); + + const days = wrapper.findAll('.van-calendar__day'); + days.at(12).trigger('click'); + days.at(18).trigger('click'); + + expect(formatRange(wrapper.emitted('select')[0][0])).toEqual('2010/1/13-'); + expect(formatRange(wrapper.emitted('select')[1][0])).toEqual( + '2010/1/13-2010/1/19' + ); + expect(wrapper.emitted('confirm')).toBeFalsy(); +}); + +test('max-range prop when showConfirm is true', async () => { + const wrapper = mount(Calendar, { + propsData: { + type: 'range', + minDate, + maxDate, + maxRange: 3, poppable: false, }, }); @@ -18,10 +41,13 @@ test('max-range prop', async () => { await later(); const days = wrapper.findAll('.van-calendar__day'); - days.at(15).trigger('click'); + days.at(12).trigger('click'); days.at(18).trigger('click'); - wrapper.find('.van-calendar__confirm').trigger('click'); + expect(formatRange(wrapper.emitted('select')[0][0])).toEqual('2010/1/13-'); + expect(formatRange(wrapper.emitted('select')[1][0])).toEqual( + '2010/1/13-2010/1/15' + ); expect(wrapper.emitted('confirm')).toBeFalsy(); }); diff --git a/src/calendar/test/utils.js b/src/calendar/test/utils.js new file mode 100644 index 000000000..2034d3af9 --- /dev/null +++ b/src/calendar/test/utils.js @@ -0,0 +1,19 @@ +export const now = new Date(); +export const minDate = new Date(2010, 0, 10); +export const maxDate = new Date(2010, 0, 20); + +export function formatDate(date) { + if (date) { + return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()}`; + } + + return ''; +} + +export function formatRange([start, end]) { + return `${formatDate(start)}-${formatDate(end)}`; +} + +export function formatMultiple(dates) { + return dates.map(formatDate).join(','); +} diff --git a/src/calendar/utils.ts b/src/calendar/utils.ts index 57d69bd56..273b096f4 100644 --- a/src/calendar/utils.ts +++ b/src/calendar/utils.ts @@ -36,7 +36,7 @@ export function compareDay(day1: Date, day2: Date) { return compareMonthResult; } -function getDayByOffset(date: Date, offset: number) { +export function getDayByOffset(date: Date, offset: number) { date = new Date(date); date.setDate(date.getDate() + offset); diff --git a/yarn.lock b/yarn.lock index d80a126dd..6a49d9761 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9031,7 +9031,7 @@ prettier@^1.18.2: prettier@^2.0.2: version "2.0.2" - resolved "https://registry.npm.taobao.org/prettier/download/prettier-2.0.2.tgz?cache=0&sync_timestamp=1585003173514&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.0.2.tgz#1ba8f3eb92231e769b7fcd7cb73ae1b6b74ade08" + resolved "https://registry.npm.taobao.org/prettier/download/prettier-2.0.2.tgz?cache=0&sync_timestamp=1585003590220&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fprettier%2Fdownload%2Fprettier-2.0.2.tgz#1ba8f3eb92231e769b7fcd7cb73ae1b6b74ade08" integrity sha1-G6jz65IjHnabf818tzrhtrdK3gg= pretty-error@^2.1.1: