fix(datetime): if no default value, don't highlight active day until one is selected (#25151)

This commit is contained in:
Amanda Johnston
2022-04-26 13:44:32 -05:00
committed by GitHub
parent e5e0e24f76
commit 98969395ab
3 changed files with 56 additions and 1 deletions

View File

@ -68,6 +68,16 @@ export class Datetime implements ComponentInterface {
private clearFocusVisible?: () => void;
private overlayIsPresenting = false;
/**
* Whether to highlight the active day with a solid circle (as opposed
* to the outline circle around today). If you don't specify an initial
* value for the datetime, it doesn't automatically init to a default to
* avoid unwanted change events firing. If the solid circle were still
* shown then, it would look like a date had already been selected, which
* is misleading UX.
*/
private highlightActiveParts = false;
private parsedMinuteValues?: number[];
private parsedHourValues?: number[];
private parsedMonthValues?: number[];
@ -1058,6 +1068,7 @@ export class Datetime implements ComponentInterface {
};
private processValue = (value?: string | null) => {
this.highlightActiveParts = !!value;
const valueToProcess = value || getToday();
const { month, day, year, hour, minute, tzOffset } = parseDate(valueToProcess);
@ -1349,6 +1360,7 @@ export class Datetime implements ComponentInterface {
}
private renderMonth(month: number, year: number) {
const { highlightActiveParts } = this;
const yearAllowed = this.parsedYearValues === undefined || this.parsedYearValues.includes(year);
const monthAllowed = this.parsedMonthValues === undefined || this.parsedMonthValues.includes(month);
const isCalMonthDisabled = !yearAllowed || !monthAllowed;
@ -1424,7 +1436,7 @@ export class Datetime implements ComponentInterface {
class={{
'calendar-day-padding': day === null,
'calendar-day': true,
'calendar-day-active': isActive,
'calendar-day-active': isActive && highlightActiveParts,
'calendar-day-today': isToday,
}}
aria-selected={ariaSelected}
@ -1434,6 +1446,14 @@ export class Datetime implements ComponentInterface {
return;
}
/**
* Note that for datetimes with confirm/cancel buttons, the value
* isn't updated until you call confirm(). We need to bring the
* solid circle back on day click for UX reasons, rather than only
* show the circle if `value` is truthy.
*/
this.highlightActiveParts = true;
this.setWorkingParts({
...this.workingParts,
month,

View File

@ -0,0 +1,30 @@
import { expect } from '@playwright/test';
import type { E2EPage } from '@utils/test/playwright';
import { test } from '@utils/test/playwright';
test.describe('datetime: selecting a day', () => {
const testHighlight = async (page: E2EPage, datetimeID: string) => {
const today = new Date();
await page.goto('/src/components/datetime/test/basic');
const todayBtn = page.locator(
`#${datetimeID} .calendar-day[data-day='${today.getDate()}'][data-month='${today.getMonth() + 1}']`
);
expect(todayBtn).toHaveClass(/calendar-day-today/);
expect(todayBtn).not.toHaveClass(/calendar-day-active/);
await todayBtn.click();
await page.waitForChanges();
expect(todayBtn).toHaveClass(/calendar-day-active/);
};
test('should not highlight a day until one is selected', async ({ page }) => {
await testHighlight(page, 'inline-datetime-no-value');
});
test('should not highlight a day until one is selected, with default-buttons', async ({ page }) => {
await testHighlight(page, 'custom-datetime');
});
});

View File

@ -261,6 +261,11 @@
<ion-datetime value="2020-03-14T14:23:00.000Z" id="inline-datetime"></ion-datetime>
</div>
<div class="grid-item">
<h2>Inline - No Default Value</h2>
<ion-datetime id="inline-datetime-no-value"></ion-datetime>
</div>
<div class="grid-item">
<h2>Popover</h2>
<ion-button onclick="presentPopover(defaultPopover, event)">Present Popover</ion-button>