mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-22 05:21:52 +08:00
refactor(popover): add wrapper style directly, get el/ev off popover
This commit is contained in:
@ -1,4 +1,4 @@
|
||||
import { Component, Element, Event, EventEmitter, Listen, Prop } from '@stencil/core';
|
||||
import { Component, Element, Event, EventEmitter, Listen, Prop, State } from '@stencil/core';
|
||||
import { AnimationBuilder, Animation, AnimationController, Config } from '../../index';
|
||||
|
||||
import { createThemedClasses } from '../../utils/theme';
|
||||
@ -20,6 +20,8 @@ import iOSLeaveAnimation from './animations/ios.leave';
|
||||
export class Popover {
|
||||
private animation: Animation;
|
||||
|
||||
@State() positioned: boolean = false;
|
||||
|
||||
@Element() private el: HTMLElement;
|
||||
|
||||
@Event() private ionPopoverDidLoad: EventEmitter;
|
||||
@ -52,12 +54,18 @@ export class Popover {
|
||||
}
|
||||
|
||||
|
||||
private positionPopover(nativeEl: HTMLElement, ev: any, props: any) {
|
||||
console.debug('Position popover', nativeEl, ev, props);
|
||||
private positionPopover() {
|
||||
const props = POPOVER_POSITION_PROPERTIES[this.mode];
|
||||
console.debug('Position popover', this.el, this.ev, props);
|
||||
|
||||
// Declare the popover elements
|
||||
let contentEl = nativeEl.querySelector('.popover-content') as HTMLElement;
|
||||
let arrowEl = nativeEl.querySelector('.popover-arrow') as HTMLElement;
|
||||
let contentEl = this.el.querySelector('.popover-content') as HTMLElement;
|
||||
let arrowEl = this.el.querySelector('.popover-arrow') as HTMLElement;
|
||||
|
||||
// If no event was passed, hide the arrow
|
||||
if (!this.ev) {
|
||||
arrowEl.style.display = 'none';
|
||||
}
|
||||
|
||||
// Set the default transform origin direction
|
||||
let origin = {
|
||||
@ -79,7 +87,7 @@ export class Popover {
|
||||
}
|
||||
|
||||
// If ev was passed, use that for target element
|
||||
let targetDim = ev && ev.target && ev.target.getBoundingClientRect();
|
||||
let targetDim = this.ev && this.ev.target && (this.ev.target as HTMLElement).getBoundingClientRect();
|
||||
|
||||
// The target is the object that dispatched the event that was passed
|
||||
let target = {
|
||||
@ -102,11 +110,6 @@ export class Popover {
|
||||
height: arrowDim.height
|
||||
}
|
||||
|
||||
// If no ev was passed, hide the arrow
|
||||
if (!targetDim) {
|
||||
arrowEl.style.display = 'none';
|
||||
}
|
||||
|
||||
let arrowCSS = {
|
||||
top: target.top + target.height,
|
||||
left: target.left + (target.width / 2) - (arrow.width / 2)
|
||||
@ -135,7 +138,7 @@ export class Popover {
|
||||
// If the popover when popped down stretches past bottom of screen,
|
||||
// make it pop up if there's room above
|
||||
if (this.showFromBottom(target, popover, body)) {
|
||||
nativeEl.className = nativeEl.className + ' popover-bottom';
|
||||
this.el.className = this.el.className + ' popover-bottom';
|
||||
origin.y = 'bottom';
|
||||
|
||||
popoverCSS.top = target.top - popover.height;
|
||||
@ -160,7 +163,7 @@ export class Popover {
|
||||
|
||||
// Since the transition starts before styling is done we
|
||||
// want to wait for the styles to apply before showing the wrapper
|
||||
this.displayWrapper();
|
||||
this.positioned = true;
|
||||
}
|
||||
|
||||
private showFromBottom(target: any, popover: any, body: any): boolean {
|
||||
@ -171,11 +174,6 @@ export class Popover {
|
||||
return target.top + target.height + popover.height > body.height;
|
||||
}
|
||||
|
||||
private displayWrapper() {
|
||||
let popoverWrapperEle = this.el.querySelector('.popover-wrapper') as HTMLElement;
|
||||
popoverWrapperEle.style.opacity = '1';
|
||||
}
|
||||
|
||||
private _present(resolve: Function) {
|
||||
if (this.animation) {
|
||||
this.animation.destroy();
|
||||
@ -199,7 +197,7 @@ export class Popover {
|
||||
animation.onFinish((a: any) => {
|
||||
a.destroy();
|
||||
this.ionViewDidEnter();
|
||||
this.positionPopover(this.el, this.ev, POPOVER_POSITION_PROPERTIES[this.mode]);
|
||||
this.positionPopover();
|
||||
resolve();
|
||||
}).play();
|
||||
});
|
||||
@ -271,19 +269,17 @@ export class Popover {
|
||||
render() {
|
||||
const ThisComponent = this.component;
|
||||
|
||||
const dialogClasses = createThemedClasses(
|
||||
this.mode,
|
||||
this.color,
|
||||
'popover-wrapper'
|
||||
);
|
||||
const wrapperClasses = createThemedClasses(this.mode, this.color, 'popover-wrapper');
|
||||
|
||||
const wrapperStyle = this.positioned ? { 'opacity' : '1' } : {};
|
||||
|
||||
return [
|
||||
<ion-backdrop
|
||||
onClick={this.backdropClick.bind(this)}
|
||||
class="popover-backdrop"
|
||||
/>,
|
||||
<div class={dialogClasses}>
|
||||
<div class="popover-arrow" />
|
||||
<div class={wrapperClasses} style={wrapperStyle}>
|
||||
<div class="popover-arrow"/>
|
||||
<div class="popover-content">
|
||||
<div class="popover-viewport">
|
||||
<ThisComponent
|
||||
|
@ -24,6 +24,7 @@
|
||||
<ion-content padding>
|
||||
<ion-button block onclick="presentPopover('profile-page', event)">Show Popover</ion-button>
|
||||
<ion-button block onclick="presentPopover('list-page', event)">Show Long List Popover</ion-button>
|
||||
<ion-button block onclick="presentPopover('profile-page')">No Event Popover</ion-button>
|
||||
|
||||
<ion-popover-controller></ion-popover-controller>
|
||||
</ion-content>
|
||||
@ -83,8 +84,6 @@
|
||||
items += '<ion-item><ion-label>Item ' + i + '</ion-label></ion-item>';
|
||||
}
|
||||
|
||||
console.log(items);
|
||||
|
||||
this.innerHTML = `
|
||||
<ion-content>
|
||||
<ion-list>
|
||||
|
Reference in New Issue
Block a user