diff --git a/ionic/components/action-sheet/action-sheet.ts b/ionic/components/action-sheet/action-sheet.ts
index bfed358662..c9f47bd696 100644
--- a/ionic/components/action-sheet/action-sheet.ts
+++ b/ionic/components/action-sheet/action-sheet.ts
@@ -6,10 +6,11 @@
* The ActionSheet is a modal menu with options to select based on an action.
*/
-import {View, Injectable, NgFor, NgIf} from 'angular2/angular2';
+import {Component, View, Injectable, NgFor, NgIf} from 'angular2/angular2';
+import {OverlayController} from '../overlay/overlay-controller';
+import {IonicConfig} from '../../config/config';
import {Icon} from '../icon/icon';
-import {Overlay} from '../overlay/overlay';
import {Animation} from '../../animations/animation';
import * as util from 'ionic/util';
@@ -52,6 +53,9 @@ import * as util from 'ionic/util';
* }
* ```
*/
+@Component({
+ selector: 'ion-action-sheet'
+})
@View({
template:
'' +
@@ -76,30 +80,42 @@ import * as util from 'ionic/util';
'',
directives: [NgFor, NgIf, Icon]
})
-class ActionSheetDirective {
+class ActionSheetCmp {
_cancel() {
this.cancel && this.cancel();
- return this.overlayRef.close();
+ return this.close();
}
_destructive() {
let shouldClose = this.destructiveButtonClicked();
if (shouldClose === true) {
- return this.overlayRef.close();
+ return this.close();
}
}
_buttonClicked(index) {
let shouldClose = this.buttonClicked(index);
if (shouldClose === true) {
- return this.overlayRef.close();
+ return this.close();
}
}
}
+
@Injectable()
-export class ActionSheet extends Overlay {
+export class ActionSheet {
+
+ constructor(ctrl: OverlayController, config: IonicConfig) {
+ this.ctrl = ctrl;
+ this._defaults = {
+ enterAnimation: config.get('actionSheetEnter'),
+ leaveAnimation: config.get('actionSheetLeave'),
+ cancelIcon: config.get('actionSheetCancelIcon'),
+ destructiveIcon: config.get('actionSheetDestructiveIcon')
+ };
+ }
+
/**
* Create and open a new Action Sheet. This is the
* public API, and most often you will only use ActionSheet.open()
@@ -108,25 +124,18 @@ export class ActionSheet extends Overlay {
* @return {Promise} Promise that resolves when the action sheet is open.
*/
open(opts={}) {
- let config = this.config;
- let defaults = {
- enterAnimation: config.get('actionSheetEnter'),
- leaveAnimation: config.get('actionSheetLeave'),
- cancelIcon: config.get('actionSheetCancelIcon'),
- destructiveIcon: config.get('actionSheetDestructiveIcon')
- };
-
- let context = util.extend(defaults, opts);
-
- return this.create(OVERLAY_TYPE, ActionSheetDirective, context, context);
+ return this.ctrl.open(OVERLAY_TYPE, ActionSheetCmp, util.extend(this._defaults, opts));
}
/**
* TODO
* @returns {TODO} TODO
*/
- get() {
- return this.getByType(OVERLAY_TYPE);
+ get(handle) {
+ if (handle) {
+ return this.ctrl.getByHandle(handle, OVERLAY_TYPE);
+ }
+ return this.ctrl.getByType(OVERLAY_TYPE);
}
}
diff --git a/ionic/components/action-sheet/test/basic/main.html b/ionic/components/action-sheet/test/basic/main.html
index e22f9e3ca7..27dcfabc84 100644
--- a/ionic/components/action-sheet/test/basic/main.html
+++ b/ionic/components/action-sheet/test/basic/main.html
@@ -1,3 +1,5 @@
+
+
diff --git a/ionic/components/app/app.ts b/ionic/components/app/app.ts
index ebf55d1e36..e269277a46 100644
--- a/ionic/components/app/app.ts
+++ b/ionic/components/app/app.ts
@@ -129,18 +129,4 @@ export class IonicApp {
return this.components[id];
}
- /**
- * Create and append the given component into the root
- * element of the app.
- *
- * @param {TODO} componentType the component to create and insert
- * @return {Promise} Promise that resolves with the ContainerRef created
- */
- appendOverlay(componentType: Type) {
- if (!this.overlayAnchor) {
- throw (' must be added to your root component\'s template');
- }
- return this.overlayAnchor.append(componentType);
- }
-
}
diff --git a/ionic/components/modal/modal.ts b/ionic/components/modal/modal.ts
index 3764cecbcf..51bdb32056 100644
--- a/ionic/components/modal/modal.ts
+++ b/ionic/components/modal/modal.ts
@@ -1,6 +1,8 @@
import {Injectable} from 'angular2/angular2';
-import {Overlay} from '../overlay/overlay';
+import {IonicApp} from '../app/app';
+import {IonicConfig} from '../../config/config';
+import {OverlayController} from '../overlay/overlay-controller';
import {Animation} from '../../animations/animation';
import * as util from 'ionic/util';
@@ -28,7 +30,14 @@ import * as util from 'ionic/util';
* ```
*/
@Injectable()
-export class Modal extends Overlay {
+export class Modal {
+
+ constructor(app: IonicApp, config: IonicConfig) {
+ // super(app, {
+ // enterAnimation: config.get('modalEnter') || 'modal-slide-in',
+ // leaveAnimation: config.get('modalLeave') || 'modal-slide-out',
+ // })
+ }
/**
* TODO
@@ -37,12 +46,7 @@ export class Modal extends Overlay {
* @returns {TODO} TODO
*/
open(ComponentType: Type, opts={}) {
- let defaults = {
- enterAnimation: this.config.get('modalEnter') || 'modal-slide-in',
- leaveAnimation: this.config.get('modalLeave') || 'modal-slide-out',
- };
-
- return this.create(OVERLAY_TYPE, ComponentType, util.extend(defaults, opts));
+ return this.create(OVERLAY_TYPE, ComponentType, opts);
}
/**
diff --git a/ionic/components/nav/nav-controller.ts b/ionic/components/nav/nav-controller.ts
index 33f6119a0d..4cfd214674 100644
--- a/ionic/components/nav/nav-controller.ts
+++ b/ionic/components/nav/nav-controller.ts
@@ -171,7 +171,7 @@ export class NavController extends Ion {
// the active view is going to be the leaving one (if one exists)
let leavingView = this.getActive() || new ViewController();
- leavingView.shouldCache = (util.isBoolean(opts.cacheleavingView) ? opts.cacheleavingView : true);
+ leavingView.shouldCache = (util.isBoolean(opts.cacheLeavingView) ? opts.cacheLeavingView : true);
leavingView.shouldDestroy = !leavingView.shouldCache;
if (leavingView.shouldDestroy) {
leavingView.willUnload();
@@ -215,7 +215,7 @@ export class NavController extends Ion {
// get the active view and set that it is staged to be leaving
// was probably the one popped from the stack
let leavingView = this.getActive() || new ViewController();
- leavingView.shouldCache = (util.isBoolean(opts.cacheleavingView) ? opts.cacheleavingView : false);
+ leavingView.shouldCache = (util.isBoolean(opts.cacheLeavingView) ? opts.cacheLeavingView : false);
leavingView.shouldDestroy = !leavingView.shouldCache;
if (leavingView.shouldDestroy) {
leavingView.willUnload();
@@ -341,7 +341,7 @@ export class NavController extends Ion {
opts.animate = opts.animate || false;
// ensure leaving views are not cached, and should be destroyed
- opts.cacheleavingView = false;
+ opts.cacheLeavingView = false;
// get the views to auto remove without having to do a transiton for each
// the last view (the currently active one) will do a normal transition out
diff --git a/ionic/components/nav/view-controller.ts b/ionic/components/nav/view-controller.ts
index f89d6170fd..042c9ebe6d 100644
--- a/ionic/components/nav/view-controller.ts
+++ b/ionic/components/nav/view-controller.ts
@@ -14,8 +14,6 @@ export class ViewController {
this.state = 0;
this.disposals = [];
- this._nbItms = [];
-
this.navbarTemplateRef = null;
}
diff --git a/ionic/components/overlay/overlay-controller.ts b/ionic/components/overlay/overlay-controller.ts
new file mode 100644
index 0000000000..a4e3706df1
--- /dev/null
+++ b/ionic/components/overlay/overlay-controller.ts
@@ -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(' 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;
diff --git a/ionic/components/overlay/overlay.ts b/ionic/components/overlay/overlay.ts
index 204cd845a9..c2ad7f8e1b 100644
--- a/ionic/components/overlay/overlay.ts
+++ b/ionic/components/overlay/overlay.ts
@@ -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 ');
+ }
+
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;
diff --git a/ionic/components/popup/popup.ts b/ionic/components/popup/popup.ts
index e9b1c75b57..bd45911ce7 100644
--- a/ionic/components/popup/popup.ts
+++ b/ionic/components/popup/popup.ts
@@ -1,9 +1,9 @@
import {FORM_DIRECTIVES, NgControl, NgControlGroup,
- Component, View, Injectable, NgClass, NgIf, NgFor} from 'angular2/angular2';
+ Component, View, ElementRef, Injectable, NgClass, NgIf, NgFor} from 'angular2/angular2';
-import {Overlay} from '../overlay/overlay';
+import {OverlayController} from '../overlay/overlay-controller';
+import {IonicConfig} from '../../config/config';
import {Animation} from '../../animations/animation';
-import {Ion} from '../ion';
import * as util from 'ionic/util';
@@ -63,25 +63,27 @@ import * as util from 'ionic/util';
* ```
*/
@Injectable()
-export class Popup extends Overlay {
+export class Popup {
+
+ constructor(ctrl: OverlayController, config: IonicConfig) {
+ this.ctrl = ctrl;
+ this._defaults = {
+ enterAnimation: config.get('popupPopIn'),
+ leaveAnimation: config.get('popupPopOut'),
+ };
+ }
/**
* TODO
* @param {TODO} opts TODO
* @returns {object} A promise
*/
- popup(opts) {
+ open(opts) {
return new Promise((resolve, reject)=> {
- let config = this.config;
- let defaults = {
- enterAnimation: config.get('popupPopIn'),
- leaveAnimation: config.get('popupPopOut'),
- };
-
opts.promiseResolve = resolve;
opts.promiseReject = reject;
- return this.create(OVERLAY_TYPE, StandardPopup, defaults, opts);
+ return this.ctrl.open(OVERLAY_TYPE, PopupCmp, util.extend(this._defaults, opts));
});
}
@@ -128,7 +130,7 @@ export class Popup extends Overlay {
]
}, opts);
- return this.popup(opts);
+ return this.open(opts);
}
/**
@@ -182,7 +184,7 @@ export class Popup extends Overlay {
cancelButton, okButton
]
}, opts);
- return this.popup(opts);
+ return this.open(opts);
}
/**
@@ -243,7 +245,7 @@ export class Popup extends Overlay {
]
}, opts);
- return this.popup(opts);
+ return this.open(opts);
}
/**
@@ -264,7 +266,7 @@ const OVERLAY_TYPE = 'popup';
@Component({
- selector: 'ion-popup-default'
+ selector: 'ion-popup'
})
@View({
template:
@@ -285,19 +287,22 @@ const OVERLAY_TYPE = 'popup';
directives: [FORM_DIRECTIVES, NgClass, NgIf, NgFor]
})
-class StandardPopup {
- constructor(popup: Popup) {
- this.popup = popup;
+class PopupCmp {
+
+ constructor(elementRef: ElementRef) {
+ this.elementRef = elementRef;
}
+
onInit() {
setTimeout(() => {
- this.element = this.overlayRef.getElementRef().nativeElement;
- this.promptInput = this.element.querySelector('input');
+ // TODO: make more better, no DOM BS
+ this.promptInput = this.elementRef.nativeElement.querySelector('input');
if (this.promptInput) {
this.promptInput.value = '';
}
});
}
+
buttonTapped(button, event) {
let promptValue = this.promptInput && this.promptInput.value;
@@ -314,20 +319,22 @@ class StandardPopup {
// Resolve with the prompt value
this.promiseResolve(promptValue);
}
- return this.overlayRef.close();
+ return this.close();
}
}
+
_cancel(event) {
this.cancel && this.cancel(event);
if (!event.defaultPrevented) {
this.promiseReject();
- return this.overlayRef.close();
+ return this.close();
}
}
}
+
class PopupAnimation extends Animation {
constructor(element) {
super(element);
@@ -342,13 +349,14 @@ class PopupAnimation extends Animation {
}
}
+
/**
- * Animations for modals
+ * Animations for popups
*/
class PopupPopIn extends PopupAnimation {
constructor(element) {
super(element);
- this.wrapper.fromTo('opacity', '0', '1')
+ this.wrapper.fromTo('opacity', '0.01', '1')
this.wrapper.fromTo('scale', '1.1', '1');
this.backdrop.fromTo('opacity', '0', '0.3')
@@ -370,7 +378,7 @@ Animation.register('popup-pop-out', PopupPopOut);
class PopupMdPopIn extends PopupPopIn {
constructor(element) {
super(element);
- this.backdrop.fromTo('opacity', '0', '0.5')
+ this.backdrop.fromTo('opacity', '0.01', '0.5')
}
}
Animation.register('popup-md-pop-in', PopupMdPopIn);
diff --git a/ionic/components/popup/test/basic/main.html b/ionic/components/popup/test/basic/main.html
index adc49714bb..928e705a0e 100644
--- a/ionic/components/popup/test/basic/main.html
+++ b/ionic/components/popup/test/basic/main.html
@@ -14,3 +14,5 @@
+
+
diff --git a/ionic/config/bootstrap.ts b/ionic/config/bootstrap.ts
index 4dcb53e6f0..f7d7b9bbc6 100644
--- a/ionic/config/bootstrap.ts
+++ b/ionic/config/bootstrap.ts
@@ -4,6 +4,7 @@ import {ROUTER_BINDINGS, HashLocationStrategy, LocationStrategy} from 'angular2/
import {IonicApp} from '../components/app/app';
import {IonicConfig} from './config';
import {IonicPlatform} from '../platform/platform';
+import {OverlayController} from '../components/overlay/overlay-controller';
import {ActionSheet} from '../components/action-sheet/action-sheet';
import {Modal} from '../components/modal/modal';
import {Popup} from '../components/popup/popup';
@@ -40,6 +41,7 @@ export function ionicBindings(configSettings) {
bind(IonicPlatform).toValue(platform),
bind(TapClick).toValue(tapClick),
bind(Events).toValue(events),
+ OverlayController,
ActionSheet,
Modal,
Popup,
diff --git a/ionic/config/decorators.ts b/ionic/config/decorators.ts
index 974ce42a60..64b826f9d6 100644
--- a/ionic/config/decorators.ts
+++ b/ionic/config/decorators.ts
@@ -49,13 +49,17 @@ export function IonicDirective(config) {
*/
export function IonicComponent(config) {
return function(cls) {
- var annotations = Reflect.getMetadata('annotations', cls) || [];
- annotations.push(new Component(appendConfig(cls, config)));
- Reflect.defineMetadata('annotations', annotations, cls);
- return cls;
+ return makeComponent(cls, appendConfig(cls, config));
}
}
+export function makeComponent(cls, config) {
+ var annotations = Reflect.getMetadata('annotations', cls) || [];
+ annotations.push(new Component(config));
+ Reflect.defineMetadata('annotations', annotations, cls);
+ return cls;
+}
+
function appendConfig(cls, config) {
config.host = config.host || {};
diff --git a/ionic/config/directives.ts b/ionic/config/directives.ts
index 53081c1257..dda378f4fe 100644
--- a/ionic/config/directives.ts
+++ b/ionic/config/directives.ts
@@ -1,6 +1,7 @@
import {CORE_DIRECTIVES, FORM_DIRECTIVES, forwardRef} from 'angular2/angular2'
import {
+ OverlayAnchor,
Menu, MenuToggle, MenuClose,
Button, Content, Scroll, Refresher,
Slides, Slide, SlideLazy,
@@ -29,6 +30,7 @@ export const IONIC_DIRECTIVES = [
FORM_DIRECTIVES,
// Content
+ forwardRef(() => OverlayAnchor),
forwardRef(() => Menu),
forwardRef(() => MenuToggle),
forwardRef(() => MenuClose),