Skip to content

Commit

Permalink
fix(material-experimental/mdc-list): support noop animations (#23117)
Browse files Browse the repository at this point in the history
Fixes that the list animations weren't being disabled with the `NoopAnimationsModule`.

(cherry picked from commit e1d775d)
  • Loading branch information
crisbeto authored and wagnermaciel committed Jul 9, 2021
1 parent bb8574f commit 279461c
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 18 deletions.
11 changes: 9 additions & 2 deletions src/material-experimental/mdc-list/list-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
RippleTarget,
setLines,
} from '@angular/material-experimental/mdc-core';
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
import {numbers} from '@material/ripple';
import {Subscription} from 'rxjs';
import {startWith} from 'rxjs/operators';
Expand All @@ -54,12 +55,16 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri
/** Host element for the list item. */
_hostElement: HTMLElement;

/** Whether animations are disabled. */
_noopAnimations: boolean;

@ContentChildren(MatListAvatarCssMatStyler, {descendants: false}) _avatars: QueryList<never>;
@ContentChildren(MatListIconCssMatStyler, {descendants: false}) _icons: QueryList<never>;

@Input()
get disableRipple(): boolean {
return this.disabled || this._disableRipple || this._listBase.disableRipple;
return this.disabled || this._disableRipple || this._listBase.disableRipple ||
this._noopAnimations;
}
set disableRipple(value: boolean) { this._disableRipple = coerceBooleanProperty(value); }
private _disableRipple: boolean = false;
Expand Down Expand Up @@ -90,12 +95,14 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri
constructor(public _elementRef: ElementRef<HTMLElement>, protected _ngZone: NgZone,
private _listBase: MatListBase, private _platform: Platform,
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS)
globalRippleOptions?: RippleGlobalOptions) {
globalRippleOptions?: RippleGlobalOptions,
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string) {
// We have to clone the object, because we don't want to mutate a global value when we assign
// the `animation` further down. The downside of doing this is that the ripple renderer won't
// pick up dynamic changes to `disabled`, but it's not something we officially support.
this.rippleConfig = {...(globalRippleOptions || {})};
this._hostElement = this._elementRef.nativeElement;
this._noopAnimations = animationMode === 'NoopAnimations';

if (!this.rippleConfig.animation) {
this.rippleConfig.animation = {
Expand Down
31 changes: 19 additions & 12 deletions src/material-experimental/mdc-list/list-option.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,29 @@
@use '../../cdk/a11y';
@use './list-option-trailing-avatar-compat';

// The MDC-based list-option uses the MDC checkbox for the selection indicators.
// We need to ensure that the checkbox styles are included for the list-option.
@include mdc-checkbox.without-ripple($query: mdc-helpers.$mat-base-styles-query);

// For compatibility with the non-MDC list, we support avatars that are shown at the end
// of the list option. We create a class similar to MDC's `--trailing-icon` one.
@include list-option-trailing-avatar-compat.core-styles($query: mdc-helpers.$mat-base-styles-query);

// The internal checkbox is purely decorative, but because it's an `input`, the user can still
// focus it by tabbing or clicking. Furthermore, `mat-list-option` has the `option` role which
// doesn't allow a nested `input`. We use `display: none` both to remove it from the tab order
// and to prevent focus from reaching it through the screen reader's forms mode. Ideally we'd
// remove the `input` completely, but we can't because MDC uses a `:checked` selector to
// toggle the selected styles.
.mat-mdc-list-option .mdc-checkbox__native-control {
display: none;
.mat-mdc-list-option {
// The MDC-based list-option uses the MDC checkbox for the selection indicators.
// We need to ensure that the checkbox styles are not included for the list-option.
@include mdc-checkbox.without-ripple(
$query: mdc-helpers.$mat-base-styles-without-animation-query);

&:not(._mat-animation-noopable) {
@include mdc-checkbox.without-ripple($query: animation);
}

// The internal checkbox is purely decorative, but because it's an `input`, the user can still
// focus it by tabbing or clicking. Furthermore, `mat-list-option` has the `option` role which
// doesn't allow a nested `input`. We use `display: none` both to remove it from the tab order
// and to prevent focus from reaching it through the screen reader's forms mode. Ideally we'd
// remove the `input` completely, but we can't because MDC uses a `:checked` selector to
// toggle the selected styles.
.mdc-checkbox__native-control {
display: none;
}
}

@include a11y.high-contrast(active, off) {
Expand Down
7 changes: 5 additions & 2 deletions src/material-experimental/mdc-list/list-option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
RippleGlobalOptions,
ThemePalette,
} from '@angular/material-experimental/mdc-core';
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
import {MatListBase, MatListItemBase} from './list-base';
import {LIST_OPTION, ListOption, MatListOptionCheckboxPosition} from './list-option-types';

Expand Down Expand Up @@ -79,6 +80,7 @@ export interface SelectionList extends MatListBase {
'[class.mdc-list-item--with-trailing-checkbox]': '_hasCheckboxAt("after")',
'[class.mat-accent]': 'color !== "primary" && color !== "warn"',
'[class.mat-warn]': 'color === "warn"',
'[class._mat-animation-noopable]': '_noopAnimations',
'(blur)': '_handleBlur()',
},
templateUrl: 'list-option.html',
Expand Down Expand Up @@ -144,8 +146,9 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit
platform: Platform,
@Inject(SELECTION_LIST) public _selectionList: SelectionList,
private _changeDetectorRef: ChangeDetectorRef,
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalRippleOptions?: RippleGlobalOptions) {
super(element, ngZone, _selectionList, platform, globalRippleOptions);
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalRippleOptions?: RippleGlobalOptions,
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string) {
super(element, ngZone, _selectionList, platform, globalRippleOptions, animationMode);

// By default, we mark all options as unselected. The MDC list foundation will
// automatically update the attribute based on selection. Note that we need to
Expand Down
7 changes: 5 additions & 2 deletions src/material-experimental/mdc-list/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
MAT_RIPPLE_GLOBAL_OPTIONS,
RippleGlobalOptions,
} from '@angular/material-experimental/mdc-core';
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
import {MatListBase, MatListItemBase} from './list-base';

@Component({
Expand Down Expand Up @@ -54,6 +55,7 @@ export class MatList extends MatListBase {}
// the trailing meta class. Note that we also add this even if there is no projected `meta`
// content. This is because there is no good way to check for remaining projected content.
'[class.mdc-list-item--with-trailing-meta]': 'lines.length !== 0',
'[class._mat-animation-noopable]': '_noopAnimations',
},
templateUrl: 'list-item.html',
encapsulation: ViewEncapsulation.None,
Expand All @@ -69,7 +71,8 @@ export class MatListItem extends MatListItemBase {
ngZone: NgZone,
listBase: MatListBase,
platform: Platform,
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalRippleOptions?: RippleGlobalOptions) {
super(element, ngZone, listBase, platform, globalRippleOptions);
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalRippleOptions?: RippleGlobalOptions,
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string) {
super(element, ngZone, listBase, platform, globalRippleOptions, animationMode);
}
}

0 comments on commit 279461c

Please sign in to comment.