Skip to content

Commit 98e7883

Browse files
committed
initial commit
0 parents  commit 98e7883

24 files changed

+576
-0
lines changed

.gitignore

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
6+
# Runtime data
7+
pids
8+
*.pid
9+
*.seed
10+
11+
# Directory for instrumented libs generated by jscoverage/JSCover
12+
lib-cov
13+
14+
# Coverage directory used by tools like istanbul
15+
coverage
16+
17+
# nyc test coverage
18+
.nyc_output
19+
20+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21+
.grunt
22+
23+
# node-waf configuration
24+
.lock-wscript
25+
26+
# Compiled binary addons (http://nodejs.org/api/addons.html)
27+
build/Release
28+
29+
# Dependency directories
30+
node_modules
31+
jspm_packages
32+
typings
33+
34+
# Optional npm cache directory
35+
.npm
36+
37+
# Optional REPL history
38+
.node_repl_history
39+
40+
# Generated files
41+
app/**/*.js
42+
app/**/*.js.map

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 Jason Watmore
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# angular2-animation-tutorial-example
2+
3+
Angular 2 / 4 - Router Animation Example & Tutorial

app/_content/app.less

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/* GENERAL STYLES AND CLASSES
2+
--------------------------------------------------------------------- */
3+
body {
4+
padding: 5px;
5+
6+
ng-component {
7+
display: block;
8+
}
9+
}
10+
11+
/* HEADER STYLES
12+
--------------------------------------------------------------------- */
13+
header {
14+
}
15+
16+
/* MAIN STYLES
17+
--------------------------------------------------------------------- */
18+
main {
19+
padding: 0 20px;
20+
min-height: 300px;
21+
22+
.products-table {
23+
margin-top: 20px;
24+
25+
.delete-column {
26+
width: 60px;
27+
}
28+
}
29+
30+
/* side form */
31+
.view-side-form {
32+
.side-form {
33+
position: absolute;
34+
z-index: 100;
35+
top: 0;
36+
right: 0;
37+
width: 80%;
38+
height: 100%;
39+
overflow: auto;
40+
background: #fff;
41+
padding: 20px;
42+
border-left: 1px solid #e0e0e0;
43+
}
44+
}
45+
}
46+
47+
/* FOOTER STYLES
48+
--------------------------------------------------------------------- */
49+
footer {
50+
text-align: center;
51+
margin-top: 20px;
52+
padding: 20px;
53+
border-top: 1px solid #ddd;
54+
}

app/_helpers/animations.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { trigger, state, animate, transition, style } from '@angular/animations';
2+
3+
export function fadeIn() {
4+
return trigger('fadeIn', [
5+
// route 'enter' transition
6+
transition(':enter', [
7+
8+
// styles at start of transition
9+
style({ opacity: 0 }),
10+
11+
// animation and styles at end of transition
12+
animate('.3s', style({ opacity: 1 }))
13+
]),
14+
]);
15+
}
16+
17+
export function slideInOut() {
18+
return trigger('slideInOut', [
19+
20+
// end state styles for route container (host)
21+
state('*', style({
22+
// the view covers the whole screen with a semi tranparent background
23+
position: 'fixed',
24+
top: 0,
25+
left: 0,
26+
right: 0,
27+
bottom: 0,
28+
backgroundColor: 'rgba(0, 0, 0, 0.8)'
29+
})),
30+
31+
// route 'enter' transition
32+
transition(':enter', [
33+
34+
// styles at start of transition
35+
style({
36+
// start with the content positioned off the right of the screen,
37+
// -400% is required instead of -100% because the negative position adds to the width of the element
38+
right: '-400%',
39+
40+
// start with background opacity set to 0 (invisible)
41+
backgroundColor: 'rgba(0, 0, 0, 0)'
42+
}),
43+
44+
// animation and styles at end of transition
45+
animate('.5s ease-in-out', style({
46+
// transition the right position to 0 which slides the content into view
47+
right: 0,
48+
49+
// transition the background opacity to 0.8 to fade it in
50+
backgroundColor: 'rgba(0, 0, 0, 0.8)'
51+
}))
52+
]),
53+
54+
// route 'leave' transition
55+
transition(':leave', [
56+
// animation and styles at end of transition
57+
animate('.5s ease-in-out', style({
58+
// transition the right position to -400% which slides the content out of view
59+
right: '-400%',
60+
61+
// transition the background opacity to 0 to fade it out
62+
backgroundColor: 'rgba(0, 0, 0, 0)'
63+
}))
64+
])
65+
])
66+
}

app/_services/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './product.service';

