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): selecting days updates value #26121

Merged
merged 15 commits into from Oct 13, 2022
Merged
94 changes: 45 additions & 49 deletions core/src/components/datetime/datetime.tsx
Expand Up @@ -561,7 +561,7 @@ export class Datetime implements ComponentInterface {
* "activePartsClone" and then falling back to
* today's DatetimeParts if no active date is selected.
*/
private getDefaultPart = () => {
private getDefaultPart = (): DatetimeParts => {
const { activePartsClone, todayParts } = this;

const firstPart = Array.isArray(activePartsClone) ? activePartsClone[0] : activePartsClone;
Expand Down Expand Up @@ -1393,7 +1393,9 @@ export class Datetime implements ComponentInterface {
}

private renderCombinedDatePickerColumn() {
const { activeParts, workingParts, locale, minParts, maxParts, todayParts, isDateEnabled } = this;
const { workingParts, locale, minParts, maxParts, todayParts, isDateEnabled } = this;

const activePart = this.getDefaultPart();

/**
* By default, generate a range of 3 months:
Expand Down Expand Up @@ -1489,12 +1491,10 @@ export class Datetime implements ComponentInterface {
...findPart,
});

if (!Array.isArray(activeParts)) {
this.setActiveParts({
...activeParts,
...findPart,
});
}
this.setActiveParts({
...activePart,
...findPart,
});

// We can re-attach the scroll listener after
// the working parts have been updated.
Expand Down Expand Up @@ -1583,7 +1583,9 @@ export class Datetime implements ComponentInterface {
return [];
}

const { activeParts, workingParts } = this;
const { workingParts } = this;

const activePart = this.getDefaultPart();

return (
<ion-picker-column-internal
Expand All @@ -1605,12 +1607,10 @@ export class Datetime implements ComponentInterface {
day: ev.detail.value,
});

if (!Array.isArray(activeParts)) {
this.setActiveParts({
...activeParts,
day: ev.detail.value,
});
}
this.setActiveParts({
...activePart,
day: ev.detail.value,
});

// We can re-attach the scroll listener after
// the working parts have been updated.
Expand All @@ -1627,7 +1627,9 @@ export class Datetime implements ComponentInterface {
return [];
}

const { activeParts, workingParts } = this;
const { workingParts } = this;

const activePart = this.getDefaultPart();

return (
<ion-picker-column-internal
Expand All @@ -1649,12 +1651,10 @@ export class Datetime implements ComponentInterface {
month: ev.detail.value,
});

if (!Array.isArray(activeParts)) {
this.setActiveParts({
...activeParts,
month: ev.detail.value,
});
}
this.setActiveParts({
...activePart,
month: ev.detail.value,
});

// We can re-attach the scroll listener after
// the working parts have been updated.
Expand All @@ -1670,7 +1670,9 @@ export class Datetime implements ComponentInterface {
return [];
}

const { activeParts, workingParts } = this;
const { workingParts } = this;

const activePart = this.getDefaultPart();

return (
<ion-picker-column-internal
Expand All @@ -1692,12 +1694,10 @@ export class Datetime implements ComponentInterface {
year: ev.detail.value,
});

if (!Array.isArray(activeParts)) {
this.setActiveParts({
...activeParts,
year: ev.detail.value,
});
}
this.setActiveParts({
...activePart,
year: ev.detail.value,
});

// We can re-attach the scroll listener after
// the working parts have been updated.
Expand Down Expand Up @@ -1750,12 +1750,10 @@ export class Datetime implements ComponentInterface {
hour: ev.detail.value,
});

if (!Array.isArray(activePart)) {
this.setActiveParts({
...activePart,
hour: ev.detail.value,
});
}
this.setActiveParts({
...activePart,
hour: ev.detail.value,
});

ev.stopPropagation();
}}
Expand All @@ -1780,12 +1778,10 @@ export class Datetime implements ComponentInterface {
minute: ev.detail.value,
});

if (!Array.isArray(activePart)) {
this.setActiveParts({
...activePart,
minute: ev.detail.value,
});
}
this.setActiveParts({
...activePart,
minute: ev.detail.value,
});

ev.stopPropagation();
}}
Expand Down Expand Up @@ -1816,13 +1812,11 @@ export class Datetime implements ComponentInterface {
hour,
});

if (!Array.isArray(activePart)) {
this.setActiveParts({
...activePart,
ampm: ev.detail.value,
hour,
});
}
this.setActiveParts({
...activePart,
ampm: ev.detail.value,
hour,
});

ev.stopPropagation();
}}
Expand Down Expand Up @@ -1914,6 +1908,8 @@ export class Datetime implements ComponentInterface {
// can free-scroll the calendar.
const isWorkingMonth = this.workingParts.month === month && this.workingParts.year === year;

const activePart = this.getDefaultPart();

return (
<div
// Non-visible months should be hidden from screen readers
Expand Down Expand Up @@ -1998,7 +1994,7 @@ export class Datetime implements ComponentInterface {
);
} else {
this.setActiveParts({
...this.activeParts,
...activePart,
month,
day,
year,
Expand Down
33 changes: 33 additions & 0 deletions core/src/components/datetime/test/basic/datetime.e2e.ts
Expand Up @@ -72,6 +72,39 @@ test.describe('datetime: selecting a day', () => {

await expect(activeDay).toHaveText('13');
});
test('should set both date and time when no value is initially set', async ({ page }) => {
await page.setContent(`
<ion-datetime locale="en-US" presentation="date-time"></ion-datetime>

<script>
const mockToday = '2022-10-10T16:22';
Date = class extends Date {
constructor(...args) {
if (args.length === 0) {
super(mockToday)
} else {
super(...args);
}
}
}
</script>
`);

await page.waitForSelector('.datetime-ready');
const datetime = page.locator('ion-datetime');
const ionChange = await page.spyOnEvent('ionChange');

// Oct 1, 2022
await page.click('.calendar-day[data-month="10"][data-year="2022"][data-day="1"]');

await ionChange.next();

const value = await datetime.evaluate((el: HTMLIonDatetimeElement) => el.value);
await expect(typeof value).toBe('string');

// Check to make sure value includes current time
await expect(value!.includes('2022-10-01T16:22')).toBe(true);
});
});

test.describe('datetime: confirm date', () => {
Expand Down
76 changes: 76 additions & 0 deletions core/src/components/datetime/test/prefer-wheel/datetime.e2e.ts
Expand Up @@ -112,6 +112,64 @@ test.describe('datetime: prefer wheel', () => {
expect(await yearValues.count()).toBe(3);
expect(await dayValues.count()).toBe(5);
});
test('selecting month should update value when no value is set', async ({ page }) => {
await page.setContent(`
<ion-datetime
presentation="date"
prefer-wheel="true"
></ion-datetime>
`);

await page.waitForSelector('.datetime-ready');

const ionChange = await page.spyOnEvent('ionChange');
const monthValues = page.locator('.month-column .picker-item:not(.picker-item-empty)');

// Change month value
await monthValues.nth(0).click();

await ionChange.next();
});
test('selecting day should update value when no value is set', async ({ page }) => {
await page.setContent(`
<ion-datetime
presentation="date"
prefer-wheel="true"
></ion-datetime>
`);

await page.waitForSelector('.datetime-ready');

const ionChange = await page.spyOnEvent('ionChange');
const dayValues = page.locator('.day-column .picker-item:not(.picker-item-empty)');

// Change day value
await dayValues.nth(0).click();

await ionChange.next();
});
test('selecting year should update value when no value is set', async ({ page }) => {
await page.setContent(`
<ion-datetime
presentation="date"
prefer-wheel="true"
></ion-datetime>
`);

await page.waitForSelector('.datetime-ready');

const ionChange = await page.spyOnEvent('ionChange');
const yearValues = page.locator('.year-column .picker-item:not(.picker-item-empty)');

/**
* Change year value
* The 0th index is the current
* year, so select something other than that.
*/
await yearValues.nth(10).click();

await ionChange.next();
});
test.describe('datetime: date wheel localization', () => {
test('should correctly localize the date data', async ({ page }) => {
await page.setContent(`
Expand Down Expand Up @@ -314,6 +372,24 @@ test.describe('datetime: prefer wheel', () => {

expect(await dayValues.count()).toBe(15);
});
test('selecting date should update value when no value is set', async ({ page }) => {
await page.setContent(`
<ion-datetime
presentation="date-time"
prefer-wheel="true"
></ion-datetime>
`);

await page.waitForSelector('.datetime-ready');

const ionChange = await page.spyOnEvent('ionChange');
const dayValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');

// Change day/month value
await dayValues.nth(0).click();

await ionChange.next();
});
});
test.describe('datetime: time-date wheel', () => {
test.beforeEach(({ skip }) => {
Expand Down