Skip to content

Commit

Permalink
feat(popover): position the popover on transition instead of create
Browse files Browse the repository at this point in the history
references #5420
  • Loading branch information
brandyscarney committed May 23, 2016
1 parent a96e36a commit 2cd1b51
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 67 deletions.
1 change: 0 additions & 1 deletion src/components/popover/popover.ios.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ $popover-ios-background: #f3f3f3 !default;
.popover-arrow {
position: absolute;
display: block;
top: -20px;
width: 20px;
height: 10px;
overflow: hidden;
Expand Down
132 changes: 76 additions & 56 deletions src/components/popover/popover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,7 @@ class PopoverCmp {
private _renderer: Renderer,
private _config: Config,
private _navParams: NavParams,
private _viewCtrl: ViewController,
private _platform: Platform
private _viewCtrl: ViewController
) {
this.d = _navParams.data.opts;
this.created = Date.now();
Expand All @@ -108,31 +107,55 @@ class PopoverCmp {
});
}

ngOnInit() {
if (this.d.event) {
this.positionView(this.d.event);
}
}

onPageDidEnter() {
let activeElement: any = document.activeElement;
if (document.activeElement) {
activeElement.blur();
}
}

positionView(ev) {
let nativeEle = this._elementRef.nativeElement;
dismiss(role): Promise<any> {
return this._viewCtrl.dismiss(null, role);
}

bdClick() {
if (this.isEnabled() && this.d.enableBackdropDismiss) {
this.dismiss('backdrop');
}
}

isEnabled() {
let tm = this._config.getNumber('overlayCreatedDiff', 750);
return (this.created + tm < Date.now());
}
}

export interface PopoverOptions {
cssClass?: string;
showBackdrop?: boolean;
enableBackdropDismiss?: boolean;
}

/**
* Animations for popover
*/
class PopoverTransition extends Transition {
constructor(opts: TransitionOptions) {
super(opts);
}

positionView(nativeEle: HTMLElement, ev) {
// Popover wrapper width and height
let popoverEle = nativeEle.querySelector('.popover-wrapper');
let popoverEle = <HTMLElement>nativeEle.querySelector('.popover-wrapper');
let popoverDim = popoverEle.getBoundingClientRect();
let popoverWidth = popoverDim.width;
let popoverHeight = popoverDim.height;

// Window body width and height
let bodyWidth = this._platform.width();
let bodyHeight = this._platform.height();
// let bodyWidth = this._platform.width();
// let bodyHeight = this._platform.height();
let bodyWidth = window.innerWidth;
let bodyHeight = window.innerHeight;

// Target element width and height
let targetDim = ev.target.getBoundingClientRect();
Expand All @@ -142,7 +165,7 @@ class PopoverCmp {
let targetHeight = targetDim.height;

// The arrow that shows above the popover on iOS
var arrowEle = nativeEle.querySelector('.popover-arrow');
var arrowEle = <HTMLElement>nativeEle.querySelector('.popover-arrow');
let arrowDim = arrowEle.getBoundingClientRect();
var arrowWidth = arrowDim.width;
var arrowHeight = arrowDim.height;
Expand Down Expand Up @@ -171,166 +194,163 @@ class PopoverCmp {
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);
nativeEle.className = nativeEle.className + ' popover-bottom';
}

this._renderer.setElementStyle(arrowEle, 'top', arrowCSS.top + 'px');
this._renderer.setElementStyle(arrowEle, 'left', arrowCSS.left + 'px');

this._renderer.setElementStyle(popoverEle, 'top', popoverCSS.top + 'px');
this._renderer.setElementStyle(popoverEle, 'left', popoverCSS.left + 'px');
}

dismiss(role): Promise<any> {
return this._viewCtrl.dismiss(null, role);
}

bdClick() {
if (this.isEnabled() && this.d.enableBackdropDismiss) {
this.dismiss('backdrop');
}
}
arrowEle.style.top = arrowCSS.top + 'px';
arrowEle.style.left = arrowCSS.left + 'px';

isEnabled() {
let tm = this._config.getNumber('overlayCreatedDiff', 750);
return (this.created + tm < Date.now());
popoverEle.style.top = popoverCSS.top + 'px';
popoverEle.style.left = popoverCSS.left + 'px';
}
}

export interface PopoverOptions {
event?: any;
cssClass?: string;
showBackdrop?: boolean;
enableBackdropDismiss?: boolean;
}

/**
* Animations for popover
*/
class PopoverPopIn extends Transition {
class PopoverPopIn extends PopoverTransition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(opts);

console.log(opts);

let ele = enteringView.pageRef().nativeElement;
this.positionView(ele, opts.ev);

let backdrop = new Animation(ele.querySelector('.backdrop'));
let arrow = new Animation(ele.querySelector('.popover-arrow'));
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));

arrow.fromTo('opacity', '0.01', '1');
wrapper.fromTo('opacity', '0.01', '1').fromTo('scale', '1.1', '1');
backdrop.fromTo('opacity', '0.01', '0.3');

