fix(datetime): persist minutes column on hour change (#24829)

Resolves #24821
This commit is contained in:
Sean Perkins
2022-02-28 13:51:52 -05:00
committed by GitHub
parent e4ec572043
commit aacb58a322
3 changed files with 156 additions and 5 deletions

View File

@ -118,6 +118,25 @@ export class PickerColumnInternal implements ComponentInterface {
}
}
componentDidRender() {
const { activeItem, items, isColumnVisible, value } = this;
if (isColumnVisible) {
if (activeItem) {
this.scrollActiveItemIntoView();
} else if (items[0]?.value !== value) {
/**
* If the picker column does not have an active item and the current value
* does not match the first item in the picker column, that means
* the value is out of bounds. In this case, we assign the value to the
* first item to match the scroll position of the column.
*
*/
this.value = items[0].value;
}
}
}
/** @internal */
@Method()
async scrollActiveItemIntoView() {
@ -129,13 +148,20 @@ export class PickerColumnInternal implements ComponentInterface {
}
private centerPickerItemInView = (target: HTMLElement, smooth = true) => {
this.el.scroll({
const { el, isColumnVisible } = this;
if (isColumnVisible) {
// (Vertical offset from parent) - (three empty picker rows) + (half the height of the target to ensure the scroll triggers)
top: target.offsetTop - (3 * target.clientHeight) + (target.clientHeight / 2),
const top = target.offsetTop - (3 * target.clientHeight) + (target.clientHeight / 2);
if (el.scrollTop !== top) {
el.scroll({
top,
left: 0,
behavior: smooth ? 'smooth' : undefined
});
}
}
}
/**
* When ionInputModeChange is emitted, each column

View File

@ -0,0 +1,56 @@
import { E2EPage, newE2EPage } from '@stencil/core/testing';
describe('picker-column-internal', () => {
let page: E2EPage;
describe('default', () => {
beforeEach(async () => {
page = await newE2EPage({
url: '/src/components/picker-column-internal/test/basic?ionic:_testing=true'
});
});
it('should render a picker item for each item', async () => {
const columns = await page.findAll('ion-picker-column-internal >>> .picker-item:not(.picker-item-empty)');
expect(columns.length).toEqual(24);
});
it('should render 6 empty picker items', async () => {
const columns = await page.findAll('ion-picker-column-internal >>> .picker-item-empty');
expect(columns.length).toEqual(6);
});
it('should not have an active item when value is not set', async () => {
const activeColumn = await page.findAll('ion-picker-column-internal >>> .picker-item-active');
expect(activeColumn.length).toEqual(0);
});
it('should have an active item when value is set', async () => {
await page.$eval('ion-picker-column-internal#default', (el: any) => {
el.value = '12';
});
await page.waitForChanges();
const activeColumn = await page.find('ion-picker-column-internal >>> .picker-item-active');
expect(activeColumn).not.toBeNull();
});
it('scrolling should change the active item', async () => {
await page.$eval('ion-picker-column-internal#default', (el: any) => {
el.scrollTop = 801;
});
await page.waitForChanges();
const activeColumn = await page.find('ion-picker-column-internal >>> .picker-item-active');
expect(activeColumn.innerText).toEqual('23');
});
});
});

View File

@ -0,0 +1,69 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8">
<title>Picker Column Internal - Basic</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>
.grid {
display: grid;
grid-template-columns: repeat(3, minmax(250px, 1fr));
grid-row-gap: 20px;
grid-column-gap: 20px;
}
h2 {
font-size: 12px;
font-weight: normal;
color: #6f7378;
margin-top: 10px;
margin-left: 5px;
}
@media screen and (max-width: 800px) {
.grid {
grid-template-columns: 1fr;
padding: 0;
}
}
</style>
</head>
<body>
<ion-app>
<ion-header translucent="true">
<ion-toolbar>
<ion-title>Picker Column Internal - Basic</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<div class="grid">
<div class="grid-item">
<h2>Default</h2>
<ion-picker-internal>
<ion-picker-column-internal id="default"></ion-picker-column-internal>
</ion-picker-internal>
</div>
</div>
</ion-content>
<script>
const defaultPickerColumn = document.getElementById('default');
const items = Array(24).fill().map((_, i) => ({
text: `${i}`,
value: i
}));
defaultPickerColumn.items = items;
</script>
</ion-app>
</body>
</html>