mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Merge remote-tracking branch 'origin/master'
Conflicts: ionic/components/nav/nav-item.js ionic/components/view/view.scss
This commit is contained in:
@@ -20,11 +20,10 @@ export * from 'ionic/components/nav/nav-item'
|
||||
export * from 'ionic/components/nav-bar/nav-bar'
|
||||
export * from 'ionic/components/slides/slides'
|
||||
export * from 'ionic/components/radio/radio'
|
||||
// export * from 'ionic/components/search-bar/search-bar'
|
||||
export * from 'ionic/components/search-bar/search-bar'
|
||||
// export * from 'ionic/components/split-view/split-view'
|
||||
export * from 'ionic/components/segment/segment'
|
||||
export * from 'ionic/components/switch/switch'
|
||||
export * from 'ionic/components/toolbar/toolbar'
|
||||
export * from 'ionic/components/view/view'
|
||||
export * from 'ionic/components/tabs/tabs'
|
||||
export * from 'ionic/components/tabs/tab'
|
||||
|
||||
@@ -117,7 +117,8 @@ ion-content {
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow-y: scroll;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
will-change: scroll-position;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import {Query} from 'angular2/src/core/annotations_impl/di';
|
||||
|
||||
console.log(Query, QueryList);
|
||||
|
||||
import {Ionic, Nav, Toolbar, ViewContainer, Aside, List, Item, Content, Button} from 'ionic/ionic';
|
||||
import {Ionic, Nav, ViewContainer, Aside, List, Item, Content, Button} from 'ionic/ionic';
|
||||
|
||||
import {ButtonPage} from './pages/button'
|
||||
import {NavPage} from './pages/nav'
|
||||
@@ -14,19 +14,22 @@ import {ListPage} from './pages/list'
|
||||
import {CardPage} from './pages/card'
|
||||
import {FormPage} from './pages/form'
|
||||
import {SegmentPage} from './pages/segment'
|
||||
import {SearchBar} from './pages/search-bar'
|
||||
import {SearchBarPage} from './pages/search-bar'
|
||||
import {IconsPage} from './pages/ionicons'
|
||||
import {TabsPage} from './pages/tabs'
|
||||
import {AsidePage} from './pages/aside'
|
||||
import {SlidePage} from './pages/slides'
|
||||
import {ActionMenuPage} from './pages/action-menu'
|
||||
import {ModalPage} from './pages/modal'
|
||||
|
||||
console.log('Loaded', Nav, NgFor, NgIf, Aside, List, ViewContainer, Item, Content, Button);
|
||||
|
||||
@Component({
|
||||
selector: 'ion-app',
|
||||
})
|
||||
@View({
|
||||
templateUrl: 'main.html',
|
||||
directives: [Nav, NgFor, NgIf, Aside, List, ViewContainer, Toolbar, Item, Content, Button]
|
||||
directives: [Nav, NgFor, NgIf, Aside, List, ViewContainer, Item, Content, Button]
|
||||
})
|
||||
export class IonicApp {
|
||||
constructor(elementRef: ElementRef) {//, @Query(Aside) nav: QueryList) {//, @Descendant() aside: Aside) {
|
||||
@@ -39,8 +42,9 @@ export class IonicApp {
|
||||
{ title: 'Cards', component: CardPage },
|
||||
{ title: 'Forms', component: FormPage },
|
||||
{ title: 'Segments', component: SegmentPage },
|
||||
{ title: 'Search Bar', component: SearchBar},
|
||||
{ title: 'Search Bar', component: SearchBarPage },
|
||||
{ title: 'Icons', component: IconsPage },
|
||||
{ title: 'Tabs', component: TabsPage },
|
||||
{ title: 'Aside', component: AsidePage },
|
||||
{ title: 'Slides', component: SlidePage},
|
||||
{ title: 'Action Menu', component: ActionMenuPage },
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
<ion-aside #aside [content]="content">
|
||||
<ion-list inset>
|
||||
<ion-item *ng-for="#c of components" (^click)="openPage(aside, c)">
|
||||
{{c.title}}
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
<ion-toolbar>
|
||||
<ion-title>Ionic 2.0</ion-title>
|
||||
</ion-toolbar>
|
||||
<ion-content>
|
||||
<ion-list inset>
|
||||
<ion-item *ng-for="#c of components" (^click)="openPage(aside, c)">
|
||||
{{c.title}}
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
</ion-content>
|
||||
</ion-aside>
|
||||
|
||||
<ion-nav #content [initial]="firstPage"></ion-nav>
|
||||
|
||||
@@ -3,7 +3,7 @@ import {Ancestor} from 'angular2/src/core/annotations_impl/visibility';
|
||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
|
||||
import {NavbarTemplate, Navbar, NavController, Button, Content} from 'ionic/ionic';
|
||||
import {Routable, NavbarTemplate, Navbar, NavController, Button, Content} from 'ionic/ionic';
|
||||
|
||||
@Component({
|
||||
selector: 'ion-view'
|
||||
@@ -43,3 +43,8 @@ export class ButtonPage {
|
||||
window.nav = nav;
|
||||
}
|
||||
}
|
||||
|
||||
new Routable(ButtonPage, {
|
||||
url: '/components/button',
|
||||
tag: 'button'
|
||||
})
|
||||
|
||||
@@ -20,8 +20,8 @@ import {List, Item, ActionMenu, Modal, ModalRef,
|
||||
like it would be on an index card or a piece of paper.
|
||||
</p>
|
||||
<p>
|
||||
Cards are great for displaying contextual informaion in a small amount of space,
|
||||
like a Tweet, today's weather report, and a photo.
|
||||
Cards are great for displaying contextual information in a small space,
|
||||
like a Tweet, today's weather report, or a photo.
|
||||
</p>
|
||||
<div class="card">
|
||||
|
||||
|
||||
@@ -3,7 +3,9 @@ import {Ancestor} from 'angular2/src/core/annotations_impl/visibility';
|
||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
|
||||
import {List, Item, ActionMenu, Modal, ModalRef,
|
||||
import {FormBuilder, Validators, formDirectives, ControlGroup} from 'angular2/forms';
|
||||
|
||||
import {List, Item, Input, ActionMenu, Modal, ModalRef,
|
||||
NavbarTemplate, Navbar, NavController, Button, Content} from 'ionic/ionic';
|
||||
|
||||
@Component({
|
||||
@@ -23,11 +25,31 @@ import {List, Item, ActionMenu, Modal, ModalRef,
|
||||
Ionic comes with a variety of useful from controls, like
|
||||
text inputs, text areas, toggle switches, and sliders.
|
||||
</p>
|
||||
<form (^submit)="doSubmit($event)" [control-group]="form">
|
||||
<ion-input>
|
||||
<input control="email" type="email" placeholder="Your email">
|
||||
</ion-input>
|
||||
<ion-input>
|
||||
<input control="password" type="password" placeholder="Your password">
|
||||
</ion-input>
|
||||
<button ion-button primary block type="submit">Submit</button>
|
||||
</form>
|
||||
</ion-content>
|
||||
`,
|
||||
directives: [NavbarTemplate, Navbar, Content, List, Item]
|
||||
directives: [formDirectives, NavbarTemplate, Navbar, Content, List, Item, Input, Button]
|
||||
})
|
||||
export class FormPage {
|
||||
constructor() {
|
||||
var fb = new FormBuilder()
|
||||
|
||||
this.form = fb.group({
|
||||
email: ['', Validators.required],
|
||||
password: ['', Validators.required],
|
||||
});
|
||||
}
|
||||
|
||||
doSubmit(event) {
|
||||
console.log('Submitted:', this.form.value);
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,19 @@ import {NgFor, DynamicComponentLoader, Injector, DomRenderer, ElementRef} from '
|
||||
import {Ancestor} from 'angular2/src/core/annotations_impl/visibility';
|
||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
import {FormBuilder, Validators, FormDirectives, ControlGroup} from 'angular2/forms';
|
||||
import {FormBuilder, Validators, formDirectives, ControlGroup} from 'angular2/forms';
|
||||
|
||||
import {Segment, SegmentButton, List, Item, ActionMenu, Modal, ModalRef,
|
||||
import {Segment, SegmentButton, SearchBar, List, Item, ActionMenu, Modal, ModalRef,
|
||||
NavbarTemplate, Navbar, NavController, Button, Content} from 'ionic/ionic';
|
||||
|
||||
console.log(NavbarTemplate, Navbar, Content, formDirectives);
|
||||
|
||||
@Component({
|
||||
selector: 'ion-view'
|
||||
})
|
||||
@View({
|
||||
template: `
|
||||
<ion-navbar *navbar><ion-title>Cards</ion-title></ion-navbar>
|
||||
<ion-navbar *navbar><ion-title>Search Bar</ion-title></ion-navbar>
|
||||
|
||||
<ion-content class="padding">
|
||||
<h2>Search Bar</h2>
|
||||
@@ -25,17 +27,20 @@ import {Segment, SegmentButton, List, Item, ActionMenu, Modal, ModalRef,
|
||||
</p>
|
||||
|
||||
<form (^submit)="doSubmit($event)" [control-group]="form">
|
||||
<ion-search-bar control="searchQuery"></ion-search-bar>
|
||||
<div>
|
||||
Query: <b>{{form.controls.searchQuery.value}}</b>
|
||||
</div>
|
||||
</form>
|
||||
</ion-content>
|
||||
`,
|
||||
directives: [NavbarTemplate, Navbar, Content, List, Item, Segment, SegmentButton]
|
||||
directives: [formDirectives, NavbarTemplate, Navbar, Content, SearchBar]
|
||||
})
|
||||
export class SegmentPage {
|
||||
export class SearchBarPage {
|
||||
constructor() {
|
||||
var fb = new FormBuilder();
|
||||
this.form = fb.group({
|
||||
mapStyle: ['hybrid', Validators.required]
|
||||
searchQuery: ['', Validators.required]
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@ import {FormBuilder, Validators, formDirectives, ControlGroup} from 'angular2/fo
|
||||
import {Segment, SegmentButton, List, Item, ActionMenu, Modal, ModalRef,
|
||||
NavbarTemplate, Navbar, NavController, Button, Content} from 'ionic/ionic';
|
||||
|
||||
console.log('imporrted', formDirectives, Segment, SegmentButton);
|
||||
|
||||
@Component({
|
||||
selector: 'ion-view'
|
||||
})
|
||||
|
||||
25
ionic/components/app/test/sink/pages/tabs.js
Normal file
25
ionic/components/app/test/sink/pages/tabs.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import {NgFor, DynamicComponentLoader, Injector, DomRenderer, ElementRef} from 'angular2/angular2';
|
||||
import {Ancestor} from 'angular2/src/core/annotations_impl/visibility';
|
||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
import {FormBuilder, Validators, formDirectives, ControlGroup} from 'angular2/forms';
|
||||
|
||||
import {NavbarTemplate, Navbar, NavController, Button, Content} from 'ionic/ionic';
|
||||
|
||||
@Component({
|
||||
selector: 'ion-view'
|
||||
})
|
||||
@View({
|
||||
template: `
|
||||
<ion-navbar *navbar><ion-title>Tabs</ion-title></ion-navbar>
|
||||
|
||||
<ion-content class="padding">
|
||||
|
||||
</ion-content>
|
||||
`,
|
||||
directives: [NavbarTemplate, Navbar, Content]
|
||||
})
|
||||
export class TabsPage {
|
||||
constructor() {
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,18 @@
|
||||
$aside-width: 304px;
|
||||
$aside-height: 304px;
|
||||
$aside-transition: 0.2s ease transform;
|
||||
$aside-width: 304px !default;
|
||||
$aside-height: 304px !default;
|
||||
$aside-transition: 0.2s ease transform !default;
|
||||
$aside-background: #fff !default;
|
||||
$aside-shadow: -1px 0px 2px rgba(0, 0, 0, 0.2), 1px 0px 2px rgba(0,0,0,0.2) !default;
|
||||
|
||||
.aside {
|
||||
display: block;
|
||||
position: absolute;
|
||||
|
||||
background: #eee;
|
||||
background: $aside-background;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
|
||||
&[type=overlay] {
|
||||
z-index: $z-index-aside-overlay;
|
||||
@@ -72,6 +78,7 @@ $aside-transition: 0.2s ease transform;
|
||||
.aside-content {
|
||||
transition: $aside-transition;
|
||||
transform: translate3d(0,0,0);
|
||||
box-shadow: $aside-shadow;
|
||||
&.aside-open-left {
|
||||
transform: translate3d($aside-width,0,0);
|
||||
}
|
||||
|
||||
@@ -201,6 +201,7 @@ a.button {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:active,
|
||||
&.activated {
|
||||
opacity: 1;
|
||||
background-color: darken($bg-color, 12%);
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
|
||||
// Card
|
||||
// --------------------------------------------------
|
||||
$card-border-color: #ccc !default;
|
||||
$card-border-radius: 2px !default;
|
||||
$card-box-shadow: 0 1px 3px rgba(0, 0, 0, .3) !default;
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
@@ -10,3 +13,24 @@
|
||||
.card .item-label {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
.card .item {
|
||||
&:first-child {
|
||||
border-top-left-radius: $card-border-radius;
|
||||
border-top-right-radius: $card-border-radius;
|
||||
|
||||
.item-content {
|
||||
border-top-left-radius: $card-border-radius;
|
||||
border-top-right-radius: $card-border-radius;
|
||||
}
|
||||
}
|
||||
&:last-child {
|
||||
border-bottom-right-radius: $card-border-radius;
|
||||
border-bottom-left-radius: $card-border-radius;
|
||||
|
||||
.item-content {
|
||||
border-bottom-right-radius: $card-border-radius;
|
||||
border-bottom-left-radius: $card-border-radius;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,16 +2,16 @@ import {bootstrap} from 'angular2/angular2'
|
||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
|
||||
import {FormBuilder, Validators, FormDirectives, ControlGroup} from 'angular2/forms';
|
||||
import {FormBuilder, Validators, formDirectives, ControlGroup} from 'angular2/forms';
|
||||
//import {Button, Switch, Form, List, Label, Item, Input, Content} from 'ionic/ionic';
|
||||
import {IONIC_DIRECTIVES} from 'ionic/ionic'
|
||||
|
||||
console.log([FormDirectives].concat(IONIC_DIRECTIVES));
|
||||
console.log([formDirectives].concat(IONIC_DIRECTIVES));
|
||||
|
||||
@Component({ selector: 'ion-app' })
|
||||
@View({
|
||||
templateUrl: 'main.html',
|
||||
directives: [FormDirectives].concat(IONIC_DIRECTIVES)
|
||||
directives: [formDirectives].concat(IONIC_DIRECTIVES)
|
||||
})
|
||||
class IonicApp {
|
||||
constructor() {
|
||||
|
||||
@@ -102,6 +102,10 @@ ion-primary-swipe-buttons {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
img {
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.item-media + .item-label {
|
||||
@@ -109,7 +113,7 @@ ion-primary-swipe-buttons {
|
||||
}
|
||||
|
||||
.item-media:last-child {
|
||||
padding-right: $item-padding;
|
||||
//padding-right: $item-padding;
|
||||
}
|
||||
|
||||
.item-note {
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as util from 'ionic/util';
|
||||
import {NavController} from './nav-controller';
|
||||
import {Nav} from './nav';
|
||||
import {NavPane, NavPaneSection} from './nav';
|
||||
import {Lifecycle} from 'ionic/components/view/lifecycle';
|
||||
|
||||
|
||||
export class NavItem {
|
||||
@@ -194,14 +195,14 @@ export class NavItem {
|
||||
|
||||
titleElement() {
|
||||
if (this._titleEle === undefined) {
|
||||
//let navbarElement = this.navbarElement();
|
||||
//if (navbarElement) {
|
||||
// let titleEle = navbarElement.querySelector('ion-title');
|
||||
// if (titleEle) {
|
||||
// this._titleEle = titleEle;
|
||||
// return this._titleEle;
|
||||
// }
|
||||
//}
|
||||
let navbarElement = this.navbarElement();
|
||||
if (navbarElement) {
|
||||
let titleEle = navbarElement.querySelector('ion-title');
|
||||
if (titleEle) {
|
||||
this._titleEle = titleEle;
|
||||
return this._titleEle;
|
||||
}
|
||||
}
|
||||
this._titleEle = null;
|
||||
}
|
||||
return this._titleEle;
|
||||
|
||||
244
ionic/components/nav/nav-item.js.orig
Normal file
244
ionic/components/nav/nav-item.js.orig
Normal file
@@ -0,0 +1,244 @@
|
||||
import {ViewContainerRef} from 'angular2/src/core/compiler/view_container_ref';
|
||||
import {bind} from 'angular2/di';
|
||||
|
||||
import * as util from 'ionic/util';
|
||||
import {NavController} from './nav-controller';
|
||||
<<<<<<< HEAD
|
||||
import {Nav} from './nav';
|
||||
import {NavPane, NavPaneSection} from './nav';
|
||||
=======
|
||||
import {Lifecycle} from 'ionic/components/view/lifecycle';
|
||||
>>>>>>> origin/master
|
||||
|
||||
|
||||
export class NavItem {
|
||||
|
||||
constructor(nav, Component, params = {}) {
|
||||
this.nav = nav;
|
||||
this.Component = Component;
|
||||
this.params = params;
|
||||
this.id = util.nextUid();
|
||||
this._titleEle = undefined;
|
||||
this._backBtn = undefined;
|
||||
this.disposals = [];
|
||||
|
||||
// if it's possible to go back from this nav item
|
||||
this.enableBack = false;
|
||||
|
||||
this.protos = {};
|
||||
}
|
||||
|
||||
addProtoViewRef(name, protoViewRef) {
|
||||
this.protos[name] = protoViewRef;
|
||||
}
|
||||
|
||||
stage() {
|
||||
// update if it's possible to go back from this nav item
|
||||
//this.enableBack = !!this.nav.getPrevious(this);
|
||||
|
||||
return this.render();;
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.isRendered) {
|
||||
console.log('showed existing view', this.id);
|
||||
return Promise.resolve();
|
||||
}
|
||||
this.isRendered = true;
|
||||
|
||||
let resolve;
|
||||
let promise = new Promise((res) => { resolve = res; });
|
||||
|
||||
// compile the Component
|
||||
this.nav.compiler.compileInHost(this.Component).then(componentProtoViewRef => {
|
||||
|
||||
<<<<<<< HEAD
|
||||
// figure out the sturcture of this Component
|
||||
// does it have a navbar? Is it tabs? Should it not have a navbar or any toolbars?
|
||||
let itemStructure = this.getStructure(componentProtoViewRef);
|
||||
=======
|
||||
this.nav.loader.loadNextToExistingLocation(this.Component, this.nav.contentElementRef, injector).then((componentRef) => {
|
||||
|
||||
Lifecycle.viewLoaded(componentRef.instance);
|
||||
|
||||
console.log('nav-item loadNextToExistingLocation', this.nav.contentElementRef);
|
||||
let navbarContainer = this.nav.navbarContainerRef;
|
||||
>>>>>>> origin/master
|
||||
|
||||
// get the appropriate NavPane which this NavItem will fit into
|
||||
this.nav.getNavPane(itemStructure).then(navPane => {
|
||||
|
||||
// create a new injector just for this NavItem
|
||||
let injector = this.nav.injector.resolveAndCreateChild([
|
||||
bind(NavController).toValue(this.nav.navCtrl),
|
||||
bind(NavParams).toValue(new NavParams(this.params)),
|
||||
bind(NavItem).toValue(this)
|
||||
]);
|
||||
|
||||
// add the content of the view to the content area
|
||||
let viewContainer = navPane.contentContainerRef;
|
||||
let hostViewRef = viewContainer.create(componentProtoViewRef, -1, null, injector);
|
||||
|
||||
this.disposals.push(() => {
|
||||
viewContainer.remove( viewContainer.indexOf(hostViewRef) );
|
||||
});
|
||||
|
||||
this.viewEle = hostViewRef._view.render._view.rootNodes[0];
|
||||
this.viewEle.classList.add('nav-item');
|
||||
|
||||
// add only the sections it needs
|
||||
if (itemStructure.navbar) {
|
||||
let navbarViewContainer = navPane.sections.navbar.viewContainerRef;
|
||||
this.navbarView = navbarViewContainer.create(this.protos.navbar, -1, null, injector);
|
||||
|
||||
this.disposals.push(() => {
|
||||
navbarViewContainer.remove( navbarViewContainer.indexOf(this.navbarView) );
|
||||
});
|
||||
}
|
||||
|
||||
resolve();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
getStructure(componentProtoViewRef) {
|
||||
// navbar - toolbar - toolbar - content - toolbar - tabbar
|
||||
let itemStructure = {
|
||||
navbar: true,
|
||||
tabbar: false,
|
||||
toolbars: [],
|
||||
key: 'c'
|
||||
};
|
||||
|
||||
return itemStructure;
|
||||
}
|
||||
// if (this.created) {
|
||||
// console.log('showed existing view', this.id);
|
||||
// return Promise.resolve();
|
||||
// }
|
||||
|
||||
// this.created = true;
|
||||
|
||||
// let resolve;
|
||||
// let promise = new Promise((res) => { resolve = res; });
|
||||
|
||||
// let injector = this.nav.injector.resolveAndCreateChild([
|
||||
// bind(NavController).toValue(this.nav.navCtrl),
|
||||
// bind(NavParams).toValue(new NavParams(this.params)),
|
||||
// bind(NavItem).toValue(this)
|
||||
// ]);
|
||||
|
||||
// this.nav.loader.loadNextToExistingLocation(this.Component, this.nav.contentElementRef, injector).then((componentRef) => {
|
||||
// let navbarContainer = this.nav.navbarContainerRef;
|
||||
|
||||
// if (componentRef && componentRef.dispose && navbarContainer) {
|
||||
// this.disposals.push(componentRef.dispose);
|
||||
|
||||
// this.viewEle = componentRef.location.domElement;
|
||||
// this.viewEle.classList.add('ion-view');
|
||||
|
||||
// if (this._navbarProto) {
|
||||
// let context = {
|
||||
// boundElementIndex: 0,
|
||||
// parentView: {
|
||||
// _view: componentRef.location.parentView._view.componentChildViews[0]
|
||||
// }
|
||||
// };
|
||||
|
||||
// let atIndex = -1;
|
||||
|
||||
// this._navbarView = navbarContainer.create(this._navbarProto, atIndex, context, injector);
|
||||
|
||||
// if (this._navbarView) {
|
||||
// this.disposals.push(() => {
|
||||
// navbarContainer.remove( navbarContainer.indexOf(this._navbarView) );
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// console.log('created view', this.id);
|
||||
// resolve();
|
||||
// });
|
||||
|
||||
// return promise;
|
||||
|
||||
|
||||
cache() {
|
||||
console.log('cached view', this.id);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
console.log('destroyed view', this.id);
|
||||
|
||||
for (let i = 0; i < this.disposals.length; i++) {
|
||||
this.disposals[i]();
|
||||
}
|
||||
|
||||
// just to help prevent any possible memory leaks
|
||||
for (let name in this) {
|
||||
if (this.hasOwnProperty(name)) {
|
||||
this[name] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
navbarProto(navbarProtoView) {
|
||||
console.log('nav-item navbarProto')
|
||||
this._navbarProto = navbarProtoView;
|
||||
}
|
||||
|
||||
viewElement() {
|
||||
return this.viewEle;
|
||||
}
|
||||
|
||||
navbarElement() {
|
||||
if (this.navbarView && this.navbarView._view) {
|
||||
return this.navbarView._view.render._view.rootNodes[0];
|
||||
}
|
||||
}
|
||||
|
||||
contentElement() {
|
||||
return this.viewEle.querySelector('ion-content');
|
||||
}
|
||||
|
||||
titleElement() {
|
||||
if (this._titleEle === undefined) {
|
||||
//let navbarElement = this.navbarElement();
|
||||
//if (navbarElement) {
|
||||
// let titleEle = navbarElement.querySelector('ion-title');
|
||||
// if (titleEle) {
|
||||
// this._titleEle = titleEle;
|
||||
// return this._titleEle;
|
||||
// }
|
||||
//}
|
||||
this._titleEle = null;
|
||||
}
|
||||
return this._titleEle;
|
||||
}
|
||||
|
||||
backButtonElement() {
|
||||
if (this._backBtn === undefined) {
|
||||
let navbarElement = this.navbarElement();
|
||||
if (navbarElement) {
|
||||
let backBtn = navbarElement.querySelector('back-button');
|
||||
if (backBtn) {
|
||||
this._backBtn = backBtn;
|
||||
return this._backBtn;
|
||||
}
|
||||
}
|
||||
this._backBtn = null;
|
||||
}
|
||||
return this._backBtn;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class NavParams {
|
||||
constructor(params) {
|
||||
util.extend(this, params);
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,14 @@ export class FirstPage {
|
||||
this.val = Math.round(Math.random() * 8999) + 1000;
|
||||
}
|
||||
|
||||
viewLoaded() {
|
||||
console.log('VIEW LOADED');
|
||||
}
|
||||
|
||||
viewWillShow() {
|
||||
console.log('VIEW WILL SHOW');
|
||||
}
|
||||
|
||||
push() {
|
||||
this.nav.push(SecondPage, { id: 8675309, myData: [1,2,3,4] }, { animation: 'ios' });
|
||||
}
|
||||
|
||||
@@ -32,8 +32,8 @@ export class SearchBar {
|
||||
cd.valueAccessor = this; //ControlDirective should inject CheckboxControlDirective
|
||||
|
||||
setTimeout(() => {
|
||||
console.log('Search bar for list', this.list);
|
||||
this.query = 'Cats';
|
||||
//console.log('Search bar for list', this.list);
|
||||
this.query = '';
|
||||
})
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ export class SearchBar {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
export class SearchPipe extends Pipe {
|
||||
constructor() {
|
||||
super();
|
||||
@@ -74,6 +75,7 @@ export class SearchPipe extends Pipe {
|
||||
return new SearchPipe(cdRef);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
new IonicComponent(SearchBar, {
|
||||
properties: {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {bootstrap, For} from 'angular2/angular2'
|
||||
import {bootstrap, NgFor} from 'angular2/angular2'
|
||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
|
||||
import { bind } from 'angular2/di';
|
||||
import { PipeRegistry } from 'angular2/change_detection';
|
||||
|
||||
import {FormBuilder, Validators, FormDirectives, Control, ControlGroup} from 'angular2/forms';
|
||||
import {FormBuilder, Validators, formDirectives, Control, ControlGroup} from 'angular2/forms';
|
||||
|
||||
import {Content} from 'ionic/components/content/content';
|
||||
import {List} from 'ionic/components/list/list';
|
||||
@@ -21,7 +21,7 @@ function randomTitle() {
|
||||
@Component({ selector: 'ion-app' })
|
||||
@View({
|
||||
templateUrl: 'main.html',
|
||||
directives: [FormDirectives].concat([Content, List, Item, SearchBar, For])
|
||||
directives: [formDirectives].concat([Content, List, Item, SearchBar, NgFor])
|
||||
})
|
||||
class IonicApp {
|
||||
constructor() {
|
||||
@@ -56,15 +56,17 @@ class IonicApp {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
import { defaultPipes } from 'angular2/change_detection';
|
||||
export var pipes = Object.assign({}, defaultPipes, {
|
||||
'search': [
|
||||
new SearchPipe()
|
||||
]
|
||||
});
|
||||
*/
|
||||
|
||||
export function main() {
|
||||
bootstrap(IonicApp, [
|
||||
bind(PipeRegistry).toValue(new PipeRegistry(pipes))
|
||||
//bind(PipeRegistry).toValue(new PipeRegistry(pipes))
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<ion-list #list>
|
||||
|
||||
<ion-item *for="#item of getItems()"><!--items | search:form.controls.searchControl.value">-->
|
||||
<ion-item *ng-for="#item of getItems()"><!--items | search:form.controls.searchControl.value">-->
|
||||
{{item.title}}
|
||||
</ion-item>
|
||||
</ion-list>
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
import {bootstrap, Switch, SwitchWhen} from 'angular2/angular2'
|
||||
import {bootstrap, NgSwitch, NgSwitchWhen} from 'angular2/angular2'
|
||||
import {Component, Directive} from 'angular2/src/core/annotations_impl/annotations';
|
||||
import {View} from 'angular2/src/core/annotations_impl/view';
|
||||
|
||||
import {Segment, SegmentButton, Content, Button} from 'ionic/ionic';
|
||||
import {FormBuilder, Validators, FormDirectives, ControlGroup} from 'angular2/forms';
|
||||
import {FormBuilder, Validators, formDirectives, ControlGroup} from 'angular2/forms';
|
||||
//import {IONIC_DIRECTIVES} from 'ionic/ionic'
|
||||
|
||||
console.log('Loaded', formDirectives, Segment, SegmentButton, Content, Button, NgSwitch, NgSwitchWhen);
|
||||
|
||||
@Component({ selector: 'ion-app' })
|
||||
@View({
|
||||
templateUrl: 'main.html',
|
||||
directives: [FormDirectives].concat([Segment, SegmentButton, Content, Button, Switch, SwitchWhen])
|
||||
directives: [formDirectives].concat([Segment, SegmentButton, Content, Button, NgSwitch, NgSwitchWhen])
|
||||
})
|
||||
class IonicApp {
|
||||
constructor() {
|
||||
|
||||
@@ -17,7 +17,7 @@ $toolbar-ios-button-text-color: #007aff !default;
|
||||
$toolbar-ios-button-background-color: transparent !default;
|
||||
|
||||
|
||||
.platform-ios .toolbar {
|
||||
.platform-ios ion-toolbar {
|
||||
|
||||
height: $toolbar-ios-height;
|
||||
background: $toolbar-ios-background;
|
||||
|
||||
@@ -10,13 +10,14 @@ $toolbar-order: (
|
||||
|
||||
|
||||
ion-toolbar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.toolbar-inner {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
14
ionic/components/view/lifecycle.js
Normal file
14
ionic/components/view/lifecycle.js
Normal file
@@ -0,0 +1,14 @@
|
||||
export class Lifecycle {
|
||||
static viewLoaded(component) {
|
||||
component.viewLoaded && component.viewLoaded();
|
||||
}
|
||||
static viewWillShow(component) {
|
||||
component.viewWillShow && component.viewWillShow();
|
||||
}
|
||||
static viewEntered(component) {
|
||||
component.viewEntered && component.viewEntered();
|
||||
}
|
||||
static viewDestroyed(component) {
|
||||
component.viewDestroyed && component.viewDestroyed();
|
||||
}
|
||||
}
|
||||
30
ionic/components/view/view.scss.orig
Normal file
30
ionic/components/view/view.scss.orig
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
ion-view {
|
||||
display: flex;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
background-color: white;
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
|
||||
// by default this is display: none;
|
||||
// and the transition animation will display it
|
||||
//display: none;
|
||||
flex-direction: column;
|
||||
|
||||
display: flex;
|
||||
|
||||
/*
|
||||
TODO: This is probably not the most common case,
|
||||
should be display flex first, then remove for special cases.
|
||||
&.show-view {
|
||||
display: flex;
|
||||
}
|
||||
*/
|
||||
|
||||
>>>>>>> origin/master
|
||||
}
|
||||
@@ -32,6 +32,10 @@ class PlatformController {
|
||||
registry[platform.name] = platform;
|
||||
}
|
||||
|
||||
getPlatform(name) {
|
||||
return registry[name];
|
||||
}
|
||||
|
||||
set(platform) {
|
||||
activePlatform = platform;
|
||||
|
||||
@@ -92,7 +96,7 @@ Platform.register({
|
||||
|
||||
// Last case is a catch-all
|
||||
Platform.setDefault({
|
||||
name: 'core'
|
||||
name: 'ios'
|
||||
});
|
||||
|
||||
Platform.set( Platform.detect() );
|
||||
Platform.set( Platform.get('ios') );//Platform.detect() );
|
||||
|
||||
219
mockup/model.js
219
mockup/model.js
@@ -1,219 +0,0 @@
|
||||
class Element {
|
||||
}
|
||||
class DomElement extends Element {
|
||||
}
|
||||
class NativeElement extends Element {
|
||||
}
|
||||
|
||||
class View {
|
||||
el: Element;
|
||||
children: List<View>
|
||||
|
||||
// Child operations
|
||||
addChild(child) {
|
||||
}
|
||||
removeChild(child) {
|
||||
}
|
||||
insertChild(child, index) {
|
||||
}
|
||||
constructor(el: Element) {
|
||||
}
|
||||
|
||||
getElement() {
|
||||
return el
|
||||
}
|
||||
}
|
||||
|
||||
class TabBarView extends View {
|
||||
tabBarButtons: List<TabBarButtonView>
|
||||
}
|
||||
class TabBarButtonView extends Button {
|
||||
icon: Icon
|
||||
title: String
|
||||
}
|
||||
|
||||
/**
|
||||
* VIEW CONTROLLERS
|
||||
*/
|
||||
|
||||
class ViewController {
|
||||
view: View;
|
||||
behaviors: List<Behavior>
|
||||
|
||||
behaviorEmit(lifeCycleEventName) {
|
||||
forEach(this.behaviors, function(behavior) {
|
||||
if(behavior[lifeCycleEventName](this.view) === false) {
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Lifecycle methods, same as Adam Lifecycle
|
||||
onCompile() {
|
||||
behaviorEmit('onCompile')
|
||||
}
|
||||
onInsert() {
|
||||
behaviorEmit('onInsert')
|
||||
}
|
||||
onRemove() {
|
||||
behaviorEmit('onRemove')
|
||||
}
|
||||
}
|
||||
|
||||
class NavViewController extends ViewController {
|
||||
viewControllers: Stack<ViewController>;
|
||||
visibleViewController: ViewController;
|
||||
|
||||
push(viewController) {
|
||||
stack.push(viewController)
|
||||
}
|
||||
pop(viewController) {
|
||||
stack.pop(viewController)
|
||||
}
|
||||
set viewControllers(v) {
|
||||
this.viewControllers = v
|
||||
}
|
||||
}
|
||||
|
||||
class TabsViewController extends ViewController {
|
||||
tabBar: TabBarView;
|
||||
viewControllers: List<ViewController>;
|
||||
|
||||
constructor() {
|
||||
this.tabBar.bind('tabClick', function(tabItem) {
|
||||
// A specific tab item was clicked
|
||||
this.selectTab(tabItem)
|
||||
})
|
||||
}
|
||||
|
||||
addTab(viewController) {
|
||||
this.viewControllers.push(viewController)
|
||||
}
|
||||
}
|
||||
|
||||
class SideMenuController extends ViewController {
|
||||
sideMenuView: SideMenuView
|
||||
contentView: View
|
||||
|
||||
constructor(contentView, side) {
|
||||
this.sideMenuView = new SideMenuView()
|
||||
|
||||
if(contentView) {
|
||||
// Explicit content view
|
||||
this.contentView = contentView
|
||||
} else {
|
||||
// Heuristic to try to find it
|
||||
this.inferContentView()
|
||||
}
|
||||
this.side = side
|
||||
|
||||
// The default behavior
|
||||
this.behaviors.push(new SideMenuContentSlideBehavior(
|
||||
this.sideMenuView,
|
||||
this.contentView
|
||||
))
|
||||
|
||||
}
|
||||
|
||||
inferContentView() {
|
||||
this.contentView = this.getParent().find('is(Content)')[0]
|
||||
/*
|
||||
var index = this.getParent().getChildren().indexOf(this.sideMenuView))
|
||||
if(this.side == 'left') {
|
||||
targetIndex = index + 1
|
||||
}
|
||||
if(this.side == 'right') {
|
||||
targetIndex = index - 1
|
||||
}
|
||||
this.contentView = this.getParent().getChildAtIndex(targetIndex)
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
class Behavior {
|
||||
// The Behavior class will hook into lifecycle events for views
|
||||
|
||||
// Component compiled
|
||||
onCompile(view) {
|
||||
}
|
||||
// Component inserted
|
||||
onInsert(view) {
|
||||
}
|
||||
|
||||
beforeCreate() {
|
||||
}
|
||||
onCreate() {
|
||||
}
|
||||
afterCreate() {
|
||||
}
|
||||
}
|
||||
|
||||
class SideMenuContentSlideBehavior extends Behavior {
|
||||
constructor(sideMenuView, contentView) {
|
||||
var gesture = new EdgePanGesture(this.onDrag, contentView)
|
||||
}
|
||||
act: function(view, lifecycle) {
|
||||
return false
|
||||
}
|
||||
onDrag: function(event) {
|
||||
// Drag out side menu
|
||||
}
|
||||
}
|
||||
class DrawerStyleBehavior extends Behavior {
|
||||
act: function(view, lifecycle) {
|
||||
var gesture = new EdgePanGesture(this.onDrag, contentView)
|
||||
return false
|
||||
}
|
||||
onInsert(view) {
|
||||
}
|
||||
onDrag: function(event) {
|
||||
// Drag out side menu
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gestures
|
||||
**/
|
||||
|
||||
class Gesture {
|
||||
}
|
||||
class EdgePanGesture extends Gesture {
|
||||
constructor(el) {
|
||||
el.onDrag(this.onDrag)
|
||||
}
|
||||
onDrag(e) {
|
||||
x = e.pageX
|
||||
y = e.pageY
|
||||
|
||||
|
||||
if(!isDragging && x > edgeThreshold) {
|
||||
// Not in threshold
|
||||
return
|
||||
} else if(!isDragging) {
|
||||
// Check if we've started yet
|
||||
if(!start) {
|
||||
start = {
|
||||
x: x
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we dragged enough (like 3 px or whatever)
|
||||
if(Math.abs(start.x - x) > dragThreshold) {
|
||||
isDragging = true
|
||||
}
|
||||
}
|
||||
}
|
||||
onDragEnd(e) {
|
||||
start = null
|
||||
x = null
|
||||
isDragging = false
|
||||
}
|
||||
}
|
||||
class PinchToZoomGesture extends Gesture {
|
||||
}
|
||||
class HoldGesture extends Gesture {
|
||||
}
|
||||
class SwipeGesture extends Gesture {
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
<ion-app>
|
||||
<ion-nav>
|
||||
<login-page>
|
||||
<button push="signup">Sign up</button>
|
||||
<button pop>Back</button>
|
||||
</login-page>
|
||||
</ion-nav>
|
||||
</ion-app>
|
||||
@@ -1,51 +0,0 @@
|
||||
/**
|
||||
* This is a mockup of how the new router might work.
|
||||
*
|
||||
* The goal of this is to help shape the new Angular router, or
|
||||
* figure out if we need to do our own implementation.
|
||||
|
||||
Some design decisions we need to figure out and agree on:
|
||||
|
||||
* Deep linking. In v1 we did a complicated nested view linking, where
|
||||
a route with a URL like /contacts/name would navigate in each sub
|
||||
view, reconstructing a whole navigation context.
|
||||
|
||||
I'm not convinced this is the right approach for v2. Instead, we might
|
||||
want to make it more explicit, where certain URLs can trigger a handler
|
||||
where navigation can be reconstructed by the developer, but with the
|
||||
default behavior of routes being navigated to in the root nav.
|
||||
*/
|
||||
|
||||
// Decorators
|
||||
|
||||
@Route({
|
||||
})
|
||||
class App extends Ionic {
|
||||
constructor(nav: Navigation) {
|
||||
nav.urls({
|
||||
templateUrl: '/contacts/:contact',
|
||||
navigate: (url, params) => {
|
||||
if(params.contactId) {
|
||||
// Explicit routing
|
||||
var contactList = new ContactList();
|
||||
rootNav.push(contactList, false // whether to animate);
|
||||
var contactPage = new ContactPage(params.contactId);
|
||||
rootNav.push(contactPage);
|
||||
|
||||
// Now the user has a 2 history navigation:
|
||||
// root -> contact list -> contact page
|
||||
//
|
||||
// But note, it was up to the developer to construct the appropriate history
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Route({
|
||||
name: 'login'
|
||||
templateUrl: '/login' // Optional
|
||||
})
|
||||
class LoginPage extends View {
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
# Router
|
||||
|
||||
|
||||
### App Views extend View
|
||||
|
||||
```
|
||||
class MyView1 extends View {
|
||||
constructor(navView) {}
|
||||
}
|
||||
|
||||
@Template({
|
||||
template: '<div>blah blah</div>'
|
||||
})
|
||||
class MyView2 extends View {
|
||||
constructor(navView) {}
|
||||
}
|
||||
|
||||
@Route({
|
||||
templateUrl: '/myview4'
|
||||
})
|
||||
class MyView4 extends View {
|
||||
constructor(navView) {}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
|
||||
### JS Nav
|
||||
|
||||
```
|
||||
navView.push(MyView2)
|
||||
|
||||
navView.push({
|
||||
controller: MyView3,
|
||||
template: 'view3.html'
|
||||
})
|
||||
|
||||
navView.push({
|
||||
animation: 'horizontal',
|
||||
controller: MyView3,
|
||||
template: 'view3.html'
|
||||
})
|
||||
|
||||
navView.push({
|
||||
templateUrl: '/whateves',
|
||||
template: '<div>crazy dynamic template</div>'
|
||||
})
|
||||
```
|
||||
|
||||
|
||||
### Markup Nav
|
||||
|
||||
```
|
||||
<a nav-link="MyView2"></a>
|
||||
|
||||
<a [nav-link]="{ controller: MyView3, template: 'view3.html', animation: horizontal }"></a>
|
||||
```
|
||||
|
||||
### Animations
|
||||
|
||||
```
|
||||
platform: Whatever the platform would have naturally done (Default)
|
||||
horizontal: Right to center when going forward. Center to right when going back
|
||||
vertial: Bottom to center when going forward. Bottom to center when going back
|
||||
right-to-center: Always right to center
|
||||
left-to-center: Always left to center
|
||||
top-to-center: Always top to center
|
||||
bottom-to-center: Always bottom to center
|
||||
```
|
||||
|
||||
|
||||
### Simple webdev:
|
||||
|
||||
1. Give markup a templateUrl: Saving the file, CMS url, or creating an endpoint serversize (django, RoR, etc)
|
||||
2. In the markup, add a link all the linked pages using `href=url`
|
||||
|
||||
Pros: Simple. Its how the web works.
|
||||
|
||||
Cons: Not ideal for web applications
|
||||
|
||||
|
||||
### Ionic v1
|
||||
|
||||
1. Create the stateProvider
|
||||
2. Create state name
|
||||
3. Give the state a url
|
||||
4. Set the state name of where the state should live (name the div)
|
||||
5. Wire up this state to the controller
|
||||
6. Wire up this state to the template
|
||||
7. In the template, add a link to all the linked pages using `href=url` or `ui-sref=stateName`
|
||||
|
||||
Pros: Centralizes all routes and URLs for easy management. Can update numerous sections of the webapp, rather than just one div. Deep linking: click to any view of the entire webapp from anywhere. Good for webapps.
|
||||
|
||||
Cons: Many repetitive steps. Confusing what each of the variables actually do. Web devs aren't familiar with JS routing.
|
||||
|
||||
|
||||
### Ionic v2 (without a markup shorthand)
|
||||
|
||||
1. Create custom view component by extending base ionic view
|
||||
2. Add template to component
|
||||
3. Add DI of nav-view to the view's constructor's arguments
|
||||
4. Add a click handler for every link
|
||||
5. In each click handler, use `navView.push()` (would each view we link to require an import on that page?)
|
||||
6. In the template, add the click handler to each of the linked views
|
||||
|
||||
Pros: Decentralized routing. More like native apps and OO languages/frameworks. Only concerned about informing it's parent navView, rather than a global configuration.
|
||||
|
||||
Cons: Decentralized routing. Creating click methods in JS and wiring them up in HTML. No/Difficult deep linking: Only can go forward and back. Only updates one div.
|
||||
Reference in New Issue
Block a user