mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 04:14:21 +08:00
fix(datetime): improve datetime sizing in modals (#24762)
Resolves #23992
This commit is contained in:
@ -811,6 +811,12 @@ export class Datetime implements ComponentInterface {
|
|||||||
navigator.maxTouchPoints > 1 ?
|
navigator.maxTouchPoints > 1 ?
|
||||||
[0.7, 1] : 1;
|
[0.7, 1] : 1;
|
||||||
|
|
||||||
|
// Intersection observers cannot accurately detect the
|
||||||
|
// intersection with a threshold of 1, when the observed
|
||||||
|
// element width is a sub-pixel value (i.e. 334.05px).
|
||||||
|
// Setting a root margin to 1px solves the issue.
|
||||||
|
const rootMargin = '1px';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Listen on the first month to
|
* Listen on the first month to
|
||||||
* prepend a new month and on the last
|
* prepend a new month and on the last
|
||||||
@ -829,15 +835,18 @@ export class Datetime implements ComponentInterface {
|
|||||||
* it applies to active gestures which is not
|
* it applies to active gestures which is not
|
||||||
* something WebKit does.
|
* something WebKit does.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
endIO = new IntersectionObserver(ev => ioCallback('end', ev), {
|
endIO = new IntersectionObserver(ev => ioCallback('end', ev), {
|
||||||
threshold,
|
threshold,
|
||||||
root: calendarBodyRef
|
root: calendarBodyRef,
|
||||||
|
rootMargin
|
||||||
});
|
});
|
||||||
endIO.observe(endMonth);
|
endIO.observe(endMonth);
|
||||||
|
|
||||||
startIO = new IntersectionObserver(ev => ioCallback('start', ev), {
|
startIO = new IntersectionObserver(ev => ioCallback('start', ev), {
|
||||||
threshold,
|
threshold,
|
||||||
root: calendarBodyRef
|
root: calendarBodyRef,
|
||||||
|
rootMargin
|
||||||
});
|
});
|
||||||
startIO.observe(startMonth);
|
startIO.observe(startMonth);
|
||||||
|
|
||||||
|
53
core/src/components/datetime/test/sub-pixel-width/e2e.ts
Normal file
53
core/src/components/datetime/test/sub-pixel-width/e2e.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { newE2EPage } from '@stencil/core/testing';
|
||||||
|
|
||||||
|
describe('datetime: sub-pixel width', () => {
|
||||||
|
|
||||||
|
test('should update the month when next button is clicked', async () => {
|
||||||
|
const page = await newE2EPage({
|
||||||
|
url: '/src/components/datetime/test/sub-pixel-width?ionic:_testing=true'
|
||||||
|
});
|
||||||
|
|
||||||
|
const openModalBtn = await page.find('#open-modal');
|
||||||
|
|
||||||
|
await openModalBtn.click();
|
||||||
|
|
||||||
|
const modal = await page.find('ion-modal');
|
||||||
|
await modal.waitForVisible();
|
||||||
|
await page.waitForTimeout(250);
|
||||||
|
|
||||||
|
const buttons = await page.findAll('ion-datetime >>> .calendar-next-prev ion-button')
|
||||||
|
|
||||||
|
await buttons[1].click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(350);
|
||||||
|
|
||||||
|
const monthYear = await page.find('ion-datetime >>> .calendar-month-year');
|
||||||
|
|
||||||
|
expect(monthYear.textContent.trim()).toBe('March 2022');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should update the month when prev button is clicked', async () => {
|
||||||
|
const page = await newE2EPage({
|
||||||
|
url: '/src/components/datetime/test/sub-pixel-width?ionic:_testing=true'
|
||||||
|
});
|
||||||
|
|
||||||
|
const openModalBtn = await page.find('#open-modal');
|
||||||
|
|
||||||
|
await openModalBtn.click();
|
||||||
|
|
||||||
|
const modal = await page.find('ion-modal');
|
||||||
|
await modal.waitForVisible();
|
||||||
|
await page.waitForTimeout(250);
|
||||||
|
|
||||||
|
const buttons = await page.findAll('ion-datetime >>> .calendar-next-prev ion-button')
|
||||||
|
|
||||||
|
await buttons[0].click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(350);
|
||||||
|
|
||||||
|
const monthYear = await page.find('ion-datetime >>> .calendar-month-year');
|
||||||
|
|
||||||
|
expect(monthYear.textContent.trim()).toBe('January 2022');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
47
core/src/components/datetime/test/sub-pixel-width/index.html
Normal file
47
core/src/components/datetime/test/sub-pixel-width/index.html
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Datetime - Sub Pixel Width</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
||||||
|
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
|
||||||
|
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
|
||||||
|
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||||
|
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||||
|
<style>
|
||||||
|
ion-datetime {
|
||||||
|
width: 334.05px;
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#background {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<ion-app>
|
||||||
|
<ion-header translucent="true">
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Datetime - Sub Pixel Width</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content class="ion-padding">
|
||||||
|
<h2>Modal</h2>
|
||||||
|
<ion-button id="open-modal">Present Modal</ion-button>
|
||||||
|
<ion-modal trigger="open-modal" id="modal">
|
||||||
|
<div id="background">
|
||||||
|
<ion-datetime id="picker" value="2022-02-01"></ion-datetime>
|
||||||
|
</div>
|
||||||
|
</ion-modal>
|
||||||
|
</ion-content>
|
||||||
|
</ion-app>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
136
core/src/components/datetime/test/zoom/e2e.ts
Normal file
136
core/src/components/datetime/test/zoom/e2e.ts
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
import { newE2EPage } from '@stencil/core/testing';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This test emulates zoom behavior in the browser to make sure
|
||||||
|
* that key functions of the ion-datetime continue to function even
|
||||||
|
* if the page is zoomed in or out.
|
||||||
|
*/
|
||||||
|
describe('datetime: zoom interactivity', () => {
|
||||||
|
|
||||||
|
let deviceScaleFactor;
|
||||||
|
|
||||||
|
describe('zoom out', () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
deviceScaleFactor = 0.75;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should update the month when next button is clicked', async () => {
|
||||||
|
const page = await newE2EPage({
|
||||||
|
url: '/src/components/datetime/test/sub-pixel-width?ionic:_testing=true'
|
||||||
|
});
|
||||||
|
|
||||||
|
page.setViewport({
|
||||||
|
width: 640,
|
||||||
|
height: 480,
|
||||||
|
deviceScaleFactor
|
||||||
|
});
|
||||||
|
|
||||||
|
const openModalBtn = await page.find('#open-modal');
|
||||||
|
|
||||||
|
await openModalBtn.click();
|
||||||
|
|
||||||
|
const modal = await page.find('ion-modal');
|
||||||
|
await modal.waitForVisible();
|
||||||
|
await page.waitForTimeout(250);
|
||||||
|
|
||||||
|
const buttons = await page.findAll('ion-datetime >>> .calendar-next-prev ion-button')
|
||||||
|
|
||||||
|
await buttons[1].click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(350);
|
||||||
|
|
||||||
|
const monthYear = await page.find('ion-datetime >>> .calendar-month-year');
|
||||||
|
|
||||||
|
expect(monthYear.textContent.trim()).toBe('March 2022');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should update the month when prev button is clicked', async () => {
|
||||||
|
const page = await newE2EPage({
|
||||||
|
url: '/src/components/datetime/test/sub-pixel-width?ionic:_testing=true'
|
||||||
|
});
|
||||||
|
|
||||||
|
const openModalBtn = await page.find('#open-modal');
|
||||||
|
|
||||||
|
await openModalBtn.click();
|
||||||
|
|
||||||
|
const modal = await page.find('ion-modal');
|
||||||
|
await modal.waitForVisible();
|
||||||
|
await page.waitForTimeout(250);
|
||||||
|
|
||||||
|
const buttons = await page.findAll('ion-datetime >>> .calendar-next-prev ion-button')
|
||||||
|
|
||||||
|
await buttons[0].click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(350);
|
||||||
|
|
||||||
|
const monthYear = await page.find('ion-datetime >>> .calendar-month-year');
|
||||||
|
|
||||||
|
expect(monthYear.textContent.trim()).toBe('January 2022');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('zoom in', () => {
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
deviceScaleFactor = 2;
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should update the month when next button is clicked', async () => {
|
||||||
|
const page = await newE2EPage({
|
||||||
|
url: '/src/components/datetime/test/sub-pixel-width?ionic:_testing=true'
|
||||||
|
});
|
||||||
|
|
||||||
|
page.setViewport({
|
||||||
|
width: 640,
|
||||||
|
height: 480,
|
||||||
|
deviceScaleFactor
|
||||||
|
});
|
||||||
|
|
||||||
|
const openModalBtn = await page.find('#open-modal');
|
||||||
|
|
||||||
|
await openModalBtn.click();
|
||||||
|
|
||||||
|
const modal = await page.find('ion-modal');
|
||||||
|
await modal.waitForVisible();
|
||||||
|
await page.waitForTimeout(250);
|
||||||
|
|
||||||
|
const buttons = await page.findAll('ion-datetime >>> .calendar-next-prev ion-button')
|
||||||
|
|
||||||
|
await buttons[1].click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(350);
|
||||||
|
|
||||||
|
const monthYear = await page.find('ion-datetime >>> .calendar-month-year');
|
||||||
|
|
||||||
|
expect(monthYear.textContent.trim()).toBe('March 2022');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should update the month when prev button is clicked', async () => {
|
||||||
|
const page = await newE2EPage({
|
||||||
|
url: '/src/components/datetime/test/sub-pixel-width?ionic:_testing=true'
|
||||||
|
});
|
||||||
|
|
||||||
|
const openModalBtn = await page.find('#open-modal');
|
||||||
|
|
||||||
|
await openModalBtn.click();
|
||||||
|
|
||||||
|
const modal = await page.find('ion-modal');
|
||||||
|
await modal.waitForVisible();
|
||||||
|
await page.waitForTimeout(250);
|
||||||
|
|
||||||
|
const buttons = await page.findAll('ion-datetime >>> .calendar-next-prev ion-button')
|
||||||
|
|
||||||
|
await buttons[0].click();
|
||||||
|
|
||||||
|
await page.waitForTimeout(350);
|
||||||
|
|
||||||
|
const monthYear = await page.find('ion-datetime >>> .calendar-month-year');
|
||||||
|
|
||||||
|
expect(monthYear.textContent.trim()).toBe('January 2022');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
42
core/src/components/datetime/test/zoom/index.html
Normal file
42
core/src/components/datetime/test/zoom/index.html
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en" dir="ltr">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Datetime - Zoom</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
||||||
|
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
|
||||||
|
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
|
||||||
|
<script src="../../../../../scripts/testing/scripts.js"></script>
|
||||||
|
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
|
||||||
|
<style>
|
||||||
|
#background {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<ion-app>
|
||||||
|
<ion-header translucent="true">
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Datetime - Zoom</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content class="ion-padding">
|
||||||
|
<h2>Modal</h2>
|
||||||
|
<ion-button id="open-modal">Present Modal</ion-button>
|
||||||
|
<ion-modal trigger="open-modal" id="modal">
|
||||||
|
<div id="background">
|
||||||
|
<ion-datetime id="picker" value="2022-02-01"></ion-datetime>
|
||||||
|
</div>
|
||||||
|
</ion-modal>
|
||||||
|
</ion-content>
|
||||||
|
</ion-app>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Reference in New Issue
Block a user