Skip to content

Commit 1ac1f83

Browse files
committed
refactor(material-experimental/mdc-list): remove usage of MDC adapter (#24994)
Reworks our list not to use MDC's adapters. (cherry picked from commit d74f86f)
1 parent b61a96f commit 1ac1f83

File tree

6 files changed

+184
-384
lines changed

6 files changed

+184
-384
lines changed

src/material-experimental/mdc-list/BUILD.bazel

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ ng_module(
3333
"//src/material/list",
3434
"@npm//@angular/core",
3535
"@npm//@angular/forms",
36-
"@npm//@material/list",
3736
],
3837
)
3938

@@ -89,7 +88,6 @@ ng_test_library(
8988
"//src/material-experimental/mdc-core",
9089
"@npm//@angular/forms",
9190
"@npm//@angular/platform-browser",
92-
"@npm//@material/list",
9391
],
9492
)
9593

src/material-experimental/mdc-list/interactive-list-base.ts

Lines changed: 0 additions & 225 deletions
This file was deleted.

src/material-experimental/mdc-list/list-base.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ export abstract class MatListItemBase implements AfterViewInit, OnDestroy, Rippl
125125
return this.disableRipple || !!this.rippleConfig.disabled;
126126
}
127127

128-
protected constructor(
128+
constructor(
129129
public _elementRef: ElementRef<HTMLElement>,
130130
protected _ngZone: NgZone,
131131
private _listBase: MatListBase,
@@ -166,15 +166,6 @@ export abstract class MatListItemBase implements AfterViewInit, OnDestroy, Rippl
166166
}
167167
}
168168

