Skip to content

Commit

Permalink
fix(material-experimental/mdc-list): fix styles for normal lists (#18632
Browse files Browse the repository at this point in the history
)

* fix(material-experimental/mdc-list): fix styles for normal lists

Fixes up various styles for the lists under the "normal lists" section
of the demo. There are still some issues around the avatars and dividers
on the last list

* fix avatars and dividers

* fix lint and api

* address feedback
  • Loading branch information
mmalerba authored Mar 12, 2020
1 parent ddc9fd6 commit dd239dd
Show file tree
Hide file tree
Showing 12 changed files with 216 additions and 63 deletions.
4 changes: 3 additions & 1 deletion .stylelintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<mat-list>
<h3 mat-subheader>Folders</h3>
<div mat-subheader>Folders</div>
<mat-list-item *ngFor="let folder of folders">
<mat-icon mat-list-icon>folder</mat-icon>
<h4 mat-line>{{folder.name}}</h4>
<p mat-line> {{folder.updated | date}} </p>
<div mat-line>{{folder.name}}</div>
<div mat-line> {{folder.updated | date}} </div>
</mat-list-item>
<mat-divider></mat-divider>
<h3 mat-subheader>Notes</h3>
<div mat-subheader>Notes</div>
<mat-list-item *ngFor="let note of notes">
<mat-icon mat-list-icon>note</mat-icon>
<h4 mat-line>{{note.name}}</h4>
<p mat-line> {{note.updated | date}} </p>
<div mat-line>{{note.name}}</div>
<div mat-line> {{note.updated | date}} </div>
</mat-list-item>
</mat-list>
42 changes: 21 additions & 21 deletions src/dev-app/list/list-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,63 +8,63 @@ <h1>mat-list demo</h1>
<h2>Normal lists</h2>

<mat-list>
<h3 mat-subheader>Items</h3>
<div mat-subheader>Items</div>
<mat-list-item *ngFor="let item of items">
{{item}}
</mat-list-item>
</mat-list>

<mat-list>
<mat-list-item *ngFor="let contact of contacts">
<h3 mat-line>{{contact.name}}</h3>
<p mat-line *ngIf="thirdLine">extra line</p>
<p mat-line class="demo-secondary-text">{{contact.headline}}</p>
<div mat-line>{{contact.name}}</div>
<div mat-line *ngIf="thirdLine">extra line</div>
<div mat-line class="demo-secondary-text">{{contact.headline}}</div>
</mat-list-item>
</mat-list>

<mat-list>
<h3 mat-subheader>Today</h3>
<div mat-subheader>Today</div>
<mat-list-item *ngFor="let message of messages; last as last">
<img mat-list-avatar [src]="message.image" alt="Image of {{message.from}}">
<h4 mat-line>{{message.from}}</h4>
<p mat-line>
<div mat-line>{{message.from}}</div>
<div mat-line>
<span>{{message.subject}} -- </span>
<span class="demo-secondary-text">{{message.message}}</span>
</p>
</div>
<mat-divider inset *ngIf="!last"></mat-divider>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item *ngFor="let message of messages">
<h4 mat-line>{{message.from}}</h4>
<p mat-line> {{message.subject}} </p>
<p mat-line class="demo-secondary-text">{{message.message}} </p>
<div mat-line>{{message.from}}</div>
<div mat-line> {{message.subject}} </div>
<div mat-line class="demo-secondary-text">{{message.message}} </div>
</mat-list-item>
</mat-list>
</div>

<div>
<h2>Dense lists</h2>
<mat-list dense>
<h3 mat-subheader>Items</h3>
<div mat-subheader>Items</div>
<mat-list-item *ngFor="let item of items">
{{item}}
</mat-list-item>
</mat-list>

<mat-list dense>
<mat-list-item *ngFor="let contact of contacts">
<h3 mat-line>{{contact.name}}</h3>
<p mat-line class="demo-secondary-text">{{contact.headline}}</p>
<div mat-line>{{contact.name}}</div>
<div mat-line class="demo-secondary-text">{{contact.headline}}</div>
</mat-list-item>
</mat-list>

<mat-list dense>
<h3 mat-subheader>Today</h3>
<div mat-subheader>Today</div>
<mat-list-item *ngFor="let message of messages">
<img mat-list-avatar [src]="message.image" alt="Image of {{message.from}}">
<h4 mat-line>{{message.from}}</h4>
<p mat-line> {{message.subject}} </p>
<p mat-line class="demo-secondary-text">{{message.message}} </p>
<div mat-line>{{message.from}}</div>
<div mat-line> {{message.subject}} </div>
<div mat-line class="demo-secondary-text">{{message.message}} </div>
</mat-list-item>
</mat-list>
</div>
Expand Down Expand Up @@ -122,7 +122,7 @@ <h2>Selection list</h2>
[disabled]="selectionListDisabled"
[disableRipple]="selectionListRippleDisabled"
color="primary">
<h3 mat-subheader>Groceries</h3>
<div mat-subheader>Groceries</div>

<mat-list-option value="bananas" checkboxPosition="before">Bananas</mat-list-option>
<mat-list-option selected value="oranges">Oranges</mat-list-option>
Expand All @@ -131,7 +131,7 @@ <h3 mat-subheader>Groceries</h3>
</mat-selection-list>

