refactor(overlay): actionsheet/popup

This commit is contained in:
Adam Bradley
2015-10-04 22:35:54 -05:00
parent dfe19a962d
commit 3324f3cc90
13 changed files with 264 additions and 262 deletions

View File

@@ -0,0 +1,156 @@
import {Component, View, NgZone, Injectable, Renderer} from 'angular2/angular2';
import {IonicApp} from '../app/app';
import {Animation} from '../../animations/animation';
import * as util from 'ionic/util';
@Injectable()
export class OverlayController {
constructor(app: IonicApp, zone: NgZone, renderer: Renderer) {
this.app = app;
this.zone = zone;
this.renderer = renderer;
this.refs = [];
}
open(overlayType, componentType: Type, opts={}) {
let resolve;
let promise = new Promise(res => { resolve = res; });
if (!this.anchor) {
console.error('<ion-overlay></ion-overlay> required in root component template to use: ' + overlayType);
return Promise.reject();
}
try {
this.anchor.append(componentType).then(ref => {
let instance = ref.instance;
ref._z = ROOT_Z_INDEX;
for (let i = 0; i < this.refs.length; i++) {
if (this.refs[i]._z >= ref._z) {
ref._z = this.refs[i]._z + 1;
}
}
this.renderer.setElementStyle(ref.location, 'zIndex', ref._z);
util.extend(instance, opts);
ref._type = overlayType;
ref._opts = opts;
ref._handle = opts.handle || (overlayType + instance.zIndex);
this.add(ref);
instance.close = (opts={}) => {
this.close(ref, opts);
};
instance.onViewLoaded && instance.onViewLoaded();
instance.onViewWillEnter && instance.onViewWillEnter();
let animation = Animation.create(ref.location.nativeElement, opts.enterAnimation);
animation.before.addClass('show-overlay');
this.app.setEnabled(false, animation.duration());
this.app.setTransitioning(true, animation.duration());
this.zone.runOutsideAngular(() => {
animation.play().then(() => {
animation.dispose();
this.zone.run(() => {
this.app.setEnabled(true);
this.app.setTransitioning(false);
instance.onViewDidEnter && instance.onViewDidEnter();
resolve();
});
});
});
}).catch(err => {
console.error(err);
});
} catch (e) {
console.error(e);
}
return promise;
}
close(ref, opts) {
let resolve;
let promise = new Promise(res => { resolve = res; });
let instance = ref.instance;
instance.onViewWillLeave && instance.onViewWillLeave();
instance.onViewWillUnload && instance.onViewWillUnload();
opts = util.extend(ref._opts, opts);
let animation = Animation.create(ref.location.nativeElement, opts.leaveAnimation);
animation.after.removeClass('show-overlay');
this.app.setEnabled(false, animation.duration());
this.app.setTransitioning(true, animation.duration());
this.zone.runOutsideAngular(() => {
animation.play().then(() => {
animation.dispose();
this.zone.run(() => {
instance.onViewDidLeave && instance.onViewDidLeave();
instance.onViewDidUnload && instance.onViewDidUnload();
this.app.setEnabled(true);
this.app.setTransitioning(false);
this.remove(ref);
resolve();
});
});
});
return promise;
}
add(ref) {
this.refs.push(ref);
}
remove(ref) {
util.array.remove(this.refs, ref);
ref.dispose && ref.dispose();
}
getByType(overlayType) {
for (let i = this.overlays.length - 1; i >= 0; i--) {
if (overlayType === this.overlays[i]._type) {
return this.overlays[i];
}
}
return null;
}
getByHandle(handle, overlayType) {
for (let i = this.overlays.length - 1; i >= 0; i--) {
if (handle === this.overlays[i]._handle && overlayType === this.overlays[i]._type) {
return this.overlays[i];
}
}
return null;
}
}
const ROOT_Z_INDEX = 1000;

View File

