Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
merged 12 commits into from
Apr 26, 2022
22 changes: 21 additions & 1 deletion core/src/components/datetime/datetime.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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[];
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
averyjohnston marked this conversation as resolved.
Show resolved Hide resolved
'calendar-day-today': isToday,
}}
aria-selected={ariaSelected}
Expand All @@ -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,
Expand Down
30 changes: 30 additions & 0 deletions core/src/components/datetime/test/basic/datetime.e2e.ts
Original file line number Diff line number Diff line change
@@ -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');
});
});
5 changes: 5 additions & 0 deletions core/src/components/datetime/test/basic/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,11 @@ <h2>Inline</h2>
<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>
Expand Down