Skip to content

Commit 308aef5

Browse files
fix(datetime): multiple month selected and flakiness display (#31053)
Issue number: resolves internal --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? Currently, the Datepicker keeps all the months visited as selected instead of only the one that is really selected On iOS devices, the month picker sometimes doesn't appear since the `datepicker-ready` class is not added ## What is the new behavior? Only the selected month appears selected in the month picker On iOS devices, an additional validation is done to add the `datepicker-ready` class ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change: 1. Describe the impact and migration path for existing applications below. 2. Update the BREAKING.md file with the breaking change. 3. Add "BREAKING CHANGE: [...]" to the commit description when merging. See https://github.com/ionic-team/ionic-framework/blob/main/docs/CONTRIBUTING.md#footer for more information. --> ## Other information The [Basic](https://ionic-framework-7el9b9l3f-ionic1.vercel.app/src/components/datetime/test/basic/?ionic:theme=ionic) test should be used to test the multiple-month selection case <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. -->
1 parent dec46b5 commit 308aef5

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

core/src/components/datetime/datetime.tsx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1086,16 +1086,17 @@ export class Datetime implements ComponentInterface {
10861086

10871087
connectedCallback() {
10881088
this.clearFocusVisible = startFocusVisible(this.el).destroy;
1089+
this.loadTimeout = setTimeout(() => {
1090+
this.ensureReadyIfVisible();
1091+
}, 100);
10891092
}
10901093

10911094
disconnectedCallback() {
10921095
if (this.clearFocusVisible) {
10931096
this.clearFocusVisible();
10941097
this.clearFocusVisible = undefined;
10951098
}
1096-
if (this.loadTimeout) {
1097-
clearTimeout(this.loadTimeout);
1098-
}
1099+
this.loadTimeoutCleanup();
10991100
}
11001101

11011102
/**
@@ -1146,6 +1147,13 @@ export class Datetime implements ComponentInterface {
11461147
});
11471148
};
11481149

1150+
private loadTimeoutCleanup = () => {
1151+
if (this.loadTimeout) {
1152+
clearTimeout(this.loadTimeout);
1153+
this.loadTimeout = undefined;
1154+
}
1155+
};
1156+
11491157
componentDidLoad() {
11501158
const { el, intersectionTrackerRef } = this;
11511159

@@ -1193,7 +1201,10 @@ export class Datetime implements ComponentInterface {
11931201
* we still initialize listeners and mark the component as ready.
11941202
*
11951203
* We schedule this after everything has had a chance to run.
1204+
*
1205+
* We also clean up the load timeout to ensure that we don't have multiple timeouts running.
11961206
*/
1207+
this.loadTimeoutCleanup();
11971208
this.loadTimeout = setTimeout(() => {
11981209
this.ensureReadyIfVisible();
11991210
}, 100);

core/src/components/datetime/test/basic/datetime.e2e.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,43 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
349349
});
350350
});
351351

352+
/**
353+
* This behavior does not differ across
354+
* modes/directions.
355+
*/
356+
357+
configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
358+
test.describe(title('datetime: month picker selection'), () => {
359+
test('datetime: month picker selection', async ({ page }) => {
360+
await page.setContent(
361+
`
362+
<ion-datetime value="2022-05-03"></ion-datetime>
363+
`,
364+
config
365+
);
366+
367+
await page.locator('.datetime-ready').waitFor();
368+
369+
const nextMonthButton = page.locator('ion-datetime .calendar-next-prev ion-button').nth(1);
370+
const monthYearButton = page.locator('ion-datetime .calendar-month-year');
371+
372+
await expect(monthYearButton).toHaveText(/May 2022/);
373+
374+
await nextMonthButton.click();
375+
await expect(monthYearButton).toHaveText(/June 2022/);
376+
377+
await nextMonthButton.click();
378+
await expect(monthYearButton).toHaveText(/July 2022/);
379+
380+
await monthYearButton.click();
381+
await page.waitForChanges();
382+
383+
const selectedMonthOptions = page.locator('.month-column ion-picker-column-option.option-active');
384+
await expect(selectedMonthOptions).toHaveCount(1);
385+
});
386+
});
387+
});
388+
352389
/**
353390
* This behavior does not differ across
354391
* modes/directions.

core/src/components/picker-column/picker-column.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { ComponentInterface, EventEmitter } from '@stencil/core';
22
import { Component, Element, Event, Host, Method, Prop, State, Watch, h } from '@stencil/core';
33
import { doc } from '@utils/browser';
4-
import { getElementRoot, raf } from '@utils/helpers';
4+
import { raf } from '@utils/helpers';
55
import { hapticSelectionChanged, hapticSelectionEnd, hapticSelectionStart } from '@utils/native/haptic';
66
import { isPlatform } from '@utils/platform';
77
import { createColorClasses } from '@utils/theme';
@@ -122,9 +122,7 @@ export class PickerColumn implements ComponentInterface {
122122
* Because this initial call to scrollActiveItemIntoView has to fire before
123123
* the scroll listener is set up, we need to manage the active class manually.
124124
*/
125-
const oldActive = getElementRoot(el).querySelector<HTMLIonPickerColumnOptionElement>(
126-
`.${PICKER_ITEM_ACTIVE_CLASS}`
127-
);
125+
const oldActive = el.querySelector<HTMLIonPickerColumnOptionElement>(`.${PICKER_ITEM_ACTIVE_CLASS}`);
128126
if (oldActive) {
129127
this.setPickerItemActiveState(oldActive, false);
130128
}

0 commit comments

Comments
 (0)