Skip to content

perf(mdc-chips): Use class for MDC adapter #19981

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 13 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions src/material-experimental/mdc-chips/chip-icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,36 @@ export class MatChipAvatar {
}
}

class ChipTrailingActionAdapter implements MDCChipTrailingActionAdapter {
constructor(private _delegate: MatChipTrailingIcon) {}

focus() {
this._delegate._elementRef.nativeElement.focus();
}

getAttribute(name: string) {
return this._delegate._elementRef.nativeElement.getAttribute(name);
}

setAttribute(name: string, value: string) {
this._delegate._elementRef.nativeElement.setAttribute(name, value);
}

// TODO(crisbeto): there's also a `trigger` parameter that the chip isn't
// handling yet. Consider passing it along once MDC start using it.
notifyInteraction() {
// TODO(crisbeto): uncomment this code once we've inverted the
// dependency on `MatChip`. this._chip._notifyInteraction();
}

// TODO(crisbeto): there's also a `key` parameter that the chip isn't
// handling yet. Consider passing it along once MDC start using it.
notifyNavigation() {
// TODO(crisbeto): uncomment this code once we've inverted the
// dependency on `MatChip`. this._chip._notifyNavigation();
}
}

/**
* Injection token that can be used to reference instances of `MatChipTrailingIcon`. It serves as
* alternative token to the actual `MatChipTrailingIcon` class which could cause unnecessary
Expand All @@ -74,30 +104,6 @@ export const MAT_CHIP_TRAILING_ICON =
})
export class MatChipTrailingIcon implements OnDestroy {
private _foundation: MDCChipTrailingActionFoundation;
private _adapter: MDCChipTrailingActionAdapter = {
focus: () => this._elementRef.nativeElement.focus(),
getAttribute: (name: string) =>
this._elementRef.nativeElement.getAttribute(name),
setAttribute:
(name: string, value: string) => {
this._elementRef.nativeElement.setAttribute(name, value);
},
// TODO(crisbeto): there's also a `trigger` parameter that the chip isn't
// handling yet. Consider passing it along once MDC start using it.
notifyInteraction:
() => {
// TODO(crisbeto): uncomment this code once we've inverted the
// dependency on `MatChip`. this._chip._notifyInteraction();
},

// TODO(crisbeto): there's also a `key` parameter that the chip isn't
// handling yet. Consider passing it along once MDC start using it.
notifyNavigation:
() => {
// TODO(crisbeto): uncomment this code once we've inverted the
// dependency on `MatChip`. this._chip._notifyNavigation();
}
};

constructor(
public _elementRef: ElementRef,
Expand All @@ -106,7 +112,7 @@ export class MatChipTrailingIcon implements OnDestroy {
// method is removed, we can't use the chip here, because it causes a
// circular import. private _chip: MatChip
) {
this._foundation = new MDCChipTrailingActionFoundation(this._adapter);
this._foundation = new MDCChipTrailingActionFoundation(new ChipTrailingActionAdapter(this));
}

ngOnDestroy() {
Expand Down
4 changes: 2 additions & 2 deletions src/material-experimental/mdc-chips/chip-listbox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {merge, Observable, Subscription} from 'rxjs';
import {startWith, takeUntil} from 'rxjs/operators';
import {MatChip, MatChipEvent} from './chip';
import {MatChipOption, MatChipSelectionChange} from './chip-option';
import {MatChipSet} from './chip-set';
import {MatChipSet, ChipSetAdapter} from './chip-set';


/** Change event object that is emitted when the chip listbox value has changed. */
Expand Down Expand Up @@ -212,7 +212,7 @@ export class MatChipListbox extends MatChipSet implements AfterContentInit, Cont
this._setSelected(index, selected);
};
// Reinitialize the foundation with our overridden adapter
this._chipSetFoundation = new MDCChipSetFoundation(this._chipSetAdapter);
this._chipSetFoundation = new MDCChipSetFoundation(new ChipSetAdapter(this));
this._updateMdcSelectionClasses();
}

Expand Down
64 changes: 45 additions & 19 deletions src/material-experimental/mdc-chips/chip-set.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,47 @@ import {MatChip, MatChipEvent} from './chip';

let uid = 0;

/** @docs-private */
export class ChipSetAdapter implements MDCChipSetAdapter {

constructor(private _delegate: MatChipSet) {}

hasClass(className: string) {
return this._delegate._hasMdcClass(className);
}

// No-op. We keep track of chips via ContentChildren, which will be updated when a chip is
// removed.
removeChipAtIndex() {
return;
}

// No-op for base chip set. MatChipListbox overrides the adapter to provide this method.
selectChipAtIndex() {
return;
}

getIndexOfChipById(id: string) {
return this._delegate._chips.toArray().findIndex(chip => chip.id === id);
}

focusChipPrimaryActionAtIndex() {}

focusChipTrailingActionAtIndex() {}

removeFocusFromChipAtIndex() {}

isRTL() {
return !!this._delegate._dir && this._delegate._dir.value === 'rtl';
}

getChipListCount() {
return this._delegate._chips.length;
}

// TODO(mmalerba): Implement using LiveAnnouncer.
announceMessage() {}
}

/**
* Boilerplate for applying mixins to MatChipSet.
Expand Down Expand Up @@ -90,22 +131,7 @@ export class MatChipSet extends _MatChipSetMixinBase implements AfterContentInit
* Implementation of the MDC chip-set adapter interface.
* These methods are called by the chip set foundation.
*/
protected _chipSetAdapter: MDCChipSetAdapter = {
hasClass: (className) => this._hasMdcClass(className),
// No-op. We keep track of chips via ContentChildren, which will be updated when a chip is
// removed.
removeChipAtIndex: () => {},
// No-op for base chip set. MatChipListbox overrides the adapter to provide this method.
selectChipAtIndex: () => {},
getIndexOfChipById: (id: string) => this._chips.toArray().findIndex(chip => chip.id === id),
focusChipPrimaryActionAtIndex: () => {},
focusChipTrailingActionAtIndex: () => {},
removeFocusFromChipAtIndex: () => {},
isRTL: () => !!this._dir && this._dir.value === 'rtl',
getChipListCount: () => this._chips.length,
// TODO(mmalerba): Implement using LiveAnnouncer.
announceMessage: () => {},
};
protected _chipSetAdapter: MDCChipSetAdapter;

/** The aria-describedby attribute on the chip list for improved a11y. */
_ariaDescribedby: string;
Expand Down Expand Up @@ -161,9 +187,9 @@ export class MatChipSet extends _MatChipSetMixinBase implements AfterContentInit

constructor(protected _elementRef: ElementRef,
protected _changeDetectorRef: ChangeDetectorRef,
@Optional() protected _dir: Directionality) {
@Optional() readonly _dir: Directionality) {
super(_elementRef);
this._chipSetFoundation = new MDCChipSetFoundation(this._chipSetAdapter);
this._chipSetFoundation = new MDCChipSetFoundation(new ChipSetAdapter(this));
}

ngAfterViewInit() {
Expand Down Expand Up @@ -214,7 +240,7 @@ export class MatChipSet extends _MatChipSetMixinBase implements AfterContentInit
}

/** Adapter method that returns true if the chip set has the given MDC class. */
protected _hasMdcClass(className: string) {
_hasMdcClass(className: string) {
return this._elementRef.nativeElement.classList.contains(className);
}

Expand Down
Loading