app/_services/product.service.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import { Injectable } from '@angular/core';
2+
3+
@Injectable()
4+
export class ProductService {
5+
getAll() {
6+
return this.getProducts();
7+
}
8+
9+
getById(id: number) {
10+
return this.getProducts().filter(product => product.id === id);
11+
}
12+
13+
save(product: any) {
14+
let products = this.getProducts();
15+
16+
if (product.id) {
17+
// update existing product
18+
19+
for (var i = 0; i < products.length; i++) {
20+
if (products[i].id === product.id) {
21+
products[i] = product;
22+
break;
23+
}
24+
}
25+
this.setProducts(products);
26+
} else {
27+
// create new product
28+
29+
// assign id
30+
var lastProduct = products[products.length - 1] || { id: 0 };
31+
product.id = lastProduct.id + 1;
32+
33+
// save to local storage
34+
products.push(product);
35+
this.setProducts(products);
36+
}
37+
}
38+
39+
delete(id: number) {
40+
let products = this.getProducts();
41+
for (var i = 0; i < products.length; i++) {
42+
var product = products[i];
43+
if (product.id === id) {
44+
products.splice(i, 1);
45+
break;
46+
}
47+
}
48+
this.setProducts(products);
49+
}
50+
51+
// private helper methods
52+
53+
private getProducts(): any[] {
54+
if (!localStorage.getItem('products')) {
55+
localStorage.setItem('products', JSON.stringify([]));
56+
}
57+
58+
return JSON.parse(localStorage.getItem('products'));
59+
}
60+
61+
private setProducts(products: any[]) {
62+
localStorage.setItem('products', JSON.stringify(products));
63+
}
64+
}

app/app-routing.module.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { NgModule } from '@angular/core';
2+
import { Routes, RouterModule } from '@angular/router';
3+
4+
import { HomeComponent } from './home/index';
5+
import { ProductListComponent, ProductAddEditComponent } from './products/index';
6+
7+
const routes: Routes = [
8+
{ path: '', pathMatch: 'full', component: HomeComponent },
9+
{
10+
path: 'products',
11+
component: ProductListComponent,
12+
children: [
13+
{ path: 'add', component: ProductAddEditComponent }
14+
]
15+
},
16+
17+
// otherwise redirect to home
18+
{ path: '**', redirectTo: '' }
19+
];
20+
21+
22+
@NgModule({
23+
imports: [RouterModule.forRoot(routes)],
24+
exports: [RouterModule]
25+
})
26+
export class AppRoutingModule { }
27+
28+
export const routedComponents = [HomeComponent, ProductListComponent, ProductAddEditComponent];

app/app.component.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!-- header -->
2+
<header>
3+
<ul class="nav nav-tabs">
4+
<li routerLinkActive="active" [routerLinkActiveOptions]="{ exact: true }"><a routerLink="/">Home</a></li>
5+
<li routerLinkActive="active"><a routerLink="/products">Products</a></li>
6+
</ul>
7+
</header>
8+
9+
<main>
10+
<router-outlet></router-outlet>
11+
</main>
12+
13+
<!-- footer -->
14+
<footer>
15+
<p>
16+
<a href="http://jasonwatmore.com">JasonWatmore.com</a>
17+
</p>
18+
</footer>

app/app.component.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Component } from '@angular/core';
2+
3+
import { ProductService } from './_services/index';
4+
5+
@Component({
6+
moduleId: module.id.toString(),
7+
selector: 'app',
8+
templateUrl: 'app.component.html'
9+
})
10+
11+
export class AppComponent {
12+
constructor(private productService: ProductService) {
13+
// add some initial products
14+
if (productService.getAll().length === 0) {
15+
productService.save({ name: 'Boardies', price: '25.00' });
16+
productService.save({ name: 'Singlet', price: '9.50' });
17+
productService.save({ name: 'Thongs (Flip Flops)', price: '12.95' });
18+
}
19+
}
20+
}

app/app.module.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { NgModule } from '@angular/core';
2+
import { BrowserModule } from '@angular/platform-browser';
3+
import { FormsModule } from '@angular/forms';
4+
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
5+
6+
import { AppComponent } from './app.component';
7+
import { AppRoutingModule, routedComponents } from './app-routing.module';
8+
import { ProductService } from './_services/index';
9+
10+
@NgModule({
11+
imports: [
12+
BrowserModule,
13+
FormsModule,
14+
AppRoutingModule,
15+
BrowserAnimationsModule
16+
],
17+
declarations: [
18+
AppComponent,
19+
routedComponents
20+
],
21+
providers: [
22+
ProductService
23+
],
24+
bootstrap: [AppComponent]
25+
})
26+
export class AppModule { }

app/home/home.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
<h1>Home</h1>
2+
<p>Angular 2 (version 4) Animation Tutorial & Example</p>

app/home/home.component.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Component } from '@angular/core';
2+
import { fadeIn } from '../_helpers/animations';
3+
4+
@Component({
5+
moduleId: module.id.toString(),
6+
templateUrl: 'home.component.html',
7+
animations: [fadeIn()],
8+
host: { '[@fadeIn]': '' }
9+
})
10+
11+
export class HomeComponent {
12+
}

app/home/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './home.component';

app/main.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2+
3+
import { AppModule } from './app.module';
4+
5+
platformBrowserDynamic().bootstrapModule(AppModule);

app/products/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './product-list.component';
2+
export * from './product-add-edit.component';

0 commit comments

Comments
 (0)