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; "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; "arrow": boolean;
/** /**
@ -5493,7 +5493,7 @@ declare namespace LocalJSX {
*/ */
"animated"?: boolean; "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; "arrow"?: boolean;
/** /**

View File

@ -168,8 +168,9 @@ export class PickerColumnCmp implements ComponentInterface {
// Update transform // Update transform
if (transform !== opt.transform) { if (transform !== opt.transform) {
opt.transform = transform; opt.transform = transform;
button.style.transform = transform;
} }
button.style.transform = transform;
// Update selected item // Update selected item
if (selected !== opt.selected) { if (selected !== opt.selected) {
opt.selected = 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,143 +1,133 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" dir="ltr"> <html lang="en" dir="ltr">
<head>
<meta charset="UTF-8" /> <head>
<title>Picker - Basic</title> <meta charset="UTF-8">
<meta <title>Picker - Basic</title>
name="viewport" <meta name="viewport"
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" 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="../../../../../css/ionic.bundle.css" rel="stylesheet" /> <link href="../../../../../scripts/testing/styles.css" rel="stylesheet">
<link href="../../../../../scripts/testing/styles.css" rel="stylesheet" /> <script src="../../../../../scripts/testing/scripts.js"></script>
<script src="../../../../../scripts/testing/scripts.js"></script> <script nomodule src="../../../../../dist/ionic/ionic.js"></script>
<script nomodule src="../../../../../dist/ionic/ionic.js"></script> <script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script>
<script type="module" src="../../../../../dist/ionic/ionic.esm.js"></script> </head>
</head> <script type="module">
<script type="module"> import { pickerController } from '../../../../dist/ionic/index.esm.js';
import { pickerController } from '../../../../dist/ionic/index.esm.js'; window.pickerController = pickerController;
window.pickerController = pickerController; </script>
<body>
<ion-app>
<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-content>
</ion-app>
<style>
.my-custom-class {
--width: 200px;
--height: 50%;
--background: #272727;
--background-rgb: 39, 39, 39;
--border-width: 2px;
--border-color: #000000;
--border-radius: 16px 16px 0 0;
color: #d6d6d6;
}
</style>
<script>
selectedIndex = 0;
const options = [{
text: '1',
value: '01'
},
{
text: '2',
value: '02'
},
{
text: '3',
value: '03'
},
{
text: '4',
value: '04'
},
{
text: '5',
value: '05'
},
{
text: '6',
value: '06'
},
{
text: '7',
value: '07'
},
{
text: '8',
value: '08'
},
{
text: '9',
value: '09'
},
{
text: '10',
value: '10'
},
{
text: '11',
value: '11'
},
{
text: '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'
},
cssClass: customClass
});
await pickerElement.present();
}
</script> </script>
<body> </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-content>
</ion-app>
<style>
.my-custom-class {
--width: 200px;
--height: 50%;
--background: #272727;
--background-rgb: 39, 39, 39;
--border-width: 2px;
--border-color: #000000;
--border-radius: 16px 16px 0 0;
color: #d6d6d6;
}
</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: [
{
text: '1',
value: '01',
},
{
text: '2',
value: '02',
},
{
text: '3',
value: '03',
},
{
text: '4',
value: '04',
},
{
text: '5',
value: '05',
},
{
text: '6',
value: '06',
},
{
text: '7',
value: '07',
},
{
text: '8',
value: '08',
},
{
text: '9',
value: '09',
},
{
text: '10',
value: '10',
},
{
text: '11',
value: '11',
},
{
text: '12',
value: '12',
},
],
},
],
htmlAttributes: {
'data-testid': 'basic-picker',
},
cssClass: customClass,
});
await pickerElement.present();
const { data, role } = await pickerElement.onDidDismiss();
console.log('Picker dismissed!', data, role);
}
</script>
</body>
</html> </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 * https://github.com/GoogleChrome/puppeteer/issues/858#issuecomment-359763824
*/ */
export const queryDeep = async (page: E2EPage, ...selectors: string[]): Promise<ElementHandle> => { 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 // eslint-disable-next-line no-async-promise-executor
return new Promise(async resolve => { return new Promise(async (resolve) => {
const [firstSelector, ...restSelectors] = selectors; const [firstSelector, ...restSelectors] = selectors;
let parentElement = await page.$(firstSelector); let parentElement = await page.$(firstSelector);
for (const selector of restSelectors) { 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 * Given an element and optional selector, use the selector if
* it exists or get the node name of that element if not. Combine * it exists or get the node name of that element if not. Combine