diff --git a/src/components/nav/nav-controller.ts b/src/components/nav/nav-controller.ts index 400b2633665..3d2ac2d12ae 100644 --- a/src/components/nav/nav-controller.ts +++ b/src/components/nav/nav-controller.ts @@ -1157,7 +1157,8 @@ export class NavController extends Ion { duration: opts.duration, easing: opts.easing, renderDelay: opts.transitionDelay || this._trnsDelay, - isRTL: this.config.platform.isRTL() + isRTL: this.config.platform.isRTL(), + ev: opts.ev, }; let transAnimation = Transition.createTransition(enteringView, @@ -1779,6 +1780,7 @@ export interface NavOptions { postLoad?: Function; progressAnimation?: boolean; climbNav?: boolean; + ev?: any; } const STATE_ACTIVE = 'active'; diff --git a/src/components/popover/popover.ios.scss b/src/components/popover/popover.ios.scss index 10c00f74ab0..b8b9db308f8 100644 --- a/src/components/popover/popover.ios.scss +++ b/src/components/popover/popover.ios.scss @@ -4,7 +4,6 @@ // iOS Popover // -------------------------------------------------- -$popover-ios-padding: 24px 34px !default; $popover-ios-min-width: 150px !default; $popover-ios-max-width: 270px !default; $popover-ios-max-height: 90% !default; @@ -14,8 +13,6 @@ $popover-ios-background: #f3f3f3 !default; .popover-wrapper { - padding: $popover-ios-padding; - min-width: $popover-ios-min-width; max-width: $popover-ios-max-width; @@ -34,8 +31,8 @@ $popover-ios-background: #f3f3f3 !default; position: absolute; display: block; top: -20px; - width: 30px; - height: 19px; + width: 20px; + height: 10px; overflow: hidden; &:after { @@ -43,14 +40,15 @@ $popover-ios-background: #f3f3f3 !default; z-index: $z-index-overlay-wrapper; - top: 12px; - left: 5px; - width: 20px; - height: 20px; + top: 3px; + left: 3px; + width: 14px; + height: 14px; + background-color: $popover-ios-background; border-radius: 3px; content: ''; - transform: rotate(-45deg); + transform: rotate(45deg); } } diff --git a/src/components/popover/popover.md.scss b/src/components/popover/popover.md.scss index cf55cb4145f..0c99afc308a 100644 --- a/src/components/popover/popover.md.scss +++ b/src/components/popover/popover.md.scss @@ -4,7 +4,6 @@ // Material Design Popover // -------------------------------------------------- -$popover-md-padding: 24px 34px !default; $popover-md-min-width: 150px !default; $popover-md-max-width: 270px !default; $popover-md-max-height: 90% !default; @@ -14,8 +13,6 @@ $popover-md-background: #fafafa !default; .popover-wrapper { - padding: $popover-md-padding; - min-width: $popover-md-min-width; max-width: $popover-md-max-width; @@ -25,11 +22,3 @@ $popover-md-background: #fafafa !default; color: $popover-md-text-color; background: $popover-md-background; } - - -// Material Design Popover Template -// ----------------------------------------- - -.popover-template { - -} diff --git a/src/components/popover/popover.scss b/src/components/popover/popover.scss index b91090877d8..140ae6e174e 100644 --- a/src/components/popover/popover.scss +++ b/src/components/popover/popover.scss @@ -3,8 +3,8 @@ // Popover // -------------------------------------------------- -$popover-min-width: 150px !default; -$popover-max-height: 90% !default; +$popover-width: 200px !default; +$popover-height: 250px !default; ion-popover { @@ -29,10 +29,20 @@ ion-popover { flex-direction: column; - min-width: $popover-min-width; - max-height: $popover-max-height; + width: $popover-width; + height: $popover-height; + + min-width: $popover-width; + max-height: $popover-height; + + overflow: hidden; opacity: 0; + + ion-page { + display: flex; + overflow: auto; + } } diff --git a/src/components/popover/popover.ts b/src/components/popover/popover.ts index 8240323fa66..e19b9c60397 100644 --- a/src/components/popover/popover.ts +++ b/src/components/popover/popover.ts @@ -1,13 +1,15 @@ -import {Component, Renderer, ElementRef, HostListener, ViewEncapsulation} from '@angular/core'; +import {Component, ViewChild, ViewContainerRef, DynamicComponentLoader} from '@angular/core'; +import {Renderer, ElementRef} from '@angular/core'; import {Animation} from '../../animations/animation'; import {Transition, TransitionOptions} from '../../transitions/transition'; import {Config} from '../../config/config'; import {NavParams} from '../nav/nav-params'; +import {Platform} from '../../platform/platform' import {isPresent, isUndefined, isDefined} from '../../util/util'; import {ViewController} from '../nav/view-controller'; -const POPOVER_BODY_PADDING = 6; +const POPOVER_BODY_PADDING = 2; /** * @name Popover @@ -16,14 +18,15 @@ const POPOVER_BODY_PADDING = 6; */ export class Popover extends ViewController { - constructor(opts: PopoverOptions = {}) { + constructor(componentType, data: any = {}, opts: PopoverOptions = {}) { opts.showBackdrop = isPresent(opts.showBackdrop) ? !!opts.showBackdrop : true; opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true; - super(PopoverCmp, opts); + data.componentType = componentType; + data.opts = opts; + super(PopoverCmp, data); this.viewType = 'popover'; this.isOverlay = true; - this.usePortal = false; // by default, popovers should not fire lifecycle events of other views // for example, when a popover enters, the current active view should @@ -44,16 +47,16 @@ export class Popover extends ViewController { * * | Option | Type | Description | * |-----------------------|------------|------------------------------------------------------------------------------------------------------------------| - * | template |`string` | The html content for the popover. | * | cssClass |`string` | An additional class for custom styles. | * | showBackdrop |`boolean` | Whether to show the backdrop. Default true. | * | enableBackdropDismiss |`boolean` | Wheather the popover should be dismissed by tapping the backdrop. Default true. | * * + * @param {object} data Any data to pass to the popover view * @param {object} opts Popover options */ - static create(opts: PopoverOptions = {}) { - return new Popover(opts); + static create(componentType, data = {}, opts: PopoverOptions = {}) { + return new Popover(componentType, data, opts); } } @@ -64,30 +67,29 @@ export class Popover extends ViewController { @Component({ selector: 'ion-popover', template: - '' + + '
' + '
' + '
' + - '
' + - '
', - host: { - 'role': 'dialog' - }, - encapsulation: ViewEncapsulation.None, + '
' + + '' }) class PopoverCmp { + @ViewChild('viewport', {read: ViewContainerRef}) viewport: ViewContainerRef; + private d: any; private id: number; private created: number; private showSpinner: boolean; - constructor( - private _viewCtrl: ViewController, - private _config: Config, + constructor(private _loader: DynamicComponentLoader, private _elementRef: ElementRef, private _renderer: Renderer, - params: NavParams + private _config: Config, + private _navParams: NavParams, + private _viewCtrl: ViewController, + private _platform: Platform ) { - this.d = params.data; + this.d = _navParams.data.opts; this.created = Date.now(); if (this.d.cssClass) { @@ -97,9 +99,18 @@ class PopoverCmp { this.id = (++popoverIds); } + onPageWillEnter() { + this._loader.loadNextToLocation(this._navParams.data.componentType, this.viewport).then(componentRef => { + this._viewCtrl.setInstance(componentRef.instance); + + // manually fire onPageWillEnter() since ModalCmp's onPageWillEnter already happened + this._viewCtrl.willEnter(); + }); + } + ngOnInit() { - if (this.d.element && this.d.event) { - this.positionView(this.d.element, this.d.event); + if (this.d.event) { + this.positionView(this.d.event); } } @@ -110,71 +121,64 @@ class PopoverCmp { } } - positionView(targetEle, ev) { - let popoverEle = this._elementRef.nativeElement; - let popoverWrapperEle = popoverEle.querySelector('.popover-wrapper'); + positionView(ev) { + let nativeEle = this._elementRef.nativeElement; - // Popover width and height - let popoverWidth = popoverWrapperEle.offsetWidth; - let popoverHeight = popoverWrapperEle.offsetHeight; + // Popover wrapper width and height + let popoverEle = nativeEle.querySelector('.popover-wrapper'); + let popoverDim = popoverEle.getBoundingClientRect(); + let popoverWidth = popoverDim.width; + let popoverHeight = popoverDim.height; // Window body width and height - let bodyWidth = window.innerWidth; - let bodyHeight = window.innerHeight; - - // Clicked element width and height - targetEle = targetEle._elementRef.nativeElement; - let targetWidth = targetEle.offsetWidth; - let targetHeight = targetEle.offsetHeight; + let bodyWidth = this._platform.width(); + let bodyHeight = this._platform.height(); - // console.log("Popover Wrapper Element", popoverWrapperEle); - // console.log("Popover Wrapper Width & Height", popoverWidth, popoverHeight); - // console.log("Body Width & Height", bodyWidth, bodyHeight); - // console.log("Target", targetEle); - // console.log("Target Width & Height", targetWidth, targetHeight); - - let popoverCSS = { - top: ev.clientY + targetHeight - (popoverHeight / 2), - left: ev.clientX - popoverWidth / 2 - }; + // Target element width and height + let targetDim = ev.target.getBoundingClientRect(); + let targetTop = targetDim.top; + let targetLeft = targetDim.left; + let targetWidth = targetDim.width; + let targetHeight = targetDim.height; // The arrow that shows above the popover on iOS - var arrowEle = popoverEle.querySelector('.popover-arrow'); - var arrowWidth = arrowEle.offsetWidth; - var arrowHeight = arrowEle.offsetHeight; - - let arrowLeft = targetWidth + targetWidth / 2 - - arrowEle.offsetWidth / 2 - popoverCSS.left; + var arrowEle = nativeEle.querySelector('.popover-arrow'); + let arrowDim = arrowEle.getBoundingClientRect(); + var arrowWidth = arrowDim.width; + var arrowHeight = arrowDim.height; let arrowCSS = { - top: ev.clientY + targetHeight - (popoverHeight / 2) - arrowHeight, - left: ev.clientX - (arrowWidth / 2) + top: targetTop + targetHeight, + left: targetLeft + (targetWidth / 2) - (arrowWidth / 2) } + let popoverCSS = { + top: targetTop + targetHeight + (arrowHeight - 1), + left: targetLeft + (targetWidth / 2) - (popoverWidth / 2) + }; + // If the popover left is less than the padding it is off screen // to the left so adjust it, else if the width of the popover // exceeds the body width it is off screen to the right so adjust if (popoverCSS.left < POPOVER_BODY_PADDING) { popoverCSS.left = POPOVER_BODY_PADDING; - arrowCSS.left = (POPOVER_BODY_PADDING * 2); } else if (popoverWidth + POPOVER_BODY_PADDING + popoverCSS.left > bodyWidth) { popoverCSS.left = bodyWidth - popoverWidth - POPOVER_BODY_PADDING; - arrowCSS.left = bodyWidth - (POPOVER_BODY_PADDING * 2) - arrowWidth; } // If the popover when popped down stretches past bottom of screen, // make it pop up if there's room above - if (popoverCSS.top + POPOVER_BODY_PADDING + popoverHeight > bodyHeight && - popoverCSS.top - popoverHeight > 0) { - popoverCSS.top = popoverCSS.top - targetHeight - popoverHeight; - this._renderer.setElementClass(this._elementRef.nativeElement, 'popover-bottom', true); + if (popoverCSS.top + POPOVER_BODY_PADDING + popoverHeight > bodyHeight && popoverCSS.top - popoverHeight > 0) { + arrowCSS.top = targetTop - (arrowHeight + 1); + popoverCSS.top = targetTop - popoverHeight - (arrowHeight - 1); + this._renderer.setElementClass(this._elementRef.nativeElement, 'popover-bottom', true); } this._renderer.setElementStyle(arrowEle, 'top', arrowCSS.top + 'px'); this._renderer.setElementStyle(arrowEle, 'left', arrowCSS.left + 'px'); - this._renderer.setElementStyle(popoverWrapperEle, 'top', popoverCSS.top + 'px'); - this._renderer.setElementStyle(popoverWrapperEle, 'left', popoverCSS.left + 'px'); + this._renderer.setElementStyle(popoverEle, 'top', popoverCSS.top + 'px'); + this._renderer.setElementStyle(popoverEle, 'left', popoverCSS.left + 'px'); } dismiss(role): Promise { @@ -194,8 +198,6 @@ class PopoverCmp { } export interface PopoverOptions { - template?: string; - element?: any; event?: any; cssClass?: string; showBackdrop?: boolean; @@ -209,6 +211,8 @@ class PopoverPopIn extends Transition { constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) { super(opts); + console.log(opts); + let ele = enteringView.pageRef().nativeElement; let backdrop = new Animation(ele.querySelector('.backdrop')); let wrapper = new Animation(ele.querySelector('.popover-wrapper')); diff --git a/src/components/popover/popover.wp.scss b/src/components/popover/popover.wp.scss index bd63fe78a4f..8320527c387 100644 --- a/src/components/popover/popover.wp.scss +++ b/src/components/popover/popover.wp.scss @@ -4,18 +4,15 @@ // Windows Popover // -------------------------------------------------- -$popover-wp-padding: 24px 34px !default; $popover-wp-min-width: 150px !default; $popover-wp-max-width: 270px !default; $popover-wp-max-height: 90% !default; $popover-wp-border-radius: 2px !default; -$popover-wp-text-color: #fff !default; -$popover-wp-background: #000 !default; +$popover-wp-text-color: #000 !default; +$popover-wp-background: #fff !default; .popover-wrapper { - padding: $popover-wp-padding; - min-width: $popover-wp-min-width; max-width: $popover-wp-max-width; @@ -25,11 +22,3 @@ $popover-wp-background: #000 !default; color: $popover-wp-text-color; background: $popover-wp-background; } - - -// Windows Popover Template -// ----------------------------------------- - -.popover-template { - -} diff --git a/src/components/popover/test/basic/index.ts b/src/components/popover/test/basic/index.ts index 6607382ea37..2496f89abbc 100644 --- a/src/components/popover/test/basic/index.ts +++ b/src/components/popover/test/basic/index.ts @@ -1,24 +1,39 @@ import {App, Page, Popover, NavController} from '../../../../../src'; +@Page({ + template: ` + + Ionic + + + + + + + ` +}) +class PopoverPage { + +} + + @Page({ templateUrl: 'main.html' }) class E2EPage { constructor(private nav: NavController) {} - presentPopover(ele, ev) { - console.log(ev); - - let popover = Popover.create({ - template: ` - My Popover - `, - element: ele, + presentPopover(ev) { + let popover = Popover.create(PopoverPage, {}, { event: ev }); this.nav.present(popover); + + this.nav.present(popover, { + ev: ev + }); } } diff --git a/src/components/popover/test/basic/main.html b/src/components/popover/test/basic/main.html index 35165d2a021..609c241a6dd 100644 --- a/src/components/popover/test/basic/main.html +++ b/src/components/popover/test/basic/main.html @@ -1,7 +1,18 @@ - + + + + + Popover - + @@ -9,7 +20,7 @@ - @@ -18,7 +29,7 @@ Popover - diff --git a/src/transitions/transition.ts b/src/transitions/transition.ts index 0e0a88dd5c2..8117ab0b55a 100644 --- a/src/transitions/transition.ts +++ b/src/transitions/transition.ts @@ -36,6 +36,7 @@ export interface TransitionOptions { direction: string; renderDelay?: number; isRTL?: boolean; + ev?: any; } let TransitionRegistry = {};