Skip to content

Commit 4db72cf

Browse files
committed
feat(popover): fix long popovers that go off the page
Allow popovers to be of dynamic height and only cut them off when they exceed the height of the body. Clean up styles for each mode. references #5420
1 parent 57a1274 commit 4db72cf

File tree

10 files changed

+101
-61
lines changed

10 files changed

+101
-61
lines changed

demos/popover/main.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,6 @@
1717

1818
<div>Sed pellentesque ipsum eget ante hendrerit maximus. Aliquam id venenatis nulla. Nullam in nibh at enim vestibulum ullamcorper. Nam felis dolor, lobortis vel est non, condimentum malesuada nisl. In metus sapien, malesuada at nulla in, pretium aliquam turpis. Quisque elementum purus mi, sed tristique turpis ultricies in. Donec feugiat dolor non ultricies ultricies. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin ut purus et diam porta cursus vitae semper mi. Donec fringilla tellus orci. Interdum et malesuada fames ac ante ipsum primis in faucibus. Nunc vitae commodo sem. Duis vehicula quam sit amet imperdiet facilisis. Pellentesque eget dignissim neque, et scelerisque libero. Maecenas molestie metus sed orci cursus, in venenatis justo dapibus.</div>
1919

20-
<p>Aenean rhoncus urna at interdum blandit. Donec ac massa nec libero vehicula tincidunt. Sed sit amet hendrerit risus. Aliquam vitae vestibulum ipsum, non feugiat orci. Vivamus eu rutrum elit. Nulla dapibus tortor non dignissim pretium. Nulla in luctus turpis. Etiam non mattis tortor, at aliquet ex. Nunc ut ante varius, auctor dui vel, volutpat elit. Nunc laoreet augue sit amet ultrices porta. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum pellentesque lobortis est, ut tincidunt ligula mollis sit amet. In porta risus arcu, quis pellentesque dolor mattis non. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</p>
20+
<div>Aenean rhoncus urna at interdum blandit. Donec ac massa nec libero vehicula tincidunt. Sed sit amet hendrerit risus. Aliquam vitae vestibulum ipsum, non feugiat orci. Vivamus eu rutrum elit. Nulla dapibus tortor non dignissim pretium. Nulla in luctus turpis. Etiam non mattis tortor, at aliquet ex. Nunc ut ante varius, auctor dui vel, volutpat elit. Nunc laoreet augue sit amet ultrices porta. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vestibulum pellentesque lobortis est, ut tincidunt ligula mollis sit amet. In porta risus arcu, quis pellentesque dolor mattis non. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae;</div>
2121
</div>
2222
</ion-content>

demos/popover/style.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ ion-col {
5454
border: 1px solid #dedede;
5555
}
5656

