fix(popover): inline popover positioning with fit-content or auto width (#26230)

Resolves #24716
This commit is contained in:
Sean Perkins
2022-11-10 16:17:43 -05:00
committed by GitHub
parent 2080ddce26
commit 0a8a958cba
4 changed files with 42 additions and 2 deletions

View File

@ -108,7 +108,7 @@ export class IonPopover {
constructor(c: ChangeDetectorRef, r: ElementRef, protected z: NgZone) {
this.el = r.nativeElement;
this.el.addEventListener('willPresent', () => {
this.el.addEventListener('ionMount', () => {
this.isCmpOpen = true;
c.detectChanges();
});

View File

@ -5907,6 +5907,10 @@ declare namespace LocalJSX {
* Emitted after the popover has presented. Shorthand for ionPopoverWillDismiss.
*/
"onDidPresent"?: (event: IonPopoverCustomEvent<void>) => void;
/**
* Emitted before the popover has presented, but after the component has been mounted in the DOM. This event exists for ion-popover to resolve an issue with the popover and the lazy build, that the transition is unable to get the correct dimensions of the popover with auto sizing. This is not required for other overlays, since the existing overlay transitions are not effected by auto sizing content.
*/
"onIonMount"?: (event: IonPopoverCustomEvent<void>) => void;
/**
* Emitted after the popover has dismissed.
*/

View File

@ -27,7 +27,12 @@ import { iosEnterAnimation } from './animations/ios.enter';
import { iosLeaveAnimation } from './animations/ios.leave';
import { mdEnterAnimation } from './animations/md.enter';
import { mdLeaveAnimation } from './animations/md.leave';
import { configureDismissInteraction, configureKeyboardInteraction, configureTriggerInteraction } from './utils';
import {
configureDismissInteraction,
configureKeyboardInteraction,
configureTriggerInteraction,
waitOneFrame,
} from './utils';
/**
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
@ -310,6 +315,19 @@ export class Popover implements ComponentInterface, PopoverInterface {
*/
@Event({ eventName: 'didDismiss' }) didDismissShorthand!: EventEmitter<OverlayEventDetail>;
/**
* Emitted before the popover has presented, but after the component
* has been mounted in the DOM.
* This event exists for ion-popover to resolve an issue with the
* popover and the lazy build, that the transition is unable to get
* the correct dimensions of the popover with auto sizing.
* This is not required for other overlays, since the existing
* overlay transitions are not effected by auto sizing content.
*
* @internal
*/
@Event() ionMount!: EventEmitter<void>;
connectedCallback() {
const { configureTriggerInteraction, el } = this;
@ -446,6 +464,20 @@ export class Popover implements ComponentInterface, PopoverInterface {
}
this.configureDismissInteraction();
// TODO: FW-2773: Apply this to only the lazy build.
if (inline === true) {
/**
* ionMount only needs to be emitted if the popover is inline.
*/
this.ionMount.emit();
/**
* Wait one raf before presenting the popover.
* This allows the lazy build enough time to
* calculate the popover dimensions for the animation.
*/
await waitOneFrame();
}
this.currentTransition = present(this, 'popoverEnter', iosEnterAnimation, mdEnterAnimation, {
event: event || this.event,
size: this.size,

View File

@ -928,3 +928,7 @@ export const shouldShowArrow = (side: PositionSide, didAdjustBounds = false, ev?
return true;
};
export const waitOneFrame = () => {
return new Promise<void>((resolve) => raf(() => resolve()));
};