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'); + }); + }); +});