diff --git a/src/lib/core/line/line.ts b/src/lib/core/line/line.ts index 65b2a7490ab..e107df0d140 100644 --- a/src/lib/core/line/line.ts +++ b/src/lib/core/line/line.ts @@ -12,6 +12,7 @@ import { ElementRef, QueryList, } from '@angular/core'; +import {startWith} from 'rxjs/operators'; import {MatCommonModule} from '../common-behaviors/common-module'; @@ -30,38 +31,38 @@ export class MatLine {} * Helper that takes a query list of lines and sets the correct class on the host. * @docs-private */ +export function setLines(lines: QueryList, element: ElementRef) { + // Note: doesn't need to unsubscribe, because `changes` + // gets completed by Angular when the view is destroyed. + lines.changes.pipe(startWith>(lines)).subscribe(({length}) => { + setClass(element, 'mat-2-line', false); + setClass(element, 'mat-3-line', false); + setClass(element, 'mat-multi-line', false); + + if (length === 2 || length === 3) { + setClass(element, `mat-${length}-line`, true); + } else if (length > 3) { + setClass(element, `mat-multi-line`, true); + } + }); +} + +/** Adds or removes a class from an element. */ +function setClass(element: ElementRef, className: string, isAdd: boolean): void { + const classList = element.nativeElement.classList; + isAdd ? classList.add(className) : classList.remove(className); +} + +/** + * Helper that takes a query list of lines and sets the correct class on the host. + * @docs-private + * @deprecated Use `setLines` instead. + * @breaking-change 8.0.0 + */ export class MatLineSetter { - constructor(private _lines: QueryList, private _element: ElementRef) { - this._setLineClass(this._lines.length); - - this._lines.changes.subscribe(() => { - this._setLineClass(this._lines.length); - }); + constructor(lines: QueryList, element: ElementRef) { + setLines(lines, element); } - - private _setLineClass(count: number): void { - this._resetClasses(); - if (count === 2 || count === 3) { - this._setClass(`mat-${count}-line`, true); - } else if (count > 3) { - this._setClass(`mat-multi-line`, true); - } - } - - private _resetClasses(): void { - this._setClass('mat-2-line', false); - this._setClass('mat-3-line', false); - this._setClass('mat-multi-line', false); - } - - private _setClass(className: string, isAdd: boolean): void { - if (isAdd) { - this._element.nativeElement.classList.add(className); - } else { - this._element.nativeElement.classList.remove(className); - } - } - } @NgModule({ diff --git a/src/lib/grid-list/grid-tile.ts b/src/lib/grid-list/grid-tile.ts index c6251fb2a9d..78207edfa04 100644 --- a/src/lib/grid-list/grid-tile.ts +++ b/src/lib/grid-list/grid-tile.ts @@ -19,7 +19,7 @@ import { ChangeDetectionStrategy, Inject, } from '@angular/core'; -import {MatLine, MatLineSetter} from '@angular/material/core'; +import {MatLine, setLines} from '@angular/material/core'; import {coerceNumberProperty} from '@angular/cdk/coercion'; import {MAT_GRID_LIST, MatGridListBase} from './grid-list-base'; @@ -70,17 +70,12 @@ export class MatGridTile { encapsulation: ViewEncapsulation.None, }) export class MatGridTileText implements AfterContentInit { - /** - * Helper that watches the number of lines in a text area and sets - * a class on the host element that matches the line count. - */ - _lineSetter: MatLineSetter; @ContentChildren(MatLine) _lines: QueryList; constructor(private _element: ElementRef) {} ngAfterContentInit() { - this._lineSetter = new MatLineSetter(this._lines, this._element); + setLines(this._lines, this._element); } } diff --git a/src/lib/list/list.ts b/src/lib/list/list.ts index 9dcaab8089b..aa0f0546c1f 100644 --- a/src/lib/list/list.ts +++ b/src/lib/list/list.ts @@ -22,7 +22,7 @@ import { CanDisableRipple, CanDisableRippleCtor, MatLine, - MatLineSetter, + setLines, mixinDisableRipple, } from '@angular/material/core'; @@ -136,9 +136,7 @@ export class MatListItem extends _MatListItemMixinBase implements AfterContentIn } ngAfterContentInit() { - // TODO: consider turning the setter into a function, it doesn't do anything as a class. - // tslint:disable-next-line:no-unused-expression - new MatLineSetter(this._lines, this._element); + setLines(this._lines, this._element); } /** Whether this list item should show a ripple effect when clicked. */ diff --git a/src/lib/list/selection-list.ts b/src/lib/list/selection-list.ts index dccd28866b4..e01f216eec1 100644 --- a/src/lib/list/selection-list.ts +++ b/src/lib/list/selection-list.ts @@ -33,7 +33,7 @@ import { import { CanDisableRipple, CanDisableRippleCtor, MatLine, - MatLineSetter, + setLines, mixinDisableRipple, } from '@angular/material/core'; import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms'; @@ -161,9 +161,7 @@ export class MatListOption extends _MatListOptionMixinBase } ngAfterContentInit() { - // TODO: consider turning the setter into a function, it doesn't do anything as a class. - // tslint:disable-next-line:no-unused-expression - new MatLineSetter(this._lines, this._element); + setLines(this._lines, this._element); } ngOnDestroy(): void {