mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-20 04:14:21 +08:00
fix(picker-column): column renders correctly with selected value (#24988)
Resolves #17664
This commit is contained in:
4
core/src/components.d.ts
vendored
4
core/src/components.d.ts
vendored
@ -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;
|
||||||
/**
|
/**
|
||||||
|
@ -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;
|
||||||
|
29
core/src/components/picker/test/basic/e2e.ts
Normal file
29
core/src/components/picker/test/basic/e2e.ts
Normal 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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
@ -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>
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user