this
.easing('ease-in-out')
.duration(200)
.add(backdrop)
.add(arrow)
.add(wrapper);
}
}
Transition.register('popover-pop-in', PopoverPopIn);


class PopoverPopOut extends Transition {
class PopoverPopOut extends PopoverTransition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(opts);

let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('.backdrop'));
let arrow = new Animation(ele.querySelector('.popover-arrow'));
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));

arrow.fromTo('opacity', '1', '0');
wrapper.fromTo('opacity', '1', '0').fromTo('scale', '1', '0.9');
backdrop.fromTo('opacity', '0.3', '0');

this
.easing('ease-in-out')
.duration(200)
.add(backdrop)
.add(arrow)
.add(wrapper);
}
}
Transition.register('popover-pop-out', PopoverPopOut);


class PopoverMdPopIn extends Transition {
class PopoverMdPopIn extends PopoverTransition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(opts);

let ele = enteringView.pageRef().nativeElement;
this.positionView(ele, opts.ev);

let backdrop = new Animation(ele.querySelector('.backdrop'));
let arrow = new Animation(ele.querySelector('.popover-arrow'));
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));

arrow.fromTo('opacity', '0.01', '1').fromTo('scale', '1.1', '1');
wrapper.fromTo('opacity', '0.01', '1').fromTo('scale', '1.1', '1');
backdrop.fromTo('opacity', '0.01', '0.5');

this
.easing('ease-in-out')
.duration(200)
.add(backdrop)
.add(wrapper);
.add(wrapper)
.add(arrow);
}
}
Transition.register('popover-md-pop-in', PopoverMdPopIn);


class PopoverMdPopOut extends Transition {
class PopoverMdPopOut extends PopoverTransition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(opts);

let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('.backdrop'));
let arrow = new Animation(ele.querySelector('.popover-arrow'));
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));

arrow.fromTo('opacity', '1', '0').fromTo('scale', '1', '0.9');
wrapper.fromTo('opacity', '1', '0').fromTo('scale', '1', '0.9');
backdrop.fromTo('opacity', '0.5', '0');

this
.easing('ease-in-out')
.duration(200)
.add(backdrop)
.add(wrapper);
.add(wrapper)
.add(arrow);
}
}
Transition.register('popover-md-pop-out', PopoverMdPopOut);



class PopoverWpPopIn extends Transition {
class PopoverWpPopIn extends PopoverTransition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(opts);

let ele = enteringView.pageRef().nativeElement;
this.positionView(ele, opts.ev);

let backdrop = new Animation(ele.querySelector('.backdrop'));
let arrow = new Animation(ele.querySelector('.popover-arrow'));
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));

arrow.fromTo('opacity', '0.01', '1').fromTo('scale', '1.3', '1');
wrapper.fromTo('opacity', '0.01', '1').fromTo('scale', '1.3', '1');
backdrop.fromTo('opacity', '0.01', '0.5');

this
.easing('cubic-bezier(0,0 0.05,1)')
.duration(200)
.add(backdrop)
.add(wrapper);
.add(wrapper)
.add(arrow);
}
}
Transition.register('popover-wp-pop-in', PopoverWpPopIn);


class PopoverWpPopOut extends Transition {
class PopoverWpPopOut extends PopoverTransition {
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
super(opts);

let ele = leavingView.pageRef().nativeElement;
let backdrop = new Animation(ele.querySelector('.backdrop'));
let arrow = new Animation(ele.querySelector('.popover-arrow'));
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));

arrow.fromTo('opacity', '1', '0').fromTo('scale', '1', '1.3');
wrapper.fromTo('opacity', '1', '0').fromTo('scale', '1', '1.3');
backdrop.fromTo('opacity', '0.5', '0');

this
.easing('ease-out')
.duration(150)
.add(backdrop)
.add(wrapper);
.add(wrapper)
.add(arrow);
}
}
Transition.register('popover-wp-pop-out', PopoverWpPopOut);
Expand Down
15 changes: 8 additions & 7 deletions src/components/popover/test/basic/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,17 @@ class PopoverPage {
templateUrl: 'main.html'
})
class E2EPage {
constructor(private nav: NavController) {}
popover: any;

presentPopover(ev) {
let popover = Popover.create(PopoverPage, {}, {
event: ev
});
constructor(private nav: NavController) {}

this.nav.present(popover);
createPopover() {
this.popover = Popover.create(PopoverPage);
}

this.nav.present(popover, {
presentPopover(ev) {
this.createPopover();
this.nav.present(this.popover, {
ev: ev
});
}
Expand Down
6 changes: 3 additions & 3 deletions src/components/popover/test/basic/main.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<ion-navbar *navbar primary>
<ion-buttons start>
<ion-buttons left>
<button (click)="presentPopover($event)">
<ion-icon name="options"></ion-icon>
<ion-icon name="person"></ion-icon>
</button>
<button (click)="presentPopover($event)">
<ion-icon name="more"></ion-icon>
<ion-icon name="search"></ion-icon>
</button>
</ion-buttons>
<ion-title>Popover</ion-title>
Expand Down

0 comments on commit 2cd1b51

Please sign in to comment.