From ed3c1e7ae3d761b9cc645bd3d39f15ef404c0bc5 Mon Sep 17 00:00:00 2001 From: Phil Liu <1308972436@qq.com> Date: Tue, 17 Dec 2024 22:05:52 +0800 Subject: [PATCH 1/3] fix(CalendarDay): fix margin calculation for calendar days at month end --- packages/vant/src/calendar/CalendarDay.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/vant/src/calendar/CalendarDay.tsx b/packages/vant/src/calendar/CalendarDay.tsx index 9673e09ab64..e635431ffdd 100644 --- a/packages/vant/src/calendar/CalendarDay.tsx +++ b/packages/vant/src/calendar/CalendarDay.tsx @@ -54,8 +54,15 @@ export default defineComponent({ } } - if (offset + (item.date?.getDate() || 1) > 28) { - style.marginBottom = 0; + if (item.date) { + const lastDay = new Date( + item.date.getFullYear(), + item.date.getMonth() + 1, + 0, + ).getDate(); + if (offset + item.date.getDate() > lastDay + offset - 7) { + style.marginBottom = 0; + } } return style; From b5a0d77fe28c6bbf53f3e66fb32442b2d844b50c Mon Sep 17 00:00:00 2001 From: Phil Liu <1308972436@qq.com> Date: Wed, 18 Dec 2024 23:23:54 +0800 Subject: [PATCH 2/3] refactor(CalendarDay): improve margin-bottom calculations and add isLastRowInMonth utility --- packages/vant/src/calendar/CalendarDay.tsx | 13 +++------ packages/vant/src/calendar/test/utils.spec.ts | 27 ++++++++++++++++++- packages/vant/src/calendar/utils.ts | 14 ++++++++++ 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/packages/vant/src/calendar/CalendarDay.tsx b/packages/vant/src/calendar/CalendarDay.tsx index e635431ffdd..f3c97e0ffcb 100644 --- a/packages/vant/src/calendar/CalendarDay.tsx +++ b/packages/vant/src/calendar/CalendarDay.tsx @@ -5,7 +5,7 @@ import { type CSSProperties, } from 'vue'; import { makeNumberProp, createNamespace, makeRequiredProp } from '../utils'; -import { bem } from './utils'; +import { bem, isLastRowInMonth } from './utils'; import type { CalendarDayItem } from './types'; const [name] = createNamespace('calendar-day'); @@ -54,15 +54,8 @@ export default defineComponent({ } } - if (item.date) { - const lastDay = new Date( - item.date.getFullYear(), - item.date.getMonth() + 1, - 0, - ).getDate(); - if (offset + item.date.getDate() > lastDay + offset - 7) { - style.marginBottom = 0; - } + if (item.date && isLastRowInMonth(item.date, offset)) { + style.marginBottom = 0; } return style; diff --git a/packages/vant/src/calendar/test/utils.spec.ts b/packages/vant/src/calendar/test/utils.spec.ts index 5e42340cd35..074f50b3229 100644 --- a/packages/vant/src/calendar/test/utils.spec.ts +++ b/packages/vant/src/calendar/test/utils.spec.ts @@ -1,4 +1,10 @@ -import { compareDay, compareMonth, getNextDay, calcDateNum } from '../utils'; +import { + compareDay, + compareMonth, + getNextDay, + calcDateNum, + isLastRowInMonth, +} from '../utils'; const date1 = new Date(2010, 0, 1); const date2 = new Date(2010, 0, 2); @@ -29,3 +35,22 @@ test('calcDateNum', () => { expect(calcDateNum([date1, date2])).toEqual(2); expect(calcDateNum([date1, date3])).toEqual(32); }); + +test('isLastRowInMonth', () => { + // test first day of month + expect(isLastRowInMonth(new Date(2024, 0, 1), 0)).toEqual(false); + + // test middle of month + expect(isLastRowInMonth(new Date(2024, 0, 22), 0)).toEqual(false); + expect(isLastRowInMonth(new Date(2024, 0, 28), 0)).toEqual(false); + + // test last week of month + expect(isLastRowInMonth(new Date(2024, 0, 29), 0)).toEqual(true); + expect(isLastRowInMonth(new Date(2024, 0, 31), 0)).toEqual(true); + + // test different offset + expect(isLastRowInMonth(new Date(2024, 0, 18), 4)).toEqual(false); + expect(isLastRowInMonth(new Date(2024, 0, 24), 4)).toEqual(false); + expect(isLastRowInMonth(new Date(2024, 0, 25), 4)).toEqual(true); + expect(isLastRowInMonth(new Date(2024, 0, 31), 4)).toEqual(true); +}); diff --git a/packages/vant/src/calendar/utils.ts b/packages/vant/src/calendar/utils.ts index 962b720df7e..8abe1dff39c 100644 --- a/packages/vant/src/calendar/utils.ts +++ b/packages/vant/src/calendar/utils.ts @@ -82,3 +82,17 @@ export function calcDateNum(date: [Date, Date]) { const day2 = date[1].getTime(); return (day2 - day1) / (1000 * 60 * 60 * 24) + 1; } + +/** + * Checks if the given date is in the last row of its month in a calendar view + * @param date The date to check + * @param offset The offset of the first day of the month + * @returns boolean indicating whether the date is in the last row + */ +export function isLastRowInMonth(date: Date, offset: number = 0) { + const lastDay = new Date(date.getFullYear(), date.getMonth() + 1, 0); + const currentPos = offset + date.getDate() - 1; + const lastDayPos = offset + lastDay.getDate() - 1; + + return Math.floor(currentPos / 7) === Math.floor(lastDayPos / 7); +} From d3af070b6a11f56ff3359202613f569f63d8e7de Mon Sep 17 00:00:00 2001 From: Phil Liu <1308972436@qq.com> Date: Wed, 18 Dec 2024 23:25:44 +0800 Subject: [PATCH 3/3] test(calendar): remove wrong margin-bottom styles of calendar in snapshots --- .../test/__snapshots__/index.spec.ts.snap | 21 ------------------- .../test/__snapshots__/prop.spec.ts.snap | 7 ------- 2 files changed, 28 deletions(-) diff --git a/packages/vant/src/calendar/test/__snapshots__/index.spec.ts.snap b/packages/vant/src/calendar/test/__snapshots__/index.spec.ts.snap index 8025cd9df9f..693b2de4d86 100644 --- a/packages/vant/src/calendar/test/__snapshots__/index.spec.ts.snap +++ b/packages/vant/src/calendar/test/__snapshots__/index.spec.ts.snap @@ -202,49 +202,42 @@ exports[`formatter prop 1`] = `