diff --git a/core/src/components/datetime/datetime.tsx b/core/src/components/datetime/datetime.tsx
index f36cd66718d..ab9939504ae 100644
--- a/core/src/components/datetime/datetime.tsx
+++ b/core/src/components/datetime/datetime.tsx
@@ -8,6 +8,7 @@ import { isRTL } from '@utils/rtl';
import { createColorClasses } from '@utils/theme';
import { caretDownSharp, caretUpSharp, chevronBack, chevronDown, chevronForward } from 'ionicons/icons';
+import { config } from '../../global/config';
import { getIonMode } from '../../global/ionic-global';
import type { Color, Mode, StyleEventDetail } from '../../interface';
@@ -1555,10 +1556,11 @@ export class Datetime implements ComponentInterface {
const left = (nextMonth as HTMLElement).offsetWidth * 2;
+ const scrollMode = config.getBoolean('animated', true) ? 'smooth' : 'instant';
calendarBodyRef.scrollTo({
top: 0,
left: left * (isRTL(this.el) ? -1 : 1),
- behavior: 'smooth',
+ behavior: scrollMode,
});
};
@@ -1575,10 +1577,11 @@ export class Datetime implements ComponentInterface {
const left = (prevMonth as HTMLElement).offsetWidth * 2;
+ const scrollMode = config.getBoolean('animated', true) ? 'smooth' : 'instant';
calendarBodyRef.scrollTo({
top: 0,
left: left * (isRTL(this.el) ? 1 : -1),
- behavior: 'smooth',
+ behavior: scrollMode,
});
};
diff --git a/core/src/components/datetime/test/basic/datetime.e2e.ts b/core/src/components/datetime/test/basic/datetime.e2e.ts
index ff7c93c046e..3d8c8f111f3 100644
--- a/core/src/components/datetime/test/basic/datetime.e2e.ts
+++ b/core/src/components/datetime/test/basic/datetime.e2e.ts
@@ -816,3 +816,83 @@ 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: animated'), () => {
+ test('next month button should instantly replace month view when animations are disabled', async ({ page }) => {
+ test.info().annotations.push({
+ type: 'issue',
+ description: 'https://github.com/ionic-team/ionic-framework/issues/30484',
+ });
+
+ await page.addInitScript(() => {
+ (window as any).__scrollToCalls = [];
+ const original = Element.prototype.scrollTo;
+ Element.prototype.scrollTo = function (this: Element, ...args: any[]) {
+ if (this.classList?.contains('calendar-body')) {
+ (window as any).__scrollToCalls.push(args[0]);
+ }
+ return (original as any).apply(this, args);
+ };
+ });
+
+ await page.setContent(
+ `
+
+
+ `,
+ config
+ );
+ await page.locator('.datetime-ready').waitFor();
+
+ const nextMonthButton = page.locator('ion-datetime .calendar-next-prev ion-button').nth(1);
+ await nextMonthButton.click();
+ await page.waitForChanges();
+
+ const scrollCalls = await page.evaluate(() => (window as any).__scrollToCalls);
+
+ expect(scrollCalls.length).toBeGreaterThan(0);
+ expect(scrollCalls[0].behavior).toBe('instant');
+ });
+
+ test('previous month button should instantly replace month view when animations are disabled', async ({ page }) => {
+ test.info().annotations.push({
+ type: 'issue',
+ description: 'https://github.com/ionic-team/ionic-framework/issues/30484',
+ });
+
+ await page.addInitScript(() => {
+ (window as any).__scrollToCalls = [];
+ const original = Element.prototype.scrollTo;
+ Element.prototype.scrollTo = function (this: Element, ...args: any[]) {
+ if (this.classList?.contains('calendar-body')) {
+ (window as any).__scrollToCalls.push(args[0]);
+ }
+ return (original as any).apply(this, args);
+ };
+ });
+
+ await page.setContent(
+ `
+
+
+ `,
+ config
+ );
+ await page.locator('.datetime-ready').waitFor();
+
+ const prevMonthButton = page.locator('ion-datetime .calendar-next-prev ion-button').nth(0);
+ await prevMonthButton.click();
+ await page.waitForChanges();
+
+ const scrollCalls = await page.evaluate(() => (window as any).__scrollToCalls);
+
+ expect(scrollCalls.length).toBeGreaterThan(0);
+ expect(scrollCalls[0].behavior).toBe('instant');
+ });
+ });
+});