File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,19 @@
|
||||
import { by } from 'protractor';
|
||||
import { locate } from './util';
|
||||
|
||||
export function getPage() {
|
||||
return by.css('app-hero-list-auto-page');
|
||||
}
|
||||
|
||||
export function getComponent() {
|
||||
return by.css('app-hero-list-auto');
|
||||
}
|
||||
|
||||
export function getComponentContainer() {
|
||||
const findContainer = () => by.css('ul');
|
||||
return locate(getComponent(), findContainer());
|
||||
}
|
||||
|
||||
export function getHeroesList() {
|
||||
return getComponentContainer().all(by.css('li'));
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { by } from 'protractor';
|
||||
import { locate } from './util';
|
||||
|
||||
export function getPage() {
|
||||
return by.css('app-hero-list-enter-leave-page');
|
||||
}
|
||||
|
||||
export function getComponent() {
|
||||
return by.css('app-hero-list-enter-leave');
|
||||
}
|
||||
|
||||
export function getComponentContainer() {
|
||||
const findContainer = () => by.css('ul');
|
||||
return locate(getComponent(), findContainer());
|
||||
}
|
||||
|
||||
export function getHeroesList() {
|
||||
return getComponentContainer().all(by.css('li'));
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { by } from 'protractor';
|
||||
import { locate } from './util';
|
||||
|
||||
export function getPage() {
|
||||
return by.css('app-hero-list-page');
|
||||
}
|
||||
|
||||
export function getComponentContainer() {
|
||||
const findContainer = () => by.css('ul');
|
||||
return locate(getPage(), findContainer());
|
||||
}
|
||||
|
||||
export function getHeroesList() {
|
||||
return getComponentContainer().all(by.css('li'));
|
||||
}
|
||||
|
||||
export function getFormInput() {
|
||||
const formInput = () => by.css('form > input');
|
||||
return locate(getPage(), formInput());
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { by } from 'protractor';
|
||||
import { locate } from './util';
|
||||
|
||||
export function getPage() {
|
||||
return by.css('app-hero-list-groups-page');
|
||||
}
|
||||
|
||||
export function getComponent() {
|
||||
return by.css('app-hero-list-groups');
|
||||
}
|
||||
|
||||
export function getComponentContainer() {
|
||||
const findContainer = () => by.css('ul');
|
||||
return locate(getComponent(), findContainer());
|
||||
}
|
||||
|
||||
export function getHeroesList() {
|
||||
return getComponentContainer().all(by.css('li'));
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import { by } from 'protractor';
|
||||
import { locate } from './util';
|
||||
|
||||
export function getPage() {
|
||||
return by.css('app-open-close-page');
|
||||
}
|
||||
|
||||
export function getComponent() {
|
||||
return by.css('app-open-close');
|
||||
}
|
||||
|
||||
export function getToggleButton() {
|
||||
const toggleButton = () => by.buttonText('Toggle Open/Close');
|
||||
return locate(getComponent(), toggleButton());
|
||||
}
|
||||
|
||||
export function getLoggingCheckbox() {
|
||||
const loggingCheckbox = () => by.css('section > input[type="checkbox"]');
|
||||
return locate(getPage(), loggingCheckbox());
|
||||
}
|
||||
|
||||
export function getComponentContainer() {
|
||||
const findContainer = () => by.css('div');
|
||||
return locate(getComponent(), findContainer());
|
||||
}
|
||||
|
||||
export async function getComponentText() {
|
||||
const findContainerText = () => by.css('div');
|
||||
const contents = locate(getComponent(), findContainerText());
|
||||
const componentText = await contents.getText();
|
||||
|
||||
return componentText;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
import { by } from 'protractor';
|
||||
import { locate } from './util';
|
||||
|
||||
export function getPage() {
|
||||
return by.css('app-status-slider-page');
|
||||
}
|
||||
|
||||
export function getComponent() {
|
||||
return by.css('app-status-slider');
|
||||
}
|
||||
|
||||
export function getToggleButton() {
|
||||
const toggleButton = () => by.buttonText('Toggle Status');
|
||||
return locate(getComponent(), toggleButton());
|
||||
}
|
||||
|
||||
export function getComponentContainer() {
|
||||
const findContainer = () => by.css('div');
|
||||
return locate(getComponent(), findContainer());
|
||||
}
|
||||
|
||||
export async function getComponentText() {
|
||||
const findContainerText = () => by.css('div');
|
||||
const contents = locate(getComponent(), findContainerText());
|
||||
const componentText = await contents.getText();
|
||||
|
||||
return componentText;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import { by } from 'protractor';
|
||||
import { locate } from './util';
|
||||
|
||||
export function getPage() {
|
||||
return by.css('app-toggle-animations-child-page');
|
||||
}
|
||||
|
||||
export function getComponent() {
|
||||
return by.css('app-open-close-toggle');
|
||||
}
|
||||
|
||||
export function getToggleButton() {
|
||||
const toggleButton = () => by.buttonText('Toggle Open/Closed');
|
||||
return locate(getComponent(), toggleButton());
|
||||
}
|
||||
|
||||
export function getToggleAnimationsButton() {
|
||||
const toggleAnimationsButton = () => by.buttonText('Toggle Animations');
|
||||
return locate(getComponent(), toggleAnimationsButton());
|
||||
}
|
||||
|
||||
export function getComponentContainer() {
|
||||
const findContainer = () => by.css('div');
|
||||
return locate(getComponent()).all(findContainer()).get(0);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import { Locator, ElementFinder, browser, by, element } from 'protractor';
|
||||
|
||||
/**
|
||||
*
|
||||
* locate(finder1, finder2) => element(finder1).element(finder2).element(finderN);
|
||||
*/
|
||||
export function locate(locator: Locator, ...locators: Locator[]) {
|
||||
return locators.reduce((current: ElementFinder, next: Locator) => {
|
||||
return current.element(next);
|
||||
}, element(locator)) as ElementFinder;
|
||||
}
|
||||
|
||||
export async function sleepFor(time = 1000) {
|
||||
return await browser.sleep(time);
|
||||
}
|
||||
|
||||
export function getLinkById(id: string) {
|
||||
return element(by.css(`a[id=${id}]`));
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<p>
|
||||
Angular's animations library makes it easy to define and apply animation effects such as page and list transitions.
|
||||
</p>
|
||||
@@ -0,0 +1,15 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-about',
|
||||
templateUrl: './about.component.html',
|
||||
styleUrls: ['./about.component.css']
|
||||
})
|
||||
export class AboutComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// #docregion
|
||||
import { animation, style, animate } from '@angular/animations';
|
||||
|
||||
export const transAnimation = animation([
|
||||
style({
|
||||
height: '{{ height }}',
|
||||
opacity: '{{ opacity }}',
|
||||
backgroundColor: '{{ backgroundColor }}'
|
||||
}),
|
||||
animate('{{ time }}')
|
||||
]);
|
||||
@@ -0,0 +1,74 @@
|
||||
// #docregion reusable
|
||||
import {
|
||||
animation, trigger, animateChild, group,
|
||||
transition, animate, style, query
|
||||
} from '@angular/animations';
|
||||
|
||||
export const transAnimation = animation([
|
||||
style({
|
||||
height: '{{ height }}',
|
||||
opacity: '{{ opacity }}',
|
||||
backgroundColor: '{{ backgroundColor }}'
|
||||
}),
|
||||
animate('{{ time }}')
|
||||
]);
|
||||
// #enddocregion reusable
|
||||
|
||||
// Routable animations
|
||||
// #docregion route-animations
|
||||
export const slideInAnimation =
|
||||
// #docregion style-view
|
||||
trigger('routeAnimations', [
|
||||
transition('HomePage <=> AboutPage', [
|
||||
style({ position: 'relative' }),
|
||||
query(':enter, :leave', [
|
||||
style({
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%'
|
||||
})
|
||||
]),
|
||||
// #enddocregion style-view
|
||||
// #docregion query
|
||||
query(':enter', [
|
||||
style({ left: '-100%'})
|
||||
]),
|
||||
query(':leave', animateChild()),
|
||||
group([
|
||||
query(':leave', [
|
||||
animate('300ms ease-out', style({ left: '100%'}))
|
||||
]),
|
||||
query(':enter', [
|
||||
animate('300ms ease-out', style({ left: '0%'}))
|
||||
])
|
||||
]),
|
||||
query(':enter', animateChild()),
|
||||
]),
|
||||
transition('* <=> FilterPage', [
|
||||
style({ position: 'relative' }),
|
||||
query(':enter, :leave', [
|
||||
style({
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: '100%'
|
||||
})
|
||||
]),
|
||||
query(':enter', [
|
||||
style({ left: '-100%'})
|
||||
]),
|
||||
query(':leave', animateChild()),
|
||||
group([
|
||||
query(':leave', [
|
||||
animate('200ms ease-out', style({ left: '100%'}))
|
||||
]),
|
||||
query(':enter', [
|
||||
animate('300ms ease-out', style({ left: '0%'}))
|
||||
])
|
||||
]),
|
||||
query(':enter', animateChild()),
|
||||
])
|
||||
// #enddocregion query
|
||||
]);
|
||||
// #enddocregion route-animations
|
||||
@@ -0,0 +1,35 @@
|
||||
// #docplaster
|
||||
// #docregion imports
|
||||
import { Component, HostBinding } from '@angular/core';
|
||||
import {
|
||||
trigger,
|
||||
state,
|
||||
style,
|
||||
animate,
|
||||
transition,
|
||||
// ...
|
||||
} from '@angular/animations';
|
||||
|
||||
// #enddocregion imports
|
||||
|
||||
// #docregion decorator, toggle-app-animations
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: 'app.component.html',
|
||||
styleUrls: ['app.component.css'],
|
||||
animations: [
|
||||
// animation triggers go here
|
||||
]
|
||||
})
|
||||
// #enddocregion decorator
|
||||
export class AppComponent {
|
||||
@HostBinding('@.disabled')
|
||||
public animationsDisabled = false;
|
||||
// #enddocregion toggle-app-animations
|
||||
|
||||
toggleAnimations() {
|
||||
this.animationsDisabled = !this.animationsDisabled;
|
||||
}
|
||||
// #docregion toggle-app-animations
|
||||
}
|
||||
// #enddocregion toggle-app-animations
|
||||
@@ -0,0 +1,7 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
section {
|
||||
margin-top: 100px;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<h1>Animations</h1>
|
||||
|
||||
Toggle All Animations <input type="checkbox" [checked]="!animationsDisabled" (click)="toggleAnimations()"/>
|
||||
|
||||
<nav>
|
||||
<a id="home" routerLink="/home" routerLinkActive="active">Home</a>
|
||||
<a id="about" routerLink="/about" routerLinkActive="active">About</a>
|
||||
<a id="open-close" routerLink="/open-close" routerLinkActive="active">Open/Close</a>
|
||||
<a id="status" routerLink="/status" routerLinkActive="active">Status Slider</a>
|
||||
<a id="toggle" routerLink="/toggle" routerLinkActive="active">Toggle Animations</a>
|
||||
<a id="enter-leave" routerLink="/enter-leave" routerLinkActive="active">Enter/Leave</a>
|
||||
<a id="auto" routerLink="/auto" routerLinkActive="active">Auto Calculation</a>
|
||||
<a id="heroes" routerLink="/heroes" routerLinkActive="active">Filter/Stagger</a>
|
||||
<a id="hero-groups" routerLink="/hero-groups" routerLinkActive="active">Hero Groups</a>
|
||||
</nav>
|
||||
|
||||
<!-- #docregion route-animations-outlet -->
|
||||
<div [@routeAnimations]="prepareRoute(outlet)" >
|
||||
<router-outlet #outlet="outlet"></router-outlet>
|
||||
</div>
|
||||
<!-- #enddocregion route-animations-outlet -->
|
||||
@@ -0,0 +1,47 @@
|
||||
// #docplaster
|
||||
// #docregion imports
|
||||
import { Component, HostBinding } from '@angular/core';
|
||||
import {
|
||||
trigger,
|
||||
state,
|
||||
style,
|
||||
animate,
|
||||
transition,
|
||||
// ...
|
||||
} from '@angular/animations';
|
||||
|
||||
// #enddocregion imports
|
||||
import { RouterOutlet } from '@angular/router';
|
||||
import { slideInAnimation } from './animations';
|
||||
|
||||
// #docregion decorator, toggle-app-animations, define
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
templateUrl: 'app.component.html',
|
||||
styleUrls: ['app.component.css'],
|
||||
animations: [
|
||||
// #enddocregion decorator
|
||||
slideInAnimation
|
||||
// #docregion decorator
|
||||
// animation triggers go here
|
||||
]
|
||||
})
|
||||
// #enddocregion decorator, define
|
||||
export class AppComponent {
|
||||
@HostBinding('@.disabled')
|
||||
public animationsDisabled = false;
|
||||
// #enddocregion toggle-app-animations
|
||||
|
||||
// #docregion prepare-router-outlet
|
||||
prepareRoute(outlet: RouterOutlet) {
|
||||
return outlet && outlet.activatedRouteData && outlet.activatedRouteData['animation'];
|
||||
}
|
||||
|
||||
// #enddocregion prepare-router-outlet
|
||||
|
||||
toggleAnimations() {
|
||||
this.animationsDisabled = !this.animationsDisabled;
|
||||
}
|
||||
// #docregion toggle-app-animations
|
||||
}
|
||||
// #enddocregion toggle-app-animations
|
||||
@@ -0,0 +1,13 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule
|
||||
],
|
||||
declarations: [ ],
|
||||
bootstrap: [ ]
|
||||
})
|
||||
export class AppModule { }
|
||||
@@ -1,43 +1,63 @@
|
||||
// #docplaster
|
||||
// #docregion route-animation-data
|
||||
import { NgModule } from '@angular/core';
|
||||
// #docregion animations-module
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
// #enddocregion animations-module
|
||||
|
||||
import { HeroTeamBuilderComponent } from './hero-team-builder.component';
|
||||
import { HeroListBasicComponent } from './hero-list-basic.component';
|
||||
import { HeroListInlineStylesComponent } from './hero-list-inline-styles.component';
|
||||
import { HeroListEnterLeaveComponent } from './hero-list-enter-leave.component';
|
||||
import { HeroListEnterLeaveStatesComponent } from './hero-list-enter-leave-states.component';
|
||||
import { HeroListCombinedTransitionsComponent } from './hero-list-combined-transitions.component';
|
||||
import { HeroListTwowayComponent } from './hero-list-twoway.component';
|
||||
import { HeroListAutoComponent } from './hero-list-auto.component';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AppComponent } from './app.component';
|
||||
import { OpenCloseComponent } from './open-close.component';
|
||||
import { OpenClosePageComponent } from './open-close-page.component';
|
||||
import { OpenCloseChildComponent } from './open-close.component.4';
|
||||
import { ToggleAnimationsPageComponent } from './toggle-animations-page.component';
|
||||
import { StatusSliderComponent } from './status-slider.component';
|
||||
import { StatusSliderPageComponent } from './status-slider-page.component';
|
||||
import { HeroListPageComponent } from './hero-list-page.component';
|
||||
import { HeroListGroupPageComponent } from './hero-list-group-page.component';
|
||||
import { HeroListGroupsComponent } from './hero-list-groups.component';
|
||||
import { HeroListMultistepComponent } from './hero-list-multistep.component';
|
||||
import { HeroListTimingsComponent } from './hero-list-timings.component';
|
||||
// #docregion animations-module
|
||||
import { HeroListEnterLeavePageComponent } from './hero-list-enter-leave-page.component';
|
||||
import { HeroListEnterLeaveComponent } from './hero-list-enter-leave.component';
|
||||
import { HeroListAutoCalcPageComponent } from './hero-list-auto-page.component';
|
||||
import { HeroListAutoComponent } from './hero-list-auto.component';
|
||||
import { HomeComponent } from './home.component';
|
||||
import { AboutComponent } from './about.component';
|
||||
|
||||
|
||||
@NgModule({
|
||||
imports: [ BrowserModule, BrowserAnimationsModule ],
|
||||
// ... more stuff ...
|
||||
// #enddocregion animations-module
|
||||
declarations: [
|
||||
HeroTeamBuilderComponent,
|
||||
HeroListBasicComponent,
|
||||
HeroListInlineStylesComponent,
|
||||
HeroListCombinedTransitionsComponent,
|
||||
HeroListTwowayComponent,
|
||||
HeroListEnterLeaveComponent,
|
||||
HeroListEnterLeaveStatesComponent,
|
||||
HeroListAutoComponent,
|
||||
HeroListTimingsComponent,
|
||||
HeroListMultistepComponent,
|
||||
HeroListGroupsComponent
|
||||
imports: [
|
||||
BrowserModule,
|
||||
BrowserAnimationsModule,
|
||||
RouterModule.forRoot([
|
||||
{ path: '', pathMatch: 'full', redirectTo: '/enter-leave' },
|
||||
{ path: 'open-close', component: OpenClosePageComponent },
|
||||
{ path: 'status', component: StatusSliderPageComponent },
|
||||
{ path: 'toggle', component: ToggleAnimationsPageComponent },
|
||||
{ path: 'heroes', component: HeroListPageComponent, data: {animation: 'FilterPage'} },
|
||||
{ path: 'hero-groups', component: HeroListGroupPageComponent },
|
||||
{ path: 'enter-leave', component: HeroListEnterLeavePageComponent },
|
||||
{ path: 'auto', component: HeroListAutoCalcPageComponent },
|
||||
{ path: 'home', component: HomeComponent, data: {animation: 'HomePage'} },
|
||||
{ path: 'about', component: AboutComponent, data: {animation: 'AboutPage'} },
|
||||
|
||||
])
|
||||
],
|
||||
bootstrap: [ HeroTeamBuilderComponent ]
|
||||
// #docregion animations-module
|
||||
// #enddocregion route-animation-data
|
||||
declarations: [
|
||||
AppComponent,
|
||||
StatusSliderComponent,
|
||||
OpenCloseComponent,
|
||||
OpenCloseChildComponent,
|
||||
OpenClosePageComponent,
|
||||
StatusSliderPageComponent,
|
||||
ToggleAnimationsPageComponent,
|
||||
HeroListPageComponent,
|
||||
HeroListGroupsComponent,
|
||||
HeroListGroupPageComponent,
|
||||
HeroListEnterLeavePageComponent,
|
||||
HeroListEnterLeaveComponent,
|
||||
HeroListAutoCalcPageComponent,
|
||||
HeroListAutoComponent,
|
||||
HomeComponent,
|
||||
AboutComponent
|
||||
],
|
||||
bootstrap: [AppComponent]
|
||||
})
|
||||
export class AppModule { }
|
||||
// #enddocregion animations-module
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { HEROES } from './mock-heroes';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-list-auto-page',
|
||||
template: `
|
||||
<section>
|
||||
<h2>Automatic Calculation</h2>
|
||||
|
||||
<app-hero-list-auto [heroes]="heroes" (remove)="onRemove($event)"></app-hero-list-auto>
|
||||
</section>
|
||||
`
|
||||
})
|
||||
export class HeroListAutoCalcPageComponent {
|
||||
heroes = HEROES.slice();
|
||||
|
||||
onRemove(id: number) {
|
||||
this.heroes = this.heroes.filter(hero => hero.id !== id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<ul class="heroes">
|
||||
<li *ngFor="let hero of heroes"
|
||||
[@shrinkOut]="'in'" (click)="removeHero(hero.id)">
|
||||
<div class="inner">
|
||||
<span class="badge">{{ hero.id }}</span>
|
||||
<span>{{ hero.name }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
Component,
|
||||
Input
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter
|
||||
} from '@angular/core';
|
||||
import {
|
||||
trigger,
|
||||
@@ -10,38 +12,30 @@ import {
|
||||
transition
|
||||
} from '@angular/animations';
|
||||
|
||||
import { Hero } from './hero.service';
|
||||
import { Hero } from './hero';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-list-auto',
|
||||
// #docregion template
|
||||
template: `
|
||||
<ul>
|
||||
<li *ngFor="let hero of heroes"
|
||||
[@shrinkOut]="'in'">
|
||||
{{hero.name}}
|
||||
</li>
|
||||
</ul>
|
||||
`,
|
||||
// #enddocregion template
|
||||
styleUrls: ['./hero-list.component.css'],
|
||||
|
||||
/* When the element leaves (transition "in => void" occurs),
|
||||
* get the element's current computed height and animate
|
||||
* it down to 0.
|
||||
*/
|
||||
// #docregion animationdef
|
||||
templateUrl: 'hero-list-auto.component.html',
|
||||
styleUrls: ['./hero-list-page.component.css'],
|
||||
// #docregion auto-calc
|
||||
animations: [
|
||||
trigger('shrinkOut', [
|
||||
state('in', style({height: '*'})),
|
||||
state('in', style({ height: '*' })),
|
||||
transition('* => void', [
|
||||
style({height: '*'}),
|
||||
animate(250, style({height: 0}))
|
||||
style({ height: '*' }),
|
||||
animate(250, style({ height: 0 }))
|
||||
])
|
||||
])
|
||||
]
|
||||
// #enddocregion animationdef
|
||||
// #enddocregion auto-calc
|
||||
})
|
||||
export class HeroListAutoComponent {
|
||||
@Input() heroes: Hero[];
|
||||
|
||||
@Output() remove = new EventEmitter<number>();
|
||||
|
||||
removeHero(id: number) {
|
||||
this.remove.emit(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
// #docplaster
|
||||
// #docregion
|
||||
// #docregion imports
|
||||
import {
|
||||
Component,
|
||||
Input
|
||||
} from '@angular/core';
|
||||
import {
|
||||
trigger,
|
||||
state,
|
||||
style,
|
||||
animate,
|
||||
transition
|
||||
} from '@angular/animations';
|
||||
// #enddocregion imports
|
||||
|
||||
import { Hero } from './hero.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-list-basic',
|
||||
// #enddocregion
|
||||
/* The click event calls hero.toggleState(), which
|
||||
* causes the state of that hero to switch from
|
||||
* active to inactive or vice versa.
|
||||
*/
|
||||
// #docregion
|
||||
// #docregion template
|
||||
template: `
|
||||
<ul>
|
||||
<li *ngFor="let hero of heroes"
|
||||
[@heroState]="hero.state"
|
||||
(click)="hero.toggleState()">
|
||||
{{hero.name}}
|
||||
</li>
|
||||
</ul>
|
||||
`,
|
||||
// #enddocregion template
|
||||
styleUrls: ['./hero-list.component.css'],
|
||||
// #enddocregion
|
||||
/**
|
||||
* Define two states, "inactive" and "active", and the end
|
||||
* styles that apply whenever the element is in those states.
|
||||
* Then define animations for transitioning between the states,
|
||||
* one in each direction
|
||||
*/
|
||||
// #docregion
|
||||
// #docregion animationdef
|
||||
animations: [
|
||||
trigger('heroState', [
|
||||
// #docregion states
|
||||
state('inactive', style({
|
||||
backgroundColor: '#eee',
|
||||
transform: 'scale(1)'
|
||||
})),
|
||||
state('active', style({
|
||||
backgroundColor: '#cfd8dc',
|
||||
transform: 'scale(1.1)'
|
||||
})),
|
||||
// #enddocregion states
|
||||
// #docregion transitions
|
||||
transition('inactive => active', animate('100ms ease-in')),
|
||||
transition('active => inactive', animate('100ms ease-out'))
|
||||
// #enddocregion transitions
|
||||
])
|
||||
]
|
||||
// #enddocregion animationdef
|
||||
})
|
||||
export class HeroListBasicComponent {
|
||||
@Input() heroes: Hero[];
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
// #docregion
|
||||
// #docregion imports
|
||||
import {
|
||||
Component,
|
||||
Input
|
||||
} from '@angular/core';
|
||||
import {
|
||||
trigger,
|
||||
state,
|
||||
style,
|
||||
animate,
|
||||
transition
|
||||
} from '@angular/animations';
|
||||
// #enddocregion imports
|
||||
|
||||
import { Hero } from './hero.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-list-combined-transitions',
|
||||
// #docregion template
|
||||
template: `
|
||||
<ul>
|
||||
<li *ngFor="let hero of heroes"
|
||||
[@heroState]="hero.state"
|
||||
(click)="hero.toggleState()">
|
||||
{{hero.name}}
|
||||
</li>
|
||||
</ul>
|
||||
`,
|
||||
// #enddocregion template
|
||||
styleUrls: ['./hero-list.component.css'],
|
||||
/*
|
||||
* Define two states, "inactive" and "active", and the end
|
||||
* styles that apply whenever the element is in those states.
|
||||
* Then define an animated transition between these two
|
||||
* states, in *both* directions.
|
||||
*/
|
||||
// #docregion animationdef
|
||||
animations: [
|
||||
trigger('heroState', [
|
||||
state('inactive', style({
|
||||
backgroundColor: '#eee',
|
||||
transform: 'scale(1)'
|
||||
})),
|
||||
state('active', style({
|
||||
backgroundColor: '#cfd8dc',
|
||||
transform: 'scale(1.1)'
|
||||
})),
|
||||
// #docregion transitions
|
||||
transition('inactive => active, active => inactive',
|
||||
animate('100ms ease-out'))
|
||||
// #enddocregion transitions
|
||||
])
|
||||
]
|
||||
// #enddocregion animationdef
|
||||
})
|
||||
export class HeroListCombinedTransitionsComponent {
|
||||
@Input() heroes: Hero[];
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { HEROES } from './mock-heroes';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-list-enter-leave-page',
|
||||
template: `
|
||||
<section>
|
||||
<h2>Enter/Leave</h2>
|
||||
|
||||
<app-hero-list-enter-leave [heroes]="heroes" (remove)="onRemove($event)"></app-hero-list-enter-leave>
|
||||
</section>
|
||||
`
|
||||
})
|
||||
export class HeroListEnterLeavePageComponent {
|
||||
heroes = HEROES.slice();
|
||||
|
||||
onRemove(id: number) {
|
||||
this.heroes = this.heroes.filter(hero => hero.id !== id);
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
import {
|
||||
Component,
|
||||
Input
|
||||
} from '@angular/core';
|
||||
import {
|
||||
trigger,
|
||||
state,
|
||||
style,
|
||||
animate,
|
||||
transition
|
||||
} from '@angular/animations';
|
||||
|
||||
import { Hero } from './hero.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-list-enter-leave-states',
|
||||
// #docregion template
|
||||
template: `
|
||||
<ul>
|
||||
<li *ngFor="let hero of heroes"
|
||||
(click)="hero.toggleState()"
|
||||
[@heroState]="hero.state">
|
||||
{{hero.name}}
|
||||
</li>
|
||||
</ul>
|
||||
`,
|
||||
// #enddocregion template
|
||||
styleUrls: ['./hero-list.component.css'],
|
||||
/* The elements here have two possible states based
|
||||
* on the hero state, "active", or "inactive". We animate
|
||||
* six transitions: Between the two states in both directions,
|
||||
* and between each state and void. With this we can animate
|
||||
* the enter and leave of elements differently based on which
|
||||
* state they are in when they are added and removed.
|
||||
*/
|
||||
// #docregion animationdef
|
||||
animations: [
|
||||
trigger('heroState', [
|
||||
state('inactive', style({transform: 'translateX(0) scale(1)'})),
|
||||
state('active', style({transform: 'translateX(0) scale(1.1)'})),
|
||||
transition('inactive => active', animate('100ms ease-in')),
|
||||
transition('active => inactive', animate('100ms ease-out')),
|
||||
transition('void => inactive', [
|
||||
style({transform: 'translateX(-100%) scale(1)'}),
|
||||
animate(100)
|
||||
]),
|
||||
transition('inactive => void', [
|
||||
animate(100, style({transform: 'translateX(100%) scale(1)'}))
|
||||
]),
|
||||
transition('void => active', [
|
||||
style({transform: 'translateX(0) scale(0)'}),
|
||||
animate(200)
|
||||
]),
|
||||
transition('active => void', [
|
||||
animate(200, style({transform: 'translateX(0) scale(0)'}))
|
||||
])
|
||||
])
|
||||
]
|
||||
// #enddocregion animationdef
|
||||
})
|
||||
export class HeroListEnterLeaveStatesComponent {
|
||||
@Input() heroes: Hero[];
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
Component,
|
||||
Input
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter
|
||||
} from '@angular/core';
|
||||
import {
|
||||
trigger,
|
||||
@@ -10,42 +12,45 @@ import {
|
||||
transition
|
||||
} from '@angular/animations';
|
||||
|
||||
import { Hero } from './hero.service';
|
||||
import { Hero } from './hero';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-list-enter-leave',
|
||||
// #docregion template
|
||||
template: `
|
||||
<ul>
|
||||
<ul class="heroes">
|
||||
<li *ngFor="let hero of heroes"
|
||||
[@flyInOut]="'in'">
|
||||
{{hero.name}}
|
||||
[@flyInOut]="'in'" (click)="removeHero(hero.id)">
|
||||
<div class="inner">
|
||||
<span class="badge">{{ hero.id }}</span>
|
||||
<span>{{ hero.name }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
`,
|
||||
// #enddocregion template
|
||||
styleUrls: ['./hero-list.component.css'],
|
||||
/* The element here always has the state "in" when it
|
||||
* is present. We animate two transitions: From void
|
||||
* to in and from in to void, to achieve an animated
|
||||
* enter and leave transition. The element enters from
|
||||
* the left and leaves to the right using translateX.
|
||||
*/
|
||||
styleUrls: ['./hero-list-page.component.css'],
|
||||
// #docregion animationdef
|
||||
animations: [
|
||||
trigger('flyInOut', [
|
||||
state('in', style({transform: 'translateX(0)'})),
|
||||
state('in', style({ transform: 'translateX(0)' })),
|
||||
transition('void => *', [
|
||||
style({transform: 'translateX(-100%)'}),
|
||||
style({ transform: 'translateX(-100%)' }),
|
||||
animate(100)
|
||||
]),
|
||||
transition('* => void', [
|
||||
animate(100, style({transform: 'translateX(100%)'}))
|
||||
animate(100, style({ transform: 'translateX(100%)' }))
|
||||
])
|
||||
])
|
||||
]
|
||||
// #enddocregion animationdef
|
||||
})
|
||||
export class HeroListEnterLeaveComponent {
|
||||
@Input() heroes: Hero[];
|
||||
@Input() heroes: Hero[];
|
||||
|
||||
@Output() remove = new EventEmitter<number>();
|
||||
|
||||
removeHero(id: number) {
|
||||
this.remove.emit(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { HEROES } from './mock-heroes';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-list-groups-page',
|
||||
template: `
|
||||
<section>
|
||||
<h2>Hero List Group</h2>
|
||||
|
||||
<app-hero-list-groups [heroes]="heroes" (remove)="onRemove($event)"></app-hero-list-groups>
|
||||
</section>
|
||||
`
|
||||
})
|
||||
export class HeroListGroupPageComponent {
|
||||
heroes = HEROES.slice();
|
||||
|
||||
onRemove(id: number) {
|
||||
this.heroes = this.heroes.filter(hero => hero.id !== id);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
Component,
|
||||
Input
|
||||
Input,
|
||||
Output,
|
||||
EventEmitter
|
||||
} from '@angular/core';
|
||||
import {
|
||||
trigger,
|
||||
@@ -11,45 +13,31 @@ import {
|
||||
group
|
||||
} from '@angular/animations';
|
||||
|
||||
import { Hero } from './hero.service';
|
||||
import { Hero } from './hero';
|
||||
|
||||
@Component({
|
||||
selector: 'app-hero-list-groups',
|
||||
template: `
|
||||
<ul>
|
||||
<ul class="heroes">
|
||||
<li *ngFor="let hero of heroes"
|
||||
[@flyInOut]="'in'">
|
||||
{{hero.name}}
|
||||
[@flyInOut]="'in'" (click)="removeHero(hero.id)">
|
||||
<div class="inner">
|
||||
<span class="badge">{{ hero.id }}</span>
|
||||
<span>{{ hero.name }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
`,
|
||||
styleUrls: ['./hero-list.component.css'],
|
||||
styles: [`
|
||||
li {
|
||||
padding: 0 !important;
|
||||
text-align: center;
|
||||
}
|
||||
`],
|
||||
/* The element here always has the state "in" when it
|
||||
* is present. We animate two transitions: From void
|
||||
* to in and from in to void, to achieve an animated
|
||||
* enter and leave transition.
|
||||
*
|
||||
* The transitions have *parallel group* that allow
|
||||
* animating several properties at the same time but
|
||||
* with different timing configurations. On enter
|
||||
* (void => *) we start the opacity animation 0.1s
|
||||
* earlier than the translation/width animation.
|
||||
* On leave (* => void) we do the opposite -
|
||||
* the translation/width animation begins immediately
|
||||
* and the opacity animation 0.1s later.
|
||||
*/
|
||||
styleUrls: ['./hero-list-page.component.css'],
|
||||
// #docregion animationdef
|
||||
animations: [
|
||||
trigger('flyInOut', [
|
||||
state('in', style({width: 120, transform: 'translateX(0)', opacity: 1})),
|
||||
state('in', style({
|
||||
width: 120,
|
||||
transform: 'translateX(0)', opacity: 1
|
||||
})),
|
||||
transition('void => *', [
|
||||
style({width: 10, transform: 'translateX(50px)', opacity: 0}),
|
||||
style({ width: 10, transform: 'translateX(50px)', opacity: 0 }),
|
||||
group([
|
||||
animate('0.3s 0.1s ease', style({
|
||||
transform: 'translateX(0)',
|
||||
@@ -77,4 +65,10 @@ import { Hero } from './hero.service';
|
||||
})
|
||||
export class HeroListGroupsComponent {
|
||||
@Input() heroes: Hero[];
|
||||
|
||||
@Output() remove = new EventEmitter<number>();
|
||||
|
||||
removeHero(id: number) {
|
||||
this.remove.emit(id);
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user