From 5b578637024ce637388553b3c951d905ece12182 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Mon, 5 Dec 2022 19:35:54 +0100 Subject: [PATCH] fix(material/list): align color scheme between single and multi selection list (#26074) MDC has the `mdc-list-item--selected` class which we were setting only on single selection `mat-list-option` to indicate using color that they're selected. After the recent change to indicate selection using a radio button, these look weird because the radio button inherits the list item theme palette while the background of the item stays as `primary`. These changes resolve the issue by treating single selection and multi-selection lists the same. **Note:** an alternative I was considering was to change the color so that it matches the radio button color, but then the appearance of the single selection list would be inconsistent with the multi-selection list. --- src/material/list/_interactive-list-theme.scss | 17 ----------------- src/material/list/list-option.ts | 3 --- src/material/list/selection-list.spec.ts | 8 +++----- 3 files changed, 3 insertions(+), 25 deletions(-) diff --git a/src/material/list/_interactive-list-theme.scss b/src/material/list/_interactive-list-theme.scss index c42a5a0305d0..8c40ba7585e8 100644 --- a/src/material/list/_interactive-list-theme.scss +++ b/src/material/list/_interactive-list-theme.scss @@ -1,13 +1,11 @@ @use 'sass:map'; @use '@material/ripple' as mdc-ripple; -@use '../core/theming/theming'; // Mixin that provides colors for the various states of an interactive list-item. MDC // 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); $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 { @@ -18,21 +16,6 @@ opacity: mdc-ripple.states-opacity($active-base-color, hover); } - &.mdc-list-item--selected { - &::before { - background: $selected-color; - opacity: mdc-ripple.states-opacity($selected-color, selected); - } - - &:not(:focus):not(.mdc-list-item--disabled):hover::before { - // The hover and selected opacities need to be combined to match with what the MDC - // ripple state would render. More details here: - // https://github.com/material-components/material-components-web/blob/348665978ce73694ad4518626dd70cdf5b984113/packages/mdc-ripple/_ripple-theme.scss#L450. - opacity: mdc-ripple.states-opacity($selected-color, hover) + - mdc-ripple.states-opacity($selected-color, selected); - } - } - &:focus::before { opacity: mdc-ripple.states-opacity($active-base-color, focus); } diff --git a/src/material/list/list-option.ts b/src/material/list/list-option.ts index c7795e0cf62a..1bcf18d1360c 100644 --- a/src/material/list/list-option.ts +++ b/src/material/list/list-option.ts @@ -64,9 +64,6 @@ export interface SelectionList extends MatListBase { host: { '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-list-item--selected]': 'selected && !_selectionList.multiple', // Based on the checkbox/radio 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")', diff --git a/src/material/list/selection-list.spec.ts b/src/material/list/selection-list.spec.ts index 1f94c69fba2e..3aff5f76e789 100644 --- a/src/material/list/selection-list.spec.ts +++ b/src/material/list/selection-list.spec.ts @@ -1041,16 +1041,14 @@ describe('MDC-based MatSelectionList without forms', () => { fixture.detectChanges(); expect(selectList.selected).toEqual([testListItem1]); - expect(listOptions[1].nativeElement.classList.contains('mdc-list-item--selected')).toBe(true); + expect(listOptions[1].nativeElement.getAttribute('aria-selected')).toBe('true'); dispatchMouseEvent(testListItem2._hostElement, 'click'); fixture.detectChanges(); expect(selectList.selected).toEqual([testListItem2]); - expect(listOptions[1].nativeElement.classList.contains('mdc-list-item--selected')).toBe( - false, - ); - expect(listOptions[2].nativeElement.classList.contains('mdc-list-item--selected')).toBe(true); + expect(listOptions[1].nativeElement.getAttribute('aria-selected')).toBe('false'); + expect(listOptions[2].nativeElement.getAttribute('aria-selected')).toBe('true'); }); it('should not show check boxes', () => {