169-
/** Gets the label for the list item. This is used for the typeahead. */
170-
_getItemLabel(): string {
171-
const titleElement = this._titles?.get(0)?._elementRef.nativeElement;
172-
// If there is no explicit title element, the unscoped text content
173-
// is treated as the list item title.
174-
const labelEl = titleElement ?? this._unscopedContent?.nativeElement;
175-
return labelEl ? labelEl.textContent ?? '' : '';
176-
}
177-
178169
/** Whether the list item has icons or avatars. */
179170
_hasIconOrAvatar() {
180171
return !!(this._avatars.length || this._icons.length);

src/material-experimental/mdc-list/list-option.ts

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88

99
import {BooleanInput, coerceBooleanProperty} from '@angular/cdk/coercion';
1010
import {SelectionModel} from '@angular/cdk/collections';
11-
import {Platform} from '@angular/cdk/platform';
1211
import {
12+
ANIMATION_MODULE_TYPE,
1313
ChangeDetectionStrategy,
1414
ChangeDetectorRef,
1515
Component,
@@ -33,10 +33,10 @@ import {
3333
RippleGlobalOptions,
3434
ThemePalette,
3535
} from '@angular/material-experimental/mdc-core';
36-
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
3736
import {MatListBase, MatListItemBase} from './list-base';
3837
import {LIST_OPTION, ListOption, MatListOptionCheckboxPosition} from './list-option-types';
3938
import {MatListItemLine, MatListItemTitle} from './list-item-sections';
39+
import {Platform} from '@angular/cdk/platform';
4040

4141
/**
4242
* Injection token that can be used to reference instances of an `SelectionList`. It serves
@@ -56,8 +56,9 @@ export interface SelectionList extends MatListBase {
5656
selectedOptions: SelectionModel<MatListOption>;
5757
compareWith: (o1: any, o2: any) => boolean;
5858
_value: string[] | null;
59-
_reportValueChange: () => void;
60-
_onTouched: () => void;
59+
_reportValueChange(): void;
60+
_emitChangeEvent(options: MatListOption[]): void;
61+
_onTouched(): void;
6162
}
6263

6364
@Component({
@@ -83,7 +84,9 @@ export interface SelectionList extends MatListBase {
8384
'[class.mat-accent]': 'color !== "primary" && color !== "warn"',
8485
'[class.mat-warn]': 'color === "warn"',
8586
'[class._mat-animation-noopable]': '_noopAnimations',
87+
'[attr.aria-selected]': 'selected',
8688
'(blur)': '_handleBlur()',
89+
'(click)': '_toggleOnInteraction()',
8790
},
8891
templateUrl: 'list-option.html',
8992
encapsulation: ViewEncapsulation.None,
@@ -97,7 +100,6 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit
97100
@ContentChildren(MatListItemLine, {descendants: true}) _lines: QueryList<MatListItemLine>;
98101
@ContentChildren(MatListItemTitle, {descendants: true}) _titles: QueryList<MatListItemTitle>;
99102
@ViewChild('unscopedContent') _unscopedContent: ElementRef<HTMLSpanElement>;
100-
@ViewChild('text') _itemText: ElementRef<HTMLElement>;
101103

102104
/**
103105
* Emits when the selected state of the option has changed.
@@ -159,21 +161,17 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit
159161
private _inputsInitialized = false;
160162

161163
constructor(
162-
element: ElementRef,
164+
elementRef: ElementRef<HTMLElement>,
163165
ngZone: NgZone,
166+
@Inject(SELECTION_LIST) private _selectionList: SelectionList,
164167
platform: Platform,
165-
@Inject(SELECTION_LIST) public _selectionList: SelectionList,
166168
private _changeDetectorRef: ChangeDetectorRef,
167-
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS) globalRippleOptions?: RippleGlobalOptions,
169+
@Optional()
170+
@Inject(MAT_RIPPLE_GLOBAL_OPTIONS)
171+
globalRippleOptions?: RippleGlobalOptions,
168172
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string,
169173
) {
170-
super(element, ngZone, _selectionList, platform, globalRippleOptions, animationMode);
171-
172-
// By default, we mark all options as unselected. The MDC list foundation will
173-
// automatically update the attribute based on selection. Note that we need to
174-
// initially set this because MDC does not set the default attributes for list
175-
// items but expects items to be set up properly in the static markup.
176-
element.nativeElement.setAttribute('aria-selected', 'false');
174+
super(elementRef, ngZone, _selectionList, platform, globalRippleOptions, animationMode);
177175
}
178176

179177
ngOnInit() {
@@ -221,6 +219,15 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit
221219
this._hostElement.focus();
222220
}
223221

222+
/** Gets the text label of the list option. Used for the typeahead functionality in the list. */
223+
getLabel() {
224+
const titleElement = this._titles?.get(0)?._elementRef.nativeElement;
225+
// If there is no explicit title element, the unscoped text content
226+
// is treated as the list item title.
227+
const labelEl = titleElement || this._unscopedContent?.nativeElement;
228+
return labelEl?.textContent || '';
229+
}
230+
224231
/** Whether a checkbox is shown at the given position. */
225232
_hasCheckboxAt(position: MatListOptionCheckboxPosition): boolean {
226233
return this._selectionList.multiple && this._getCheckboxPosition() === position;
@@ -280,4 +287,22 @@ export class MatListOption extends MatListItemBase implements ListOption, OnInit
280287
_markForCheck() {
281288
this._changeDetectorRef.markForCheck();
282289
}
290+
291+
/** Toggles the option's value based on a user interacion. */
292+
_toggleOnInteraction() {
293+
if (!this.disabled) {
294+
if (this._selectionList.multiple) {
295+
this.selected = !this.selected;
296+
this._selectionList._emitChangeEvent([this]);
297+
} else if (!this.selected) {
298+
this.selected = true;
299+
this._selectionList._emitChangeEvent([this]);
300+
}
301+
}
302+
}
303+
304+
/** Sets the tabindex of the list option. */
305+
_setTabindex(value: number) {
306+
this._hostElement.setAttribute('tabindex', value + '');
307+
}
283308
}

0 commit comments

Comments
 (0)