Skip to content

Commit 296ec72

Browse files
committed
feat: add past and future parts to cells in date picker calendar
1 parent d474a72 commit 296ec72

File tree

4 files changed

+71
-8
lines changed

4 files changed

+71
-8
lines changed

packages/date-picker/src/vaadin-date-picker-helper.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ export function getISOWeekNumber(date) {
3636
return Math.floor(daysSinceFirstOfJanuary / 7 + 1);
3737
}
3838

39+
/**
40+
* Creates a new object with the same date, but sets the hours, minutes, seconds and milliseconds to 0.
41+
*
42+
* @param {Date} date
43+
* @return {Date} The same date time elements set to 0.
44+
*/
45+
export function normalizeDate(date) {
46+
const normalizedDate = new Date(date);
47+
normalizedDate.setHours(0, 0, 0, 0);
48+
return normalizedDate;
49+
}
50+
3951
/**
4052
* Check if two dates are equal.
4153
*
@@ -45,11 +57,7 @@ export function getISOWeekNumber(date) {
4557
*/
4658
export function dateEquals(date1, date2) {
4759
return (
48-
date1 instanceof Date &&
49-
date2 instanceof Date &&
50-
date1.getFullYear() === date2.getFullYear() &&
51-
date1.getMonth() === date2.getMonth() &&
52-
date1.getDate() === date2.getDate()
60+
date1 instanceof Date && date2 instanceof Date && normalizeDate(date1).getTime() === normalizeDate(date2).getTime()
5361
);
5462
}
5563

packages/date-picker/src/vaadin-lit-month-calendar.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { html, LitElement } from 'lit';
77
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
88
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
99
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
10-
import { dateAllowed, dateEquals } from './vaadin-date-picker-helper.js';
10+
import { dateAllowed, dateEquals, normalizeDate } from './vaadin-date-picker-helper.js';
1111
import { MonthCalendarMixin } from './vaadin-month-calendar-mixin.js';
1212
import { monthCalendarStyles } from './vaadin-month-calendar-styles.js';
1313

@@ -62,13 +62,17 @@ class MonthCalendar extends MonthCalendarMixin(ThemableMixin(PolylitMixin(LitEle
6262
const isFocused = dateEquals(date, this.focusedDate);
6363
const isSelected = dateEquals(date, this.selectedDate);
6464
const isDisabled = !dateAllowed(date, this.minDate, this.maxDate, this.isDateDisabled);
65+
const greaterThanToday = normalizeDate(date) > normalizeDate(new Date());
66+
const lessThanToday = normalizeDate(date) < normalizeDate(new Date());
6567
6668
const parts = [
6769
'date',
6870
isDisabled && 'disabled',
6971
isFocused && 'focused',
7072
isSelected && 'selected',
7173
this._isToday(date) && 'today',
74+
greaterThanToday && 'future',
75+
lessThanToday && 'past',
7276
].filter(Boolean);
7377
7478
return html`

packages/date-picker/src/vaadin-month-calendar.js

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import '@polymer/polymer/lib/elements/dom-repeat.js';
77
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
88
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
99
import { registerStyles, ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
10-
import { dateAllowed, dateEquals } from './vaadin-date-picker-helper.js';
10+
import { dateAllowed, dateEquals, normalizeDate } from './vaadin-date-picker-helper.js';
1111
import { MonthCalendarMixin } from './vaadin-month-calendar-mixin.js';
1212
import { monthCalendarStyles } from './vaadin-month-calendar-styles.js';
1313

@@ -110,8 +110,11 @@ class MonthCalendar extends MonthCalendarMixin(ThemableMixin(PolymerElement)) {
110110
// eslint-disable-next-line @typescript-eslint/max-params
111111
__getDatePart(date, focusedDate, selectedDate, minDate, maxDate, isDateDisabled) {
112112
const result = ['date'];
113+
const dayDisabled = this.__isDayDisabled(date, minDate, maxDate, isDateDisabled);
114+
const greaterThanToday = normalizeDate(date) > normalizeDate(new Date());
115+
const lessThanToday = normalizeDate(date) < normalizeDate(new Date());
113116

114-
if (this.__isDayDisabled(date, minDate, maxDate, isDateDisabled)) {
117+
if (dayDisabled) {
115118
result.push('disabled');
116119
}
117120

@@ -127,6 +130,14 @@ class MonthCalendar extends MonthCalendarMixin(ThemableMixin(PolymerElement)) {
127130
result.push('today');
128131
}
129132

133+
if (lessThanToday) {
134+
result.push('past');
135+
}
136+
137+
if (greaterThanToday) {
138+
result.push('future');
139+
}
140+
130141
return result.join(' ');
131142
}
132143

packages/date-picker/test/month-calendar.common.js

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,46 @@ describe('vaadin-month-calendar', () => {
161161
expect(monthCalendar.selectedDate).to.be.undefined;
162162
});
163163

164+
describe('past and future dates', () => {
165+
let yesterdayCell, todayCell, tomorrowCell;
166+
let clock;
167+
beforeEach(async () => {
168+
clock = sinon.useFakeTimers({
169+
now: new Date('2024-08-16'),
170+
toFake: ['Date'],
171+
});
172+
173+
const today = new Date();
174+
175+
monthCalendar.month = today;
176+
await nextRender();
177+
178+
todayCell = getDateCells(monthCalendar).find((dateElement) => dateElement.date.getDate() === today.getDate());
179+
yesterdayCell = todayCell.previousElementSibling;
180+
tomorrowCell = todayCell.nextElementSibling;
181+
});
182+
183+
afterEach(() => {
184+
clock.restore();
185+
});
186+
187+
it('should add past part to past dates', () => {
188+
expect(yesterdayCell.getAttribute('part')).to.contain('past');
189+
});
190+
191+
it('should not add past part to today', () => {
192+
expect(todayCell.getAttribute('part')).to.not.contain('past');
193+
});
194+
195+
it('should add future part to future dates', () => {
196+
expect(tomorrowCell.getAttribute('part')).to.contain('future');
197+
});
198+
199+
it('should not add future part to today', () => {
200+
expect(todayCell.getAttribute('part')).to.not.contain('future');
201+
});
202+
});
203+
164204
describe('i18n', () => {
165205
beforeEach(async () => {
166206
monthCalendar.i18n = {

0 commit comments

Comments
 (0)