Skip to content

Commit 5d06c4a

Browse files
committed
feat(popover): support popping from bottom or top of screen
Closes #1986
1 parent 25ee658 commit 5d06c4a

File tree

3 files changed

+56
-13
lines changed

3 files changed

+56
-13
lines changed

Diff for: js/angular/service/popover.js

+20-8
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@
6565

6666

6767
IonicModule
68-
.factory('$ionicPopover', ['$ionicModal', '$ionicPosition', '$document',
69-
function($ionicModal, $ionicPosition, $document) {
68+
.factory('$ionicPopover', ['$ionicModal', '$ionicPosition', '$document', '$window',
69+
function($ionicModal, $ionicPosition, $document, $window) {
7070

7171
var POPOVER_BODY_PADDING = 6;
7272

@@ -81,23 +81,35 @@ function($ionicModal, $ionicPosition, $document) {
8181
var targetEle = angular.element(target.target || target);
8282
var buttonOffset = $ionicPosition.offset( targetEle );
8383
var popoverWidth = popoverEle.prop('offsetWidth');
84+
var popoverHeight = popoverEle.prop('offsetHeight');
8485
var bodyWidth = $document[0].body.clientWidth;
85-
var bodyHeight = $document[0].body.clientHeight;
86+
// clientHeight doesn't work on all platforms for body
87+
var bodyHeight = $window.innerHeight;
8688

8789
var popoverCSS = {
88-
top: buttonOffset.top + buttonOffset.height,
8990
left: buttonOffset.left + buttonOffset.width / 2 - popoverWidth / 2
9091
};
92+
var arrowEle = jqLite(popoverEle[0].querySelector('.popover-arrow'));
9193

92-
if(popoverCSS.left < POPOVER_BODY_PADDING) {
94+
if (popoverCSS.left < POPOVER_BODY_PADDING) {
9395
popoverCSS.left = POPOVER_BODY_PADDING;
9496
} else if(popoverCSS.left + popoverWidth + POPOVER_BODY_PADDING > bodyWidth) {
9597
popoverCSS.left = bodyWidth - popoverWidth - POPOVER_BODY_PADDING;
9698
}
9799

98-
var arrowEle = popoverEle[0].querySelector('.popover-arrow');
99-
angular.element(arrowEle).css({
100-
left: (buttonOffset.left - popoverCSS.left) + (buttonOffset.width / 2) - (arrowEle.offsetWidth / 2) + 'px'
100+
// If the popover when popped down stretches past bottom of screen,
101+
// make it pop up
102+
if (buttonOffset.top + buttonOffset.height + popoverHeight > bodyHeight) {
103+
popoverCSS.top = buttonOffset.top - popoverHeight;
104+
popoverEle.removeClass('popover-top').addClass('popover-bottom');
105+
} else {
106+
popoverCSS.top = buttonOffset.top + buttonOffset.height;
107+
popoverEle.removeClass('popover-bottom').addClass('popover-top');
108+
}
109+
110+
arrowEle.css({
111+
left: buttonOffset.left + buttonOffset.width / 2 -
112+
arrowEle.prop('offsetWidth') / 2 - popoverCSS.left + 'px'
101113
});
102114

103115
popoverEle.css({

Diff for: scss/_popover.scss

+23-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
z-index: $z-index-popover;
2727
display: block;
2828
margin-left: -$popover-width / 2;
29-
margin-top: 12px;
3029
height: $popover-height;
3130
width: $popover-width;
3231
background-color: $popover-bg-color;
@@ -40,6 +39,13 @@
4039
.item:last-child {
4140
border-bottom: 0;
4241
}
42+
43+
&.popover-top {
44+
margin-top: 12px;
45+
}
46+
&.popover-bottom {
47+
margin-top: -12px;
48+
}
4349
}
4450

4551

@@ -71,6 +77,7 @@
7177
.popover {
7278
box-shadow: $popover-box-shadow-ios;
7379
}
80+
7481
.popover,
7582
.popover .bar-header {
7683
border-radius: $popover-border-radius-ios;
@@ -84,8 +91,6 @@
8491
}
8592
.popover-arrow {
8693
position: absolute;
87-
top: -17px;
88-
left: 43%;
8994
display: block;
9095
width: 30px;
9196
height: 19px;
@@ -103,6 +108,15 @@
103108
@include rotate(-45deg);
104109
}
105110
}
111+
.popover-top .popover-arrow {
112+
top: -17px;
113+
}
114+
.popover-bottom .popover-arrow {
115+
bottom: -10px;
116+
&:after {
117+
top: -6px;
118+
}
119+
}
106120
}
107121

108122

@@ -112,13 +126,18 @@
112126
.popover {
113127
background-color: $popover-bg-color-android;
114128
box-shadow: $popover-box-shadow-android;
115-
margin-top: -32px;
116129

117130
.item {
118131
border-color: $popover-bg-color-android;
119132
background-color: $popover-bg-color-android;
120133
color: #4d4d4d;
121134
}
135+
&.popover-top {
136+
margin-top: -32px;
137+
}
138+
&.popover-bottom {
139+
margin-top: 32px;
140+
}
122141
}
123142

124143
.popover-backdrop,

Diff for: test/html/popover.html

+13-1
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,24 @@ <h1 class="title">Popover</h1>
2828
Content? Yes, content.
2929
</ion-content>
3030

31-
<ion-footer-bar>
31+
<ion-footer-bar class="bar-subfooter">
3232
<button class="button" ng-click="setPlatform('ios')">iOS</button>
3333
<button class="button" ng-click="setPlatform('android')">Android</button>
3434
<button class="button" ng-click="setPlatform('base')">Base</button>
3535
</ion-footer-bar>
3636

37+
<ion-footer-bar>
38+
<div class="buttons">
39+
<button class="button button-icon ion-android-more" ng-click="openPopover($event)"></button>
40+
</div>
41+
<h1 class="title">Popover</h1>
42+
<div class="buttons">
43+
<button class="button" ng-click="openPopover2($event)">Popover 2</button>
44+
<button class="button" ng-click="openPopover($event)">Popover</button>
45+
<button class="button" ng-click="openPopover($event)">Popover</button>
46+
</div>
47+
</ion-footer-bar>
48+
3749

3850
<script id="popover.html" type="text/ng-template">
3951
<ion-popover-view ng-controller="PopoverCtrl">

0 commit comments

Comments
 (0)