mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 19:57:22 +08:00
fix(datetime): if no default value, don't highlight active day until one is selected (#25151)
This commit is contained in:
@ -68,6 +68,16 @@ export class Datetime implements ComponentInterface {
|
|||||||
private clearFocusVisible?: () => void;
|
private clearFocusVisible?: () => void;
|
||||||
private overlayIsPresenting = false;
|
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 parsedMinuteValues?: number[];
|
||||||
private parsedHourValues?: number[];
|
private parsedHourValues?: number[];
|
||||||
private parsedMonthValues?: number[];
|
private parsedMonthValues?: number[];
|
||||||
@ -1058,6 +1068,7 @@ export class Datetime implements ComponentInterface {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private processValue = (value?: string | null) => {
|
private processValue = (value?: string | null) => {
|
||||||
|
this.highlightActiveParts = !!value;
|
||||||
const valueToProcess = value || getToday();
|
const valueToProcess = value || getToday();
|
||||||
const { month, day, year, hour, minute, tzOffset } = parseDate(valueToProcess);
|
const { month, day, year, hour, minute, tzOffset } = parseDate(valueToProcess);
|
||||||
|
|
||||||
@ -1349,6 +1360,7 @@ export class Datetime implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private renderMonth(month: number, year: number) {
|
private renderMonth(month: number, year: number) {
|
||||||
|
const { highlightActiveParts } = this;
|
||||||
const yearAllowed = this.parsedYearValues === undefined || this.parsedYearValues.includes(year);
|
const yearAllowed = this.parsedYearValues === undefined || this.parsedYearValues.includes(year);
|
||||||
const monthAllowed = this.parsedMonthValues === undefined || this.parsedMonthValues.includes(month);
|
const monthAllowed = this.parsedMonthValues === undefined || this.parsedMonthValues.includes(month);
|
||||||
const isCalMonthDisabled = !yearAllowed || !monthAllowed;
|
const isCalMonthDisabled = !yearAllowed || !monthAllowed;
|
||||||
@ -1424,7 +1436,7 @@ export class Datetime implements ComponentInterface {
|
|||||||
class={{
|
class={{
|
||||||
'calendar-day-padding': day === null,
|
'calendar-day-padding': day === null,
|
||||||
'calendar-day': true,
|
'calendar-day': true,
|
||||||
'calendar-day-active': isActive,
|
'calendar-day-active': isActive && highlightActiveParts,
|
||||||
'calendar-day-today': isToday,
|
'calendar-day-today': isToday,
|
||||||
}}
|
}}
|
||||||
aria-selected={ariaSelected}
|
aria-selected={ariaSelected}
|
||||||
@ -1434,6 +1446,14 @@ export class Datetime implements ComponentInterface {
|
|||||||
return;
|
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.setWorkingParts({
|
||||||
...this.workingParts,
|
...this.workingParts,
|
||||||
month,
|
month,
|
||||||
|
30
core/src/components/datetime/test/basic/datetime.e2e.ts
Normal file
30
core/src/components/datetime/test/basic/datetime.e2e.ts
Normal 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');
|
||||||
|
});
|
||||||
|
});
|
@ -261,6 +261,11 @@
|
|||||||
<ion-datetime value="2020-03-14T14:23:00.000Z" id="inline-datetime"></ion-datetime>
|
<ion-datetime value="2020-03-14T14:23:00.000Z" id="inline-datetime"></ion-datetime>
|
||||||
</div>
|
</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">
|
<div class="grid-item">
|
||||||
<h2>Popover</h2>
|
<h2>Popover</h2>
|
||||||
<ion-button onclick="presentPopover(defaultPopover, event)">Present Popover</ion-button>
|
<ion-button onclick="presentPopover(defaultPopover, event)">Present Popover</ion-button>
|
||||||
|
Reference in New Issue
Block a user