@@ -1,195 +1,27 @@
import {Component, View, DirectiveBinding} from 'angular2/angular2';
import {Component, View, ElementRef, DynamicComponentLoader} from 'angular2/angular2';
import {IonicApp} from '../app/app';
import {Animation} from '../../animations/animation';
import * as util from 'ionic/util';
export class Overlay {
constructor(app: IonicApp) {
this.app = app;
}
create(overlayType, componentType: Type, opts={}, context=null) {
return new Promise((resolve, reject) => {
let app = this.app;
let annotation = new Component({
selector: 'ion-' + overlayType,
host: {
'[style.z-index]': 'zIndex',
'class': overlayType
}
});
let overlayComponentType = DirectiveBinding.createFromType(componentType, annotation);
// create a unique token that works as a cache key
overlayComponentType.token = overlayType + componentType.name;
app.appendOverlay(overlayComponentType).then(ref => {
let overlayRef = new OverlayRef(app, overlayType, opts, ref, context);
overlayRef._open(opts).then(() => {
resolve(overlayRef);
});
}).catch(err => {
console.error('Overlay appendOverlay:', err);
reject(err);
});
}).catch(err => {
console.error('Overlay create:', err);
});
}
getByType(overlayType) {
if (this.app) {
for (let i = this.app.overlays.length - 1; i >= 0; i--) {
if (overlayType === this.app.overlays[i]._type) {
return this.app.overlays[i];
}
}
}
return null;
}
getByHandle(handle, overlayType) {
if (this.app) {
for (let i = this.app.overlays.length - 1; i >= 0; i--) {
if (handle === this.app.overlays[i]._handle &&
overlayType === this.app.overlays[i]._type) {
return this.app.overlays[i];
}
}
}
return null;
}
}
export class OverlayRef {
constructor(app, overlayType, opts, ref, context) {
this.app = app;
let overlayInstance = (ref && ref.instance);
if (!overlayInstance) return;
if (context) {
util.extend(ref.instance, context);
}
this._instance = overlayInstance;
overlayInstance.onViewLoaded && overlayInstance.onViewLoaded();
this.zIndex = ROOT_Z_INDEX;
for (let i = 0; i < app.overlays.length; i++) {
if (app.overlays[i].zIndex >= this.zIndex) {
this.zIndex = app.overlays[i].zIndex + 1;
}
}
overlayInstance.zIndex = this.zIndex;
overlayInstance.overlayRef = this;
overlayInstance.close = (instanceOpts) => {
this.close(instanceOpts);
};
this._elementRef = ref.location;
this._type = overlayType;
this._opts = opts;
this._handle = opts.handle || this.zIndex;
this._dispose = () => {
this._instance = null;
ref.dispose && ref.dispose();
util.array.remove(app.overlays, this);
};
app.overlays.push(this);
}
getElementRef() {
return this._elementRef;
}
_open(opts={}) {
return new Promise(resolve => {
let instance = this._instance || {};
instance.onViewWillEnter && instance.onViewWillEnter();
let animationName = (opts && opts.animation) || this._opts.enterAnimation;
let animation = Animation.create(this._elementRef.nativeElement, animationName);
animation.before.addClass('show-overlay');
this.app.setEnabled(false, animation.duration());
this.app.setTransitioning(true, animation.duration());
this.app.zoneRunOutside(() => {
animation.play().then(() => {
this.app.zoneRun(() => {
this.app.setEnabled(true);
this.app.setTransitioning(false);
animation.dispose();
instance.onViewDidEnter && instance.onViewDidEnter();
resolve();
});
});
});
}).catch(err => {
console.error(err);
});
}
close(opts={}) {
return new Promise(resolve => {
let instance = this._instance || {};
instance.onViewWillLeave && instance.onViewWillLeave();
instance.onViewWillUnload && instance.onViewWillUnload();
let animationName = (opts && opts.animation) || this._opts.leaveAnimation;
let animation = Animation.create(this._elementRef.nativeElement, animationName);
animation.after.removeClass('show-overlay');
this.app.setEnabled(false, animation.duration());
this.app.setTransitioning(true, animation.duration());
animation.play().then(() => {
instance.onViewDidLeave && instance.onViewDidLeave();
instance.onViewDidUnload && instance.onViewDidUnload();
this._dispose();
this.app.setEnabled(true);
this.app.setTransitioning(false);
animation.dispose();
resolve();
})
}).catch(err => {
console.error(err);
});
}
}
import {OverlayController} from './overlay-controller';
@Component({
selector: 'ion-overlays'
selector: 'ion-overlay'
})
@View({
template: ''
})
export class OverlaysContainer {
constructor(app: IonicApp, elementRef: ElementRef, loader: DynamicComponentLoader) {
export class OverlayAnchor {
constructor(
overlayCtrl: OverlayController,
elementRef: ElementRef,
loader: DynamicComponentLoader
) {
if (overlayCtrl.anchor) {
throw ('An app should only have one <ion-overlays></ion-overlays>');
}
this.elementRef = elementRef;
this.loader = loader;
app.overlayAnchor = this;
overlayCtrl.anchor = this;
}
append(componentType) {
@@ -198,6 +30,3 @@ export class OverlaysContainer {
});
}
}
const ROOT_Z_INDEX = 1000;