57+
.wp .dot {
58+
border: 2px solid #ccc;
59+
}
60+
5761
.hairlines .text-smaller,
5862
.hairlines .row-dots,
5963
.hairlines .dot {

src/components/popover/popover.ios.scss

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
@import "../../globals.core";
2-
@import "./popover";
32

43
// iOS Popover
54
// --------------------------------------------------
65

7-
$popover-ios-min-width: 150px !default;
8-
$popover-ios-max-width: 270px !default;
6+
$popover-ios-width: 200px !default;
97
$popover-ios-max-height: 90% !default;
8+
109
$popover-ios-border-radius: 10px !default;
1110
$popover-ios-text-color: #000 !default;
1211

@@ -16,8 +15,7 @@ $popover-ios-arrow-background: $popover-ios-background !default;
1615

1716

1817
.popover-content {
19-
min-width: $popover-ios-min-width;
20-
max-width: $popover-ios-max-width;
18+
width: $popover-ios-width;
2119

2220
max-height: $popover-ios-max-height;
2321

src/components/popover/popover.md.scss

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,29 @@
11
@import "../../globals.core";
2-
@import "./popover";
32

43
// Material Design Popover
54
// --------------------------------------------------
65

7-
$popover-md-min-width: 200px !default;
8-
$popover-md-max-width: 270px !default;
6+
$popover-md-width: 200px !default;
97
$popover-md-max-height: 90% !default;
8+
109
$popover-md-border-radius: 2px !default;
11-
$popover-md-box-shadow-color: rgba(0, 0, 0, .3) !default;
12-
$popover-md-box-shadow: 0px 3px 12px 2px $alert-md-box-shadow-color !default;
1310
$popover-md-text-color: #000 !default;
14-
1511
$popover-md-background: #fafafa !default;
12+
$popover-md-box-shadow-color: rgba(0, 0, 0, .3) !default;
13+
$popover-md-box-shadow: 0 3px 12px 2px $alert-md-box-shadow-color !default;
14+
1615
$popover-md-item-background: $popover-md-background !default;
1716

1817

1918
.popover-content {
20-
min-width: $popover-md-min-width;
21-
max-width: $popover-md-max-width;
19+
width: $popover-md-width;
2220

2321
max-height: $popover-md-max-height;
2422

25-
box-shadow: $popover-md-box-shadow;
2623
border-radius: $popover-md-border-radius;
2724
color: $popover-md-text-color;
2825
background: $popover-md-background;
26+
box-shadow: $popover-md-box-shadow;
2927
}
3028

3129
.popover-content .item {

src/components/popover/popover.scss

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33
// Popover
44
// --------------------------------------------------
55

6-
$popover-width: 200px !default;
7-
$popover-height: 250px !default;
8-
96

107
ion-popover {
118
position: absolute;
@@ -22,8 +19,9 @@ ion-popover {
2219
}
2320

2421
.popover-wrapper {
25-
opacity: 0;
2622
z-index: $z-index-overlay-wrapper;
23+
24+
opacity: 0;
2725
}
2826

2927
.popover-content {
@@ -32,19 +30,15 @@ ion-popover {
3230

3331
display: flex;
3432

35-
overflow: hidden;
33+
overflow: auto;
3634

3735
flex-direction: column;
3836

39-
width: $popover-width;
40-
min-width: $popover-width;
41-
42-
height: $popover-height;
43-
max-height: $popover-height;
37+
min-height: 200px;
4438

4539
ion-page {
40+
position: relative;
4641
display: flex;
47-
overflow: auto;
4842
}
4943
}
5044

src/components/popover/popover.ts

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {Config} from '../../config/config';
77
import {NavParams} from '../nav/nav-params';
88
import {Platform} from '../../platform/platform';
99
import {isPresent, isUndefined, isDefined} from '../../util/util';
10+
import {nativeRaf} from '../../util/dom';
1011
import {ViewController} from '../nav/view-controller';
1112

1213
const POPOVER_BODY_PADDING = 2;
@@ -108,7 +109,7 @@ class PopoverCmp {
108109
this._loader.loadNextToLocation(this._navParams.data.componentType, this.viewport).then(componentRef => {
109110
this._viewCtrl.setInstance(componentRef.instance);
110111

111-
// manually fire onPageWillEnter() since ModalCmp's onPageWillEnter already happened
112+
// manually fire onPageWillEnter() since PopoverCmp's onPageWillEnter already happened
112113
this._viewCtrl.willEnter();
113114
});
114115
}
@@ -150,6 +151,7 @@ class PopoverTransition extends Transition {
150151
super(opts);
151152
}
152153

154+
153155
positionView(nativeEle: HTMLElement, ev) {
154156
// Popover content width and height
155157
let popoverEle = <HTMLElement>nativeEle.querySelector('.popover-content');
@@ -158,8 +160,6 @@ class PopoverTransition extends Transition {
158160
let popoverHeight = popoverDim.height;
159161

160162
// Window body width and height
161-
// let bodyWidth = this._platform.width();
162-
// let bodyHeight = this._platform.height();
163163
let bodyWidth = window.innerWidth;
164164
let bodyHeight = window.innerHeight;
165165

@@ -197,10 +197,13 @@ class PopoverTransition extends Transition {
197197

198198
// If the popover when popped down stretches past bottom of screen,
199199
// make it pop up if there's room above
200-
if (popoverCSS.top + POPOVER_BODY_PADDING + popoverHeight > bodyHeight && popoverCSS.top - popoverHeight > 0) {
200+
if (targetTop + targetHeight + popoverHeight > bodyHeight && targetTop - popoverHeight > 0) {
201201
arrowCSS.top = targetTop - (arrowHeight + 1);
202202
popoverCSS.top = targetTop - popoverHeight - (arrowHeight - 1);
203203
nativeEle.className = nativeEle.className + ' popover-bottom';
204+
// If there isn't room for it to pop up above the target cut it off
205+
} else if (targetTop + targetHeight + popoverHeight > bodyHeight) {
206+
popoverEle.style.bottom = POPOVER_BODY_PADDING + '%';
204207
}
205208

206209
arrowEle.style.top = arrowCSS.top + 'px';
@@ -212,39 +215,44 @@ class PopoverTransition extends Transition {
212215
}
213216

214217
class PopoverPopIn extends PopoverTransition {
215-
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
218+
constructor(private enteringView: ViewController, private leavingView: ViewController, private opts: TransitionOptions) {
216219
super(opts);
217220

218221
let ele = enteringView.pageRef().nativeElement;
219-
this.positionView(ele, opts.ev);
220222

221223
let backdrop = new Animation(ele.querySelector('.backdrop'));
222224
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));
223225

224226
wrapper.fromTo('opacity', '0.01', '1');
225-
backdrop.fromTo('opacity', '0.01', '0.1');
227+
backdrop.fromTo('opacity', '0.01', '0.08');
226228

227229
this
228230
.easing('ease')
229231
.duration(100)
230-
.before.addClass('show-page')
231232
.add(backdrop)
232233
.add(wrapper);
233234
}
235+
236+
play() {
237+
nativeRaf(() => {
238+
this.positionView(this.enteringView.pageRef().nativeElement, this.opts.ev);
239+
super.play();
240+
});
241+
}
234242
}
235243
Transition.register('popover-pop-in', PopoverPopIn);
236244

237245

238246
class PopoverPopOut extends PopoverTransition {
239-
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
247+
constructor(private enteringView: ViewController, private leavingView: ViewController, private opts: TransitionOptions) {
240248
super(opts);
241249

242250
let ele = leavingView.pageRef().nativeElement;
243251
let backdrop = new Animation(ele.querySelector('.backdrop'));
244252
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));
245253

246254
wrapper.fromTo('opacity', '1', '0');
247-
backdrop.fromTo('opacity', '0.1', '0');
255+
backdrop.fromTo('opacity', '0.08', '0');
248256

249257
this
250258
.easing('ease')
@@ -257,45 +265,46 @@ Transition.register('popover-pop-out', PopoverPopOut);
257265

258266

259267
class PopoverMdPopIn extends PopoverTransition {
260-
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
268+
constructor(private enteringView: ViewController, private leavingView: ViewController, private opts: TransitionOptions) {
261269
super(opts);
262270

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

266-
let backdrop = new Animation(ele.querySelector('.backdrop'));
267274
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));
268275

269276
wrapper.fromTo('opacity', '0.01', '1');
270-
backdrop.fromTo('opacity', '0', '0');
271277

272278
this
273279
.easing('ease')
274280
.duration(100)
275281
.fadeIn()
276-
.add(backdrop)
277282
.add(wrapper);
278283
}
284+
285+
play() {
286+
nativeRaf(() => {
287+
this.positionView(this.enteringView.pageRef().nativeElement, this.opts.ev);
288+
super.play();
289+
});
290+
}
279291
}
280292
Transition.register('popover-md-pop-in', PopoverMdPopIn);
281293

282294

283295
class PopoverMdPopOut extends PopoverTransition {
284-
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
296+
constructor(private enteringView: ViewController, private leavingView: ViewController, private opts: TransitionOptions) {
285297
super(opts);
286298

287299
let ele = leavingView.pageRef().nativeElement;
288-
let backdrop = new Animation(ele.querySelector('.backdrop'));
289300
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));
290301

291302
wrapper.fromTo('opacity', '1', '0');
292-
backdrop.fromTo('opacity', '0', '0');
293303

294304
this
295305
.easing('ease')
296306
.duration(500)
297307
.fadeIn()
298-
.add(backdrop)
299308
.add(wrapper);
300309
}
301310
}
@@ -304,45 +313,46 @@ Transition.register('popover-md-pop-out', PopoverMdPopOut);
304313

305314

306315
class PopoverWpPopIn extends PopoverTransition {
307-
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
316+
constructor(private enteringView: ViewController, private leavingView: ViewController, private opts: TransitionOptions) {
308317
super(opts);
309318

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

313-
let backdrop = new Animation(ele.querySelector('.backdrop'));
314322
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));
315323

316324
wrapper.fromTo('opacity', '0.01', '1');
317-
backdrop.fromTo('opacity', '0.01', '0.5');
318325

319326
this
320327
.easing('ease')
321328
.duration(100)
322329
.fadeIn()
323-
.add(backdrop)
324330
.add(wrapper);
325331
}
332+
333+
play() {
334+
nativeRaf(() => {
335+
this.positionView(this.enteringView.pageRef().nativeElement, this.opts.ev);
336+
super.play();
337+
});
338+
}
326339
}
327340
Transition.register('popover-wp-pop-in', PopoverWpPopIn);
328341

329342

330343
class PopoverWpPopOut extends PopoverTransition {
331-
constructor(enteringView: ViewController, leavingView: ViewController, opts: TransitionOptions) {
344+
constructor(private enteringView: ViewController, private leavingView: ViewController, private opts: TransitionOptions) {
332345
super(opts);
333346

334347
let ele = leavingView.pageRef().nativeElement;
335-
let backdrop = new Animation(ele.querySelector('.backdrop'));
336348
let wrapper = new Animation(ele.querySelector('.popover-wrapper'));
337349

338350
wrapper.fromTo('opacity', '1', '0');
339-
backdrop.fromTo('opacity', '0.5', '0');
340351

341352
this
342353
.easing('ease')
343354
.duration(500)
344355
.fadeIn()
345-
.add(backdrop)
346356
.add(wrapper);
347357
}
348358
}

src/components/popover/popover.wp.scss

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
11
@import "../../globals.core";
2-
@import "./popover";
32

43
// Windows Popover
54
// --------------------------------------------------
65

7-
$popover-wp-min-width: 200px !default;
8-
$popover-wp-max-width: 270px !default;
6+
$popover-wp-width: 200px !default;
97
$popover-wp-max-height: 90% !default;
10-
$popover-wp-border-radius: 2px !default;
11-
$popover-wp-text-color: #000 !default;
128

9+
$popover-wp-border: 2px solid #ccc !default;
10+
$popover-wp-border-radius: 0 !default;
11+
12+
$popover-wp-text-color: #000 !default;
1313
$popover-wp-background: #f2f2f2 !default;
1414
$popover-wp-item-background: $popover-wp-background !default;
1515

1616

1717
.popover-content {
18-
min-width: $popover-wp-min-width;
19-
max-width: $popover-wp-max-width;
18+
width: $popover-wp-width;
2019

2120
max-height: $popover-wp-max-height;
2221

22+
border: $popover-wp-border;
2323
border-radius: $popover-wp-border-radius;
2424
color: $popover-wp-text-color;
2525
background: $popover-wp-background;

0 commit comments

Comments
 (0)