Skip to content

Commit 3aa5ca4

Browse files
authored
chore: Update MDC to latest alpha (#16772)
* Revert "Revert "Update MDC to latest alpha (#16724)" (#16770)" This reverts commit cc8f37f. * minor tweak to mdc chips adapter for latest upstream update to unbreak pantheon angular already manages focus fully and this hook does negligible good and a lot of harm (e.g., focusing thigns that were never meant to be focused). long term we probably want to consolidate the code, but for now just keep it unbroken. squash this commit into the main PR
1 parent 18b9ef3 commit 3aa5ca4

File tree

9 files changed

+564
-510
lines changed

9 files changed

+564
-510
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
},
3838
"version": "8.1.3",
3939
"requiredAngularVersion": "^8.0.0 || ^9.0.0-0",
40-
"requiredMDCVersion": "^3.0.0",
40+
"requiredMDCVersion": "^4.0.0-alpha.0",
4141
"dependencies": {
4242
"@angular/animations": "^8.2.2",
4343
"@angular/common": "^8.2.2",
@@ -50,7 +50,7 @@
5050
"@types/youtube": "^0.0.38",
5151
"@webcomponents/custom-elements": "^1.1.0",
5252
"core-js": "^2.6.1",
53-
"material-components-web": "^3.0.0",
53+
"material-components-web": "^4.0.0-alpha.0",
5454
"rxjs": "^6.5.2",
5555
"systemjs": "0.19.43",
5656
"tsickle": "^0.35.0",

src/material-experimental/mdc-chips/chip-grid.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,13 @@ export class MatChipGridChange {
6060
class MatChipGridBase extends MatChipSet {
6161
constructor(_elementRef: ElementRef,
6262
_changeDetectorRef: ChangeDetectorRef,
63+
_dir: Directionality,
6364
public _defaultErrorStateMatcher: ErrorStateMatcher,
6465
public _parentForm: NgForm,
6566
public _parentFormGroup: FormGroupDirective,
6667
/** @docs-private */
6768
public ngControl: NgControl) {
68-
super(_elementRef, _changeDetectorRef);
69+
super(_elementRef, _changeDetectorRef, _dir);
6970
}
7071
}
7172
const _MatChipGridMixinBase: CanUpdateErrorStateCtor & typeof MatChipGridBase =
@@ -237,14 +238,14 @@ export class MatChipGrid extends _MatChipGridMixinBase implements AfterContentIn
237238

238239
constructor(_elementRef: ElementRef,
239240
_changeDetectorRef: ChangeDetectorRef,
240-
@Optional() private _dir: Directionality,
241+
@Optional() _dir: Directionality,
241242
@Optional() _parentForm: NgForm,
242243
@Optional() _parentFormGroup: FormGroupDirective,
243244
_defaultErrorStateMatcher: ErrorStateMatcher,
244245
/** @docs-private */
245246
@Optional() @Self() public ngControl: NgControl) {
246-
super(_elementRef, _changeDetectorRef, _defaultErrorStateMatcher, _parentForm, _parentFormGroup,
247-
ngControl);
247+
super(_elementRef, _changeDetectorRef, _dir, _defaultErrorStateMatcher, _parentForm,
248+
_parentFormGroup, ngControl);
248249
if (this.ngControl) {
249250
this.ngControl.valueAccessor = this;
250251
}

src/material-experimental/mdc-chips/chip-icons.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,11 @@ import {Subject} from 'rxjs';
3535
})
3636
export class MatChipAvatar {
3737
constructor(private _changeDetectorRef: ChangeDetectorRef,
38-
private _elementRef: ElementRef) {}
38+
private _elementRef: ElementRef<HTMLElement>) {}
3939

4040
/** Sets whether the given CSS class should be applied to the leading icon. */
4141
setClass(cssClass: string, active: boolean) {
42-
const element = this._elementRef.nativeElement;
43-
active ? element.addClass(cssClass) : element.removeClass(cssClass);
42+
this._elementRef.nativeElement.classList.toggle(cssClass, active);
4443
this._changeDetectorRef.markForCheck();
4544
}
4645
}
@@ -58,15 +57,25 @@ export class MatChipAvatar {
5857
}
5958
})
6059
export class MatChipTrailingIcon {
60+
constructor(public _elementRef: ElementRef) {}
61+
62+
focus() {
63+
this._elementRef.nativeElement.focus();
64+
}
65+
66+
/** Sets an attribute on the icon. */
67+
setAttribute(name: string, value: string) {
68+
this._elementRef.nativeElement.setAttribute(name, value);
69+
}
6170
}
6271

