mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-17 18:54:11 +08:00
feat(popover): add ability to pass event to present method (#23827)
resolves #23813
This commit is contained in:
@ -887,7 +887,7 @@ ion-popover,prop,triggerAction,"click" | "context-menu" | "hover",'click',false,
|
||||
ion-popover,method,dismiss,dismiss(data?: any, role?: string | undefined, dismissParentPopover?: boolean) => Promise<boolean>
|
||||
ion-popover,method,onDidDismiss,onDidDismiss<T = any>() => Promise<OverlayEventDetail<T>>
|
||||
ion-popover,method,onWillDismiss,onWillDismiss<T = any>() => Promise<OverlayEventDetail<T>>
|
||||
ion-popover,method,present,present() => Promise<void>
|
||||
ion-popover,method,present,present(event?: MouseEvent | TouchEvent | PointerEvent | undefined) => Promise<void>
|
||||
ion-popover,event,didDismiss,OverlayEventDetail<any>,true
|
||||
ion-popover,event,didPresent,void,true
|
||||
ion-popover,event,ionPopoverDidDismiss,OverlayEventDetail<any>,true
|
||||
|
4
core/src/components.d.ts
vendored
4
core/src/components.d.ts
vendored
@ -1829,9 +1829,9 @@ export namespace Components {
|
||||
"onWillDismiss": <T = any>() => Promise<OverlayEventDetail<T>>;
|
||||
"overlayIndex": number;
|
||||
/**
|
||||
* Present the popover overlay after it has been created.
|
||||
* Present the popover overlay after it has been created. Developers can pass a mouse, touch, or pointer event to position the popover relative to where that event was dispatched.
|
||||
*/
|
||||
"present": () => Promise<void>;
|
||||
"present": (event?: MouseEvent | TouchEvent | PointerEvent | undefined) => Promise<void>;
|
||||
/**
|
||||
* When opening a popover from a trigger, we should not be modifying the `event` prop from inside the component. Additionally, when pressing the "Right" arrow key, we need to shift focus to the first descendant in the newly presented popover.
|
||||
*/
|
||||
|
@ -1,4 +1,8 @@
|
||||
import { AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Mode } from '../../interface';
|
||||
import { AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, Mode, OverlayInterface } from '../../interface';
|
||||
|
||||
export interface PopoverInterface extends OverlayInterface {
|
||||
present: (event?: MouseEvent | TouchEvent | PointerEvent) => Promise<void>;
|
||||
}
|
||||
|
||||
export interface PopoverOptions<T extends ComponentRef = ComponentRef> {
|
||||
component: T;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Component, ComponentInterface, Element, Event, EventEmitter, Host, Method, Prop, State, Watch, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, OverlayEventDetail, OverlayInterface, PopoverSize, PositionAlign, PositionReference, PositionSide, TriggerAction } from '../../interface';
|
||||
import { AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate, OverlayEventDetail, PopoverInterface, PopoverSize, PositionAlign, PositionReference, PositionSide, TriggerAction } from '../../interface';
|
||||
import { CoreDelegate, attachComponent, detachComponent } from '../../utils/framework-delegate';
|
||||
import { addEventListener, raf } from '../../utils/helpers';
|
||||
import { BACKDROP, dismiss, eventMethod, focusFirstDescendant, prepareOverlay, present } from '../../utils/overlays';
|
||||
@ -32,7 +32,7 @@ import { configureDismissInteraction, configureKeyboardInteraction, configureTri
|
||||
},
|
||||
shadow: true
|
||||
})
|
||||
export class Popover implements ComponentInterface, OverlayInterface {
|
||||
export class Popover implements ComponentInterface, PopoverInterface {
|
||||
|
||||
private usersElement?: HTMLElement;
|
||||
private triggerEl?: HTMLElement | null;
|
||||
@ -48,7 +48,6 @@ export class Popover implements ComponentInterface, OverlayInterface {
|
||||
private inline = false;
|
||||
private workingDelegate?: FrameworkDelegate;
|
||||
|
||||
private triggerEv?: Event;
|
||||
private focusDescendantOnPresent = false;
|
||||
|
||||
lastFocus?: HTMLElement;
|
||||
@ -305,12 +304,10 @@ export class Popover implements ComponentInterface, OverlayInterface {
|
||||
*/
|
||||
@Method()
|
||||
async presentFromTrigger(event?: any, focusDescendant = false) {
|
||||
this.triggerEv = event;
|
||||
this.focusDescendantOnPresent = focusDescendant;
|
||||
|
||||
await this.present();
|
||||
await this.present(event);
|
||||
|
||||
this.triggerEv = undefined;
|
||||
this.focusDescendantOnPresent = false;
|
||||
}
|
||||
|
||||
@ -349,9 +346,12 @@ export class Popover implements ComponentInterface, OverlayInterface {
|
||||
|
||||
/**
|
||||
* Present the popover overlay after it has been created.
|
||||
* Developers can pass a mouse, touch, or pointer event
|
||||
* to position the popover relative to where that event
|
||||
* was dispatched.
|
||||
*/
|
||||
@Method()
|
||||
async present(): Promise<void> {
|
||||
async present(event?: MouseEvent | TouchEvent | PointerEvent): Promise<void> {
|
||||
if (this.presented) {
|
||||
return;
|
||||
}
|
||||
@ -381,7 +381,7 @@ export class Popover implements ComponentInterface, OverlayInterface {
|
||||
this.configureDismissInteraction();
|
||||
|
||||
this.currentTransition = present(this, 'popoverEnter', iosEnterAnimation, mdEnterAnimation, {
|
||||
event: this.event || this.triggerEv,
|
||||
event: event || this.event,
|
||||
size: this.size,
|
||||
trigger: this.triggerEl,
|
||||
reference: this.reference,
|
||||
|
@ -577,9 +577,12 @@ Type: `Promise<OverlayEventDetail<T>>`
|
||||
|
||||
|
||||
|
||||
### `present() => Promise<void>`
|
||||
### `present(event?: MouseEvent | TouchEvent | PointerEvent | undefined) => Promise<void>`
|
||||
|
||||
Present the popover overlay after it has been created.
|
||||
Developers can pass a mouse, touch, or pointer event
|
||||
to position the popover relative to where that event
|
||||
was dispatched.
|
||||
|
||||
#### Returns
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { newE2EPage } from '@stencil/core/testing';
|
||||
|
||||
test('popover: inline', async () => {
|
||||
test('popover: inline, isOpen and event props', async () => {
|
||||
const page = await newE2EPage({ url: '/src/components/popover/test/inline?ionic:_testing=true' });
|
||||
const screenshotCompares = [];
|
||||
|
||||
await page.click('ion-button');
|
||||
await page.click('ion-button#props');
|
||||
await page.waitForSelector('ion-popover');
|
||||
|
||||
let popover = await page.find('ion-popover');
|
||||
@ -21,7 +21,43 @@ test('popover: inline', async () => {
|
||||
|
||||
popover = await page.find('ion-popover');
|
||||
|
||||
await page.click('ion-button');
|
||||
await page.click('ion-button#props');
|
||||
await page.waitForSelector('ion-popover');
|
||||
|
||||
let popoverAgain = await page.find('ion-popover');
|
||||
|
||||
expect(popoverAgain).not.toBe(null);
|
||||
await popoverAgain.waitForVisible();
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot());
|
||||
|
||||
for (const screenshotCompare of screenshotCompares) {
|
||||
expect(screenshotCompare).toMatchScreenshot();
|
||||
}
|
||||
});
|
||||
|
||||
test('popover: inline, present method', async () => {
|
||||
const page = await newE2EPage({ url: '/src/components/popover/test/inline?ionic:_testing=true' });
|
||||
const screenshotCompares = [];
|
||||
|
||||
await page.click('ion-button#method');
|
||||
await page.waitForSelector('ion-popover');
|
||||
|
||||
let popover = await page.find('ion-popover');
|
||||
|
||||
expect(popover).not.toBe(null);
|
||||
await popover.waitForVisible();
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot());
|
||||
|
||||
await popover.callMethod('dismiss');
|
||||
await popover.waitForNotVisible();
|
||||
|
||||
screenshotCompares.push(await page.compareScreenshot('dismiss'));
|
||||
|
||||
popover = await page.find('ion-popover');
|
||||
|
||||
await page.click('ion-button#method');
|
||||
await page.waitForSelector('ion-popover');
|
||||
|
||||
let popoverAgain = await page.find('ion-popover');
|
||||
|
@ -18,7 +18,8 @@
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding">
|
||||
<ion-button onclick="openPopover(event)">Open Popover</ion-button>
|
||||
<ion-button id="props" onclick="openPopover(event)">Open Popover via Props</ion-button>
|
||||
<ion-button id="method" onclick="openPopoverMethod(event)">Open Popover via Present Method</ion-button>
|
||||
|
||||
<ion-popover>
|
||||
<ion-content class="ion-padding">
|
||||
@ -35,6 +36,10 @@
|
||||
popover.event = ev;
|
||||
}
|
||||
|
||||
const openPopoverMethod = (ev) => {
|
||||
popover.present(ev);
|
||||
}
|
||||
|
||||
popover.addEventListener('didDismiss', () => {
|
||||
popover.isOpen = false;
|
||||
popover.event = undefined;
|
||||
|
Reference in New Issue
Block a user