mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-07 15:07:13 +08:00
fix(datetime): clamp date between min and max when using month picker (#27185)
<!-- Please refer to our contributing documentation for any questions on submitting a pull request, or let us know here if you need any help: https://ionicframework.com/docs/building/contributing --> <!-- Some docs updates need to be made in the `ionic-docs` repo, in a separate PR. See https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#modifying-documentation for details. --> <!-- 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 using the dropdown month picker, the value is updated when the month is changed, to follow native behavior. However, because only the month is updated (the day remains the same), it's possible for the newly chosen date to fall outside the min/max bounds of the datetime. For example, if you have a datetime with `min="2021-01-15" value="2021-02-01"`, then use the month picker to switch to January, the new value will be `2021-01-01` which is earlier than the `min`. <!-- Issues are required for both bug fixes and features. --> Issue URL: Resolves #27027 ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> When updating the `activeParts` in any scenario, the date to set is now clamped between the max and min. ## 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. -->
This commit is contained in:
@ -240,6 +240,7 @@ test.describe('datetime: minmax', () => {
|
|||||||
skip.rtl();
|
skip.rtl();
|
||||||
skip.mode('ios', 'This implementation is the same across modes.');
|
skip.mode('ios', 'This implementation is the same across modes.');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should reset to min time if out of bounds', async ({ page }) => {
|
test('should reset to min time if out of bounds', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<ion-datetime
|
<ion-datetime
|
||||||
@ -259,6 +260,7 @@ test.describe('datetime: minmax', () => {
|
|||||||
|
|
||||||
await expect(datetime).toHaveJSProperty('value', '2022-10-10T08:00:00');
|
await expect(datetime).toHaveJSProperty('value', '2022-10-10T08:00:00');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should reset to max time if out of bounds', async ({ page }) => {
|
test('should reset to max time if out of bounds', async ({ page }) => {
|
||||||
await page.setContent(`
|
await page.setContent(`
|
||||||
<ion-datetime
|
<ion-datetime
|
||||||
@ -278,6 +280,28 @@ test.describe('datetime: minmax', () => {
|
|||||||
|
|
||||||
await expect(datetime).toHaveJSProperty('value', '2022-10-10T08:00:00');
|
await expect(datetime).toHaveJSProperty('value', '2022-10-10T08:00:00');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should adjust to in-bounds when using month picker', async ({ page }) => {
|
||||||
|
await page.setContent(`
|
||||||
|
<ion-datetime
|
||||||
|
min="2022-01-15"
|
||||||
|
value="2022-02-01"
|
||||||
|
presentation="date"
|
||||||
|
></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)');
|
||||||
|
|
||||||
|
await monthYearToggle.click();
|
||||||
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
await monthColumnItems.nth(0).click(); // switch to January
|
||||||
|
await page.waitForChanges();
|
||||||
|
|
||||||
|
await expect(datetime).toHaveJSProperty('value', '2022-01-15T00:00:00');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test.describe('datetime: confirm button', () => {
|
test.describe('datetime: confirm button', () => {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import type { DatetimeParts } from '../datetime-interface';
|
|||||||
|
|
||||||
import { isSameDay } from './comparison';
|
import { isSameDay } from './comparison';
|
||||||
import { getNumDaysInMonth } from './helpers';
|
import { getNumDaysInMonth } from './helpers';
|
||||||
import { parseAmPm } from './parse';
|
import { clampDate, parseAmPm } from './parse';
|
||||||
|
|
||||||
const twoDigit = (val: number | undefined): string => {
|
const twoDigit = (val: number | undefined): string => {
|
||||||
return ('0' + (val !== undefined ? Math.abs(val) : '0')).slice(-2);
|
return ('0' + (val !== undefined ? Math.abs(val) : '0')).slice(-2);
|
||||||
@ -333,7 +333,8 @@ export const calculateHourFromAMPM = (currentParts: DatetimeParts, newAMPM: 'am'
|
|||||||
/**
|
/**
|
||||||
* Updates parts to ensure that month and day
|
* Updates parts to ensure that month and day
|
||||||
* values are valid. For days that do not exist,
|
* values are valid. For days that do not exist,
|
||||||
* the closest valid day is used.
|
* or are outside the min/max bounds, the closest
|
||||||
|
* valid day is used.
|
||||||
*/
|
*/
|
||||||
export const validateParts = (
|
export const validateParts = (
|
||||||
parts: DatetimeParts,
|
parts: DatetimeParts,
|
||||||
@ -341,7 +342,7 @@ export const validateParts = (
|
|||||||
maxParts?: DatetimeParts
|
maxParts?: DatetimeParts
|
||||||
): DatetimeParts => {
|
): DatetimeParts => {
|
||||||
const { month, day, year } = parts;
|
const { month, day, year } = parts;
|
||||||
const partsCopy = { ...parts };
|
const partsCopy = clampDate({ ...parts }, minParts, maxParts);
|
||||||
|
|
||||||
const numDays = getNumDaysInMonth(month, year);
|
const numDays = getNumDaysInMonth(month, year);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user