Skip to content

Commit f20c7e4

Browse files
committed
feat(fullscreen): add fullscreen property to ion-content
1 parent 7842991 commit f20c7e4

File tree

4 files changed

+95
-45
lines changed

4 files changed

+95
-45
lines changed

src/components/content/content.ts

Lines changed: 83 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {Component, ElementRef, Optional, NgZone, ChangeDetectionStrategy, ViewEncapsulation} from '@angular/core';
1+
import {ChangeDetectionStrategy, Component, ElementRef, Input, NgZone, Optional, ViewEncapsulation} from '@angular/core';
22

33
import {App} from '../app/app';
44
import {Ion} from '../ion';
@@ -8,6 +8,7 @@ import {nativeRaf, nativeTimeout, transitionEnd} from '../../util/dom';
88
import {ScrollView} from '../../util/scroll-view';
99
import {Tabs} from '../tabs/tabs';
1010
import {ViewController} from '../nav/view-controller';
11+
import {isTrueProperty} from '../../util/util';
1112

1213

1314
/**
@@ -59,19 +60,23 @@ import {ViewController} from '../nav/view-controller';
5960
}
6061
})
6162
export class Content extends Ion {
62-
private _computedTop: number;
63-
private _computedBottom: number;
6463
private _paddingTop: number;
64+
private _paddingRight: number;
6565
private _paddingBottom: number;
66+
private _paddingLeft: number;
67+
private _lastTop: number;
68+
private _lastBottom: number;
6669
private _scrollPadding: number;
6770
private _headerHeight: number;
6871
private _footerHeight: number;
69-
private _tabbarOnTop: boolean = null;
72+
private _tabbarHeight: number;
73+
private _tabbarPlacement: string;
7074
private _inputPolling: boolean = false;
7175
private _scroll: ScrollView;
7276
private _scLsn: Function;
7377
private _scrollEle: HTMLElement;
7478
private _sbPadding: boolean;
79+
private _fullscreen: boolean;
7580

7681
constructor(
7782
private _elementRef: ElementRef,
@@ -322,6 +327,22 @@ export class Content extends Ion {
322327
this.getNativeElement().classList.add(className);
323328
}
324329

330+
/**
331+
* @input {boolean} By default, content is positioned between the headers
332+
* and footers. However, using `fullscreen="true"`, the content will be
333+
* able to scroll "under" the headers and footers. At first glance the
334+
* fullscreen option may not look any different than the default, however,
335+
* by adding a transparency effect to a header then the content can be
336+
* seen under the header as the user scrolls.
337+
*/
338+
@Input()
339+
get fullscreen(): boolean {
340+
return !!this._fullscreen;
341+
}
342+
set fullscreen(val: boolean) {
343+
this._fullscreen = isTrueProperty(val);
344+
}
345+
325346
/**
326347
* @private
327348
* DOM WRITE
@@ -414,13 +435,12 @@ export class Content extends Ion {
414435
* DOM READ
415436
*/
416437
readDimensions() {
417-
this._computedTop = 0 ;
418-
this._computedBottom = 0;
419438
this._paddingTop = 0;
439+
this._paddingRight = 0;
420440
this._paddingBottom = 0;
441+
this._paddingLeft = 0;
421442
this._headerHeight = 0;
422-
this._footerHeight = 0;
423-
this._tabbarOnTop = null;
443+
this._tabbarPlacement = null;
424444

425445
let ele: HTMLElement = this._elementRef.nativeElement;
426446
let parentEle: HTMLElement = ele.parentElement;
@@ -430,43 +450,34 @@ export class Content extends Ion {
430450
ele = <HTMLElement>parentEle.children[i];
431451

432452
if (ele.tagName === 'ION-CONTENT') {
433-
computedStyle = getComputedStyle(ele);
434-
this._computedTop = parsePxUnit(computedStyle.paddingTop);
435-
this._paddingTop += this._computedTop;
436-
437-
this._computedBottom = parsePxUnit(computedStyle.paddingBottom);
438-
this._paddingBottom += this._computedBottom;
453+
if (this._fullscreen) {
454+
computedStyle = getComputedStyle(ele);
455+
this._paddingTop = parsePxUnit(computedStyle.paddingTop);
456+
this._paddingBottom = parsePxUnit(computedStyle.paddingBottom);
457+
this._paddingRight = parsePxUnit(computedStyle.paddingRight);
458+
this._paddingLeft = parsePxUnit(computedStyle.paddingLeft);
459+
}
439460

440461
} else if (ele.tagName === 'ION-HEADER') {
441462
this._headerHeight = ele.clientHeight;
442-
this._paddingTop += this._headerHeight;
443463

444464
} else if (ele.tagName === 'ION-FOOTER') {
445465
this._footerHeight = ele.clientHeight;
446-
this._paddingBottom += this._footerHeight;
447466
}
448467
}
449468

450469
ele = parentEle;
451470
let tabbarEle: HTMLElement;
452-
let tabbarOnTop: boolean;
453471

454472
while (ele && ele.tagName !== 'ION-MODAL' && !ele.classList.contains('tab-subpage')) {
455473

456474
if (ele.tagName === 'ION-TABS') {
457475
tabbarEle = <HTMLElement>ele.firstElementChild;
458-
tabbarOnTop = ele.getAttribute('tabbarplacement') === 'top';
459-
460-
if (tabbarOnTop) {
461-
this._paddingTop += tabbarEle.clientHeight;
462-
463-
} else {
464-
this._paddingBottom += tabbarEle.clientHeight;
465-
}
476+
this._tabbarHeight = tabbarEle.clientHeight;
466477

467-
if (this._tabbarOnTop === null) {
478+
if (this._tabbarPlacement === null) {
468479
// this is the first tabbar found, remember it's position
469-
this._tabbarOnTop = tabbarOnTop;
480+
this._tabbarPlacement = ele.getAttribute('tabbarplacement');
470481
}
471482
}
472483

@@ -479,18 +490,54 @@ export class Content extends Ion {
479490
* DOM WRITE
480491
*/
481492
writeDimensions() {
482-
// only add inline padding styles if the computed padding value, which would
483-
// have come from the app's css, is different than the new padding value
484-
if (this._paddingTop !== this._computedTop) {
485-
this._scrollEle.style.paddingTop = (this._paddingTop > 0 ? this._paddingTop + 'px' : '');
486-
}
493+
let newVal: number;
494+
495+
// only write when it has changed
496+
if (this._fullscreen) {
497+
// adjust the content with padding, allowing content to scroll under headers/footers
498+
// however, on iOS you cannot control the margins of the scrollbar (last tested iOS9.2)
499+
// only add inline padding styles if the computed padding value, which would
500+
// have come from the app's css, is different than the new padding value
501+
502+
newVal = this._headerHeight + this._paddingTop;
503+
if (this._tabbarPlacement === 'top') {
504+
newVal += this._tabbarHeight;
505+
}
506+
if (newVal !== this._lastTop) {
507+
this._scrollEle.style.paddingTop = (newVal > 0 ? newVal + 'px' : '');
508+
}
509+
510+
newVal = this._footerHeight + this._paddingBottom;
511+
if (this._tabbarPlacement === 'bottom') {
512+
newVal += this._tabbarHeight;
513+
}
514+
if (newVal !== this._lastBottom) {
515+
this._scrollEle.style.paddingBottom = (newVal > 0 ? newVal + 'px' : '');
516+
}
487517

488-
if (this._paddingBottom !== this._computedBottom) {
489-
this._scrollEle.style.paddingBottom = (this._paddingBottom > 0 ? this._paddingBottom + 'px' : '');
518+
} else {
519+
// adjust the content with margins
520+
newVal = this._headerHeight;
521+
if (this._tabbarPlacement === 'top') {
522+
newVal += this._tabbarHeight;
523+
}
524+
if (newVal !== this._lastTop) {
525+
this._scrollEle.style.marginTop = (newVal > 0 ? newVal + 'px' : '');
526+
}
527+
528+
newVal = this._footerHeight;
529+
if (this._tabbarPlacement === 'bottom') {
530+
newVal += this._tabbarHeight;
531+
}
532+
if (newVal !== this._lastBottom) {
533+
this._scrollEle.style.marginBottom = (newVal > 0 ? newVal + 'px' : '');
534+
}
490535
}
491536

492-
if (this._tabbarOnTop !== null && this._tabs) {
493-
if (this._tabbarOnTop) {
537+
538+
if (this._tabbarPlacement !== null && this._tabs) {
539+
// set the position of the tabbar
540+
if (this._tabbarPlacement === 'top') {
494541
this._tabs.setTabbarPosition(this._headerHeight, -1);
495542

496543
} else {

src/components/nav/test/basic/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ class FullPage {
214214
</ion-toolbar>
215215
</ion-header>
216216
217-
<ion-content padding>
217+
<ion-content padding fullscreen>
218218
<p><button class="e2eFrom3To2" (click)="nav.pop()">Pop</button></p>
219219
<p><button (click)="pushAnother()">Push to AnotherPage</button></p>
220220
<p><button (click)="pushFullPage()">Push to FullPage</button></p>

src/components/nav/test/child-navs/e2e.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

src/components/tabs/tabs.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,8 @@ export class Tabs extends Ion {
158158
private _onReady: any = null;
159159
private _sbPadding: boolean;
160160
private _useHighlight: boolean;
161+
private _top: number;
162+
private _bottom: number;
161163

162164
/**
163165
* @private
@@ -518,11 +520,15 @@ export class Tabs extends Ion {
518520
* DOM WRITE
519521
*/
520522
setTabbarPosition(top: number, bottom: number) {
521-
let tabbarEle = <HTMLElement>this._tabbar.nativeElement;
522-
523-
tabbarEle.style.top = (top > -1 ? top + 'px' : '');
524-
tabbarEle.style.bottom = (bottom > -1 ? bottom + 'px' : '');
525-
tabbarEle.classList.add('show-tabbar');
523+
if (this._top !== top || this._bottom !== bottom) {
524+
let tabbarEle = <HTMLElement>this._tabbar.nativeElement;
525+
tabbarEle.style.top = (top > -1 ? top + 'px' : '');
526+
tabbarEle.style.bottom = (bottom > -1 ? bottom + 'px' : '');
527+
tabbarEle.classList.add('show-tabbar');
528+
529+
this._top = top;
530+
this._bottom = bottom;
531+
}
526532
}
527533

528534
}

0 commit comments

Comments
 (0)