diff --git a/guides/getting-started.md b/guides/getting-started.md
index 679676f8cc07..bcbc142137ed 100644
--- a/guides/getting-started.md
+++ b/guides/getting-started.md
@@ -1,20 +1,55 @@
-For help getting started with a new Angular app, check out the [Angular CLI](https://cli.angular.io/).
+For help getting started with a new Angular app, check out the
+[Angular CLI](https://cli.angular.io/).
For existing apps, follow these steps to begin using Angular Material.
-## Step 1: Install Angular Material
+## Step 1: Install Angular Material
```bash
npm install --save @angular/material
```
-## Step 2: Import the Module
-
-Add MaterialModule as an import in your app's root NgModule.
-
+## Step 2: Animations
+
+Some Material components depend on the Angular animations module in order to be able to do
+more advanced transitions. If you want these animations to work in your app, you have to
+install the `@angular/animations` module and include the `BrowserAnimationsModule` in your app.
+
+```bash
+npm install --save @angular/animations
+```
+
```ts
-import { MaterialModule } from '@angular/material';
-
+import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
+
+@NgModule({
+ ...
+ imports: [BrowserAnimationsModule],
+ ...
+})
+export class PizzaPartyAppModule { }
+```
+
+If you don't want to add another dependency to your project, you can use the `NoopAnimationsModule`.
+
+```ts
+import {NoopAnimationsModule} from '@angular/platform-browser/animations';
+
+@NgModule({
+ ...
+ imports: [NoopAnimationsModule],
+ ...
+})
+export class PizzaPartyAppModule { }
+```
+
+## Step 3: Import the Module
+
+Add MaterialModule as an import in your app's root NgModule.
+
+```ts
+import {MaterialModule} from '@angular/material';
+
@NgModule({
...
imports: [MaterialModule],
@@ -23,9 +58,9 @@ import { MaterialModule } from '@angular/material';
export class PizzaPartyAppModule { }
```
-## Step 3: Include Theming
+## Step 4: Include Theming
-Including a theme is **required** to apply all of the core and theme styles to your application.
+Including a theme is **required** to apply all of the core and theme styles to your application.
To get started with a prebuilt theme, include the following in your app's index.html:
@@ -35,16 +70,17 @@ To get started with a prebuilt theme, include the following in your app's index.
Note that your app's project structure may have a different relative location for your node_modules.
-For more information on theming and instructions on how to create a custom theme, see the [theming guide](./theming.md).
+For more information on theming and instructions on how to create a custom theme, see the
+[theming guide](./theming.md).
-## Step 4: Gesture Support
+## Step 5: Gesture Support
-Some components (`md-slide-toggle`, `md-slider`, `mdTooltip`) rely on
+Some components (`md-slide-toggle`, `md-slider`, `mdTooltip`) rely on
[HammerJS](http://hammerjs.github.io/) for gestures. In order to get the full feature-set of these
components, HammerJS must be loaded into the application.
-You can add HammerJS to your application via [npm](https://www.npmjs.com/package/hammerjs), a CDN
-(such as the [Google CDN](https://developers.google.com/speed/libraries/#hammerjs)), or served
+You can add HammerJS to your application via [npm](https://www.npmjs.com/package/hammerjs), a CDN
+(such as the [Google CDN](https://developers.google.com/speed/libraries/#hammerjs)), or served
directly from your app.
To install via npm, use the following command:
@@ -57,22 +93,25 @@ After installing, import it on your app's root module.
import 'hammerjs';
```
-## Step 5 (Optional): Add Material Icons
+## Step 6 (Optional): Add Material Icons
+
+If you want your `md-icon` components to use [Material Icons](https://material.io/icons/),
+load the font in your `index.html`.
-If you want your `md-icon` components to use [Material Icons](https://material.io/icons/), load the font in your `index.html`.
-
```html
```
-For more information on using Material Icons, check out the [Material Icons Guide](https://google.github.io/material-design-icons/).
+For more information on using Material Icons, check out the
+[Material Icons Guide](https://google.github.io/material-design-icons/).
+
+Note that `md-icon` has support for any font or svg icons, so using Material Icons is
+just one option.
-Note that `md-icon` has support for any font or svg icons, so using Material Icons is just one option.
-
## Configuring SystemJS
-If your project is using SystemJS for module loading, you will need to add `@angular/material`
+If your project is using SystemJS for module loading, you will need to add `@angular/material`
to the SystemJS configuration:
```js
diff --git a/package.json b/package.json
index a214163a9cb3..82187c24b8ab 100644
--- a/package.json
+++ b/package.json
@@ -25,22 +25,23 @@
"node": ">= 5.4.1 < 7"
},
"dependencies": {
- "@angular/common": "^2.3.0",
- "@angular/compiler": "^2.3.0",
- "@angular/core": "^2.3.0",
- "@angular/forms": "^2.3.0",
- "@angular/http": "^2.3.0",
- "@angular/platform-browser": "^2.3.0",
+ "@angular/animations": "^4.0.0-rc.5",
+ "@angular/common": "^4.0.0-rc.5",
+ "@angular/compiler": "^4.0.0-rc.5",
+ "@angular/core": "^4.0.0-rc.5",
+ "@angular/forms": "^4.0.0-rc.5",
+ "@angular/http": "^4.0.0-rc.5",
+ "@angular/platform-browser": "^4.0.0-rc.5",
"core-js": "^2.4.1",
"rxjs": "^5.0.1",
"systemjs": "0.19.43",
- "zone.js": "^0.7.2"
+ "zone.js": "^0.8.4"
},
"devDependencies": {
- "@angular/compiler-cli": "^2.3.0",
- "@angular/platform-browser-dynamic": "^2.3.0",
- "@angular/platform-server": "^2.3.0",
- "@angular/router": "^3.3.0",
+ "@angular/compiler-cli": "^4.0.0-rc.5",
+ "@angular/platform-browser-dynamic": "^4.0.0-rc.5",
+ "@angular/platform-server": "^4.0.0-rc.5",
+ "@angular/router": "^4.0.0-rc.5",
"@types/chalk": "^0.4.31",
"@types/fs-extra": "0.0.37",
"@types/glob": "^5.0.30",
@@ -106,7 +107,7 @@
"ts-node": "^2.1.0",
"tslint": "^4.4.2",
"tslint-no-unused-var": "0.0.6",
- "typescript": "~2.0.10",
+ "typescript": "~2.1.6",
"uglify-js": "^2.8.7",
"web-animations-js": "^2.2.2"
}
diff --git a/src/demo-app/demo-app-module.ts b/src/demo-app/demo-app-module.ts
index 0263eff112fc..31a6f99798eb 100644
--- a/src/demo-app/demo-app-module.ts
+++ b/src/demo-app/demo-app-module.ts
@@ -2,8 +2,9 @@ import {NgModule, ApplicationRef} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {HttpModule} from '@angular/http';
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
-import {DemoApp, Home} from './demo-app/demo-app';
import {RouterModule} from '@angular/router';
+import {BrowserAnimationsModule} from '@angular/platform-browser/animations';
+import {DemoApp, Home} from './demo-app/demo-app';
import {
MaterialModule,
OverlayContainer,
@@ -44,9 +45,11 @@ import {AutocompleteDemo} from './autocomplete/autocomplete-demo';
import {InputDemo} from './input/input-demo';
import {StyleDemo} from './style/style-demo';
+
@NgModule({
imports: [
BrowserModule,
+ BrowserAnimationsModule,
FormsModule,
HttpModule,
ReactiveFormsModule,
diff --git a/src/demo-app/dialog/dialog-demo.html b/src/demo-app/dialog/dialog-demo.html
index ec05d8f1ae04..45e7ba5925ca 100644
--- a/src/demo-app/dialog/dialog-demo.html
+++ b/src/demo-app/dialog/dialog-demo.html
@@ -67,6 +67,6 @@
Other options
Last close result: {{lastCloseResult}}
-
+
I'm a template dialog. I've been opened {{numTemplateOpens}} times!
-
+
diff --git a/src/demo-app/overlay/overlay-demo.html b/src/demo-app/overlay/overlay-demo.html
index 91af08845104..c431cffc15fc 100644
--- a/src/demo-app/overlay/overlay-demo.html
+++ b/src/demo-app/overlay/overlay-demo.html
@@ -15,16 +15,16 @@
Open menu
-
- `,
+ `,
})
class ConnectedOverlayDirectiveTest {
isOpen = false;
diff --git a/src/lib/core/overlay/overlay.spec.ts b/src/lib/core/overlay/overlay.spec.ts
index 328809e4d272..46ebcb18454b 100644
--- a/src/lib/core/overlay/overlay.spec.ts
+++ b/src/lib/core/overlay/overlay.spec.ts
@@ -307,7 +307,7 @@ class PizzaMsg { }
/** Test-bed component that contains a TempatePortal and an ElementRef. */
-@Component({template: `Cake`})
+@Component({template: `Cake`})
class TestComponentWithTemplatePortals {
@ViewChild(TemplatePortalDirective) templatePortal: TemplatePortalDirective;
diff --git a/src/lib/core/portal/README.md b/src/lib/core/portal/README.md
index c8c1b3b5cfb1..214823de6b3e 100644
--- a/src/lib/core/portal/README.md
+++ b/src/lib/core/portal/README.md
@@ -34,13 +34,13 @@ be built upon.
##### `TemplatePortalDirective`
-Used to get a portal from a ``. `TemplatePortalDirectives` *is* a `Portal`.
+Used to get a portal from a ``. `TemplatePortalDirectives` *is* a `Portal`.
Usage:
```html
-
+
The content of this template is captured by the portal.
-
+
@@ -68,5 +68,5 @@ Used to add a portal host to a template. `PortalHostDirective` *is* a `PortalHos
Usage:
```html
-
+
```
diff --git a/src/lib/core/portal/portal-directives.ts b/src/lib/core/portal/portal-directives.ts
index 4db6cb366b23..2091e6b12947 100644
--- a/src/lib/core/portal/portal-directives.ts
+++ b/src/lib/core/portal/portal-directives.ts
@@ -17,9 +17,9 @@ import {Portal, TemplatePortal, ComponentPortal, BasePortalHost} from './portal'
* the directive instance itself can be attached to a host, enabling declarative use of portals.
*
* Usage:
- *
+ *
*
Hello {{name}}
- *
+ *
*/
@Directive({
selector: '[cdk-portal], [portal]',
@@ -37,7 +37,7 @@ export class TemplatePortalDirective extends TemplatePortal {
* directly attached to it, enabling declarative use.
*
* Usage:
- *
+ *
*/
@Directive({
selector: '[cdkPortalHost], [portalHost]',
diff --git a/src/lib/core/portal/portal.spec.ts b/src/lib/core/portal/portal.spec.ts
index 1c4bc9f7d33d..f441531e5ebf 100644
--- a/src/lib/core/portal/portal.spec.ts
+++ b/src/lib/core/portal/portal.spec.ts
@@ -70,7 +70,7 @@ describe('Portals', () => {
expect(hostContainer.textContent).toContain('Chocolate');
});
- it('should load a portal', () => {
+ it('should load a portal', () => {
let testAppComponent = fixture.debugElement.componentInstance;
// Detect changes initially so that the component's ViewChildren are resolved.
@@ -85,7 +85,7 @@ describe('Portals', () => {
expect(hostContainer.textContent).toContain('Cake');
});
- it('should load a portal with the `*` sugar', () => {
+ it('should load a portal with the `*` sugar', () => {
let testAppComponent = fixture.debugElement.componentInstance;
// Detect changes initially so that the component's ViewChildren are resolved.
@@ -100,7 +100,7 @@ describe('Portals', () => {
expect(hostContainer.textContent).toContain('Pie');
});
- it('should load a portal with a binding', () => {
+ it('should load a portal with a binding', () => {
let testAppComponent = fixture.debugElement.componentInstance;
// Detect changes initially so that the component's ViewChildren are resolved.
@@ -331,14 +331,14 @@ class ArbitraryViewContainerRefComponent {
selector: 'portal-test',
template: `
-
+
- Cake
+ Cake
Pie
- {{fruit}} `,
+ {{fruit}} `,
})
class PortalTestApp {
@ViewChildren(TemplatePortalDirective) portals: QueryList;
diff --git a/src/lib/core/testing/wrapped-error-message.ts b/src/lib/core/testing/wrapped-error-message.ts
new file mode 100644
index 000000000000..4c1c4297163e
--- /dev/null
+++ b/src/lib/core/testing/wrapped-error-message.ts
@@ -0,0 +1,8 @@
+/**
+ * Gets a RegExp used to detect an angular wrapped error message.
+ * See https://github.com/angular/angular/issues/8348
+ */
+export function wrappedErrorMessage(e: Error) {
+ const escapedMessage = e.message.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
+ return new RegExp(escapedMessage);
+};
diff --git a/src/lib/dialog/dialog-container.html b/src/lib/dialog/dialog-container.html
index 9ca2bad1e9cf..5b263ad218a4 100644
--- a/src/lib/dialog/dialog-container.html
+++ b/src/lib/dialog/dialog-container.html
@@ -1 +1 @@
-
+
diff --git a/src/lib/dialog/dialog-container.ts b/src/lib/dialog/dialog-container.ts
index 8816385f4272..82f0185611fd 100644
--- a/src/lib/dialog/dialog-container.ts
+++ b/src/lib/dialog/dialog-container.ts
@@ -7,14 +7,16 @@ import {
OnDestroy,
Renderer,
ElementRef,
+ EventEmitter,
+} from '@angular/core';
+import {
animate,
+ trigger,
state,
style,
transition,
- trigger,
- AnimationTransitionEvent,
- EventEmitter,
-} from '@angular/core';
+ AnimationEvent,
+} from '@angular/animations';
import {BasePortalHost, ComponentPortal, PortalHostDirective, TemplatePortal} from '../core';
import {MdDialogConfig} from './dialog-config';
import {MdDialogContentAlreadyAttachedError} from './dialog-errors';
@@ -139,7 +141,7 @@ export class MdDialogContainer extends BasePortalHost implements OnDestroy {
* Callback, invoked whenever an animation on the host completes.
* @docs-private
*/
- _onAnimationDone(event: AnimationTransitionEvent) {
+ _onAnimationDone(event: AnimationEvent) {
this._onAnimationStateChange.emit(event.toState as MdDialogContainerAnimationState);
}
diff --git a/src/lib/dialog/dialog.spec.ts b/src/lib/dialog/dialog.spec.ts
index ec156ae7c3f5..001564ea1dfb 100644
--- a/src/lib/dialog/dialog.spec.ts
+++ b/src/lib/dialog/dialog.spec.ts
@@ -7,7 +7,8 @@ import {
TestBed,
tick,
} from '@angular/core/testing';
-import {NgModule,
+import {
+ NgModule,
Component,
Directive,
ViewChild,
@@ -16,6 +17,7 @@ import {NgModule,
Inject,
} from '@angular/core';
import {By} from '@angular/platform-browser';
+import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {MdDialogModule} from './index';
import {MdDialog} from './dialog';
import {MdDialogContainer} from './dialog-container';
@@ -450,6 +452,7 @@ describe('MdDialog', () => {
expect(overlayContainerElement.querySelectorAll('.mat-dialog-container').length).toBe(1);
(overlayContainerElement.querySelector('button[md-dialog-close]') as HTMLElement).click();
+ viewContainerFixture.detectChanges();
viewContainerFixture.whenStable().then(() => {
expect(overlayContainerElement.querySelectorAll('.mat-dialog-container').length).toBe(0);
@@ -616,7 +619,7 @@ const TEST_DIRECTIVES = [
];
@NgModule({
- imports: [MdDialogModule],
+ imports: [MdDialogModule, NoopAnimationsModule],
exports: TEST_DIRECTIVES,
declarations: TEST_DIRECTIVES,
entryComponents: [
diff --git a/src/lib/input/input-container.spec.ts b/src/lib/input/input-container.spec.ts
index 541af30cab1f..e5f98722d5bc 100644
--- a/src/lib/input/input-container.spec.ts
+++ b/src/lib/input/input-container.spec.ts
@@ -6,6 +6,7 @@ import {MdInputModule} from './index';
import {MdInputContainer, MdInputDirective} from './input-container';
import {Platform} from '../core/platform/platform';
import {PlatformModule} from '../core/platform/index';
+import {wrappedErrorMessage} from '../core/testing/wrapped-error-message';
import {
MdInputContainerMissingMdInputError,
MdInputContainerPlaceholderConflictError,
@@ -227,28 +228,28 @@ describe('MdInputContainer', function () {
let fixture = TestBed.createComponent(MdInputContainerInvalidHintTestController);
expect(() => fixture.detectChanges()).toThrowError(
- angularWrappedErrorMessage(new MdInputContainerDuplicatedHintError('start')));
+ wrappedErrorMessage(new MdInputContainerDuplicatedHintError('start')));
});
it('validates there\'s only one hint label per side (attribute)', () => {
let fixture = TestBed.createComponent(MdInputContainerInvalidHint2TestController);
expect(() => fixture.detectChanges()).toThrowError(
- angularWrappedErrorMessage(new MdInputContainerDuplicatedHintError('start')));
+ wrappedErrorMessage(new MdInputContainerDuplicatedHintError('start')));
});
it('validates there\'s only one placeholder', () => {
let fixture = TestBed.createComponent(MdInputContainerInvalidPlaceholderTestController);
expect(() => fixture.detectChanges()).toThrowError(
- angularWrappedErrorMessage(new MdInputContainerPlaceholderConflictError()));
+ wrappedErrorMessage(new MdInputContainerPlaceholderConflictError()));
});
it('validates that mdInput child is present', () => {
let fixture = TestBed.createComponent(MdInputContainerMissingMdInputTestController);
expect(() => fixture.detectChanges()).toThrowError(
- angularWrappedErrorMessage(new MdInputContainerMissingMdInputError()));
+ wrappedErrorMessage(new MdInputContainerMissingMdInputError()));
});
it('validates the type', () => {
@@ -774,16 +775,3 @@ class MdTextareaWithBindings {
template: ``
})
class MdInputContainerMissingMdInputTestController {}
-
-/**
- * Gets a RegExp used to detect an angular wrapped error message.
- * See https://github.com/angular/angular/issues/8348
- */
-const angularWrappedErrorMessage = (e: Error) =>
- new RegExp(`.*caused by: ${regexpEscape(e.message)}$`);
-
-/**
- * Escape a string for use inside a RegExp.
- * Based on https://github.com/sindresorhus/escape-string-regex
- */
-const regexpEscape = (s: string) => s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
diff --git a/src/lib/menu/index.ts b/src/lib/menu/index.ts
index 87b541aca49e..cc3763c6dcf7 100644
--- a/src/lib/menu/index.ts
+++ b/src/lib/menu/index.ts
@@ -8,7 +8,12 @@ import {MdRippleModule} from '../core/ripple/index';
@NgModule({
- imports: [OverlayModule, CommonModule, MdRippleModule, CompatibilityModule],
+ imports: [
+ OverlayModule,
+ CommonModule,
+ MdRippleModule,
+ CompatibilityModule,
+ ],
exports: [MdMenu, MdMenuItem, MdMenuTrigger, CompatibilityModule],
declarations: [MdMenu, MdMenuItem, MdMenuTrigger],
})
diff --git a/src/lib/menu/menu-animations.ts b/src/lib/menu/menu-animations.ts
index 8186a3f3945f..4d1caf5bf2a5 100644
--- a/src/lib/menu/menu-animations.ts
+++ b/src/lib/menu/menu-animations.ts
@@ -1,11 +1,11 @@
import{
- AnimationEntryMetadata,
trigger,
state,
style,
animate,
- transition
-} from '@angular/core';
+ transition,
+ AnimationTriggerMetadata,
+} from '@angular/animations';
/**
* Below are all the animations for the md-menu component.
@@ -23,7 +23,7 @@ import{
*/
// TODO(kara): switch to :enter and :leave once Mobile Safari is sorted out.
-export const transformMenu: AnimationEntryMetadata = trigger('transformMenu', [
+export const transformMenu: AnimationTriggerMetadata = trigger('transformMenu', [
state('showing', style({
opacity: 1,
transform: `scale(1)`
@@ -44,7 +44,7 @@ export const transformMenu: AnimationEntryMetadata = trigger('transformMenu', [
* This animation fades in the background color and content of the menu panel
* after its containing element is scaled in.
*/
-export const fadeInItems: AnimationEntryMetadata = trigger('fadeInItems', [
+export const fadeInItems: AnimationTriggerMetadata = trigger('fadeInItems', [
state('showing', style({opacity: 1})),
transition('void => *', [
style({opacity: 0}),
diff --git a/src/lib/menu/menu.html b/src/lib/menu/menu.html
index 3360ab135e2e..989bf1f56acb 100644
--- a/src/lib/menu/menu.html
+++ b/src/lib/menu/menu.html
@@ -1,9 +1,9 @@
-
+
-
+
diff --git a/src/lib/menu/menu.spec.ts b/src/lib/menu/menu.spec.ts
index 3199b475a2e7..849e84a8aa76 100644
--- a/src/lib/menu/menu.spec.ts
+++ b/src/lib/menu/menu.spec.ts
@@ -1,5 +1,6 @@
import {TestBed, async, ComponentFixture} from '@angular/core/testing';
import {By} from '@angular/platform-browser';
+import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {
Component,
ElementRef,
@@ -28,7 +29,7 @@ describe('MdMenu', () => {
beforeEach(async(() => {
dir = 'ltr';
TestBed.configureTestingModule({
- imports: [MdMenuModule.forRoot()],
+ imports: [MdMenuModule.forRoot(), NoopAnimationsModule],
declarations: [SimpleMenu, PositionedMenu, OverlapMenu, CustomMenuPanel, CustomMenu],
providers: [
{provide: OverlayContainer, useFactory: () => {
@@ -70,7 +71,7 @@ describe('MdMenu', () => {
}).not.toThrowError();
});
- it('should close the menu when a click occurs outside the menu', async(() => {
+ it('should close the menu when a click occurs outside the menu', () => {
const fixture = TestBed.createComponent(SimpleMenu);
fixture.detectChanges();
fixture.componentInstance.trigger.openMenu();
@@ -79,10 +80,8 @@ describe('MdMenu', () => {
backdrop.click();
fixture.detectChanges();
- fixture.whenStable().then(() => {
- expect(overlayContainerElement.textContent).toBe('');
- });
- }));
+ expect(overlayContainerElement.textContent).toBe('');
+ });
it('should open a custom menu', () => {
const fixture = TestBed.createComponent(CustomMenu);
@@ -469,10 +468,10 @@ class OverlapMenu implements TestableMenu {
@Component({
selector: 'custom-menu',
template: `
-
+
Custom Menu header
-
+
`,
exportAs: 'mdCustomMenu'
})
diff --git a/src/lib/package.json b/src/lib/package.json
index b4f5821253d5..cddf22febea6 100644
--- a/src/lib/package.json
+++ b/src/lib/package.json
@@ -21,8 +21,8 @@
},
"homepage": "https://github.com/angular/material2#readme",
"peerDependencies": {
- "@angular/core": "^2.3.0",
- "@angular/common": "^2.3.0",
- "@angular/http": "^2.3.0"
+ "@angular/core": "^4.0.0-rc.5",
+ "@angular/common": "^4.0.0-rc.5",
+ "@angular/http": "^4.0.0-rc.5"
}
}
diff --git a/src/lib/select/index.ts b/src/lib/select/index.ts
index e5390113f94a..6e667948034a 100644
--- a/src/lib/select/index.ts
+++ b/src/lib/select/index.ts
@@ -6,7 +6,12 @@ import {CompatibilityModule, OverlayModule} from '../core';
@NgModule({
- imports: [CommonModule, OverlayModule, MdOptionModule, CompatibilityModule],
+ imports: [
+ CommonModule,
+ OverlayModule,
+ MdOptionModule,
+ CompatibilityModule,
+ ],
exports: [MdSelect, MdOptionModule, CompatibilityModule],
declarations: [MdSelect],
})
diff --git a/src/lib/select/select-animations.ts b/src/lib/select/select-animations.ts
index a8d7ae1f0d41..42201b4bcc01 100644
--- a/src/lib/select/select-animations.ts
+++ b/src/lib/select/select-animations.ts
@@ -1,11 +1,11 @@
import {
animate,
- AnimationEntryMetadata,
+ AnimationTriggerMetadata,
state,
style,
transition,
trigger,
-} from '@angular/core';
+} from '@angular/animations';
/**
* The following are all the animations for the md-select component, with each
@@ -19,7 +19,7 @@ import {
* it to either the top left corner (ltr) or top right corner (rtl) of the trigger,
* depending on the text direction of the application.
*/
-export const transformPlaceholder: AnimationEntryMetadata = trigger('transformPlaceholder', [
+export const transformPlaceholder: AnimationTriggerMetadata = trigger('transformPlaceholder', [
state('floating-ltr', style({
top: '-22px',
left: '-2px',
@@ -42,7 +42,7 @@ export const transformPlaceholder: AnimationEntryMetadata = trigger('transformPl
*
* When the panel is removed from the DOM, it simply fades out linearly.
*/
-export const transformPanel: AnimationEntryMetadata = trigger('transformPanel', [
+export const transformPanel: AnimationTriggerMetadata = trigger('transformPanel', [
state('showing', style({
opacity: 1,
minWidth: 'calc(100% + 32px)',
@@ -66,7 +66,7 @@ export const transformPanel: AnimationEntryMetadata = trigger('transformPanel',
* select's options. It is time delayed to occur 100ms after the overlay
* panel has transformed in.
*/
-export const fadeInContent: AnimationEntryMetadata = trigger('fadeInContent', [
+export const fadeInContent: AnimationTriggerMetadata = trigger('fadeInContent', [
state('showing', style({opacity: 1})),
transition('void => showing', [
style({opacity: 0}),
diff --git a/src/lib/select/select.html b/src/lib/select/select.html
index 7e4a09e8832b..9c9f0eefac97 100644
--- a/src/lib/select/select.html
+++ b/src/lib/select/select.html
@@ -13,7 +13,7 @@
-
-
+
diff --git a/src/lib/select/select.spec.ts b/src/lib/select/select.spec.ts
index a428799717e9..df1fb46f739a 100644
--- a/src/lib/select/select.spec.ts
+++ b/src/lib/select/select.spec.ts
@@ -9,6 +9,7 @@ import {
ChangeDetectionStrategy,
OnInit,
} from '@angular/core';
+import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {MdSelectModule} from './index';
import {OverlayContainer} from '../core/overlay/overlay-container';
import {MdSelect, MdSelectFloatPlaceholderType} from './select';
@@ -20,6 +21,8 @@ import {
} from '@angular/forms';
import {ViewportRuler} from '../core/overlay/position/viewport-ruler';
import {dispatchFakeEvent} from '../core/testing/dispatch-events';
+import {wrappedErrorMessage} from '../core/testing/wrapped-error-message';
+
describe('MdSelect', () => {
let overlayContainerElement: HTMLElement;
@@ -27,7 +30,7 @@ describe('MdSelect', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
- imports: [MdSelectModule.forRoot(), ReactiveFormsModule, FormsModule],
+ imports: [MdSelectModule.forRoot(), ReactiveFormsModule, FormsModule, NoopAnimationsModule],
declarations: [
BasicSelect,
NgModelSelect,
@@ -589,67 +592,67 @@ describe('MdSelect', () => {
let fixture: ComponentFixture;
let trigger: HTMLElement;
- beforeEach(() => {
+ beforeEach(fakeAsync(() => {
fixture = TestBed.createComponent(BasicSelect);
fixture.detectChanges();
trigger = fixture.debugElement.query(By.css('.mat-select-trigger')).nativeElement;
- });
+ }));
- it('should float the placeholder when the panel is open and unselected', () => {
- expect(fixture.componentInstance.select._getPlaceholderAnimationState())
- .toEqual('', 'Expected placeholder to initially have a normal position.');
+ it('should float the placeholder when the panel is open and unselected', () => {
+ expect(fixture.componentInstance.select._getPlaceholderAnimationState())
+ .toEqual('', 'Expected placeholder to initially have a normal position.');
- trigger.click();
- fixture.detectChanges();
- expect(fixture.componentInstance.select._getPlaceholderAnimationState())
- .toEqual('floating-ltr', 'Expected placeholder to animate up to floating position.');
+ trigger.click();
+ fixture.detectChanges();
+ expect(fixture.componentInstance.select._getPlaceholderAnimationState())
+ .toEqual('floating-ltr', 'Expected placeholder to animate up to floating position.');
- const backdrop =
- overlayContainerElement.querySelector('.cdk-overlay-backdrop') as HTMLElement;
- backdrop.click();
- fixture.detectChanges();
+ const backdrop =
+ overlayContainerElement.querySelector('.cdk-overlay-backdrop') as HTMLElement;
+ backdrop.click();
+ fixture.detectChanges();
- expect(fixture.componentInstance.select._getPlaceholderAnimationState())
- .toEqual('', 'Expected placeholder to animate back down to normal position.');
- });
+ expect(fixture.componentInstance.select._getPlaceholderAnimationState())
+ .toEqual('', 'Expected placeholder to animate back down to normal position.');
+ });
- it('should float the placeholder without animation when value is set', () => {
- fixture.componentInstance.control.setValue('pizza-1');
- fixture.detectChanges();
+ it('should float the placeholder without animation when value is set', () => {
+ fixture.componentInstance.control.setValue('pizza-1');
+ fixture.detectChanges();
- const placeholderEl =
- fixture.debugElement.query(By.css('.mat-select-placeholder')).nativeElement;
+ const placeholderEl =
+ fixture.debugElement.query(By.css('.mat-select-placeholder')).nativeElement;
- expect(placeholderEl.classList)
- .toContain('mat-floating-placeholder', 'Expected placeholder to display as floating.');
- expect(fixture.componentInstance.select._getPlaceholderAnimationState())
- .toEqual('', 'Expected animation state to be empty to avoid animation.');
- });
+ expect(placeholderEl.classList)
+ .toContain('mat-floating-placeholder', 'Expected placeholder to display as floating.');
+ expect(fixture.componentInstance.select._getPlaceholderAnimationState())
+ .toEqual('', 'Expected animation state to be empty to avoid animation.');
+ });
- it('should use the floating-rtl state when the dir is rtl', () => {
- dir.value = 'rtl';
+ it('should use the floating-rtl state when the dir is rtl', () => {
+ dir.value = 'rtl';
- trigger.click();
- fixture.detectChanges();
- expect(fixture.componentInstance.select._getPlaceholderAnimationState())
- .toEqual('floating-rtl');
- });
+ trigger.click();
+ fixture.detectChanges();
+ expect(fixture.componentInstance.select._getPlaceholderAnimationState())
+ .toEqual('floating-rtl');
+ });
+ it('should add a class to the panel when the menu is done animating', fakeAsync(() => {
+ trigger.click();
+ fixture.detectChanges();
- it('should add a class to the panel when the menu is done animating', fakeAsync(() => {
- trigger.click();
- fixture.detectChanges();
+ const panel = overlayContainerElement.querySelector('.mat-select-panel');
- const panel = overlayContainerElement.querySelector('.mat-select-panel');
+ expect(panel.classList).not.toContain('mat-select-panel-done-animating');
- expect(panel.classList).not.toContain('mat-select-panel-done-animating');
+ tick(250);
+ fixture.detectChanges();
- tick(250);
- fixture.detectChanges();
+ expect(panel.classList).toContain('mat-select-panel-done-animating');
+ }));
- expect(panel.classList).toContain('mat-select-panel-done-animating');
- }));
});
describe('positioning', () => {
@@ -1566,13 +1569,13 @@ describe('MdSelect', () => {
it('should throw an exception when trying to set a non-array value', () => {
expect(() => {
testInstance.control.setValue('not-an-array');
- }).toThrowError(MdSelectNonArrayValueError);
+ }).toThrowError(wrappedErrorMessage(new MdSelectNonArrayValueError()));
});
it('should throw an exception when trying to change multiple mode after init', () => {
expect(() => {
testInstance.select.multiple = false;
- }).toThrowError(MdSelectDynamicMultipleError);
+ }).toThrowError(wrappedErrorMessage(new MdSelectDynamicMultipleError()));
});
it('should pass the `multiple` value to all of the option instances', async(() => {
diff --git a/src/lib/select/select.ts b/src/lib/select/select.ts
index 32915f501b2c..c220082e5db2 100644
--- a/src/lib/select/select.ts
+++ b/src/lib/select/select.ts
@@ -447,6 +447,7 @@ export class MdSelect implements AfterContentInit, ControlValueAccessor, OnDestr
this.onOpen.emit();
} else {
this.onClose.emit();
+ this._panelDoneAnimating = false;
}
}
diff --git a/src/lib/slide-toggle/slide-toggle.spec.ts b/src/lib/slide-toggle/slide-toggle.spec.ts
index 4599ead4f14d..ddce38d7225b 100644
--- a/src/lib/slide-toggle/slide-toggle.spec.ts
+++ b/src/lib/slide-toggle/slide-toggle.spec.ts
@@ -680,7 +680,7 @@ class SlideToggleTestApp {
@Component({
selector: 'slide-toggle-forms-test-app',
template: `
- `
diff --git a/src/lib/snack-bar/index.ts b/src/lib/snack-bar/index.ts
index 99dfe54532c1..0e7ef00181e2 100644
--- a/src/lib/snack-bar/index.ts
+++ b/src/lib/snack-bar/index.ts
@@ -7,7 +7,12 @@ import {SimpleSnackBar} from './simple-snack-bar';
@NgModule({
- imports: [OverlayModule, PortalModule, CommonModule, CompatibilityModule],
+ imports: [
+ OverlayModule,
+ PortalModule,
+ CommonModule,
+ CompatibilityModule,
+ ],
exports: [MdSnackBarContainer, CompatibilityModule],
declarations: [MdSnackBarContainer, SimpleSnackBar],
entryComponents: [MdSnackBarContainer, SimpleSnackBar],
diff --git a/src/lib/snack-bar/snack-bar-container.html b/src/lib/snack-bar/snack-bar-container.html
index 9ca2bad1e9cf..5b263ad218a4 100644
--- a/src/lib/snack-bar/snack-bar-container.html
+++ b/src/lib/snack-bar/snack-bar-container.html
@@ -1 +1 @@
-
+
diff --git a/src/lib/snack-bar/snack-bar-container.ts b/src/lib/snack-bar/snack-bar-container.ts
index d191067a0914..519735f9363c 100644
--- a/src/lib/snack-bar/snack-bar-container.ts
+++ b/src/lib/snack-bar/snack-bar-container.ts
@@ -2,17 +2,19 @@ import {
Component,
ComponentRef,
ViewChild,
- trigger,
- state,
- style,
- transition,
- animate,
- AnimationTransitionEvent,
NgZone,
OnDestroy,
Renderer,
ElementRef,
} from '@angular/core';
+import {
+ trigger,
+ state,
+ style,
+ transition,
+ animate,
+ AnimationEvent,
+} from '@angular/animations';
import {
BasePortalHost,
ComponentPortal,
@@ -103,7 +105,7 @@ export class MdSnackBarContainer extends BasePortalHost implements OnDestroy {
}
/** Handle end of animations, updating the state of the snackbar. */
- onAnimationEnd(event: AnimationTransitionEvent) {
+ onAnimationEnd(event: AnimationEvent) {
if (event.toState === 'void' || event.toState === 'complete') {
this._completeExit();
}
diff --git a/src/lib/snack-bar/snack-bar.spec.ts b/src/lib/snack-bar/snack-bar.spec.ts
index 84904665aca4..2eef079ec69a 100644
--- a/src/lib/snack-bar/snack-bar.spec.ts
+++ b/src/lib/snack-bar/snack-bar.spec.ts
@@ -9,6 +9,7 @@ import {
} from '@angular/core/testing';
import {NgModule, Component, Directive, ViewChild, ViewContainerRef} from '@angular/core';
import {CommonModule} from '@angular/common';
+import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {MdSnackBarModule, MdSnackBar, MdSnackBarConfig, SimpleSnackBar} from './index';
import {OverlayContainer, LiveAnnouncer} from '../core';
@@ -28,7 +29,7 @@ describe('MdSnackBar', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
- imports: [MdSnackBarModule.forRoot(), SnackBarTestModule],
+ imports: [MdSnackBarModule.forRoot(), SnackBarTestModule, NoopAnimationsModule],
providers: [
{provide: OverlayContainer, useFactory: () => {
overlayContainerElement = document.createElement('div');
@@ -353,7 +354,7 @@ describe('MdSnackBar with parent MdSnackBar', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
- imports: [MdSnackBarModule.forRoot(), SnackBarTestModule],
+ imports: [MdSnackBarModule.forRoot(), SnackBarTestModule, NoopAnimationsModule],
declarations: [ComponentThatProvidesMdSnackBar],
providers: [
{provide: OverlayContainer, useFactory: () => {
diff --git a/src/lib/system-config-spec.ts b/src/lib/system-config-spec.ts
index 20b147518c83..d61dff43538e 100644
--- a/src/lib/system-config-spec.ts
+++ b/src/lib/system-config-spec.ts
@@ -18,6 +18,10 @@ System.config({
'@angular/http/testing': 'vendor/@angular/http/bundles/http-testing.umd.js',
'@angular/forms': 'vendor/@angular/forms/bundles/forms.umd.js',
'@angular/forms/testing': 'vendor/@angular/forms/bundles/forms-testing.umd.js',
+ '@angular/animations': 'vendor/@angular/animations/bundles/animations.umd.js',
+ '@angular/animations/browser': 'vendor/@angular/animations/bundles/animations-browser.umd.js',
+ '@angular/platform-browser/animations':
+ 'vendor/@angular/platform-browser/bundles/platform-browser-animations.umd.js',
'@angular/platform-browser': 'vendor/@angular/platform-browser/bundles/platform-browser.umd.js',
'@angular/platform-browser/testing':
'vendor/@angular/platform-browser/bundles/platform-browser-testing.umd.js',
diff --git a/src/lib/tabs/index.ts b/src/lib/tabs/index.ts
index eff6d6da7d84..33c32f02c1cb 100644
--- a/src/lib/tabs/index.ts
+++ b/src/lib/tabs/index.ts
@@ -16,7 +16,12 @@ import {SCROLL_DISPATCHER_PROVIDER} from '../core/overlay/scroll/scroll-dispatch
@NgModule({
- imports: [CommonModule, PortalModule, MdRippleModule, ObserveContentModule],
+ imports: [
+ CommonModule,
+ PortalModule,
+ MdRippleModule,
+ ObserveContentModule,
+ ],
// Don't export all components because some are only to be used internally.
exports: [
MdTabGroup,
diff --git a/src/lib/tabs/tab-body.html b/src/lib/tabs/tab-body.html
index d1af7a7fd53c..73e619466fbf 100644
--- a/src/lib/tabs/tab-body.html
+++ b/src/lib/tabs/tab-body.html
@@ -2,5 +2,5 @@
[@translateTab]="_canBeAnimated ? _position : null"
(@translateTab.start)="_onTranslateTabStarted($event)"
(@translateTab.done)="_onTranslateTabComplete($event)">
-
+
diff --git a/src/lib/tabs/tab-body.spec.ts b/src/lib/tabs/tab-body.spec.ts
index 4d6840097c4a..a205922ff0f1 100644
--- a/src/lib/tabs/tab-body.spec.ts
+++ b/src/lib/tabs/tab-body.spec.ts
@@ -1,5 +1,6 @@
import {async, ComponentFixture, TestBed, flushMicrotasks, fakeAsync} from '@angular/core/testing';
import {Component, ViewChild, TemplateRef, ViewContainerRef} from '@angular/core';
+import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {LayoutDirection, Dir} from '../core/rtl/dir';
import {TemplatePortal} from '../core/portal/portal';
import {MdTabBody} from './tab-body';
@@ -14,7 +15,7 @@ describe('MdTabBody', () => {
beforeEach(async(() => {
dir = 'ltr';
TestBed.configureTestingModule({
- imports: [CommonModule, PortalModule, MdRippleModule],
+ imports: [CommonModule, PortalModule, MdRippleModule, NoopAnimationsModule],
declarations: [
MdTabBody,
SimpleTabBodyApp,
@@ -149,9 +150,9 @@ describe('MdTabBody', () => {
describe('on centered', () => {
let fixture: ComponentFixture;
- beforeEach(() => {
+ beforeEach(fakeAsync(() => {
fixture = TestBed.createComponent(SimpleTabBodyApp);
- });
+ }));
it('should attach the content when centered and detach when not', fakeAsync(() => {
fixture.componentInstance.position = 1;
@@ -187,7 +188,7 @@ describe('MdTabBody', () => {
@Component({
template: `
- Tab Body Content
+ Tab Body Content
`
})
diff --git a/src/lib/tabs/tab-body.ts b/src/lib/tabs/tab-body.ts
index 416ac2ec6565..ec5bbfe90018 100644
--- a/src/lib/tabs/tab-body.ts
+++ b/src/lib/tabs/tab-body.ts
@@ -5,18 +5,20 @@ import {
Output,
EventEmitter,
OnInit,
- trigger,
- state,
- style,
- animate,
- transition,
- AnimationTransitionEvent,
ElementRef,
Optional,
ChangeDetectorRef,
AfterViewChecked,
AfterContentChecked,
} from '@angular/core';
+import {
+ trigger,
+ state,
+ style,
+ animate,
+ transition,
+ AnimationEvent,
+} from '@angular/animations';
import {TemplatePortal, PortalHostDirective, Dir, LayoutDirection} from '../core';
import 'rxjs/add/operator/map';
@@ -165,13 +167,13 @@ export class MdTabBody implements OnInit, AfterViewChecked, AfterContentChecked
}
}
- _onTranslateTabStarted(e: AnimationTransitionEvent) {
+ _onTranslateTabStarted(e: AnimationEvent) {
if (this._isCenterPosition(e.toState)) {
this.onCentering.emit(this._elementRef.nativeElement.clientHeight);
}
}
- _onTranslateTabComplete(e: AnimationTransitionEvent) {
+ _onTranslateTabComplete(e: AnimationEvent) {
// If the end state is that the tab is not centered, then detach the content.
if (!this._isCenterPosition(e.toState) && !this._isCenterPosition(this._position)) {
this._portalHost.detach();
diff --git a/src/lib/tabs/tab-group.html b/src/lib/tabs/tab-group.html
index 07e81b31f48d..c25a37b5e7c2 100644
--- a/src/lib/tabs/tab-group.html
+++ b/src/lib/tabs/tab-group.html
@@ -12,12 +12,12 @@
(click)="tabHeader.focusIndex = selectedIndex = i">
-
-
-
+
+
+
- {{tab.textLabel}}
+ {{tab.textLabel}}
diff --git a/src/lib/tabs/tab-group.spec.ts b/src/lib/tabs/tab-group.spec.ts
index 3ae944edcfc9..eb9c443f6ffd 100644
--- a/src/lib/tabs/tab-group.spec.ts
+++ b/src/lib/tabs/tab-group.spec.ts
@@ -3,6 +3,7 @@ import {
} from '@angular/core/testing';
import {MdTabGroup, MdTabsModule, MdTabHeaderPosition} from './index';
import {Component, ViewChild} from '@angular/core';
+import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {By} from '@angular/platform-browser';
import {Observable} from 'rxjs/Observable';
import {MdTab} from './tab';
@@ -13,7 +14,7 @@ import {FakeViewportRuler} from '../core/overlay/position/fake-viewport-ruler';
describe('MdTabGroup', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
- imports: [MdTabsModule.forRoot()],
+ imports: [MdTabsModule.forRoot(), NoopAnimationsModule],
declarations: [
SimpleTabsTestApp,
SimpleDynamicTabsTestApp,
@@ -297,15 +298,15 @@ describe('MdTabGroup', () => {
(focusChange)="handleFocus($event)"
(selectChange)="handleSelection($event)">
- Tab One
+ Tab One
Tab one content
- Tab Two
+ Tab Two
Tab two content
- Tab Three
+ Tab Three
Tab three content
@@ -331,7 +332,7 @@ class SimpleTabsTestApp {
(focusChange)="handleFocus($event)"
(selectChange)="handleSelection($event)">
- {{tab.label}}
+ {{tab.label}}
{{tab.content}}
@@ -384,15 +385,15 @@ class BindedTabsTestApp {
template: `
- Tab One
+ Tab One
Tab one content
- Tab Two
+ Tab Two
Tab two content
- Tab Three
+ Tab Three
Tab three content
@@ -404,7 +405,7 @@ class DisabledTabsTestApp {}
template: `
- {{ tab.label }}
+ {{ tab.label }}
{{ tab.content }}
diff --git a/src/lib/tabs/tab.html b/src/lib/tabs/tab.html
index d3c3a8152654..398c819fa896 100644
--- a/src/lib/tabs/tab.html
+++ b/src/lib/tabs/tab.html
@@ -1,4 +1,4 @@
-
+
diff --git a/src/lib/tabs/tab.ts b/src/lib/tabs/tab.ts
index 5018bc3252db..530075c7d8af 100644
--- a/src/lib/tabs/tab.ts
+++ b/src/lib/tabs/tab.ts
@@ -13,7 +13,7 @@ import {MdTabLabel} from './tab-label';
templateUrl: 'tab.html',
})
export class MdTab implements OnInit {
- /** Content for the tab label given by . */
+ /** Content for the tab label given by . */
@ContentChild(MdTabLabel) templateLabel: MdTabLabel;
/** Template inside the MdTab view that contains an . */
diff --git a/src/lib/tabs/tabs.md b/src/lib/tabs/tabs.md
index 06f6d3ee9821..e24e7a1b0a30 100644
--- a/src/lib/tabs/tabs.md
+++ b/src/lib/tabs/tabs.md
@@ -10,10 +10,10 @@ tab labels in the header.
### Events
-The `selectChange` output event is emitted when the active tab changes.
+The `selectChange` output event is emitted when the active tab changes.
The `focusChange` output event is emitted when the user puts focus on any of the tab labels in
-the header, usually through keyboard navigation.
+the header, usually through keyboard navigation.
### Labels
@@ -37,16 +37,16 @@ For more complex labels, add a template with the `md-tab-label` directive inside
```html
-
+
The best pasta
-
+
Best pasta restaurants
...
-
+ thumb_down The worst sushi
-
+
Terrible sushi restaurants
...
@@ -58,7 +58,7 @@ For more complex labels, add a template with the `md-tab-label` directive inside
By default, the tab group will not change its height to the height of the currently active tab. To
change this, set the `dynamicHeight` input to true. The tab body will animate its height according
to the height of the active tab.
-
+
### Tabs and navigation
While `` is used to switch between views within a single route, `