Skip to content

Commit 1ffe706

Browse files
committed
refactor(cdk/overlay): add config option for disabling animations
Currently the CDK overlay uses `ANIMATION_MODULE_TYPE` to implicitly disable the backdrop animation, however we want to introduce a Material-specific way of disabling animations. These changes add a config option that we can use to do so.
1 parent 0a4cd91 commit 1ffe706

File tree

16 files changed

+39
-5
lines changed

16 files changed

+39
-5
lines changed

goldens/cdk/dialog/index.api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ export class DialogConfig<D = unknown, R = unknown, C extends BasePortalOutlet =
127127
};
128128
data?: D | null;
129129
direction?: Direction;
130+
disableAnimations?: boolean;
130131
disableClose?: boolean;
131132
hasBackdrop?: boolean;
132133
height?: string;

goldens/cdk/overlay/index.api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ export class OverlayConfig {
299299
constructor(config?: OverlayConfig);
300300
backdropClass?: string | string[];
301301
direction?: Direction | Directionality;
302+
disableAnimations?: boolean;
302303
disposeOnNavigation?: boolean;
303304
hasBackdrop?: boolean;
304305
height?: number | string;

src/cdk/dialog/dialog-config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,11 @@ export class DialogConfig<D = unknown, R = unknown, C extends BasePortalOutlet =
138138
*/
139139
closeOnOverlayDetachments?: boolean = true;
140140

141+
/**
142+
* Whether the built-in overlay animations should be disabled.
143+
*/
144+
disableAnimations?: boolean = false;
145+
141146
/**
142147
* Providers that will be exposed to the contents of the dialog. Can also
143148
* be provided as a function in order to generate the providers lazily.

src/cdk/dialog/dialog.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ export class Dialog implements OnDestroy {
190190
width: config.width,
191191
height: config.height,
192192
disposeOnNavigation: config.closeOnNavigation,
193+
disableAnimations: config.disableAnimations,
193194
});
194195

195196
if (config.backdropClass) {

src/cdk/overlay/overlay-config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ export class OverlayConfig {
2727
/** Custom class to add to the backdrop */
2828
backdropClass?: string | string[] = 'cdk-overlay-dark-backdrop';
2929

30+
/** Whether to disable any built-in animations. */
31+
disableAnimations?: boolean;
32+
3033
/** The width of the overlay panel. If a number is provided, pixel units are assumed. */
3134
width?: number | string;
3235

src/cdk/overlay/overlay.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export class Overlay {
8686
this._document,
8787
this._location,
8888
this._outsideClickDispatcher,
89-
this._animationsModuleType === 'NoopAnimations',
89+
config?.disableAnimations ?? this._animationsModuleType === 'NoopAnimations',
9090
this._injector.get(EnvironmentInjector),
9191
this._renderer,
9292
);

src/material/autocomplete/autocomplete-trigger.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
4545
import {
4646
MatOption,
4747
MatOptionSelectionChange,
48+
_animationsDisabled,
4849
_countGroupLabelsBeforeOption,
4950
_getOptionScrollPosition,
5051
} from '../core';
@@ -149,6 +150,7 @@ export class MatAutocompleteTrigger
149150
private _viewportRuler = inject(ViewportRuler);
150151
private _scrollStrategy = inject(MAT_AUTOCOMPLETE_SCROLL_STRATEGY);
151152
private _renderer = inject(Renderer2);
153+
private _animationsDisabled = _animationsDisabled();
152154
private _defaults = inject<MatAutocompleteDefaultOptions | null>(
153155
MAT_AUTOCOMPLETE_DEFAULT_OPTIONS,
154156
{optional: true},
@@ -903,6 +905,7 @@ export class MatAutocompleteTrigger
903905
hasBackdrop: this._defaults?.hasBackdrop,
904906
backdropClass: this._defaults?.backdropClass,
905907
panelClass: this._defaults?.overlayPanelClass,
908+
disableAnimations: this._animationsDisabled,
906909
});
907910
}
908911

src/material/bottom-sheet/bottom-sheet.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {Injectable, TemplateRef, InjectionToken, OnDestroy, inject} from '@angul
1313
import {MAT_BOTTOM_SHEET_DATA, MatBottomSheetConfig} from './bottom-sheet-config';
1414
import {MatBottomSheetContainer} from './bottom-sheet-container';
1515
import {MatBottomSheetRef} from './bottom-sheet-ref';
16+
import {_animationsDisabled} from '../core';
1617

