diff --git a/package.json b/package.json index a8da1645b367..95afbc651d38 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "@types/googlemaps": "^3.43.1", "@types/youtube": "^0.0.42", "core-js-bundle": "^3.8.2", - "material-components-web": "^12.0.0-canary.a23ecb682.0", + "material-components-web": "^12.0.0-canary.00b5899dc.0", "rxjs": "^6.5.3", "rxjs-tslint-rules": "^4.33.1", "systemjs": "0.19.43", @@ -95,53 +95,53 @@ "@bazel/terser": "3.5.0", "@bazel/typescript": "3.5.0", "@firebase/app-types": "^0.6.1", - "@material/animation": "^12.0.0-canary.a23ecb682.0", - "@material/auto-init": "^12.0.0-canary.a23ecb682.0", - "@material/banner": "^12.0.0-canary.a23ecb682.0", - "@material/base": "^12.0.0-canary.a23ecb682.0", - "@material/button": "^12.0.0-canary.a23ecb682.0", - "@material/card": "^12.0.0-canary.a23ecb682.0", - "@material/checkbox": "^12.0.0-canary.a23ecb682.0", - "@material/chips": "^12.0.0-canary.a23ecb682.0", - "@material/circular-progress": "^12.0.0-canary.a23ecb682.0", - "@material/data-table": "^12.0.0-canary.a23ecb682.0", - "@material/density": "^12.0.0-canary.a23ecb682.0", - "@material/dialog": "^12.0.0-canary.a23ecb682.0", - "@material/dom": "^12.0.0-canary.a23ecb682.0", - "@material/drawer": "^12.0.0-canary.a23ecb682.0", - "@material/elevation": "^12.0.0-canary.a23ecb682.0", - "@material/fab": "^12.0.0-canary.a23ecb682.0", - "@material/feature-targeting": "^12.0.0-canary.a23ecb682.0", - "@material/floating-label": "^12.0.0-canary.a23ecb682.0", - "@material/form-field": "^12.0.0-canary.a23ecb682.0", - "@material/icon-button": "^12.0.0-canary.a23ecb682.0", - "@material/image-list": "^12.0.0-canary.a23ecb682.0", - "@material/layout-grid": "^12.0.0-canary.a23ecb682.0", - "@material/line-ripple": "^12.0.0-canary.a23ecb682.0", - "@material/linear-progress": "^12.0.0-canary.a23ecb682.0", - "@material/list": "^12.0.0-canary.a23ecb682.0", - "@material/menu": "^12.0.0-canary.a23ecb682.0", - "@material/menu-surface": "^12.0.0-canary.a23ecb682.0", - "@material/notched-outline": "^12.0.0-canary.a23ecb682.0", - "@material/radio": "^12.0.0-canary.a23ecb682.0", - "@material/ripple": "^12.0.0-canary.a23ecb682.0", - "@material/rtl": "^12.0.0-canary.a23ecb682.0", - "@material/segmented-button": "^12.0.0-canary.a23ecb682.0", - "@material/select": "^12.0.0-canary.a23ecb682.0", - "@material/shape": "^12.0.0-canary.a23ecb682.0", - "@material/slider": "^12.0.0-canary.a23ecb682.0", - "@material/snackbar": "^12.0.0-canary.a23ecb682.0", - "@material/switch": "^12.0.0-canary.a23ecb682.0", - "@material/tab": "^12.0.0-canary.a23ecb682.0", - "@material/tab-bar": "^12.0.0-canary.a23ecb682.0", - "@material/tab-indicator": "^12.0.0-canary.a23ecb682.0", - "@material/tab-scroller": "^12.0.0-canary.a23ecb682.0", - "@material/textfield": "^12.0.0-canary.a23ecb682.0", - "@material/theme": "^12.0.0-canary.a23ecb682.0", - "@material/tooltip": "^12.0.0-canary.a23ecb682.0", - "@material/top-app-bar": "^12.0.0-canary.a23ecb682.0", - "@material/touch-target": "^12.0.0-canary.a23ecb682.0", - "@material/typography": "^12.0.0-canary.a23ecb682.0", + "@material/animation": "^12.0.0-canary.00b5899dc.0", + "@material/auto-init": "^12.0.0-canary.00b5899dc.0", + "@material/banner": "^12.0.0-canary.00b5899dc.0", + "@material/base": "^12.0.0-canary.00b5899dc.0", + "@material/button": "^12.0.0-canary.00b5899dc.0", + "@material/card": "^12.0.0-canary.00b5899dc.0", + "@material/checkbox": "^12.0.0-canary.00b5899dc.0", + "@material/chips": "^12.0.0-canary.00b5899dc.0", + "@material/circular-progress": "^12.0.0-canary.00b5899dc.0", + "@material/data-table": "^12.0.0-canary.00b5899dc.0", + "@material/density": "^12.0.0-canary.00b5899dc.0", + "@material/dialog": "^12.0.0-canary.00b5899dc.0", + "@material/dom": "^12.0.0-canary.00b5899dc.0", + "@material/drawer": "^12.0.0-canary.00b5899dc.0", + "@material/elevation": "^12.0.0-canary.00b5899dc.0", + "@material/fab": "^12.0.0-canary.00b5899dc.0", + "@material/feature-targeting": "^12.0.0-canary.00b5899dc.0", + "@material/floating-label": "^12.0.0-canary.00b5899dc.0", + "@material/form-field": "^12.0.0-canary.00b5899dc.0", + "@material/icon-button": "^12.0.0-canary.00b5899dc.0", + "@material/image-list": "^12.0.0-canary.00b5899dc.0", + "@material/layout-grid": "^12.0.0-canary.00b5899dc.0", + "@material/line-ripple": "^12.0.0-canary.00b5899dc.0", + "@material/linear-progress": "^12.0.0-canary.00b5899dc.0", + "@material/list": "^12.0.0-canary.00b5899dc.0", + "@material/menu": "^12.0.0-canary.00b5899dc.0", + "@material/menu-surface": "^12.0.0-canary.00b5899dc.0", + "@material/notched-outline": "^12.0.0-canary.00b5899dc.0", + "@material/radio": "^12.0.0-canary.00b5899dc.0", + "@material/ripple": "^12.0.0-canary.00b5899dc.0", + "@material/rtl": "^12.0.0-canary.00b5899dc.0", + "@material/segmented-button": "^12.0.0-canary.00b5899dc.0", + "@material/select": "^12.0.0-canary.00b5899dc.0", + "@material/shape": "^12.0.0-canary.00b5899dc.0", + "@material/slider": "^12.0.0-canary.00b5899dc.0", + "@material/snackbar": "^12.0.0-canary.00b5899dc.0", + "@material/switch": "^12.0.0-canary.00b5899dc.0", + "@material/tab": "^12.0.0-canary.00b5899dc.0", + "@material/tab-bar": "^12.0.0-canary.00b5899dc.0", + "@material/tab-indicator": "^12.0.0-canary.00b5899dc.0", + "@material/tab-scroller": "^12.0.0-canary.00b5899dc.0", + "@material/textfield": "^12.0.0-canary.00b5899dc.0", + "@material/theme": "^12.0.0-canary.00b5899dc.0", + "@material/tooltip": "^12.0.0-canary.00b5899dc.0", + "@material/top-app-bar": "^12.0.0-canary.00b5899dc.0", + "@material/touch-target": "^12.0.0-canary.00b5899dc.0", + "@material/typography": "^12.0.0-canary.00b5899dc.0", "@octokit/rest": "18.3.5", "@rollup/plugin-babel": "^5.3.0", "@rollup/plugin-commonjs": "^18.0.0", diff --git a/packages.bzl b/packages.bzl index 378f3b6db6a2..e2e56ebf586b 100644 --- a/packages.bzl +++ b/packages.bzl @@ -2,7 +2,7 @@ # all in-sync. This map is passed to each ng_package rule to stamp out the appropriate # version for the placeholders. ANGULAR_PACKAGE_VERSION = "^12.0.0 || ^13.0.0-0" -MDC_PACKAGE_VERSION = "^12.0.0-canary.a23ecb682.0" +MDC_PACKAGE_VERSION = "^12.0.0-canary.00b5899dc.0" TSLIB_PACKAGE_VERSION = "^2.1.0" RXJS_PACKAGE_VERSION = "^6.5.3" diff --git a/src/dev-app/list/list-demo.ts b/src/dev-app/list/list-demo.ts index 42a691b852ed..34aeb757fb69 100644 --- a/src/dev-app/list/list-demo.ts +++ b/src/dev-app/list/list-demo.ts @@ -35,13 +35,13 @@ export class ListDemo { from: 'Nancy', subject: 'Brunch?', message: 'Did you want to go on Sunday? I was thinking that might work.', - image: 'https://angular.io/generated/images/bios/julie-ralph.jpg' + image: 'https://angular.io/generated/images/bios/cindygreenekaplan.jpg' }, { from: 'Mary', subject: 'Summer BBQ', message: 'Wish I could come, but I have some prior obligations.', - image: 'https://angular.io/generated/images/bios/juleskremer.jpg' + image: 'https://angular.io/generated/images/bios/twerske.jpg' }, { from: 'Bobby', diff --git a/src/dev-app/mdc-list/mdc-list-demo.ts b/src/dev-app/mdc-list/mdc-list-demo.ts index 4863acbe50e0..7a3e62d175d5 100644 --- a/src/dev-app/mdc-list/mdc-list-demo.ts +++ b/src/dev-app/mdc-list/mdc-list-demo.ts @@ -35,13 +35,13 @@ export class MdcListDemo { from: 'Nancy', subject: 'Brunch?', message: 'Did you want to go on Sunday? I was thinking that might work.', - image: 'https://angular.io/generated/images/bios/julie-ralph.jpg' + image: 'https://angular.io/generated/images/bios/cindygreenekaplan.jpg' }, { from: 'Mary', subject: 'Summer BBQ', message: 'Wish I could come, but I have some prior obligations.', - image: 'https://angular.io/generated/images/bios/juleskremer.jpg' + image: 'https://angular.io/generated/images/bios/twerske.jpg' }, { from: 'Bobby', diff --git a/src/material-experimental/mdc-list/BUILD.bazel b/src/material-experimental/mdc-list/BUILD.bazel index 9b4ecfdf6029..a2aa591e7c94 100644 --- a/src/material-experimental/mdc-list/BUILD.bazel +++ b/src/material-experimental/mdc-list/BUILD.bazel @@ -66,6 +66,7 @@ sass_binary( "external/npm/node_modules", ], deps = [ + ":mdc_list_scss_lib", "//src/material-experimental/mdc-helpers:mdc_helpers_scss_lib", "//src/material-experimental/mdc-helpers:mdc_scss_deps_lib", ], diff --git a/src/material-experimental/mdc-list/_interactive-list-theme.scss b/src/material-experimental/mdc-list/_interactive-list-theme.scss index 84135ba60947..82be8905608c 100644 --- a/src/material-experimental/mdc-list/_interactive-list-theme.scss +++ b/src/material-experimental/mdc-list/_interactive-list-theme.scss @@ -6,29 +6,29 @@ // has integrated styles for these states but relies on their complex ripples for it. @mixin private-interactive-list-item-state-colors($config) { $is-dark-theme: map.get($config, is-dark); - $state-opacities: - if($is-dark-theme, mdc-ripple.$light-ink-opacities, mdc-ripple.$dark-ink-opacities); + $active-base-color: if($is-dark-theme, white, black); + $selected-color: theming.get-color-from-palette(map.get($config, primary)); .mat-mdc-list-item-interactive { &::before { - background: if($is-dark-theme, white, black); + background: $active-base-color; } - &.mdc-deprecated-list-item--selected::before { - background: theming.get-color-from-palette(map.get($config, primary)); - opacity: map.get($state-opacities, selected); + &.mdc-list-item--selected::before { + background: $selected-color; + opacity: mdc-ripple.states-opacity($selected-color, selected); } &:focus::before { - opacity: map.get($state-opacities, focus); + opacity: mdc-ripple.states-opacity($active-base-color, focus); } } - // MDC still shows focus/selected state if the option is disabled. Just the hover - // styles should not show up. - .mat-mdc-list-item-interactive:not(.mdc-deprecated-list-item--disabled) { + // MDC still shows focus/selected state if the item is disabled. + // Just hover styles should not show up for disabled items. + .mat-mdc-list-item-interactive:not(.mdc-list-item--disabled) { &:hover::before { - opacity: map.get($state-opacities, hover); + opacity: mdc-ripple.states-opacity($active-base-color, hover); } } } diff --git a/src/material-experimental/mdc-list/_list-option-theme.scss b/src/material-experimental/mdc-list/_list-option-theme.scss index 642ad8e0dfca..031af6384ace 100644 --- a/src/material-experimental/mdc-list/_list-option-theme.scss +++ b/src/material-experimental/mdc-list/_list-option-theme.scss @@ -1,41 +1,27 @@ -@use '@material/theme/theme' as mdc-theme; @use '@material/checkbox' as mdc-checkbox; -@use '@material/list' as mdc-list; @use '../mdc-checkbox/checkbox-theme'; @use '../mdc-helpers/mdc-helpers'; - +@use './list-option-trailing-avatar-compat'; // Mixin that overrides the selected item and checkbox colors for list options. By // default, the MDC list uses the `primary` color for list items. The MDC checkbox // inside list options by default uses the `primary` color too. @mixin private-list-option-color-override($color) { - & .mdc-deprecated-list-item__meta, & .mdc-deprecated-list-item__graphic { + & .mdc-list-item__start, & .mdc-list-item__end { @include checkbox-theme.private-checkbox-styles-with-color($color); } - - &.mdc-deprecated-list-item--selected { - @include mdc-list.deprecated-item-primary-text-ink-color($color); - @include mdc-list.deprecated-item-graphic-ink-color($color); - - &::before { - @include mdc-theme.prop(background, $color); - } - } } @mixin private-list-option-density-styles($density-scale) { - .mat-mdc-list-option { - .mdc-deprecated-list-item__meta, .mdc-deprecated-list-item__graphic { - .mdc-checkbox { - @include mdc-checkbox.density($density-scale, $query: mdc-helpers.$mat-base-styles-query); - } - } - } + @include list-option-trailing-avatar-compat.density-styles($density-scale); } @mixin private-list-option-typography-styles() { + @include list-option-trailing-avatar-compat.core-styles( + $query: mdc-helpers.$mat-typography-styles-query); + .mat-mdc-list-option { - .mdc-deprecated-list-item__meta, .mdc-deprecated-list-item__graphic { + .mdc-list-item__start, .mdc-list-item__end { @include mdc-checkbox.without-ripple($query: mdc-helpers.$mat-typography-styles-query); } } diff --git a/src/material-experimental/mdc-list/_list-option-trailing-avatar-compat.scss b/src/material-experimental/mdc-list/_list-option-trailing-avatar-compat.scss new file mode 100644 index 000000000000..24c84560b408 --- /dev/null +++ b/src/material-experimental/mdc-list/_list-option-trailing-avatar-compat.scss @@ -0,0 +1,53 @@ +@use '@material/typography/typography'; +@use '@material/feature-targeting/feature-targeting'; +@use '@material/density/functions' as density-functions; +@use '@material/list/evolution-mixins' as mdc-list; +@use '@material/list/evolution-variables' as mdc-list-variables; + +// For compatibility with the non-MDC selection list, we support avatars that are +// shown at the end of the list option. This is not supported by the MDC list as the +// spec only defines avatars at the beginning of a list item. For selection list options, +// we support changing the checkbox position to `before`. This results in the avatar from +// the list start being moved to the end. Similar to MDC's `--trailing-icon` class, we +// implement a `--trailing-avatar` class that is based on the original `--leading-avatar` +// implementation. See: https://github.com/material-components/material-components-web/blob/3f342c3f4715fd3587f327ce4ea6b5dd314c5c55/packages/mdc-list/_evolution-mixins.scss#L198-L217 + +@mixin core-styles($query) { + $feat-structure: feature-targeting.create-target($query, structure); + + .mat-mdc-list-option-with-trailing-avatar { + @include mdc-list.item-end-spacing(16px, $query: $query); + @include mdc-list.item-end-size(40px, $query: $query); + + &.mdc-list-item--with-two-lines { + .mdc-list-item__primary-text { + @include typography.text-baseline($top: 32px, $bottom: 20px, $query: $query); + } + } + + .mdc-list-item__end { + @include feature-targeting.targets($feat-structure) { + border-radius: 50%; + } + } + } +} + +@mixin density-styles($density-scale) { + $one-line-tall-height: density-functions.prop-value( + $density-config: mdc-list-variables.$one-line-item-tall-density-config, + $density-scale: $density-scale, + $property-name: height, + ); + + $two-line-tall-height: density-functions.prop-value( + $density-config: mdc-list-variables.$two-line-item-tall-density-config, + $density-scale: $density-scale, + $property-name: height, + ); + + .mat-mdc-list-option-with-trailing-avatar { + @include mdc-list.one-line-item-height($one-line-tall-height); + @include mdc-list.two-line-item-height($two-line-tall-height); + } +} diff --git a/src/material-experimental/mdc-list/_list-theme.scss b/src/material-experimental/mdc-list/_list-theme.scss index bb5e33b9fb8b..ac1eea9c964b 100644 --- a/src/material-experimental/mdc-list/_list-theme.scss +++ b/src/material-experimental/mdc-list/_list-theme.scss @@ -1,5 +1,4 @@ -@use '@material/density' as mdc-density; -@use '@material/list' as mdc-list; +@use '@material/list/evolution-mixins' as mdc-list; @use './interactive-list-theme'; @use './list-option-theme'; @use '../mdc-helpers/mdc-helpers'; @@ -18,7 +17,7 @@ @include interactive-list-theme.private-interactive-list-item-state-colors($config); @include mdc-helpers.mat-using-mdc-theme($config) { - @include mdc-list.deprecated-without-ripple($query: mdc-helpers.$mat-theme-styles-query); + @include mdc-list.without-ripple($query: mdc-helpers.$mat-theme-styles-query); .mat-mdc-list-option { @include list-option-theme.private-list-option-color-override(primary); @@ -34,19 +33,11 @@ @mixin density($config-or-theme) { $density-scale: theming.get-density-config($config-or-theme); - $height: mdc-density.prop-value( - $density-config: mdc-list.$deprecated-single-line-density-config, - $density-scale: $density-scale, - $property-name: height, - ); - // MDC list provides a mixin called `mdc-list-single-line-density`, but we cannot use - // that mixin, as the generated generated density styles are scoped to - // `.mdc-deprecated-list-item`, while the styles should actually only affect single-line list - // items. This has been reported as a bug in the MDC repository: - // https://github.com/material-components/material-components-web/issues/5737. - .mat-mdc-list-item-single-line { - @include mdc-list.deprecated-single-line-height($height); + .mat-mdc-list-item { + @include mdc-list.one-line-item-density($density-scale); + @include mdc-list.two-line-item-density($density-scale); + @include mdc-list.three-line-item-density($density-scale); } @include list-option-theme.private-list-option-density-styles($density-scale); @@ -56,7 +47,7 @@ $config: typography.private-typography-to-2018-config( theming.get-typography-config($config-or-theme)); @include mdc-helpers.mat-using-mdc-typography($config) { - @include mdc-list.deprecated-without-ripple($query: mdc-helpers.$mat-typography-styles-query); + @include mdc-list.without-ripple($query: mdc-helpers.$mat-typography-styles-query); @include list-option-theme.private-list-option-typography-styles(); } } diff --git a/src/material-experimental/mdc-list/action-list.ts b/src/material-experimental/mdc-list/action-list.ts index ed7f2df7d925..44cfd7639330 100644 --- a/src/material-experimental/mdc-list/action-list.ts +++ b/src/material-experimental/mdc-list/action-list.ts @@ -14,7 +14,7 @@ import {MatListBase} from './list-base'; exportAs: 'matActionList', template: '', host: { - 'class': 'mat-mdc-action-list mat-mdc-list-base mdc-deprecated-list', + 'class': 'mat-mdc-action-list mat-mdc-list-base mdc--list', }, styleUrls: ['list.css'], encapsulation: ViewEncapsulation.None, diff --git a/src/material-experimental/mdc-list/list-base.ts b/src/material-experimental/mdc-list/list-base.ts index dc3564ca38fe..c36b585db02c 100644 --- a/src/material-experimental/mdc-list/list-base.ts +++ b/src/material-experimental/mdc-list/list-base.ts @@ -65,7 +65,6 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri private _disableRipple: boolean = false; /** Whether the list-item is disabled. */ - @HostBinding('class.mdc-deprecated-list-item--disabled') @HostBinding('class.mdc-list-item--disabled') @HostBinding('attr.aria-disabled') @Input() @@ -155,11 +154,17 @@ export abstract class MatListItemBase implements AfterContentInit, OnDestroy, Ri this._subscriptions.add(this.lines.changes.pipe(startWith(this.lines)) .subscribe((lines: QueryList>) => { toggleClass(this._hostElement, 'mat-mdc-list-item-single-line', lines.length <= 1); + toggleClass(this._hostElement, 'mdc-list-item--with-one-line', lines.length <= 1); + lines.forEach((line: ElementRef, index: number) => { + toggleClass( + this._hostElement, 'mdc-list-item--with-two-lines', lines.length === 2); + toggleClass( + this._hostElement, 'mdc-list-item--with-three-lines', lines.length === 3); toggleClass(line.nativeElement, - 'mdc-deprecated-list-item__primary-text', index === 0 && lines.length > 1); + 'mdc-list-item__primary-text', index === 0 && lines.length > 1); toggleClass( - line.nativeElement, 'mdc-deprecated-list-item__secondary-text', index !== 0); + line.nativeElement, 'mdc-list-item__secondary-text', index !== 0); }); setLines(lines, this._elementRef, 'mat-mdc'); })); diff --git a/src/material-experimental/mdc-list/list-item.html b/src/material-experimental/mdc-list/list-item.html index ddcea90b6b1b..e00076915380 100644 --- a/src/material-experimental/mdc-list/list-item.html +++ b/src/material-experimental/mdc-list/list-item.html @@ -2,15 +2,15 @@ - + - + diff --git a/src/material-experimental/mdc-list/list-option.html b/src/material-experimental/mdc-list/list-option.html index 13acdd055c47..41ab9651188e 100644 --- a/src/material-experimental/mdc-list/list-option.html +++ b/src/material-experimental/mdc-list/list-option.html @@ -25,26 +25,26 @@ - + - + - + - + - + diff --git a/src/material-experimental/mdc-list/list-option.scss b/src/material-experimental/mdc-list/list-option.scss index 305cef366e29..c126fbbbc244 100644 --- a/src/material-experimental/mdc-list/list-option.scss +++ b/src/material-experimental/mdc-list/list-option.scss @@ -2,11 +2,16 @@ @use '@material/list' as mdc-list; @use '../mdc-helpers/mdc-helpers'; @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 diff --git a/src/material-experimental/mdc-list/list-option.ts b/src/material-experimental/mdc-list/list-option.ts index 5a9af758fca0..ba8d91b4aa68 100644 --- a/src/material-experimental/mdc-list/list-option.ts +++ b/src/material-experimental/mdc-list/list-option.ts @@ -62,12 +62,21 @@ export interface SelectionList extends MatListBase { exportAs: 'matListOption', styleUrls: ['list-option.css'], host: { - 'class': 'mat-mdc-list-item mat-mdc-list-option mdc-deprecated-list-item', + 'class': 'mat-mdc-list-item mat-mdc-list-option mdc-list-item', 'role': 'option', // As per MDC, only list items in single selection mode should receive the `--selected` // class. For multi selection, the checkbox is used as indicator. - '[class.mdc-deprecated-list-item--selected]': 'selected && !_selectionList.multiple', - '[class.mat-mdc-list-item-with-avatar]': '_hasIconOrAvatar()', + '[class.mdc-list-item--selected]': 'selected && !_selectionList.multiple', + // Based on the checkbox position and whether there are icons or avatars, we apply MDC's + // list-item `--leading` and `--trailing` classes. + '[class.mdc-list-item--with-leading-avatar]': '_hasProjected("avatars", "before")', + '[class.mdc-list-item--with-leading-icon]': '_hasProjected("icons", "before")', + '[class.mdc-list-item--with-trailing-icon]': '_hasProjected("icons", "after")', + '[class.mat-mdc-list-option-with-trailing-avatar]': '_hasProjected("avatars", "after")', + // Based on the checkbox position, we apply the `--leading` or `--trailing` MDC classes + // which ensure that the checkbox is positioned correctly within the list item. + '[class.mdc-list-item--with-leading-checkbox]': '_hasCheckboxAt("before")', + '[class.mdc-list-item--with-trailing-checkbox]': '_hasCheckboxAt("after")', '[class.mat-accent]': 'color !== "primary" && color !== "warn"', '[class.mat-warn]': 'color === "warn"', '(blur)': '_handleBlur()', @@ -188,14 +197,22 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit this._hostElement.focus(); } - /** Whether the checkbox should be shown at the given position. */ - _shouldShowCheckboxAt(position: MatListOptionCheckboxPosition): boolean { + /** Whether a checkbox is shown at the given position. */ + _hasCheckboxAt(position: MatListOptionCheckboxPosition): boolean { return this._selectionList.multiple && this._getCheckboxPosition() === position; } - /** Whether icons and avatars should be shown at the given position. */ - _shouldShowIconsAndAvatarsAt(position: 'before'|'after'): boolean { - return this._getCheckboxPosition() !== position && this._hasIconOrAvatar(); + /** Whether icons or avatars are shown at the given position. */ + _hasIconsOrAvatarsAt(position: 'before'|'after'): boolean { + return this._hasProjected('icons', position) || this._hasProjected('avatars', position); + } + + /** Gets whether the given type of element is projected at the specified position. */ + _hasProjected(type: 'icons'|'avatars', position: 'before'|'after'): boolean { + // If the checkbox is shown at the specified position, neither icons or + // avatars can be shown at the position. + return this._getCheckboxPosition() !== position && + (type === 'avatars' ? this._avatars.length !== 0 : this._icons.length !== 0); } _handleBlur() { diff --git a/src/material-experimental/mdc-list/list-styling.ts b/src/material-experimental/mdc-list/list-styling.ts index 654f1ad2712e..835098430795 100644 --- a/src/material-experimental/mdc-list/list-styling.ts +++ b/src/material-experimental/mdc-list/list-styling.ts @@ -10,17 +10,17 @@ import {Directive, Inject, Optional} from '@angular/core'; import {LIST_OPTION, ListOption} from './list-option-types'; /** - * MDC uses the very intuitively named classes `.mdc-deprecated-list-item__graphic` and - * `.mat-list-item__meta` to position content such as icons or checkboxes that comes either before - * or after the text content respectively. This directive detects the placement of the checkbox and - * applies the correct MDC class to position the icon/avatar on the opposite side. + * MDC uses the very intuitively named classes `.mdc-list-item__start` and `.mat-list-item__end` + * to position content such as icons or checkboxes that comes either before or after the text + * content respectively. This directive detects the placement of the checkbox and applies the + * correct MDC class to position the icon/avatar on the opposite side. * @docs-private */ @Directive({ selector: '[mat-list-avatar], [matListAvatar], [mat-list-icon], [matListIcon]', host: { - '[class.mdc-deprecated-list-item__graphic]': '_isAlignedAtStart()', - '[class.mdc-deprecated-list-item__meta]': '!_isAlignedAtStart()', + '[class.mdc-list-item__start]': '_isAlignedAtStart()', + '[class.mdc-list-item__end]': '!_isAlignedAtStart()', } }) export class MatListGraphicAlignmentStyler { @@ -62,6 +62,6 @@ export class MatListIconCssMatStyler {} selector: '[mat-subheader], [matSubheader]', // 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-deprecated-list-group__subheader'} + host: {'class': 'mat-mdc-subheader mdc-list-group__subheader'} }) export class MatListSubheaderCssMatStyler {} diff --git a/src/material-experimental/mdc-list/list.scss b/src/material-experimental/mdc-list/list.scss index 116807d9a15c..e51c7f214739 100644 --- a/src/material-experimental/mdc-list/list.scss +++ b/src/material-experimental/mdc-list/list.scss @@ -1,9 +1,8 @@ -@use '@material/list' as mdc-list; +@use '@material/list/evolution-mixins' as mdc-list; @use '../mdc-helpers/mdc-helpers'; @use '../../material/core/style/layout-common'; -@use '../../cdk/a11y'; -@include mdc-list.deprecated-without-ripple($query: mdc-helpers.$mat-base-styles-query); +@include mdc-list.without-ripple($query: mdc-helpers.$mat-base-styles-query); // MDC expects the list element to be a `
    `, since we use `` instead we need to // explicitly set `display: block` @@ -11,72 +10,6 @@ display: block; } -// .mdc-deprecated-list-item__primary-text adds its own margin settings, so only reset if it doesn't -// have that class -.mat-mdc-list-base .mdc-deprecated-list-item__text > :not(.mdc-deprecated-list-item__primary-text), -.mat-mdc-list-base .mdc-deprecated-list-item__text > :not(.mdc-deprecated-list-item__primary-text) { - margin: 0; - - // Fixes the gap between the 2nd & 3rd lines. - &.mdc-deprecated-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-deprecated-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-deprecated-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.$deprecated-side-padding - $size; - - width: $size; - height: $size; - border-radius: 50%; - - // Avatars that come before the text have the .mdc-deprecated-list-item__graphic class. - // MDC's .mdc-deprecated-list--avatar-list class would normally apply overrides to set the - // appropriate margins for avatar images, but since ours is a per-list-item setting we need to add - // similar styles ourselves. - &.mdc-deprecated-list-item__graphic { - margin-left: 0; - margin-right: $margin-value; - - [dir='rtl'] & { - margin-left: $margin-value; - margin-right: 0; - } - } -} - -.mat-mdc-list-avatar { - // MDC's styles don't specify this, but they probably should. It gives a nicer experience when the - // image is not 1:1 aspect ratio. - // See https://github.com/material-components/material-components-web/issues/5897 - object-fit: cover; -} - // MDC expects that the list items are always `
  • `, since we actually use `