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