mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-15 09:34:19 +08:00
fix(datetime): changing months work if partially visible (#27917)
Issue number: resolves #27913 --------- <!-- 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? <!-- Please describe the current behavior that you are modifying. --> When determining what the changed month is, we grab the element at the center of the datetime and then grab the nearest calendar month. This works fine if the datetime is fully in view, but if the center point is out of the viewport then this will return `null`. As a result, scrolling in the datetime will break. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> - We now check scroll position instead of querying for DOM elements at coordinates. This allows the view to continue to update even if the entire calendar body is outside the viewport. ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. --> Dev build: `7.2.2-dev.11690996559.1019674a`
This commit is contained in:
@ -883,21 +883,18 @@ export class Datetime implements ComponentInterface {
|
||||
|
||||
const getChangedMonth = (parts: DatetimeParts): DatetimeParts | undefined => {
|
||||
const box = calendarBodyRef.getBoundingClientRect();
|
||||
const root = this.el!.shadowRoot!;
|
||||
|
||||
/**
|
||||
* Get the element that is in the center of the calendar body.
|
||||
* This will be an element inside of the active month.
|
||||
* If the current scroll position is all the way to the left
|
||||
* then we have scrolled to the previous month.
|
||||
* Otherwise, assume that we have scrolled to the next
|
||||
* month. We have a tolerance of 2px to account for
|
||||
* sub pixel rendering.
|
||||
*
|
||||
* Check below the next line ensures that we did not
|
||||
* swipe and abort (i.e. we swiped but we are still on the current month).
|
||||
*/
|
||||
const elementAtCenter = root.elementFromPoint(box.x + box.width / 2, box.y + box.height / 2);
|
||||
/**
|
||||
* If there is no element then the
|
||||
* component may be re-rendering on a slow device.
|
||||
*/
|
||||
if (!elementAtCenter) return;
|
||||
|
||||
const month = elementAtCenter.closest('.calendar-month');
|
||||
if (!month) return;
|
||||
const month = calendarBodyRef.scrollLeft <= 2 ? startMonth : endMonth;
|
||||
|
||||
/**
|
||||
* The edge of the month must be lined up with
|
||||
|
@ -301,21 +301,20 @@ configs({ directions: ['ltr'], modes: ['ios'] }).forEach(({ title, config }) =>
|
||||
<ion-datetime
|
||||
min="2022-01-15"
|
||||
value="2022-02-01"
|
||||
presentation="date"
|
||||
presentation="month-year"
|
||||
></ion-datetime>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
const datetime = page.locator('ion-datetime');
|
||||
const monthYearToggle = page.locator('ion-datetime .calendar-month-year');
|
||||
const monthColumnItems = page.locator('ion-datetime .month-column .picker-item:not(.picker-item-empty)');
|
||||
const ionChange = await page.spyOnEvent('ionChange');
|
||||
|
||||
await monthYearToggle.click();
|
||||
await page.waitForChanges();
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
await monthColumnItems.nth(0).click(); // switch to January
|
||||
await page.waitForChanges();
|
||||
await ionChange.next();
|
||||
|
||||
await expect(datetime).toHaveJSProperty('value', '2022-01-15T00:00:00');
|
||||
});
|
||||
|
@ -34,13 +34,14 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
`,
|
||||
config
|
||||
);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const datetime = page.locator('ion-datetime');
|
||||
const activeDayButton = page.locator('.calendar-day-active');
|
||||
const monthYearButton = page.locator('.calendar-month-year');
|
||||
const monthColumn = page.locator('.month-column');
|
||||
const yearColumn = page.locator('.year-column');
|
||||
const ionChange = await page.spyOnEvent('ionChange');
|
||||
|
||||
await datetime.evaluate((el: HTMLIonDatetimeElement) => (el.value = '2021-10-05'));
|
||||
|
||||
@ -49,11 +50,9 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
||||
await page.waitForChanges();
|
||||
|
||||
// Select October 2021
|
||||
// The year will automatically switch to 2021 when selecting 10
|
||||
await monthColumn.locator('.picker-item[data-value="10"]').click();
|
||||
await page.waitForChanges();
|
||||
|
||||
await yearColumn.locator('.picker-item[data-value="2021"]').click();
|
||||
await page.waitForChanges();
|
||||
await ionChange.next();
|
||||
|
||||
// Close month/year picker
|
||||
await monthYearButton.click();
|
||||
|
Reference in New Issue
Block a user