diff --git a/src/material/tabs/_tabs-common.scss b/src/material/tabs/_tabs-common.scss index 5d20f0373135..a395cddb1271 100644 --- a/src/material/tabs/_tabs-common.scss +++ b/src/material/tabs/_tabs-common.scss @@ -1,4 +1,5 @@ @import '../core/style/variables'; +@import '../core/style/noop-animation'; @import '../../cdk/a11y/a11y'; $mat-tab-bar-height: 48px !default; @@ -61,6 +62,7 @@ $mat-tab-animation-duration: 500ms !default; @mixin ink-bar { $height: 2px; + @include _noop-animation(); position: absolute; bottom: 0; height: $height; diff --git a/src/material/tabs/ink-bar.ts b/src/material/tabs/ink-bar.ts index e04fdc68773d..e6e62c562ece 100644 --- a/src/material/tabs/ink-bar.ts +++ b/src/material/tabs/ink-bar.ts @@ -6,7 +6,8 @@ * found in the LICENSE file at https://angular.io/license */ -import {Directive, ElementRef, Inject, InjectionToken, NgZone} from '@angular/core'; +import {Directive, ElementRef, Inject, InjectionToken, NgZone, Optional} from '@angular/core'; +import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; /** @@ -46,13 +47,15 @@ export function _MAT_INK_BAR_POSITIONER_FACTORY(): _MatInkBarPositioner { selector: 'mat-ink-bar', host: { 'class': 'mat-ink-bar', + '[class._mat-animation-noopable]': `_animationMode === 'NoopAnimations'`, }, }) export class MatInkBar { constructor( private _elementRef: ElementRef, private _ngZone: NgZone, - @Inject(_MAT_INK_BAR_POSITIONER) private _inkBarPositioner: _MatInkBarPositioner) { } + @Inject(_MAT_INK_BAR_POSITIONER) private _inkBarPositioner: _MatInkBarPositioner, + @Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string) { } /** * Calculates the styles from the provided element in order to align the ink-bar to that element. diff --git a/src/material/tabs/tab-group.html b/src/material/tabs/tab-group.html index a72e9451a471..2654b7809d0b 100644 --- a/src/material/tabs/tab-group.html +++ b/src/material/tabs/tab-group.html @@ -31,7 +31,10 @@ -
+
-
+
diff --git a/src/material/tabs/tab-header.scss b/src/material/tabs/tab-header.scss index 946ed5cdced8..2ff126ff163e 100644 --- a/src/material/tabs/tab-header.scss +++ b/src/material/tabs/tab-header.scss @@ -1,6 +1,7 @@ @import '../core/style/variables'; @import '../core/style/layout-common'; @import '../core/style/vendor-prefixes'; +@import '../core/style/noop-animation'; @import './tabs-common'; .mat-tab-header { @@ -79,6 +80,7 @@ } .mat-tab-list { + @include _noop-animation(); flex-grow: 1; position: relative; transition: transform 500ms cubic-bezier(0.35, 0, 0.25, 1); diff --git a/src/material/tabs/tab-header.ts b/src/material/tabs/tab-header.ts index 5783f1858f93..f242fa2076c6 100644 --- a/src/material/tabs/tab-header.ts +++ b/src/material/tabs/tab-header.ts @@ -21,6 +21,7 @@ import { EventEmitter, Input, NgZone, + Inject, OnDestroy, Optional, Output, @@ -36,6 +37,7 @@ import {MatInkBar} from './ink-bar'; import {MatTabLabelWrapper} from './tab-label-wrapper'; import {FocusKeyManager} from '@angular/cdk/a11y'; import {Platform, normalizePassiveListenerOptions} from '@angular/cdk/platform'; +import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; /** Config used to bind passive event listeners */ @@ -165,7 +167,9 @@ export class MatTabHeader extends _MatTabHeaderMixinBase private _viewportRuler: ViewportRuler, @Optional() private _dir: Directionality, private _ngZone: NgZone, - private _platform: Platform) { + private _platform: Platform, + // @breaking-change 9.0.0 `_animationMode` parameter to be made required. + @Optional() @Inject(ANIMATION_MODULE_TYPE) public _animationMode?: string) { super(); // Bind the `mouseleave` event on the outside since it doesn't change anything in the view. diff --git a/src/material/tabs/tab-nav-bar/tab-nav-bar.ts b/src/material/tabs/tab-nav-bar/tab-nav-bar.ts index a43d1d3d046f..96cd09394ac4 100644 --- a/src/material/tabs/tab-nav-bar/tab-nav-bar.ts +++ b/src/material/tabs/tab-nav-bar/tab-nav-bar.ts @@ -47,6 +47,7 @@ import {merge, of as observableOf, Subject} from 'rxjs'; import {takeUntil} from 'rxjs/operators'; import {MatInkBar} from '../ink-bar'; import {FocusMonitor} from '@angular/cdk/a11y'; +import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations'; // Boilerplate for applying mixins to MatTabNav. @@ -222,7 +223,8 @@ export class MatTabLink extends _MatTabLinkMixinBase private _tabNavBar: MatTabNav, public _elementRef: ElementRef, ngZone: NgZone, platform: Platform, @Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalRippleOptions: RippleGlobalOptions|null, - @Attribute('tabindex') tabIndex: string, private _focusMonitor: FocusMonitor) { + @Attribute('tabindex') tabIndex: string, private _focusMonitor: FocusMonitor, + @Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string) { super(); this._tabLinkRipple = new RippleRenderer(this, ngZone, _elementRef, platform); @@ -231,6 +233,10 @@ export class MatTabLink extends _MatTabLinkMixinBase this.tabIndex = parseInt(tabIndex) || 0; _focusMonitor.monitor(_elementRef); + + if (animationMode === 'NoopAnimations') { + this.rippleConfig.animation = {enterDuration: 0, exitDuration: 0}; + } } ngOnDestroy() { diff --git a/tools/public_api_guard/material/tabs.d.ts b/tools/public_api_guard/material/tabs.d.ts index 0d1eb36d7368..bc10d0aec2d0 100644 --- a/tools/public_api_guard/material/tabs.d.ts +++ b/tools/public_api_guard/material/tabs.d.ts @@ -10,7 +10,8 @@ export interface _MatInkBarPositioner { export declare const MAT_TABS_CONFIG: InjectionToken<{}>; export declare class MatInkBar { - constructor(_elementRef: ElementRef, _ngZone: NgZone, _inkBarPositioner: _MatInkBarPositioner); + _animationMode?: string | undefined; + constructor(_elementRef: ElementRef, _ngZone: NgZone, _inkBarPositioner: _MatInkBarPositioner, _animationMode?: string | undefined); alignToElement(element: HTMLElement): void; hide(): void; show(): void; @@ -75,6 +76,7 @@ export declare class MatTabContent { } export declare class MatTabGroup extends _MatTabGroupMixinBase implements AfterContentInit, AfterContentChecked, OnDestroy, CanColor, CanDisableRipple { + _animationMode?: string | undefined; _tabBodyWrapper: ElementRef; _tabHeader: MatTabHeader; _tabs: QueryList; @@ -87,7 +89,7 @@ export declare class MatTabGroup extends _MatTabGroupMixinBase implements AfterC selectedIndex: number | null; readonly selectedIndexChange: EventEmitter; readonly selectedTabChange: EventEmitter; - constructor(elementRef: ElementRef, _changeDetectorRef: ChangeDetectorRef, defaultConfig?: MatTabsConfig); + constructor(elementRef: ElementRef, _changeDetectorRef: ChangeDetectorRef, defaultConfig?: MatTabsConfig, _animationMode?: string | undefined); _focusChanged(index: number): void; _getTabContentId(i: number): string; _getTabIndex(tab: MatTab, idx: number): number | null; @@ -102,6 +104,7 @@ export declare class MatTabGroup extends _MatTabGroupMixinBase implements AfterC } export declare class MatTabHeader extends _MatTabHeaderMixinBase implements AfterContentChecked, AfterContentInit, AfterViewInit, OnDestroy, CanDisableRipple { + _animationMode?: string | undefined; _disableScrollAfter: boolean; _disableScrollBefore: boolean; _inkBar: MatInkBar; @@ -116,7 +119,7 @@ export declare class MatTabHeader extends _MatTabHeaderMixinBase implements Afte scrollDistance: number; readonly selectFocusedIndex: EventEmitter; selectedIndex: number; - constructor(_elementRef: ElementRef, _changeDetectorRef: ChangeDetectorRef, _viewportRuler: ViewportRuler, _dir: Directionality, _ngZone: NgZone, _platform: Platform); + constructor(_elementRef: ElementRef, _changeDetectorRef: ChangeDetectorRef, _viewportRuler: ViewportRuler, _dir: Directionality, _ngZone: NgZone, _platform: Platform, _animationMode?: string | undefined); _alignInkBarToSelectedTab(): void; _checkPaginationEnabled(): void; _checkScrollingControls(): void; @@ -162,7 +165,7 @@ export declare class MatTabLink extends _MatTabLinkMixinBase implements OnDestro active: boolean; rippleConfig: RippleConfig & RippleGlobalOptions; readonly rippleDisabled: boolean; - constructor(_tabNavBar: MatTabNav, _elementRef: ElementRef, ngZone: NgZone, platform: Platform, globalRippleOptions: RippleGlobalOptions | null, tabIndex: string, _focusMonitor: FocusMonitor); + constructor(_tabNavBar: MatTabNav, _elementRef: ElementRef, ngZone: NgZone, platform: Platform, globalRippleOptions: RippleGlobalOptions | null, tabIndex: string, _focusMonitor: FocusMonitor, animationMode?: string); ngOnDestroy(): void; }