Skip to content

Commit 9896939

Browse files
fix(datetime): if no default value, don't highlight active day until one is selected (#25151)
1 parent e5e0e24 commit 9896939

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

core/src/components/datetime/datetime.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ export class Datetime implements ComponentInterface {
6868
private clearFocusVisible?: () => void;
6969
private overlayIsPresenting = false;
7070

71+
/**
72+
* Whether to highlight the active day with a solid circle (as opposed
73+
* to the outline circle around today). If you don't specify an initial
74+
* value for the datetime, it doesn't automatically init to a default to
75+
* avoid unwanted change events firing. If the solid circle were still
76+
* shown then, it would look like a date had already been selected, which
77+
* is misleading UX.
78+
*/
79+
private highlightActiveParts = false;
80+
7181
private parsedMinuteValues?: number[];
7282
private parsedHourValues?: number[];
7383
private parsedMonthValues?: number[];
@@ -1058,6 +1068,7 @@ export class Datetime implements ComponentInterface {
10581068
};
10591069

10601070
private processValue = (value?: string | null) => {
1071+
this.highlightActiveParts = !!value;
10611072
const valueToProcess = value || getToday();
10621073
const { month, day, year, hour, minute, tzOffset } = parseDate(valueToProcess);
10631074

@@ -1349,6 +1360,7 @@ export class Datetime implements ComponentInterface {
13491360
}
13501361

13511362
private renderMonth(month: number, year: number) {
1363+
const { highlightActiveParts } = this;
13521364
const yearAllowed = this.parsedYearValues === undefined || this.parsedYearValues.includes(year);
13531365
const monthAllowed = this.parsedMonthValues === undefined || this.parsedMonthValues.includes(month);
13541366
const isCalMonthDisabled = !yearAllowed || !monthAllowed;
@@ -1424,7 +1436,7 @@ export class Datetime implements ComponentInterface {
14241436
class={{
14251437
'calendar-day-padding': day === null,
14261438
'calendar-day': true,
1427-
'calendar-day-active': isActive,
1439+
'calendar-day-active': isActive && highlightActiveParts,
14281440
'calendar-day-today': isToday,
14291441
}}
14301442
aria-selected={ariaSelected}
@@ -1434,6 +1446,14 @@ export class Datetime implements ComponentInterface {
14341446
return;
14351447
}
14361448

1449+
/**
1450+
* Note that for datetimes with confirm/cancel buttons, the value
1451+
* isn't updated until you call confirm(). We need to bring the
1452+
* solid circle back on day click for UX reasons, rather than only
1453+
* show the circle if `value` is truthy.
1454+
*/
1455+
this.highlightActiveParts = true;
1456+
14371457
this.setWorkingParts({
14381458
...this.workingParts,
14391459
month,
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { expect } from '@playwright/test';
2+
import type { E2EPage } from '@utils/test/playwright';
3+
import { test } from '@utils/test/playwright';
4+
5+
test.describe('datetime: selecting a day', () => {
6+
const testHighlight = async (page: E2EPage, datetimeID: string) => {
7+
const today = new Date();
8+
await page.goto('/src/components/datetime/test/basic');
9+
10+
const todayBtn = page.locator(
11+
`#${datetimeID} .calendar-day[data-day='${today.getDate()}'][data-month='${today.getMonth() + 1}']`
12+
);
13+
14+
expect(todayBtn).toHaveClass(/calendar-day-today/);
15+
expect(todayBtn).not.toHaveClass(/calendar-day-active/);
16+
17+
await todayBtn.click();
18+
await page.waitForChanges();
19+
20+
expect(todayBtn).toHaveClass(/calendar-day-active/);
21+
};
22+
23+
test('should not highlight a day until one is selected', async ({ page }) => {
24+
await testHighlight(page, 'inline-datetime-no-value');
25+
});
26+
27+
test('should not highlight a day until one is selected, with default-buttons', async ({ page }) => {
28+
await testHighlight(page, 'custom-datetime');
29+
});
30+
});

core/src/components/datetime/test/basic/index.html

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,11 @@ <h2>Inline</h2>
261261
<ion-datetime value="2020-03-14T14:23:00.000Z" id="inline-datetime"></ion-datetime>
262262
</div>
263263

264+
<div class="grid-item">
265+
<h2>Inline - No Default Value</h2>
266+
<ion-datetime id="inline-datetime-no-value"></ion-datetime>
267+
</div>
268+
264269
<div class="grid-item">
265270
<h2>Popover</h2>
266271
<ion-button onclick="presentPopover(defaultPopover, event)">Present Popover</ion-button>

0 commit comments

Comments
 (0)