6372
/**
6473
* Boilerplate for applying mixins to MatChipRemove.
6574
* @docs-private
6675
*/
6776
class MatChipRemoveBase extends MatChipTrailingIcon {
68-
constructor(public _elementRef: ElementRef) {
69-
super();
77+
constructor(_elementRef: ElementRef) {
78+
super(_elementRef);
7079
}
7180
}
7281

src/material-experimental/mdc-chips/chip-listbox.ts

Lines changed: 11 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import {FocusKeyManager} from '@angular/cdk/a11y';
1010
import {Directionality} from '@angular/cdk/bidi';
1111
import {coerceBooleanProperty} from '@angular/cdk/coercion';
12-
import {HOME, END} from '@angular/cdk/keycodes';
12+
import {END, HOME} from '@angular/cdk/keycodes';
1313
import {
1414
AfterContentInit,
1515
ChangeDetectionStrategy,
@@ -26,7 +26,7 @@ import {
2626
ViewEncapsulation
2727
} from '@angular/core';
2828
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
29-
import {MDCChipSetAdapter, MDCChipSetFoundation} from '@material/chips';
29+
import {MDCChipSetFoundation} from '@material/chips';
3030
import {merge, Observable, Subscription} from 'rxjs';
3131
import {startWith, takeUntil} from 'rxjs/operators';
3232
import {MatChip, MatChipEvent} from './chip';
@@ -96,22 +96,6 @@ export class MatChipListbox extends MatChipSet implements AfterContentInit, Cont
9696
/** Subscription to focus changes in the chips. */
9797
private _chipFocusSubscription: Subscription | null;
9898

99-
/**
100-
* Implementation of the MDC chip-set adapter interface.
101-
* These methods are called by the chip set foundation.
102-
*
103-
* Overrides the base MatChipSet adapter to provide a setSelected method.
104-
*/
105-
protected _chipSetAdapter: MDCChipSetAdapter = {
106-
hasClass: (className: string) => this._hasMdcClass(className),
107-
// No-op. We keep track of chips via ContentChildren, which will be updated when a chip is
108-
// removed.
109-
removeChip: () => {},
110-
setSelected: (chipId: string, selected: boolean) => {
111-
this._setSelected(chipId, selected);
112-
}
113-
};
114-
11599
/** The FocusKeyManager which handles focus. */
116100
_keyManager: FocusKeyManager<MatChip>;
117101

@@ -223,8 +207,11 @@ export class MatChipListbox extends MatChipSet implements AfterContentInit, Cont
223207

224208
constructor(protected _elementRef: ElementRef,
225209
_changeDetectorRef: ChangeDetectorRef,
226-
@Optional() private _dir: Directionality) {
227-
super(_elementRef, _changeDetectorRef);
210+
@Optional() _dir: Directionality) {
211+
super(_elementRef, _changeDetectorRef, _dir);
212+
this._chipSetAdapter.selectChipAtIndex = (index: number, selected: boolean) => {
213+
this._setSelected(index, selected);
214+
};
228215
// Reinitialize the foundation with our overridden adapter
229216
this._chipSetFoundation = new MDCChipSetFoundation(this._chipSetAdapter);
230217
this._updateMdcSelectionClasses();
@@ -319,8 +306,8 @@ export class MatChipListbox extends MatChipSet implements AfterContentInit, Cont
319306
}
320307

321308
/** Selects or deselects a chip by id. */
322-
_setSelected(chipId: string, selected: boolean) {
323-
const chip = this._chips.find(c => c.id === chipId);
309+
_setSelected(index: number, selected: boolean) {
310+
const chip = this._chips.toArray()[index];
324311
if (chip && chip.selected != selected) {
325312
chip.toggleSelected(true);
326313
}
@@ -468,7 +455,7 @@ export class MatChipListbox extends MatChipSet implements AfterContentInit, Cont
468455

469456
/** Initializes the key manager to manage focus. */
470457
private _initKeyManager() {
471-
this._keyManager = new FocusKeyManager<MatChipOption>(this._chips)
458+
this._keyManager = new FocusKeyManager<MatChip>(this._chips)
472459
.withWrap()
473460
.withVerticalOrientation()
474461
.withHorizontalOrientation(this._dir ? this._dir.value : 'ltr');
@@ -543,7 +530,7 @@ export class MatChipListbox extends MatChipSet implements AfterContentInit, Cont
543530
this._chipSelectionSubscription = this.chipSelectionChanges.subscribe(
544531
(chipSelectionChange: MatChipSelectionChange) => {
545532
this._chipSetFoundation.handleChipSelection(
546-
chipSelectionChange.source.id, chipSelectionChange.selected);
533+
chipSelectionChange.source.id, chipSelectionChange.selected, false);
547534
if (chipSelectionChange.isUserInput) {
548535
this._propagateChanges();
549536
}

src/material-experimental/mdc-chips/chip-set.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {Directionality} from '@angular/cdk/bidi';
910
import {coerceBooleanProperty} from '@angular/cdk/coercion';
1011
import {
1112
AfterContentInit,
@@ -17,18 +18,15 @@ import {
1718
ElementRef,
1819
Input,
1920
OnDestroy,
21+
Optional,
2022
QueryList,
2123
ViewEncapsulation
2224
} from '@angular/core';
25+
import {HasTabIndex, HasTabIndexCtor, mixinTabIndex} from '@angular/material/core';
2326
import {MDCChipSetAdapter, MDCChipSetFoundation} from '@material/chips';
24-
import {MatChip, MatChipEvent} from './chip';
2527
import {merge, Observable, Subject, Subscription} from 'rxjs';
2628
import {startWith, takeUntil} from 'rxjs/operators';
27-
import {
28-
HasTabIndex,
29-
HasTabIndexCtor,
30-
mixinTabIndex,
31-
} from '@angular/material/core';
29+
import {MatChip, MatChipEvent} from './chip';
3230

3331

3432
let uid = 0;
@@ -97,9 +95,15 @@ export class MatChipSet extends _MatChipSetMixinBase implements AfterContentInit
9795
hasClass: (className) => this._hasMdcClass(className),
9896
// No-op. We keep track of chips via ContentChildren, which will be updated when a chip is
9997
// removed.
100-
removeChip: () => {},
98+
removeChipAtIndex: () => {},
10199
// No-op for base chip set. MatChipListbox overrides the adapter to provide this method.
102-
setSelected: () => {}
100+
selectChipAtIndex: () => {},
101+
getIndexOfChipById: (id: string) => this._chips.toArray().findIndex(chip => chip.id === id),
102+
focusChipPrimaryActionAtIndex: () => {},
103+
focusChipTrailingActionAtIndex: () => {},
104+
removeFocusFromChipAtIndex: () => {},
105+
isRTL: () => !!this._dir && this._dir.value === 'rtl',
106+
getChipListCount: () => this._chips.length,
103107
};
104108

105109
/** The aria-describedby attribute on the chip list for improved a11y. */
@@ -151,7 +155,8 @@ export class MatChipSet extends _MatChipSetMixinBase implements AfterContentInit
151155
@ContentChildren(MatChip) _chips: QueryList<MatChip>;
152156

153157
constructor(protected _elementRef: ElementRef,
154-
protected _changeDetectorRef: ChangeDetectorRef) {
158+
protected _changeDetectorRef: ChangeDetectorRef,
159+
@Optional() protected _dir: Directionality) {
155160
super(_elementRef);
156161
this._chipSetFoundation = new MDCChipSetFoundation(this._chipSetAdapter);
157162
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<ng-content select="mat-chip-avatar, [matChipAvatar]"></ng-content>
2-
<div class="mdc-chip__text"><ng-content></ng-content></div>
2+
<div class="mdc-chip__text mdc-chip__action--primary"><ng-content></ng-content></div>
33
<ng-content select="mat-chip-trailing-icon,[matChipRemove],[matChipTrailingIcon]"></ng-content>

src/material-experimental/mdc-chips/chip.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9+
import {Directionality} from '@angular/cdk/bidi';
910
import {coerceBooleanProperty} from '@angular/cdk/coercion';
1011
import {Platform} from '@angular/cdk/platform';
1112
import {ANIMATION_MODULE_TYPE} from '@angular/platform-browser/animations';
@@ -247,28 +248,41 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
247248
// No-op. We call dispatchSelectionEvent ourselves in MatChipOption, because we want to
248249
// specify whether selection occurred via user input.
249250
},
251+
notifyNavigation: () => {
252+
// TODO: This is a new feature added by MDC; consider exposing this event to users in the
253+
// future.
254+
},
250255
notifyTrailingIconInteraction: () => this.removeIconInteraction.emit(this.id),
251256
notifyRemoval: () => this.removed.emit({chip: this}),
252-
getComputedStyleValue: (propertyName) => {
253-
return window.getComputedStyle(this._elementRef.nativeElement).getPropertyValue(propertyName);
254-
},
257+
getComputedStyleValue: propertyName =>
258+
window.getComputedStyle(this._elementRef.nativeElement).getPropertyValue(propertyName),
255259
setStyleProperty: (propertyName: string, value: string) => {
256260
this._elementRef.nativeElement.style.setProperty(propertyName, value);
257261
},
258-
hasLeadingIcon: () => { return !!this.leadingIcon; },
259-
setAttr: (name: string, value: string) => {
262+
hasLeadingIcon: () => !!this.leadingIcon,
263+
hasTrailingAction: () => !!this.trailingIcon,
264+
isRTL: () => !!this._dir && this._dir.value === 'rtl',
265+
focusPrimaryAction: () => {
266+
// Angular Material MDC chips fully manage focus. TODO: Managing focus and handling keyboard
267+
// events was added by MDC after our implementation; consider consolidating.
268+
},
269+
focusTrailingAction: () => {},
270+
setTrailingActionAttr: (attr, value) =>
271+
this.trailingIcon && this.trailingIcon.setAttribute(attr, value),
272+
setPrimaryActionAttr: (name: string, value: string) => {
260273
// MDC is currently using this method to set aria-checked on choice and filter chips,
261274
// which in the MDC templates have role="checkbox" and role="radio" respectively.
262275
// We have role="option" on those chips instead, so we do not want aria-checked.
263-
if (name === 'aria-checked') {
276+
// Since we also manage the tabindex ourselves, we don't allow MDC to set it.
277+
if (name === 'aria-checked' || name === 'tabindex') {
264278
return;
265279
}
266280
this._elementRef.nativeElement.setAttribute(name, value);
267281
},
268282
// The 2 functions below are used by the MDC ripple, which we aren't using,
269283
// so they will never be called
270284
getRootBoundingClientRect: () => this._elementRef.nativeElement.getBoundingClientRect(),
271-
getCheckmarkBoundingClientRect: () => { return null; },
285+
getCheckmarkBoundingClientRect: () => null,
272286
};
273287

274288
constructor(
@@ -278,6 +292,7 @@ export class MatChip extends _MatChipMixinBase implements AfterContentInit, Afte
278292
protected _ngZone: NgZone,
279293
@Optional() @Inject(MAT_RIPPLE_GLOBAL_OPTIONS)
280294
private _globalRippleOptions: RippleGlobalOptions | null,
295+
@Optional() private _dir: Directionality,
281296
// @breaking-change 8.0.0 `animationMode` parameter to become required.
282297
@Optional() @Inject(ANIMATION_MODULE_TYPE) animationMode?: string) {
283298
super(_elementRef);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ sass_library(
118118
"@npm//:node_modules/@material/theme/_variables.scss",
119119
"@npm//:node_modules/@material/top-app-bar/_mixins.scss",
120120
"@npm//:node_modules/@material/top-app-bar/_variables.scss",
121+
"@npm//:node_modules/@material/touch-target/_mixins.scss",
122+
"@npm//:node_modules/@material/touch-target/_variables.scss",
121123
"@npm//:node_modules/@material/typography/_functions.scss",
122124
"@npm//:node_modules/@material/typography/_mixins.scss",
123125
"@npm//:node_modules/@material/typography/_variables.scss",

0 commit comments

Comments
 (0)