fix(picker-column): column renders correctly with selected value (#24988)

Resolves #17664
This commit is contained in:
Sean Perkins
2022-04-04 14:46:57 -04:00
committed by GitHub
parent bcd00c7a6e
commit 83186598ed
5 changed files with 175 additions and 152 deletions

View File

@ -1856,7 +1856,7 @@ export namespace Components {
*/
"animated": boolean;
/**
* If `true`, the popover will display an arrow that points at the `reference` when running in `ios` mode on mobile. Does not apply in `md` mode or on desktop.
* If `true`, the popover will display an arrow that points at the `reference` when running in `ios` mode. Does not apply in `md` mode.
*/
"arrow": boolean;
/**
@ -5493,7 +5493,7 @@ declare namespace LocalJSX {
*/
"animated"?: boolean;
/**
* If `true`, the popover will display an arrow that points at the `reference` when running in `ios` mode on mobile. Does not apply in `md` mode or on desktop.
* If `true`, the popover will display an arrow that points at the `reference` when running in `ios` mode. Does not apply in `md` mode.
*/
"arrow"?: boolean;
/**

View File

@ -168,8 +168,9 @@ export class PickerColumnCmp implements ComponentInterface {
// Update transform
if (transform !== opt.transform) {
opt.transform = transform;
button.style.transform = transform;
}
button.style.transform = transform;
// Update selected item
if (selected !== opt.selected) {
opt.selected = selected;

View File

@ -0,0 +1,29 @@
import { newE2EPage } from '@stencil/core/testing';
describe('picker: basic', () => {
it('should match existing screenshots', async () => {
const page = await newE2EPage({
url: '/src/components/picker/test/basic?ionic:_testing=true',
});
const compares = [];
await page.click('#basic');
await page.waitForEvent('ionPickerDidPresent');
compares.push(await page.compareScreenshot('picker initial state'));
await page.click('ion-picker .save-btn');
await page.click('#basic');
await page.waitForEvent('ionPickerDidPresent');
compares.push(await page.compareScreenshot('picker opened with selected value'));
for (const compare of compares) {
expect(compare).toMatchScreenshot();
}
});
});

View File

@ -1,35 +1,28 @@
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" />
<head>
<meta charset="UTF-8">
<title>Picker - Basic</title>
<meta
name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
/>
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet" />
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" />
<meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
<link href="../../../../../css/ionic.bundle.css" rel="stylesheet">
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<script src="../../../../../scripts/testing/scripts.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
</head>
<script type="module">
</head>
<script type="module">
import { pickerController } from '../../../../dist/ionic/index.esm.js';
window.pickerController = pickerController;
</script>
<body>
</script>
<body>
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>Picker - Basic</ion-title>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding">
<ion-button id="basic" expand="block" onclick="presentPicker()">Show Picker</ion-button>
<ion-button id="custom" expand="block" onclick="presentPicker('my-custom-class')"
>Show Custom Picker</ion-button
>
<ion-button id="custom" expand="block" onclick="presentPicker('my-custom-class')">Show Custom Picker</ion-button>
</ion-content>
</ion-app>
@ -49,95 +42,92 @@
</style>
<script>
async function presentPicker(customClass) {
const pickerElement = await pickerController.create({
buttons: [
{
text: 'Cancel',
role: 'cancel',
handler: () => console.log('Clicked Cancel!'),
},
{
text: 'Save',
handler: () => console.log('Clicked Save!'),
},
{
text: 'Log',
handler: (val) => {
console.log('Clicked Log. Do not Dismiss.', val);
return false;
},
},
],
columns: [
{
name: 'hours',
prefix: 'total',
suffix: 'hours',
options: [
{
selectedIndex = 0;
const options = [{
text: '1',
value: '01',
value: '01'
},
{
text: '2',
value: '02',
value: '02'
},
{
text: '3',
value: '03',
value: '03'
},
{
text: '4',
value: '04',
value: '04'
},
{
text: '5',
value: '05',
value: '05'
},
{
text: '6',
value: '06',
value: '06'
},
{
text: '7',
value: '07',
value: '07'
},
{
text: '8',
value: '08',
value: '08'
},
{
text: '9',
value: '09',
value: '09'
},
{
text: '10',
value: '10',
value: '10'
},
{
text: '11',
value: '11',
value: '11'
},
{
text: '12',
value: '12',
},
],
},
],
value: '12'
}];
async function presentPicker(customClass) {
const pickerElement = await pickerController.create({
buttons: [{
text: 'Cancel',
role: 'cancel',
handler: () => console.log('Clicked Cancel!')
}, {
text: 'Save',
cssClass: 'save-btn',
handler: (ev) => {
const v = ev.hours.value;
selectedIndex = options.findIndex(opt => opt.value === v);
}
}, {
text: 'Log',
handler: (val) => {
return false;
}
}],
columns: [{
name: 'hours',
selectedIndex: selectedIndex,
prefix: 'total',
suffix: 'hours',
options: [...options]
}],
htmlAttributes: {
'data-testid': 'basic-picker',
'data-testid': 'basic-picker'
},
cssClass: customClass,
cssClass: customClass
});
await pickerElement.present();
const { data, role } = await pickerElement.onDidDismiss();
console.log('Picker dismissed!', data, role);
}
</script>
</body>
</body>
</html>

View File

@ -147,20 +147,23 @@ export const waitForFunctionTestContext = async (fn: any, params: any, interval
* https://github.com/GoogleChrome/puppeteer/issues/858#issuecomment-359763824
*/
export const queryDeep = async (page: E2EPage, ...selectors: string[]): Promise<ElementHandle> => {
const shadowSelectorFn = (el: Element, selector: string): Element | null => (el?.shadowRoot) && el.shadowRoot.querySelector(selector);
const shadowSelectorFn = (el: Element, selector: string): Element | null =>
el?.shadowRoot && el.shadowRoot.querySelector(selector);
// eslint-disable-next-line no-async-promise-executor
return new Promise(async resolve => {
return new Promise(async (resolve) => {
const [firstSelector, ...restSelectors] = selectors;
let parentElement = await page.$(firstSelector);
for (const selector of restSelectors) {
parentElement = await page.evaluateHandle(shadowSelectorFn, parentElement, selector) as any;
parentElement = (await page.evaluateHandle(shadowSelectorFn, parentElement, selector)) as any;
}
if (parentElement) { resolve(parentElement); }
if (parentElement) {
resolve(parentElement);
}
});
};
};
/**
* Given an element and optional selector, use the selector if
* it exists or get the node name of that element if not. Combine