mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix(datetime): setting max/min does not increase number of nodes rendered (#26065)
resolves #26059
This commit is contained in:
@@ -19,7 +19,7 @@ import { isRTL } from '../../utils/rtl';
|
||||
import { createColorClasses } from '../../utils/theme';
|
||||
import type { PickerColumnItem } from '../picker-column-internal/picker-column-internal-interfaces';
|
||||
|
||||
import { isSameDay, warnIfValueOutOfBounds } from './utils/comparison';
|
||||
import { isSameDay, warnIfValueOutOfBounds, isBefore, isAfter } from './utils/comparison';
|
||||
import {
|
||||
generateMonths,
|
||||
getDaysOfMonth,
|
||||
@@ -32,7 +32,7 @@ import {
|
||||
getCombinedDateColumnData,
|
||||
} from './utils/data';
|
||||
import { formatValue, getLocalizedTime, getMonthAndDay, getMonthAndYear } from './utils/format';
|
||||
import { is24Hour, isLocaleDayPeriodRTL, isMonthFirstLocale } from './utils/helpers';
|
||||
import { is24Hour, isLocaleDayPeriodRTL, isMonthFirstLocale, getNumDaysInMonth } from './utils/helpers';
|
||||
import {
|
||||
calculateHourFromAMPM,
|
||||
convertDataToISO,
|
||||
@@ -1400,23 +1400,24 @@ export class Datetime implements ComponentInterface {
|
||||
* Previous month, current month, and next month
|
||||
*/
|
||||
const monthsToRender = generateMonths(workingParts);
|
||||
const lastMonth = monthsToRender[monthsToRender.length - 1];
|
||||
|
||||
/**
|
||||
* generateMonths returns the day data as well,
|
||||
* but we do not want the day value to act as a max/min
|
||||
* on the data we are going to generate.
|
||||
* Ensure that users can select the entire window of dates.
|
||||
*/
|
||||
for (let i = 0; i <= monthsToRender.length - 1; i++) {
|
||||
monthsToRender[i].day = null;
|
||||
}
|
||||
monthsToRender[0].day = 1;
|
||||
lastMonth.day = getNumDaysInMonth(lastMonth.month, lastMonth.year);
|
||||
|
||||
/**
|
||||
* If developers have provided their own
|
||||
* min/max values, use that instead. Otherwise,
|
||||
* fallback to the default range of 3 months.
|
||||
* Narrow the dates rendered based on min/max dates (if any).
|
||||
* The `min` date is used if the min is after the generated min month.
|
||||
* The `max` date is used if the max is before the generated max month.
|
||||
* This ensures that the sliding window always stays at 3 months
|
||||
* but still allows future dates to be lazily rendered based on any min/max
|
||||
* constraints.
|
||||
*/
|
||||
const min = minParts || monthsToRender[0];
|
||||
const max = maxParts || monthsToRender[monthsToRender.length - 1];
|
||||
const min = minParts !== undefined && isAfter(minParts, monthsToRender[0]) ? minParts : monthsToRender[0];
|
||||
const max = maxParts !== undefined && isBefore(maxParts, lastMonth) ? maxParts : lastMonth;
|
||||
|
||||
const result = getCombinedDateColumnData(
|
||||
locale,
|
||||
@@ -1426,6 +1427,7 @@ export class Datetime implements ComponentInterface {
|
||||
this.parsedDayValues,
|
||||
this.parsedMonthValues
|
||||
);
|
||||
|
||||
let items = result.items;
|
||||
const parts = result.parts;
|
||||
|
||||
|
||||
@@ -14,14 +14,37 @@ test.describe('datetime: prefer wheel', () => {
|
||||
* are rendering quirks on Linux
|
||||
* if the datetime is too small.
|
||||
*/
|
||||
test.describe('datetime: date wheel rendering', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
test.describe('datetime: wheel rendering', () => {
|
||||
test('should not have visual regressions for date wheel', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime size="cover" presentation="date" prefer-wheel="true" value="2019-05-30"></ion-datetime>
|
||||
`);
|
||||
|
||||
expect(await page.screenshot()).toMatchSnapshot(`datetime-wheel-date-diff-${page.getSnapshotSettings()}.png`);
|
||||
});
|
||||
test('should not have visual regressions for date-time wheel', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime size="cover" presentation="date-time" prefer-wheel="true" value="2019-05-30T16:30:00"></ion-datetime>
|
||||
`);
|
||||
|
||||
expect(await page.screenshot()).toMatchSnapshot(
|
||||
`datetime-wheel-date-time-diff-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
});
|
||||
test('should not have visual regressions for time-date wheel', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime size="cover" presentation="time-date" prefer-wheel="true" value="2019-05-30T16:30:00"></ion-datetime>
|
||||
`);
|
||||
|
||||
expect(await page.screenshot()).toMatchSnapshot(
|
||||
`datetime-wheel-time-date-diff-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
});
|
||||
});
|
||||
test.describe('datetime: date wheel', () => {
|
||||
test.beforeEach(({ skip }) => {
|
||||
skip.rtl();
|
||||
});
|
||||
test('should respect the min bounds', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime presentation="date" prefer-wheel="true" min="2019-05-05" max="2023-10-01" value="2019-05-30"></ion-datetime>
|
||||
@@ -149,15 +172,9 @@ test.describe('datetime: prefer wheel', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
test.describe('datetime: date-time wheel rendering', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime size="cover" presentation="date-time" prefer-wheel="true" value="2019-05-30T16:30:00"></ion-datetime>
|
||||
`);
|
||||
|
||||
expect(await page.screenshot()).toMatchSnapshot(
|
||||
`datetime-wheel-date-time-diff-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
test.describe('datetime: date-time wheel', () => {
|
||||
test.beforeEach(({ skip }) => {
|
||||
skip.rtl();
|
||||
});
|
||||
test('should respect the min bounds', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
@@ -249,20 +266,58 @@ test.describe('datetime: prefer wheel', () => {
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const dateValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
|
||||
const dateColumn = page.locator('.date-column');
|
||||
const dateValues = dateColumn.locator('.picker-item:not(.picker-item-empty)');
|
||||
|
||||
expect(await dateValues.count()).toBe(397);
|
||||
expect(await dateValues.count()).toBe(90);
|
||||
|
||||
/**
|
||||
* Select 1st item to change the dates rendered
|
||||
*/
|
||||
await expect(dateValues.nth(0)).toHaveAttribute('data-value', '2022-1-1');
|
||||
await dateColumn.evaluate((el: HTMLElement) => (el.scrollTop = 0));
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(dateValues.nth(0)).toHaveAttribute('data-value', '2021-12-1');
|
||||
});
|
||||
});
|
||||
test.describe('datetime: time-date wheel rendering', () => {
|
||||
test('should not have visual regressions', async ({ page }) => {
|
||||
test('should keep sliding window if default window is within min and max constraints', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime size="cover" presentation="time-date" prefer-wheel="true" value="2019-05-30T16:30:00"></ion-datetime>
|
||||
<ion-datetime
|
||||
presentation="date-time"
|
||||
prefer-wheel="true"
|
||||
value="2022-06-01"
|
||||
max="2030-01-01"
|
||||
min="2010-01-01"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
expect(await page.screenshot()).toMatchSnapshot(
|
||||
`datetime-wheel-time-date-diff-${page.getSnapshotSettings()}.png`
|
||||
);
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const dayValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
|
||||
|
||||
expect(await dayValues.count()).toBe(92);
|
||||
});
|
||||
test('should narrow sliding window if default window is not within min and max constraints', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
presentation="date-time"
|
||||
prefer-wheel="true"
|
||||
value="2022-06-01"
|
||||
max="2022-05-15"
|
||||
min="2022-05-01"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const dayValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
|
||||
|
||||
expect(await dayValues.count()).toBe(15);
|
||||
});
|
||||
});
|
||||
test.describe('datetime: time-date wheel', () => {
|
||||
test.beforeEach(({ skip }) => {
|
||||
skip.rtl();
|
||||
});
|
||||
test('should respect the min bounds', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
@@ -354,9 +409,53 @@ test.describe('datetime: prefer wheel', () => {
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const dateValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
|
||||
const dateColumn = page.locator('.date-column');
|
||||
const dateValues = dateColumn.locator('.picker-item:not(.picker-item-empty)');
|
||||
|
||||
expect(await dateValues.count()).toBe(397);
|
||||
expect(await dateValues.count()).toBe(90);
|
||||
|
||||
/**
|
||||
* Select 1st item to change the dates rendered
|
||||
*/
|
||||
await expect(dateValues.nth(0)).toHaveAttribute('data-value', '2022-1-1');
|
||||
await dateColumn.evaluate((el: HTMLElement) => (el.scrollTop = 0));
|
||||
await page.waitForChanges();
|
||||
|
||||
await expect(dateValues.nth(0)).toHaveAttribute('data-value', '2021-12-1');
|
||||
});
|
||||
test('should keep sliding window if default window is within min and max constraints', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
presentation="time-date"
|
||||
prefer-wheel="true"
|
||||
value="2022-06-01"
|
||||
max="2030-01-01"
|
||||
min="2010-01-01"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const dayValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
|
||||
|
||||
expect(await dayValues.count()).toBe(92);
|
||||
});
|
||||
test('should narrow sliding window if default window is not within min and max constraints', async ({ page }) => {
|
||||
await page.setContent(`
|
||||
<ion-datetime
|
||||
presentation="time-date"
|
||||
prefer-wheel="true"
|
||||
value="2022-06-01"
|
||||
max="2022-05-15"
|
||||
min="2022-05-01"
|
||||
></ion-datetime>
|
||||
`);
|
||||
|
||||
await page.waitForSelector('.datetime-ready');
|
||||
|
||||
const dayValues = page.locator('.date-column .picker-item:not(.picker-item-empty)');
|
||||
|
||||
expect(await dayValues.count()).toBe(15);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user