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 getChangedMonth = (parts: DatetimeParts): DatetimeParts | undefined => {
|
||||||
const box = calendarBodyRef.getBoundingClientRect();
|
const box = calendarBodyRef.getBoundingClientRect();
|
||||||
const root = this.el!.shadowRoot!;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the element that is in the center of the calendar body.
|
* If the current scroll position is all the way to the left
|
||||||
* This will be an element inside of the active month.
|
* 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);
|
const month = calendarBodyRef.scrollLeft <= 2 ? startMonth : endMonth;
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The edge of the month must be lined up with
|
* The edge of the month must be lined up with
|
||||||
|
@ -301,21 +301,20 @@ configs({ directions: ['ltr'], modes: ['ios'] }).forEach(({ title, config }) =>
|
|||||||
<ion-datetime
|
<ion-datetime
|
||||||
min="2022-01-15"
|
min="2022-01-15"
|
||||||
value="2022-02-01"
|
value="2022-02-01"
|
||||||
presentation="date"
|
presentation="month-year"
|
||||||
></ion-datetime>
|
></ion-datetime>
|
||||||
`,
|
`,
|
||||||
config
|
config
|
||||||
);
|
);
|
||||||
|
|
||||||
const datetime = page.locator('ion-datetime');
|
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 monthColumnItems = page.locator('ion-datetime .month-column .picker-item:not(.picker-item-empty)');
|
||||||
|
const ionChange = await page.spyOnEvent('ionChange');
|
||||||
|
|
||||||
await monthYearToggle.click();
|
await page.waitForSelector('.datetime-ready');
|
||||||
await page.waitForChanges();
|
|
||||||
|
|
||||||
await monthColumnItems.nth(0).click(); // switch to January
|
await monthColumnItems.nth(0).click(); // switch to January
|
||||||
await page.waitForChanges();
|
await ionChange.next();
|
||||||
|
|
||||||
await expect(datetime).toHaveJSProperty('value', '2022-01-15T00:00:00');
|
await expect(datetime).toHaveJSProperty('value', '2022-01-15T00:00:00');
|
||||||
});
|
});
|
||||||
|
@ -34,13 +34,14 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) =>
|
|||||||
`,
|
`,
|
||||||
config
|
config
|
||||||
);
|
);
|
||||||
|
|
||||||
await page.waitForSelector('.datetime-ready');
|
await page.waitForSelector('.datetime-ready');
|
||||||
|
|
||||||
const datetime = page.locator('ion-datetime');
|
const datetime = page.locator('ion-datetime');
|
||||||
const activeDayButton = page.locator('.calendar-day-active');
|
const activeDayButton = page.locator('.calendar-day-active');
|
||||||
const monthYearButton = page.locator('.calendar-month-year');
|
const monthYearButton = page.locator('.calendar-month-year');
|
||||||
const monthColumn = page.locator('.month-column');
|
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'));
|
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();
|
await page.waitForChanges();
|
||||||
|
|
||||||
// Select October 2021
|
// Select October 2021
|
||||||
|
// The year will automatically switch to 2021 when selecting 10
|
||||||
await monthColumn.locator('.picker-item[data-value="10"]').click();
|
await monthColumn.locator('.picker-item[data-value="10"]').click();
|
||||||
await page.waitForChanges();
|
await ionChange.next();
|
||||||
|
|
||||||
await yearColumn.locator('.picker-item[data-value="2021"]').click();
|
|
||||||
await page.waitForChanges();
|
|
||||||
|
|
||||||
// Close month/year picker
|
// Close month/year picker
|
||||||
await monthYearButton.click();
|
await monthYearButton.click();
|
||||||
|
Reference in New Issue
Block a user