<mat-selection-list [disableRipple]="selectionListRippleDisabled">
<h3 mat-subheader>Dogs</h3>
<div mat-subheader>Dogs</div>

<mat-list-option checkboxPosition="before">
<img matListAvatar src="https://material.angular.io/assets/img/examples/shiba1.jpg">
Expand Down Expand Up @@ -170,7 +170,7 @@ <h2>Single Selection list</h2>
[(ngModel)]="favoriteOptions"
[multiple]="false"
color="primary">
<h3 mat-subheader>Favorite Grocery</h3>
<div mat-subheader>Favorite Grocery</div>

<mat-list-option value="bananas">Bananas</mat-list-option>
<mat-list-option selected value="oranges">Oranges</mat-list-option>
Expand Down
40 changes: 20 additions & 20 deletions src/dev-app/mdc-list/mdc-list-demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,63 +8,63 @@ <h1>mat-list demo</h1>
<h2>Normal lists</h2>

<mat-list>
<h3 mat-subheader>Items</h3>
<div mat-subheader>Items</div>
<mat-list-item *ngFor="let item of items">
{{item}}
</mat-list-item>
</mat-list>

<mat-list>
<mat-list-item *ngFor="let contact of contacts">
<h3 mat-line>{{contact.name}}</h3>
<p mat-line *ngIf="thirdLine">extra line</p>
<p mat-line class="demo-secondary-text">{{contact.headline}}</p>
<div mat-line>{{contact.name}}</div>
<div mat-line *ngIf="thirdLine">extra line</div>
<div mat-line>{{contact.headline}}</div>
</mat-list-item>
</mat-list>

<mat-list>
<h3 mat-subheader>Today</h3>
<div mat-subheader>Today</div>
<mat-list-item *ngFor="let message of messages; last as last">
<img mat-list-avatar [src]="message.image" alt="Image of {{message.from}}">
<h4 mat-line>{{message.from}}</h4>
<p mat-line>
<div mat-line>{{message.from}}</div>
<div mat-line>
<span>{{message.subject}} -- </span>
<span class="demo-secondary-text">{{message.message}}</span>
</p>
<span>{{message.message}}</span>
</div>
<mat-divider inset *ngIf="!last"></mat-divider>
</mat-list-item>
<mat-divider></mat-divider>
<mat-list-item *ngFor="let message of messages">
<h4 mat-line>{{message.from}}</h4>
<p mat-line> {{message.subject}} </p>
<p mat-line class="demo-secondary-text">{{message.message}} </p>
<div mat-line>{{message.from}}</div>
<div mat-line>{{message.subject}}</div>
<div mat-line>{{message.message}}</div>
</mat-list-item>
</mat-list>
</div>

<div>
<h2>Dense lists</h2>
<mat-list dense>
<h3 mat-subheader>Items</h3>
<div mat-subheader>Items</div>
<mat-list-item *ngFor="let item of items">
{{item}}
</mat-list-item>
</mat-list>

<mat-list dense>
<mat-list-item *ngFor="let contact of contacts">
<h3 mat-line>{{contact.name}}</h3>
<p mat-line class="demo-secondary-text">{{contact.headline}}</p>
<div mat-line>{{contact.name}}</div>
<div mat-line>{{contact.headline}}</div>
</mat-list-item>
</mat-list>

<mat-list dense>
<h3 mat-subheader>Today</h3>
<div mat-subheader>Today</div>
<mat-list-item *ngFor="let message of messages">
<img mat-list-avatar [src]="message.image" alt="Image of {{message.from}}">
<h4 mat-line>{{message.from}}</h4>
<p mat-line> {{message.subject}} </p>
<p mat-line class="demo-secondary-text">{{message.message}} </p>
<div mat-line>{{message.from}}</div>
<div mat-line> {{message.subject}} </div>
<div mat-line>{{message.message}} </div>
</mat-list-item>
</mat-list>
</div>
Expand All @@ -90,7 +90,7 @@ <h2>Nav lists</h2>
<a mat-list-item *ngFor="let link of links; last as last" href="http://www.google.com">
<mat-icon mat-list-icon>folder</mat-icon>
<span mat-line>{{ link.name }}</span>
<span mat-line class="demo-secondary-text"> Description </span>
<span mat-line> Description </span>
<mat-divider inset *ngIf="!last"></mat-divider>
</a>
</mat-nav-list>
Expand Down
38 changes: 37 additions & 1 deletion src/material-experimental/mdc-list/list-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<ElementRef<Element>>;

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<ElementRef<Element>>) => {
lines.forEach((line: ElementRef<Element>, 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();
}
}
2 changes: 2 additions & 0 deletions src/material-experimental/mdc-list/list-item.html
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
<ng-content select="[mat-list-avatar],[matListAvatar],[mat-list-icon],[matListIcon]"></ng-content>
<span class="mdc-list-item__text"><ng-content></ng-content></span>
<ng-content select="mat-divider"></ng-content>
73 changes: 73 additions & 0 deletions src/material-experimental/mdc-list/list.scss
Original file line number Diff line number Diff line change
@@ -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);
Expand All @@ -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;
}
}
}
Loading

0 comments on commit dd239dd

Please sign in to comment.