diff --git a/core/src/components/datetime/datetime.tsx b/core/src/components/datetime/datetime.tsx
index c591972fd8d..e73cd55e0b8 100644
--- a/core/src/components/datetime/datetime.tsx
+++ b/core/src/components/datetime/datetime.tsx
@@ -1086,6 +1086,9 @@ export class Datetime implements ComponentInterface {
connectedCallback() {
this.clearFocusVisible = startFocusVisible(this.el).destroy;
+ this.loadTimeout = setTimeout(() => {
+ this.ensureReadyIfVisible();
+ }, 100);
}
disconnectedCallback() {
@@ -1093,9 +1096,7 @@ export class Datetime implements ComponentInterface {
this.clearFocusVisible();
this.clearFocusVisible = undefined;
}
- if (this.loadTimeout) {
- clearTimeout(this.loadTimeout);
- }
+ this.loadTimeoutCleanup();
}
/**
@@ -1146,6 +1147,13 @@ export class Datetime implements ComponentInterface {
});
};
+ private loadTimeoutCleanup = () => {
+ if (this.loadTimeout) {
+ clearTimeout(this.loadTimeout);
+ this.loadTimeout = undefined;
+ }
+ };
+
componentDidLoad() {
const { el, intersectionTrackerRef } = this;
@@ -1193,7 +1201,10 @@ export class Datetime implements ComponentInterface {
* we still initialize listeners and mark the component as ready.
*
* We schedule this after everything has had a chance to run.
+ *
+ * We also clean up the load timeout to ensure that we don't have multiple timeouts running.
*/
+ this.loadTimeoutCleanup();
this.loadTimeout = setTimeout(() => {
this.ensureReadyIfVisible();
}, 100);
diff --git a/core/src/components/datetime/test/basic/datetime.e2e.ts b/core/src/components/datetime/test/basic/datetime.e2e.ts
index 6104d0014cf..bbc6033374f 100644
--- a/core/src/components/datetime/test/basic/datetime.e2e.ts
+++ b/core/src/components/datetime/test/basic/datetime.e2e.ts
@@ -349,6 +349,43 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
});
});
+/**
+ * This behavior does not differ across
+ * modes/directions.
+ */
+
+configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => {
+ test.describe(title('datetime: month picker selection'), () => {
+ test('datetime: month picker selection', async ({ page }) => {
+ await page.setContent(
+ `
+
+ `,
+ config
+ );
+
+ await page.locator('.datetime-ready').waitFor();
+
+ const nextMonthButton = page.locator('ion-datetime .calendar-next-prev ion-button').nth(1);
+ const monthYearButton = page.locator('ion-datetime .calendar-month-year');
+
+ await expect(monthYearButton).toHaveText(/May 2022/);
+
+ await nextMonthButton.click();
+ await expect(monthYearButton).toHaveText(/June 2022/);
+
+ await nextMonthButton.click();
+ await expect(monthYearButton).toHaveText(/July 2022/);
+
+ await monthYearButton.click();
+ await page.waitForChanges();
+
+ const selectedMonthOptions = page.locator('.month-column ion-picker-column-option.option-active');
+ await expect(selectedMonthOptions).toHaveCount(1);
+ });
+ });
+});
+
/**
* This behavior does not differ across
* modes/directions.
diff --git a/core/src/components/picker-column/picker-column.tsx b/core/src/components/picker-column/picker-column.tsx
index 905ba8cf81e..53d6ca90d17 100644
--- a/core/src/components/picker-column/picker-column.tsx
+++ b/core/src/components/picker-column/picker-column.tsx
@@ -1,7 +1,7 @@
import type { ComponentInterface, EventEmitter } from '@stencil/core';
import { Component, Element, Event, Host, Method, Prop, State, Watch, h } from '@stencil/core';
import { doc } from '@utils/browser';
-import { getElementRoot, raf } from '@utils/helpers';
+import { raf } from '@utils/helpers';
import { hapticSelectionChanged, hapticSelectionEnd, hapticSelectionStart } from '@utils/native/haptic';
import { isPlatform } from '@utils/platform';
import { createColorClasses } from '@utils/theme';
@@ -122,9 +122,7 @@ export class PickerColumn implements ComponentInterface {
* Because this initial call to scrollActiveItemIntoView has to fire before
* the scroll listener is set up, we need to manage the active class manually.
*/
- const oldActive = getElementRoot(el).querySelector(
- `.${PICKER_ITEM_ACTIVE_CLASS}`
- );
+ const oldActive = el.querySelector(`.${PICKER_ITEM_ACTIVE_CLASS}`);
if (oldActive) {
this.setPickerItemActiveState(oldActive, false);
}