1718
/** Injection token that can be used to specify default bottom sheet options. */
1819
export const MAT_BOTTOM_SHEET_DEFAULT_OPTIONS = new InjectionToken<MatBottomSheetConfig>(
@@ -26,6 +27,7 @@ export const MAT_BOTTOM_SHEET_DEFAULT_OPTIONS = new InjectionToken<MatBottomShee
2627
export class MatBottomSheet implements OnDestroy {
2728
private _overlay = inject(Overlay);
2829
private _parentBottomSheet = inject(MatBottomSheet, {optional: true, skipSelf: true});
30+
private _animationsDisabled = _animationsDisabled();
2931
private _defaultOptions = inject<MatBottomSheetConfig>(MAT_BOTTOM_SHEET_DEFAULT_OPTIONS, {
3032
optional: true,
3133
});
@@ -89,6 +91,7 @@ export class MatBottomSheet implements OnDestroy {
8991
container: MatBottomSheetContainer,
9092
scrollStrategy: _config.scrollStrategy || this._overlay.scrollStrategies.block(),
9193
positionStrategy: this._overlay.position().global().centerHorizontally().bottom('0'),
94+
disableAnimations: this._animationsDisabled,
9295
templateContext: () => ({bottomSheetRef: ref}),
9396
providers: (cdkRef, _cdkConfig, container) => {
9497
ref = new MatBottomSheetRef(cdkRef, _config, container as MatBottomSheetContainer);

src/material/core/private/ripple-loader.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,10 +175,10 @@ export class MatRippleLoader implements OnDestroy {
175175
const globalOptions = this._globalRippleOptions;
176176
const enterDuration = this._animationsDisabled
177177
? 0
178-
: globalOptions?.animation?.enterDuration ?? defaultRippleAnimationConfig.enterDuration;
178+
: (globalOptions?.animation?.enterDuration ?? defaultRippleAnimationConfig.enterDuration);
179179
const exitDuration = this._animationsDisabled
180180
? 0
181-
: globalOptions?.animation?.exitDuration ?? defaultRippleAnimationConfig.exitDuration;
181+
: (globalOptions?.animation?.exitDuration ?? defaultRippleAnimationConfig.exitDuration);
182182
const target: RippleTarget = {
183183
rippleDisabled:
184184
this._animationsDisabled || globalOptions?.disabled || host.hasAttribute(matRippleDisabled),

src/material/datepicker/datepicker-base.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@ export abstract class MatDatepickerBase<
394394
private _dateAdapter = inject<DateAdapter<D>>(DateAdapter, {optional: true})!;
395395
private _dir = inject(Directionality, {optional: true});
396396
private _model = inject<MatDateSelectionModel<S, D>>(MatDateSelectionModel);
397+
private _animationsDisabled = _animationsDisabled();
397398

398399
private _scrollStrategy = inject(MAT_DATEPICKER_SCROLL_STRATEGY);
399400
private _inputStateChanges = Subscription.EMPTY;
@@ -769,6 +770,7 @@ export abstract class MatDatepickerBase<
769770
direction: this._dir || 'ltr',
770771
scrollStrategy: isDialog ? this._overlay.scrollStrategies.block() : this._scrollStrategy(),
771772
panelClass: `mat-datepicker-${isDialog ? 'dialog' : 'popup'}`,
773+
disableAnimations: this._animationsDisabled,
772774
}),
773775
));
774776

src/material/dialog/dialog-container.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,11 @@ export class MatDialogContainer extends CdkDialogContainer<MatDialogConfig> impl
7777
private _hostElement: HTMLElement = this._elementRef.nativeElement;
7878
/** Duration of the dialog open animation. */
7979
private _enterAnimationDuration = this._animationsEnabled
80-
? parseCssTime(this._config.enterAnimationDuration) ?? OPEN_ANIMATION_DURATION
80+
? (parseCssTime(this._config.enterAnimationDuration) ?? OPEN_ANIMATION_DURATION)
8181
: 0;
8282
/** Duration of the dialog close animation. */
8383
private _exitAnimationDuration = this._animationsEnabled
84-
? parseCssTime(this._config.exitAnimationDuration) ?? CLOSE_ANIMATION_DURATION
84+
? (parseCssTime(this._config.exitAnimationDuration) ?? CLOSE_ANIMATION_DURATION)
8585
: 0;
8686
/** Current timer for dialog animations. */
8787
private _animationTimer: ReturnType<typeof setTimeout> | null = null;

src/material/dialog/dialog.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {defer, Observable, Subject} from 'rxjs';
2323
import {Dialog, DialogConfig} from '@angular/cdk/dialog';
2424
import {startWith} from 'rxjs/operators';
2525
import {_IdGenerator} from '@angular/cdk/a11y';
26+
import {_animationsDisabled} from '../core';
2627

2728
/** Injection token that can be used to access the data that was passed in to a dialog. */
2829
export const MAT_DIALOG_DATA = new InjectionToken<any>('MatMdcDialogData');
@@ -55,6 +56,7 @@ export class MatDialog implements OnDestroy {
5556
private _parentDialog = inject(MatDialog, {optional: true, skipSelf: true});
5657
private _idGenerator = inject(_IdGenerator);
5758
protected _dialog = inject(Dialog);
59+
private _animationsDisabled = _animationsDisabled();
5860

5961
private readonly _openDialogsAtThisLevel: MatDialogRef<any>[] = [];
6062
private readonly _afterAllClosedAtThisLevel = new Subject<void>();
@@ -146,6 +148,10 @@ export class MatDialog implements OnDestroy {
146148
// Disable closing on detachments so that we can sync up the animation.
147149
// The Material dialog ref handles this manually.
148150
closeOnOverlayDetachments: false,
151+
disableAnimations:
152+
this._animationsDisabled ||
153+
config.enterAnimationDuration?.toLocaleString() === '0' ||
154+
config.exitAnimationDuration?.toString() === '0',
149155
container: {
150156
type: this._dialogContainerType,
151157
providers: () => [

src/material/menu/menu-trigger.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import {throwMatMenuRecursiveError} from './menu-errors';
4747
import {MatMenuItem} from './menu-item';
4848
import {MAT_MENU_PANEL, MatMenuPanel} from './menu-panel';
4949
import {MenuPositionX, MenuPositionY} from './menu-positions';
50+
import {_animationsDisabled} from '../core';
5051

5152
/** Injection token that determines the scroll handling while the menu is open. */
5253
export const MAT_MENU_SCROLL_STRATEGY = new InjectionToken<() => ScrollStrategy>(
@@ -117,6 +118,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
117118
private _ngZone = inject(NgZone);
118119
private _scrollStrategy = inject(MAT_MENU_SCROLL_STRATEGY);
119120
private _changeDetectorRef = inject(ChangeDetectorRef);
121+
private _animationsDisabled = _animationsDisabled();
120122
private _cleanupTouchstart: () => void;
121123

122124
private _portal: TemplatePortal;
@@ -447,6 +449,7 @@ export class MatMenuTrigger implements AfterContentInit, OnDestroy {
447449
panelClass: menu.overlayPanelClass,
448450
scrollStrategy: this._scrollStrategy(),
449451
direction: this._dir || 'ltr',
452+
disableAnimations: this._animationsDisabled,
450453
});
451454
}
452455

src/material/snack-bar/snack-bar.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {MAT_SNACK_BAR_DATA, MatSnackBarConfig} from './snack-bar-config';
2525
import {MatSnackBarRef} from './snack-bar-ref';
2626
import {ComponentPortal, TemplatePortal} from '@angular/cdk/portal';
2727
import {takeUntil} from 'rxjs/operators';
28+
import {_animationsDisabled} from '../core';
2829

2930
/**
3031
* @docs-private
@@ -55,6 +56,7 @@ export class MatSnackBar implements OnDestroy {
5556
private _breakpointObserver = inject(BreakpointObserver);
5657
private _parentSnackBar = inject(MatSnackBar, {optional: true, skipSelf: true});
5758
private _defaultConfig = inject<MatSnackBarConfig>(MAT_SNACK_BAR_DEFAULT_OPTIONS);
59+
private _animationsDisabled = _animationsDisabled();
5860

5961
/**
6062
* Reference to the current snack bar in the view *at this level* (in the Angular injector tree).
@@ -295,6 +297,7 @@ export class MatSnackBar implements OnDestroy {
295297
}
296298

297299
overlayConfig.positionStrategy = positionStrategy;
300+
overlayConfig.disableAnimations = this._animationsDisabled;
298301
return this._overlay.create(overlayConfig);
299302
}
300303

src/material/timepicker/timepicker.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ export class MatTimepicker<D> implements OnDestroy, MatOptionParentComponent {
343343
scrollStrategy: this._scrollStrategyFactory(),
344344
direction: this._dir || 'ltr',
345345
hasBackdrop: false,
346+
disableAnimations: this._animationsDisabled,
346347
});
347348

348349
this._overlayRef.detachments().subscribe(() => this.close());

src/material/tooltip/tooltip.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ export class MatTooltip implements OnDestroy, AfterViewInit {
207207
protected _dir = inject(Directionality);
208208
private _injector = inject(Injector);
209209
private _viewContainerRef = inject(ViewContainerRef);
210+
private _animationsDisabled = _animationsDisabled();
210211
private _defaultOptions = inject<MatTooltipDefaultOptions>(MAT_TOOLTIP_DEFAULT_OPTIONS, {
211212
optional: true,
212213
});
@@ -550,6 +551,7 @@ export class MatTooltip implements OnDestroy, AfterViewInit {
550551
positionStrategy: strategy,
551552
panelClass: `${this._cssClassPrefix}-${PANEL_CLASS}`,
552553
scrollStrategy: this._injector.get(MAT_TOOLTIP_SCROLL_STRATEGY)(),
554+
disableAnimations: this._animationsDisabled,
553555
});
554556

555557
this._updatePosition(this._overlayRef);

0 commit comments

Comments
 (0)