diff --git a/.stylelintrc.json b/.stylelintrc.json
index a162e2394e36..cd68ab6a477d 100644
--- a/.stylelintrc.json
+++ b/.stylelintrc.json
@@ -87,7 +87,9 @@
"selector-max-id": 0,
"no-missing-end-of-source-newline": true,
"no-eol-whitespace": true,
- "max-line-length": 100,
+ "max-line-length": [100, {
+ "ignorePattern": "/https?://.*/"
+ }],
"linebreaks": "unix",
"selector-class-pattern": ["^_?(mat-|cdk-|example-|demo-|ng-|mdc-|map-)", {
"resolveNestedSelectors": true
diff --git a/src/components-examples/material/list/list-sections/list-sections-example.html b/src/components-examples/material/list/list-sections/list-sections-example.html
index ecb32bb2e8e6..935f0e77178a 100644
--- a/src/components-examples/material/list/list-sections/list-sections-example.html
+++ b/src/components-examples/material/list/list-sections/list-sections-example.html
@@ -1,15 +1,15 @@
- Folders
+ Folders
folder
- {{folder.name}}
- {{folder.updated | date}}
+ {{folder.name}}
+ {{folder.updated | date}}
- Notes
+ Notes
note
- {{note.name}}
- {{note.updated | date}}
+ {{note.name}}
+ {{note.updated | date}}
diff --git a/src/dev-app/list/list-demo.html b/src/dev-app/list/list-demo.html
index 83918a690db0..b238517189eb 100644
--- a/src/dev-app/list/list-demo.html
+++ b/src/dev-app/list/list-demo.html
@@ -8,7 +8,7 @@
mat-list demo
Normal lists
- Items
+ Items
{{item}}
@@ -16,28 +16,28 @@ Items
- {{contact.name}}
- extra line
- {{contact.headline}}
+ {{contact.name}}
+ extra line
+ {{contact.headline}}
- Today
+ Today
- {{message.from}}
-
+
{{message.from}}
+
{{message.subject}} --
{{message.message}}
-
+
- {{message.from}}
- {{message.subject}}
- {{message.message}}
+ {{message.from}}
+ {{message.subject}}
+ {{message.message}}
@@ -45,7 +45,7 @@ {{message.from}}
Dense lists
- Items
+ Items
{{item}}
@@ -53,18 +53,18 @@ Items
- {{contact.name}}
- {{contact.headline}}
+ {{contact.name}}
+ {{contact.headline}}
- Today
+ Today
- {{message.from}}
- {{message.subject}}
- {{message.message}}
+ {{message.from}}
+ {{message.subject}}
+ {{message.message}}
@@ -122,7 +122,7 @@ Selection list
[disabled]="selectionListDisabled"
[disableRipple]="selectionListRippleDisabled"
color="primary">
- Groceries
+ Groceries
Bananas
Oranges
@@ -131,7 +131,7 @@ Groceries
- Dogs
+ Dogs
@@ -170,7 +170,7 @@ Single Selection list
[(ngModel)]="favoriteOptions"
[multiple]="false"
color="primary">
- Favorite Grocery
+ Favorite Grocery
Bananas
Oranges
diff --git a/src/dev-app/mdc-list/mdc-list-demo.html b/src/dev-app/mdc-list/mdc-list-demo.html
index 80fe14661e23..83cbb5ed2020 100644
--- a/src/dev-app/mdc-list/mdc-list-demo.html
+++ b/src/dev-app/mdc-list/mdc-list-demo.html
@@ -8,7 +8,7 @@ mat-list demo
Normal lists
- Items
+ Items
{{item}}
@@ -16,28 +16,28 @@ Items
- {{contact.name}}
- extra line
- {{contact.headline}}
+ {{contact.name}}
+ extra line
+ {{contact.headline}}
- Today
+ Today
- {{message.from}}
-
+
{{message.from}}
+
{{message.subject}} --
- {{message.message}}
-
+ {{message.message}}
+
- {{message.from}}
- {{message.subject}}
- {{message.message}}
+ {{message.from}}
+ {{message.subject}}
+ {{message.message}}
@@ -45,7 +45,7 @@ {{message.from}}
Dense lists
- Items
+ Items
{{item}}
@@ -53,18 +53,18 @@ Items
- {{contact.name}}
- {{contact.headline}}
+ {{contact.name}}
+ {{contact.headline}}
- Today
+ Today
- {{message.from}}
- {{message.subject}}
- {{message.message}}
+ {{message.from}}
+ {{message.subject}}
+ {{message.message}}
@@ -90,7 +90,7 @@ Nav lists
folder
{{ link.name }}
- Description
+ Description
diff --git a/src/material-experimental/mdc-list/list-base.ts b/src/material-experimental/mdc-list/list-base.ts
index 1c42e8a22378..a233d777b733 100644
--- a/src/material-experimental/mdc-list/list-base.ts
+++ b/src/material-experimental/mdc-list/list-base.ts
@@ -6,6 +6,42 @@
* found in the LICENSE file at https://angular.io/license
*/
+import {AfterContentInit, ElementRef, NgZone, OnDestroy, QueryList} from '@angular/core';
+import {setLines} from '@angular/material/core';
+import {Subscription} from 'rxjs';
+import {startWith} from 'rxjs/operators';
+
export class MatListBase {}
-export class MatListItemBase {}
+export class MatListItemBase implements AfterContentInit, OnDestroy {
+ lines: QueryList>;
+
+ private _subscriptions = new Subscription();
+
+ constructor(protected _element: ElementRef, protected _ngZone: NgZone) {}
+
+ ngAfterContentInit() {
+ this._monitorLines();
+ }
+
+ /**
+ * Subscribes to changes in `MatLine` content children and annotates them appropriately when they
+ * change.
+ */
+ private _monitorLines() {
+ this._ngZone.runOutsideAngular(() => {
+ this._subscriptions.add(this.lines.changes.pipe(startWith(this.lines))
+ .subscribe((lines: QueryList>) => {
+ lines.forEach((line: ElementRef, index: number) => {
+ line.nativeElement.classList.toggle('mdc-list-item__primary-text', index === 0);
+ line.nativeElement.classList.toggle('mdc-list-item__secondary-text', index !== 0);
+ });
+ setLines(lines, this._element, 'mat-mdc');
+ }));
+ });
+ }
+
+ ngOnDestroy() {
+ this._subscriptions.unsubscribe();
+ }
+}
diff --git a/src/material-experimental/mdc-list/list-item.html b/src/material-experimental/mdc-list/list-item.html
index 91b88fdf57fa..fbaeab2cecaa 100644
--- a/src/material-experimental/mdc-list/list-item.html
+++ b/src/material-experimental/mdc-list/list-item.html
@@ -1 +1,3 @@
+
+
diff --git a/src/material-experimental/mdc-list/list.scss b/src/material-experimental/mdc-list/list.scss
index efba495ceb33..e08b039b73e7 100644
--- a/src/material-experimental/mdc-list/list.scss
+++ b/src/material-experimental/mdc-list/list.scss
@@ -1,4 +1,5 @@
@import '@material/list/mixins.import';
+@import '@material/list/variables.import';
@import '../mdc-helpers/mdc-helpers';
@include mdc-list-without-ripple($query: $mat-base-styles-query);
@@ -8,3 +9,75 @@
.mat-mdc-list-base {
display: block;
}
+
+// .mdc-list-item__primary-text adds its own margin settings, so only reset if it doesn't have that
+// class
+.mat-mdc-list-base .mdc-list-item__text > :not(.mdc-list-item__primary-text),
+.mat-mdc-list-base .mdc-list-item__text > :not(.mdc-list-item__primary-text) {
+ margin: 0;
+
+ // Fixes the gap between the 2nd & 3rd lines.
+ &.mdc-list-item__secondary-text {
+ margin-top: -3px;
+ }
+}
+
+
+// MDC does have 2-line support, but it's a per-list setting, whereas ours applies to individual
+// items. Therefore, we need to add our own styles.
+.mat-mdc-2-line {
+ height: 72px;
+
+ .mdc-list-item__text {
+ align-self: flex-start;
+ }
+}
+
+// MDC does not support more than 2 lines, so we need to add our own styles.
+.mat-mdc-3-line {
+ height: 88px;
+
+ .mdc-list-item__text {
+ align-self: flex-start;
+ }
+}
+
+// MDC supports avatars, but it's a per-list setting, whereas ours applies to individual
+// items. Therefore, we need to add our own styles.
+.mat-mdc-list-avatar {
+ // Styles here come from `$mdc-list-graphic-size_`:
+ // https://github.com/material-components/material-components-web/blob/3ca8c4c45a3d2a654ef3cb8fc7525bcde37badf0/packages/mdc-list/_mixins.scss#L538
+ $size: 40px;
+ $margin-value: 72px - $mdc-list-side-padding - $size;
+
+ margin-left: 0;
+ margin-right: $margin-value;
+ width: $size;
+ height: $size;
+ border-radius: 50%;
+
+ // `.mdc-list-item` added for extra specificity to override MDC's built in styles.
+ [dir='rtl'] .mdc-list-item & {
+ margin-left: $margin-value;
+ margin-right: 0;
+ }
+}
+
+// MDC doesn't have list dividers, so we use mat-divider and style appropriately.
+.mat-mdc-list-item,
+.mat-mdc-list-option {
+ .mat-divider-inset {
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ }
+
+ .mat-mdc-list-avatar ~ .mat-divider-inset {
+ margin-left: 72px;
+
+ [dir='rtl'] & {
+ margin-right: 72px;
+ }
+ }
+}
diff --git a/src/material-experimental/mdc-list/list.ts b/src/material-experimental/mdc-list/list.ts
index cc0d4c205cfb..343ca498420b 100644
--- a/src/material-experimental/mdc-list/list.ts
+++ b/src/material-experimental/mdc-list/list.ts
@@ -6,7 +6,17 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {ChangeDetectionStrategy, Component, Directive, ViewEncapsulation} from '@angular/core';
+import {
+ ChangeDetectionStrategy,
+ Component,
+ ContentChildren,
+ Directive,
+ ElementRef,
+ NgZone,
+ QueryList,
+ ViewEncapsulation
+} from '@angular/core';
+import {MatLine} from '@angular/material/core';
import {MatListBase, MatListItemBase} from './list-base';
/**
@@ -15,7 +25,7 @@ import {MatListBase, MatListItemBase} from './list-base';
*/
@Directive({
selector: '[mat-list-avatar], [matListAvatar]',
- host: {'class': 'mat-mdc-list-avatar'}
+ host: {'class': 'mat-mdc-list-avatar mdc-list-item__graphic'}
})
export class MatListAvatarCssMatStyler {}
@@ -25,7 +35,7 @@ export class MatListAvatarCssMatStyler {}
*/
@Directive({
selector: '[mat-list-icon], [matListIcon]',
- host: {'class': 'mat-mdc-list-icon'}
+ host: {'class': 'mat-mdc-list-icon mdc-list-item__graphic'}
})
export class MatListIconCssMatStyler {}
@@ -35,7 +45,9 @@ export class MatListIconCssMatStyler {}
*/
@Directive({
selector: '[mat-subheader], [matSubheader]',
- host: {'class': 'mat-mdc-subheader'}
+ // TODO(mmalerba): MDC's subheader font looks identical to the list item font, figure out why and
+ // make a change in one of the repos to visually distinguish.
+ host: {'class': 'mat-mdc-subheader mdc-list-group__subheader'}
})
export class MatListSubheaderCssMatStyler {}
@@ -62,4 +74,11 @@ export class MatList extends MatListBase {}
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class MatListItem extends MatListItemBase {}
+export class MatListItem extends MatListItemBase {
+ @ContentChildren(MatLine, {read: ElementRef, descendants: true}) lines:
+ QueryList>;
+
+ constructor(element: ElementRef, ngZone: NgZone) {
+ super(element, ngZone);
+ }
+}
diff --git a/src/material-experimental/mdc-list/module.ts b/src/material-experimental/mdc-list/module.ts
index dd26e817da30..081a23ba2cf6 100644
--- a/src/material-experimental/mdc-list/module.ts
+++ b/src/material-experimental/mdc-list/module.ts
@@ -7,6 +7,7 @@
*/
import {NgModule} from '@angular/core';
+import {MatLineModule} from '@angular/material/core';
import {MatDividerModule} from '@angular/material/divider';
import {MatActionList} from './action-list';
import {
@@ -20,6 +21,7 @@ import {MatNavList} from './nav-list';
import {MatListOption, MatSelectionList} from './selection-list';
@NgModule({
+ imports: [MatLineModule],
exports: [
MatList,
MatActionList,
@@ -31,6 +33,7 @@ import {MatListOption, MatSelectionList} from './selection-list';
MatListIconCssMatStyler,
MatListSubheaderCssMatStyler,
MatDividerModule,
+ MatLineModule,
],
declarations: [
MatList,
diff --git a/src/material-experimental/mdc-list/selection-list.ts b/src/material-experimental/mdc-list/selection-list.ts
index ea725da19ce2..f42aa9384420 100644
--- a/src/material-experimental/mdc-list/selection-list.ts
+++ b/src/material-experimental/mdc-list/selection-list.ts
@@ -6,8 +6,18 @@
* found in the LICENSE file at https://angular.io/license
*/
-import {ChangeDetectionStrategy, Component, forwardRef, ViewEncapsulation} from '@angular/core';
+import {
+ ChangeDetectionStrategy,
+ Component,
+ ContentChildren,
+ ElementRef,
+ forwardRef,
+ NgZone,
+ QueryList,
+ ViewEncapsulation
+} from '@angular/core';
import {NG_VALUE_ACCESSOR} from '@angular/forms';
+import {MatLine} from '@angular/material/core';
import {MatListBase, MatListItemBase} from './list-base';
const MAT_SELECTION_LIST_VALUE_ACCESSOR: any = {
@@ -49,4 +59,11 @@ export class MatSelectionList extends MatListBase {}
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
})
-export class MatListOption extends MatListItemBase {}
+export class MatListOption extends MatListItemBase {
+ @ContentChildren(MatLine, {read: ElementRef, descendants: true}) lines:
+ QueryList>;
+
+ constructor(element: ElementRef, ngZone: NgZone) {
+ super(element, ngZone);
+ }
+}
diff --git a/src/material/core/line/line.ts b/src/material/core/line/line.ts
index 724a1dfe1226..33888dd858e2 100644
--- a/src/material/core/line/line.ts
+++ b/src/material/core/line/line.ts
@@ -31,18 +31,19 @@ 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) {
+export function setLines(lines: QueryList, element: ElementRef,
+ prefix = 'mat') {
// 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);
+ setClass(element, `${prefix}-2-line`, false);
+ setClass(element, `${prefix}-3-line`, false);
+ setClass(element, `${prefix}-multi-line`, false);
if (length === 2 || length === 3) {
- setClass(element, `mat-${length}-line`, true);
+ setClass(element, `${prefix}-${length}-line`, true);
} else if (length > 3) {
- setClass(element, `mat-multi-line`, true);
+ setClass(element, `${prefix}-multi-line`, true);
}
});
}
diff --git a/tools/public_api_guard/material/core.d.ts b/tools/public_api_guard/material/core.d.ts
index 28990691207f..61775aa88254 100644
--- a/tools/public_api_guard/material/core.d.ts
+++ b/tools/public_api_guard/material/core.d.ts
@@ -457,7 +457,7 @@ export declare type SanityChecks = boolean | GranularSanityChecks;
export declare const JAN = 0, FEB = 1, MAR = 2, APR = 3, MAY = 4, JUN = 5, JUL = 6, AUG = 7, SEP = 8, OCT = 9, NOV = 10, DEC = 11;
-export declare function setLines(lines: QueryList, element: ElementRef): void;
+export declare function setLines(lines: QueryList, element: ElementRef, prefix?: string): void;
export declare class ShowOnDirtyErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean;