diff --git a/demos/popover/index.ts b/demos/popover/index.ts index 7175dd77cc..f64da678d1 100644 --- a/demos/popover/index.ts +++ b/demos/popover/index.ts @@ -4,7 +4,7 @@ import {App, Page, Popover, NavController, Content, NavParams} from 'ionic-angul @Page({ template: ` - + diff --git a/src/components/popover/popover.ts b/src/components/popover/popover.ts index b784db91e1..39d0ea600d 100644 --- a/src/components/popover/popover.ts +++ b/src/components/popover/popover.ts @@ -10,7 +10,8 @@ import {isPresent, isUndefined, isDefined} from '../../util/util'; import {nativeRaf, CSS} from '../../util/dom'; import {ViewController} from '../nav/view-controller'; -const POPOVER_BODY_PADDING = 2; +const POPOVER_IOS_BODY_PADDING = 2; +const POPOVER_MD_BODY_PADDING = 12; /** * @name Popover @@ -240,8 +241,7 @@ class PopoverTransition extends Transition { super(opts); } - - positionView(nativeEle: HTMLElement, ev) { + mdPositionView(nativeEle: HTMLElement, ev) { let originY = 'top'; let originX = 'left'; @@ -257,19 +257,73 @@ class PopoverTransition extends Transition { let bodyWidth = window.innerWidth; let bodyHeight = window.innerHeight; - let targetTop = (bodyHeight / 2) - (popoverHeight / 2); - let targetLeft = bodyWidth / 2; - let targetWidth = 0; - let targetHeight = 0; + // If ev was passed, use that for target element + let targetDim = ev && ev.target && ev.target.getBoundingClientRect(); + + let targetTop = targetDim && targetDim.top || (bodyHeight / 2) - (popoverHeight / 2); + let targetLeft = targetDim && targetDim.left || bodyWidth / 2 - (popoverWidth / 2); + let targetWidth = targetDim && targetDim.width || 0; + let targetHeight = targetDim && targetDim.height || 0; + + let popoverCSS = { + top: targetTop, + left: targetLeft + }; + + // 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_MD_BODY_PADDING) { + popoverCSS.left = POPOVER_MD_BODY_PADDING; + } else if (popoverWidth + POPOVER_MD_BODY_PADDING + popoverCSS.left > bodyWidth) { + popoverCSS.left = bodyWidth - popoverWidth - POPOVER_MD_BODY_PADDING; + originX = 'right'; + } + + // If the popover when popped down stretches past bottom of screen, + // make it pop up if there's room above + if (targetTop + targetHeight + popoverHeight > bodyHeight && targetTop - popoverHeight > 0) { + popoverCSS.top = targetTop - popoverHeight; + nativeEle.className = nativeEle.className + ' popover-bottom'; + originY = 'bottom'; + // If there isn't room for it to pop up above the target cut it off + } else if (targetTop + targetHeight + popoverHeight > bodyHeight) { + popoverEle.style.bottom = POPOVER_MD_BODY_PADDING + 'px'; + } + + popoverEle.style.top = popoverCSS.top + 'px'; + popoverEle.style.left = popoverCSS.left + 'px'; + + popoverEle.style[CSS.transformOrigin] = originY + ' ' + originX; + + // Since the transition starts before styling is done we + // want to wait for the styles to apply before showing the wrapper + popoverWrapperEle.style.opacity = '1'; + } + + iosPositionView(nativeEle: HTMLElement, ev) { + let originY = 'top'; + let originX = 'left'; + + let popoverWrapperEle = nativeEle.querySelector('.popover-wrapper'); + + // Popover content width and height + let popoverEle = nativeEle.querySelector('.popover-content'); + 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; // If ev was passed, use that for target element - if (ev && ev.target) { - let targetDim = ev.target.getBoundingClientRect(); - targetTop = targetDim.top; - targetLeft = targetDim.left; - targetWidth = targetDim.width; - targetHeight = targetDim.height; - } + let targetDim = ev && ev.target && ev.target.getBoundingClientRect(); + + let targetTop = targetDim && targetDim.top || (bodyHeight / 2) - (popoverHeight / 2); + let targetLeft = targetDim && targetDim.left || bodyWidth / 2; + let targetWidth = targetDim && targetDim.width || 0; + let targetHeight = targetDim && targetDim.height || 0; // The arrow that shows above the popover on iOS var arrowEle = nativeEle.querySelector('.popover-arrow'); @@ -290,10 +344,10 @@ class PopoverTransition extends Transition { // 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; - } else if (popoverWidth + POPOVER_BODY_PADDING + popoverCSS.left > bodyWidth) { - popoverCSS.left = bodyWidth - popoverWidth - POPOVER_BODY_PADDING; + if (popoverCSS.left < POPOVER_IOS_BODY_PADDING) { + popoverCSS.left = POPOVER_IOS_BODY_PADDING; + } else if (popoverWidth + POPOVER_IOS_BODY_PADDING + popoverCSS.left > bodyWidth) { + popoverCSS.left = bodyWidth - popoverWidth - POPOVER_IOS_BODY_PADDING; originX = 'right'; } @@ -306,7 +360,7 @@ class PopoverTransition extends Transition { originY = 'bottom'; // If there isn't room for it to pop up above the target cut it off } else if (targetTop + targetHeight + popoverHeight > bodyHeight) { - popoverEle.style.bottom = POPOVER_BODY_PADDING + '%'; + popoverEle.style.bottom = POPOVER_IOS_BODY_PADDING + '%'; } arrowEle.style.top = arrowCSS.top + 'px'; @@ -344,7 +398,7 @@ class PopoverPopIn extends PopoverTransition { play() { nativeRaf(() => { - this.positionView(this.enteringView.pageRef().nativeElement, this.opts.ev); + this.iosPositionView(this.enteringView.pageRef().nativeElement, this.opts.ev); super.play(); }); } @@ -394,7 +448,7 @@ class PopoverMdPopIn extends PopoverTransition { play() { nativeRaf(() => { - this.positionView(this.enteringView.pageRef().nativeElement, this.opts.ev); + this.mdPositionView(this.enteringView.pageRef().nativeElement, this.opts.ev); super.play(); }); } diff --git a/src/components/popover/test/basic/index.ts b/src/components/popover/test/basic/index.ts index 9c41e395a1..15a28ccb04 100644 --- a/src/components/popover/test/basic/index.ts +++ b/src/components/popover/test/basic/index.ts @@ -4,7 +4,7 @@ import {App, Page, Popover, NavController, Content, NavParams, ViewController} f @Page({ template: ` - + diff --git a/src/components/popover/test/basic/main.html b/src/components/popover/test/basic/main.html index d1893649aa..3ebe3c85fc 100644 --- a/src/components/popover/test/basic/main.html +++ b/src/components/popover/test/basic/main.html @@ -19,6 +19,11 @@ + + +