fix(menu): menu's content is resized properly

fixes #8504
This commit is contained in:
Manu Mtz.-Almeida
2016-10-10 15:45:22 +02:00
committed by Adam Bradley
parent bcbe03c480
commit db72a7d26b
7 changed files with 75 additions and 42 deletions

View File

@ -1,4 +1,4 @@
import { Directive, ElementRef, Input } from '@angular/core'; import { Directive, ElementRef, Input, Renderer } from '@angular/core';
import { GestureController } from '../../gestures/gesture-controller'; import { GestureController } from '../../gestures/gesture-controller';
import { isTrueProperty } from '../../util/util'; import { isTrueProperty } from '../../util/util';
@ -19,7 +19,10 @@ export class Backdrop {
private _gestureID: number = null; private _gestureID: number = null;
@Input() disableScroll = true; @Input() disableScroll = true;
constructor(private _gestureCtrl: GestureController, private _elementRef: ElementRef) {} constructor(
private _gestureCtrl: GestureController,
private _elementRef: ElementRef,
private _renderer: Renderer) { }
ngOnInit() { ngOnInit() {
if (isTrueProperty(this.disableScroll)) { if (isTrueProperty(this.disableScroll)) {
@ -38,4 +41,8 @@ export class Backdrop {
return this._elementRef.nativeElement; return this._elementRef.nativeElement;
} }
setElementClass(className: string, add: boolean) {
this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
}
} }

View File

@ -488,7 +488,9 @@ export class Content extends Ion {
this._tabsPlacement = null; this._tabsPlacement = null;
let ele: HTMLElement = this._elementRef.nativeElement; let ele: HTMLElement = this._elementRef.nativeElement;
if (!ele) return; if (!ele) {
return;
}
let parentEle: HTMLElement = ele.parentElement; let parentEle: HTMLElement = ele.parentElement;
let computedStyle: any; let computedStyle: any;

View File

@ -29,9 +29,7 @@ ion-menu.show-menu {
bottom: 0; bottom: 0;
left: 0; left: 0;
display: flex; display: block;
flex-direction: column;
width: $menu-width; width: $menu-width;
@ -41,7 +39,7 @@ ion-menu.show-menu {
.menu-inner > ion-header, .menu-inner > ion-header,
.menu-inner > ion-content, .menu-inner > ion-content,
.menu-inner > ion-footer { .menu-inner > ion-footer {
position: relative; position: absolute;
} }
ion-menu[side=right] > .menu-inner { ion-menu[side=right] > .menu-inner {

View File

@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component, ElementRef, EventEmitter, Input, NgZone, Output, Renderer, ViewChild, ViewEncapsulation } from '@angular/core'; import { ChangeDetectionStrategy, Component, ContentChild, ElementRef, EventEmitter, Input, NgZone, Output, Renderer, ViewChild, ViewEncapsulation } from '@angular/core';
import { Backdrop } from '../backdrop/backdrop'; import { Backdrop } from '../backdrop/backdrop';
import { Config } from '../../config/config'; import { Config } from '../../config/config';
@ -10,7 +10,7 @@ import { MenuType } from './menu-types';
import { Platform } from '../../platform/platform'; import { Platform } from '../../platform/platform';
import { GestureController } from '../../gestures/gesture-controller'; import { GestureController } from '../../gestures/gesture-controller';
import { UIEventManager } from '../../util/ui-event-manager'; import { UIEventManager } from '../../util/ui-event-manager';
import { Content } from '../content/content';
/** /**
* @name Menu * @name Menu
@ -208,6 +208,11 @@ export class Menu {
*/ */
@ViewChild(Backdrop) backdrop: Backdrop; @ViewChild(Backdrop) backdrop: Backdrop;
/**
* @private
*/
@ContentChild(Content) menuContent: Content;
/** /**
* @input {any} A reference to the content element the menu should use. * @input {any} A reference to the content element the menu should use.
*/ */
@ -303,48 +308,47 @@ export class Menu {
* @private * @private
*/ */
ngOnInit() { ngOnInit() {
let self = this; this._init = true;
self._init = true;
let content = self.content; let content = this.content;
self._cntEle = (content instanceof Node) ? content : content && content.getNativeElement && content.getNativeElement(); this._cntEle = (content instanceof Node) ? content : content && content.getNativeElement && content.getNativeElement();
// requires content element // requires content element
if (!self._cntEle) { if (!this._cntEle) {
return console.error('Menu: must have a [content] element to listen for drag events on. Example:\n\n<ion-menu [content]="content"></ion-menu>\n\n<ion-nav #content></ion-nav>'); return console.error('Menu: must have a [content] element to listen for drag events on. Example:\n\n<ion-menu [content]="content"></ion-menu>\n\n<ion-nav #content></ion-nav>');
} }
// normalize the "side" // normalize the "side"
if (self.side !== 'left' && self.side !== 'right') { if (this.side !== 'left' && this.side !== 'right') {
self.side = 'left'; this.side = 'left';
} }
self._renderer.setElementAttribute(self._elementRef.nativeElement, 'side', self.side); this.setElementAttribute('side', this.side);
// normalize the "type" // normalize the "type"
if (!self.type) { if (!this.type) {
self.type = self._config.get('menuType'); this.type = this._config.get('menuType');
} }
self._renderer.setElementAttribute(self._elementRef.nativeElement, 'type', self.type); this.setElementAttribute('type', this.type);
// add the gestures // add the gestures
self._cntGesture = new MenuContentGesture(self, document.body); this._cntGesture = new MenuContentGesture(this, document.body);
// register listeners if this menu is enabled // register listeners if this menu is enabled
// check if more than one menu is on the same side // check if more than one menu is on the same side
let hasEnabledSameSideMenu = self._menuCtrl.getMenus().some(m => { let hasEnabledSameSideMenu = this._menuCtrl.getMenus().some(m => {
return m.side === self.side && m.enabled; return m.side === this.side && m.enabled;
}); });
if (hasEnabledSameSideMenu) { if (hasEnabledSameSideMenu) {
// auto-disable if another menu on the same side is already enabled // auto-disable if another menu on the same side is already enabled
self._isEnabled = false; this._isEnabled = false;
} }
self._setListeners(); this._setListeners();
self._cntEle.classList.add('menu-content'); this._cntEle.classList.add('menu-content');
self._cntEle.classList.add('menu-content-' + self.type); this._cntEle.classList.add('menu-content-' + this.type);
// register this menu with the app's menu controller // register this menu with the app's menu controller
self._menuCtrl.register(self); this._menuCtrl.register(this);
} }
/** /**
@ -468,8 +472,9 @@ export class Menu {
private _before() { private _before() {
// this places the menu into the correct location before it animates in // this places the menu into the correct location before it animates in
// this css class doesn't actually kick off any animations // this css class doesn't actually kick off any animations
this.getNativeElement().classList.add('show-menu'); this.menuContent && this.menuContent.resize();
this.getBackdropElement().classList.add('show-backdrop'); this.setElementClass('show-menu', true);
this.backdrop.setElementClass('show-backdrop', true);
this._keyboard.close(); this._keyboard.close();
this._isAnimating = true; this._isAnimating = true;
} }
@ -482,11 +487,10 @@ export class Menu {
this.isOpen = isOpen; this.isOpen = isOpen;
this._isAnimating = false; this._isAnimating = false;
(<any>this._cntEle.classList)[isOpen ? 'add' : 'remove']('menu-content-open');
this._events.unlistenAll(); this._events.unlistenAll();
if (isOpen) { if (isOpen) {
this._cntEle.classList.add('menu-content-open');
let callback = this.onBackdropClick.bind(this); let callback = this.onBackdropClick.bind(this);
this._events.pointerEvents({ this._events.pointerEvents({
element: this._cntEle, element: this._cntEle,
@ -499,8 +503,10 @@ export class Menu {
this.ionOpen.emit(true); this.ionOpen.emit(true);
} else { } else {
this.getNativeElement().classList.remove('show-menu'); this._cntEle.classList.remove('menu-content-open');
this.getBackdropElement().classList.remove('show-backdrop'); this.setElementClass('show-menu', false);
this.backdrop.setElementClass('show-menu', false);
this.ionClose.emit(true); this.ionClose.emit(true);
} }
} }
@ -597,6 +603,17 @@ export class Menu {
return this._menuCtrl; return this._menuCtrl;
} }
/**
* @private
*/
setElementClass(className: string, add: boolean) {
this._renderer.setElementClass(this._elementRef.nativeElement, className, add);
}
setElementAttribute(attributeName: string, value: string) {
this._renderer.setElementAttribute(this._elementRef.nativeElement, attributeName, value);
}
/** /**
* @private * @private
*/ */

View File

@ -7,7 +7,6 @@
</ion-header> </ion-header>
<ion-content> <ion-content>
<ion-list> <ion-list>
<button ion-item menuToggle="left" detail-none> <button ion-item menuToggle="left" detail-none>
@ -18,6 +17,13 @@
</button> </button>
</ion-list> </ion-list>
<p>Close Left Menu and Show alert buttons</p>
<div f></div>
<div f></div>
<div f></div>
<div f></div>
</ion-content> </ion-content>
</ion-menu> </ion-menu>
@ -31,7 +37,6 @@
</ion-header> </ion-header>
<ion-content> <ion-content>
<ion-list> <ion-list>
<button ion-item menuToggle="right" detail-none> <button ion-item menuToggle="right" detail-none>
@ -39,6 +44,13 @@
</button> </button>
</ion-list> </ion-list>
<p>Only one close button</p>
<div f></div>
<div f></div>
<div f></div>
<div f></div>
</ion-content> </ion-content>
</ion-menu> </ion-menu>

View File

@ -6,7 +6,6 @@ import { Content } from '../content/content';
import { DeepLinker } from '../../navigation/deep-linker'; import { DeepLinker } from '../../navigation/deep-linker';
import { Ion } from '../ion'; import { Ion } from '../ion';
import { isBlank } from '../../util/util'; import { isBlank } from '../../util/util';
import { nativeRaf } from '../../util/dom';
import { NavController } from '../../navigation/nav-controller'; import { NavController } from '../../navigation/nav-controller';
import { NavControllerBase } from '../../navigation/nav-controller-base'; import { NavControllerBase } from '../../navigation/nav-controller-base';
import { NavOptions, DIRECTION_SWITCH } from '../../navigation/nav-util'; import { NavOptions, DIRECTION_SWITCH } from '../../navigation/nav-util';
@ -476,10 +475,7 @@ export class Tabs extends Ion implements AfterViewInit {
if (alreadyLoaded && selectedPage) { if (alreadyLoaded && selectedPage) {
let content = <Content>selectedPage.getContent(); let content = <Content>selectedPage.getContent();
if (content && content instanceof Content) { if (content && content instanceof Content) {
nativeRaf(() => { content.resize();
content.readDimensions();
content.writeDimensions();
});
} }
} }
}); });

View File

@ -14,6 +14,7 @@ export class PageTransition extends Transition {
this.enteringPage = new Animation(this.enteringView.pageRef()); this.enteringPage = new Animation(this.enteringView.pageRef());
this.add(this.enteringPage.beforeAddClass('show-page')); this.add(this.enteringPage.beforeAddClass('show-page'));
// Resize content before transition starts
this.beforeAddRead(this.readDimensions.bind(this)); this.beforeAddRead(this.readDimensions.bind(this));
this.beforeAddWrite(this.writeDimensions.bind(this)); this.beforeAddWrite(this.writeDimensions.bind(this));
} }