Skip to content

Commit 7596532

Browse files
authored
fix(material-experimental/mdc-chips): use MDC-based form field (#20880)
* Changes the MDC chips module to depend on the MDC form field module since we generally don't support mixing MDC and non-MDC components. * Fixes that the MDC chip input didn't work inside of an MDC form field. * Switches the MDC chips demo to use mostly MDC components. * Fixes some tests that broke after the switch to the MDC form field.
1 parent 5b1660e commit 7596532

File tree

13 files changed

+58
-46
lines changed

13 files changed

+58
-46
lines changed

src/dev-app/mdc-chips/BUILD.bazel

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ ng_module(
1010
":mdc_chips_demo_scss",
1111
],
1212
deps = [
13+
"//src/material-experimental/mdc-button",
14+
"//src/material-experimental/mdc-card",
15+
"//src/material-experimental/mdc-checkbox",
1316
"//src/material-experimental/mdc-chips",
14-
"//src/material/button",
15-
"//src/material/card",
16-
"//src/material/checkbox",
17-
"//src/material/form-field",
17+
"//src/material-experimental/mdc-core",
18+
"//src/material-experimental/mdc-form-field",
1819
"//src/material/icon",
1920
"//src/material/toolbar",
2021
"@npm//@angular/router",

src/dev-app/mdc-chips/mdc-chips-demo-module.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
import {CommonModule} from '@angular/common';
1010
import {NgModule} from '@angular/core';
1111
import {FormsModule, ReactiveFormsModule} from '@angular/forms';
12-
import {MatButtonModule} from '@angular/material/button';
13-
import {MatCardModule} from '@angular/material/card';
14-
import {MatCheckboxModule} from '@angular/material/checkbox';
15-
import {MatFormFieldModule} from '@angular/material/form-field';
16-
import {MatToolbarModule} from '@angular/material/toolbar';
12+
import {MatButtonModule} from '@angular/material-experimental/mdc-button';
13+
import {MatCardModule} from '@angular/material-experimental/mdc-card';
14+
import {MatCheckboxModule} from '@angular/material-experimental/mdc-checkbox';
15+
import {MatFormFieldModule} from '@angular/material-experimental/mdc-form-field';
1716
import {MatChipsModule} from '@angular/material-experimental/mdc-chips';
17+
import {MatToolbarModule} from '@angular/material/toolbar';
1818
import {MatIconModule} from '@angular/material/icon';
1919
import {RouterModule} from '@angular/router';
2020
import {MdcChipsDemo} from './mdc-chips-demo';

src/dev-app/mdc-chips/mdc-chips-demo.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ <h4>Multi selection</h4>
135135
<h4>Input is last child of chip grid</h4>
136136

137137
<mat-form-field class="demo-has-chip-list">
138+
<mat-label>New Contributor...</mat-label>
138139
<mat-chip-grid #chipGrid1 [(ngModel)]="selectedPeople" required [disabled]="disableInputs">
139140
<mat-chip-row *ngFor="let person of people"
140141
[editable]="editable"
@@ -144,7 +145,6 @@ <h4>Input is last child of chip grid</h4>
144145
<mat-icon matChipRemove>cancel</mat-icon>
145146
</mat-chip-row>
146147
<input [disabled]="disableInputs"
147-
placeholder="New Contributor..."
148148
[matChipInputFor]="chipGrid1"
149149
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
150150
[matChipInputAddOnBlur]="addOnBlur"
@@ -155,14 +155,14 @@ <h4>Input is last child of chip grid</h4>
155155
<h4>Input is next sibling child of chip grid</h4>
156156

157157
<mat-form-field>
158+
<mat-label>New Contributor...</mat-label>
158159
<mat-chip-grid #chipGrid2 [(ngModel)]="selectedPeople" required [disabled]="disableInputs">
159160
<mat-chip-row *ngFor="let person of people" (removed)="remove(person)">
160161
{{person.name}}
161162
<mat-icon matChipRemove>cancel</mat-icon>
162163
</mat-chip-row>
163164
</mat-chip-grid>
164-
<input placeholder="New Contributor..."
165-
[matChipInputFor]="chipGrid2"
165+
<input [matChipInputFor]="chipGrid2"
166166
[matChipInputSeparatorKeyCodes]="separatorKeysCodes"
167167
[matChipInputAddOnBlur]="addOnBlur"
168168
(matChipInputTokenEnd)="add($event)" />

src/dev-app/mdc-chips/mdc-chips-demo.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
max-width: 200px;
55
}
66

7-
.mat-card {
7+
.mat-mdc-card {
88
padding: 0;
99
margin: 16px;
1010

src/dev-app/mdc-chips/mdc-chips-demo.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import {COMMA, ENTER} from '@angular/cdk/keycodes';
1010
import {Component} from '@angular/core';
11-
import {ThemePalette} from '@angular/material/core';
11+
import {ThemePalette} from '@angular/material-experimental/mdc-core';
1212
import {MatChipInputEvent, MatChipEditedEvent} from '@angular/material-experimental/mdc-chips';
1313

1414
export interface Person {

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ ng_module(
2222
deps = [
2323
"//src:dev_mode_types",
2424
"//src/material-experimental/mdc-core",
25-
"//src/material/form-field",
25+
"//src/material-experimental/mdc-form-field",
2626
"@npm//@angular/animations",
2727
"@npm//@angular/common",
2828
"@npm//@angular/core",
@@ -69,8 +69,8 @@ ng_test_library(
6969
"//src/cdk/testing",
7070
"//src/cdk/testing/private",
7171
"//src/material-experimental/mdc-core",
72-
"//src/material/form-field",
73-
"//src/material/input",
72+
"//src/material-experimental/mdc-form-field",
73+
"//src/material-experimental/mdc-input",
7474
"@npm//@angular/animations",
7575
"@npm//@angular/common",
7676
"@npm//@angular/forms",
@@ -84,6 +84,10 @@ ng_test_library(
8484
ng_web_test_suite(
8585
name = "unit_tests",
8686
static_files = [
87+
"@npm//:node_modules/@material/textfield/dist/mdc.textfield.js",
88+
"@npm//:node_modules/@material/line-ripple/dist/mdc.lineRipple.js",
89+
"@npm//:node_modules/@material/notched-outline/dist/mdc.notchedOutline.js",
90+
"@npm//:node_modules/@material/dom/dist/mdc.dom.js",
8791
"@npm//:node_modules/@material/chips/dist/mdc.chips.js",
8892
"@npm//:node_modules/@material/ripple/dist/mdc.ripple.js",
8993
],

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

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ import {
3333
} from '@angular/core';
3434
import {ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
3535
import {FormControl, FormsModule, NgForm, ReactiveFormsModule, Validators} from '@angular/forms';
36-
import {MatFormFieldModule} from '@angular/material/form-field';
37-
import {MatInputModule} from '@angular/material/input';
36+
import {MatFormFieldModule} from '@angular/material-experimental/mdc-form-field';
37+
import {MatInputModule} from '@angular/material-experimental/mdc-input';
3838
import {By} from '@angular/platform-browser';
3939
import {BrowserAnimationsModule, NoopAnimationsModule} from '@angular/platform-browser/animations';
4040
import {Subject} from 'rxjs';
@@ -668,7 +668,6 @@ describe('MDC-based MatChipGrid', () => {
668668
.toEqual(null, `Expected the control's value to be empty initially.`);
669669

670670
const nativeInput = fixture.nativeElement.querySelector('input');
671-
// tick();
672671
nativeInput.focus();
673672

674673
typeInElement(nativeInput, '123');
@@ -750,20 +749,20 @@ describe('MDC-based MatChipGrid', () => {
750749
});
751750

752751
it('should set an asterisk after the placeholder if the control is required', () => {
753-
let requiredMarker = fixture.debugElement.query(By.css('.mat-form-field-required-marker'))!;
752+
let requiredMarker = fixture.debugElement.query(By.css('.mdc-floating-label--required'))!;
754753
expect(requiredMarker)
755754
.toBeNull(`Expected placeholder not to have an asterisk, as control was not required.`);
756755

757756
fixture.componentInstance.isRequired = true;
758757
fixture.detectChanges();
759758

760-
requiredMarker = fixture.debugElement.query(By.css('.mat-form-field-required-marker'))!;
759+
requiredMarker = fixture.debugElement.query(By.css('.mdc-floating-label--required'))!;
761760
expect(requiredMarker)
762761
.not.toBeNull(`Expected placeholder to have an asterisk, as control was required.`);
763762
});
764763

765764
it('should blur the form field when the active chip is blurred', fakeAsync(() => {
766-
const formField: HTMLElement = fixture.nativeElement.querySelector('.mat-form-field');
765+
const formField: HTMLElement = fixture.nativeElement.querySelector('.mat-mdc-form-field');
767766

768767
dispatchFakeEvent(nativeChips[0], 'focusin');
769768
fixture.detectChanges();
@@ -926,8 +925,8 @@ describe('MDC-based MatChipGrid', () => {
926925
});
927926

928927
it('sets the aria-describedby to reference errors when in error state', () => {
929-
let hintId =
930-
fixture.debugElement.query(By.css('.mat-hint'))!.nativeElement.getAttribute('id');
928+
let hintId = fixture.debugElement.query(By.css('.mat-mdc-form-field-hint'))!.nativeElement
929+
.getAttribute('id');
931930
let describedBy = chipGridEl.getAttribute('aria-describedby');
932931

933932
expect(hintId).toBeTruthy('hint should be shown');
@@ -936,7 +935,7 @@ describe('MDC-based MatChipGrid', () => {
936935
fixture.componentInstance.formControl.markAsTouched();
937936
fixture.detectChanges();
938937

939-
let errorIds = fixture.debugElement.queryAll(By.css('.mat-error'))
938+
let errorIds = fixture.debugElement.queryAll(By.css('.mat-mdc-form-field-error'))
940939
.map(el => el.nativeElement.getAttribute('id')).join(' ');
941940
describedBy = chipGridEl.getAttribute('aria-describedby');
942941

@@ -1039,13 +1038,14 @@ class FormFieldChipGrid {
10391038
@Component({
10401039
template: `
10411040
<mat-form-field>
1041+
<mat-label>New food...</mat-label>
10421042
<mat-chip-grid #chipGrid
10431043
placeholder="Food" [formControl]="control" [required]="isRequired">
10441044
<mat-chip-row *ngFor="let food of foods" [value]="food.value" (removed)="remove(food)">
10451045
{{ food.viewValue }}
10461046
</mat-chip-row>
10471047
</mat-chip-grid>
1048-
<input placeholder="New food..."
1048+
<input
10491049
[matChipInputFor]="chipGrid"
10501050
[matChipInputSeparatorKeyCodes]="separatorKeyCodes"
10511051
[matChipInputAddOnBlur]="addOnBlur"

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import {
3434
ErrorStateMatcher,
3535
mixinErrorState,
3636
} from '@angular/material-experimental/mdc-core';
37-
import {MatFormFieldControl} from '@angular/material/form-field';
37+
import {MatFormFieldControl} from '@angular/material-experimental/mdc-form-field';
3838
import {MatChipTextControl} from './chip-text-control';
3939
import {merge, Observable, Subscription} from 'rxjs';
4040
import {startWith, takeUntil} from 'rxjs/operators';

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

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {PlatformModule} from '@angular/cdk/platform';
44
import {dispatchKeyboardEvent} from '@angular/cdk/testing/private';
55
import {Component, DebugElement, ViewChild} from '@angular/core';
66
import {waitForAsync, ComponentFixture, fakeAsync, TestBed, tick} from '@angular/core/testing';
7-
import {MatFormFieldModule} from '@angular/material/form-field';
7+
import {MatFormFieldModule} from '@angular/material-experimental/mdc-form-field';
88
import {By} from '@angular/platform-browser';
99
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
1010
import {Subject} from 'rxjs';
@@ -18,6 +18,10 @@ import {
1818
} from './index';
1919

2020

21+
// The following tests have been removed, because the use
22+
// cases are not support by the MDC-based components:
23+
// - should propagate the dynamic `placeholder` value to the form field
24+
2125
describe('MDC-based MatChipInput', () => {
2226
let fixture: ComponentFixture<any>;
2327
let testChipInput: TestChipInput;
@@ -74,21 +78,6 @@ describe('MDC-based MatChipInput', () => {
7478
expect(inputNativeElement.getAttribute('placeholder')).toBe('bound placeholder');
7579
});
7680

77-
it('should propagate the dynamic `placeholder` value to the form field', () => {
78-
fixture.componentInstance.placeholder = 'add a chip';
79-
fixture.detectChanges();
80-
81-
const label: HTMLElement = fixture.nativeElement.querySelector('.mat-form-field-label');
82-
83-
expect(label).toBeTruthy();
84-
expect(label.textContent).toContain('add a chip');
85-
86-
fixture.componentInstance.placeholder = 'or don\'t';
87-
fixture.detectChanges();
88-
89-
expect(label.textContent).toContain('or don\'t');
90-
});
91-
9281
it('should become disabled if the list is disabled', () => {
9382
expect(inputNativeElement.hasAttribute('disabled')).toBe(false);
9483
expect(chipInputDirective.disabled).toBe(false);
@@ -143,6 +132,12 @@ describe('MDC-based MatChipInput', () => {
143132
expect(gridElement.getAttribute('tabindex')).toBe('0', 'Expected tabindex to remain 0');
144133
}));
145134

135+
it('should set input styling classes', () => {
136+
expect(inputNativeElement.classList).toContain('mat-mdc-input-element');
137+
expect(inputNativeElement.classList).toContain('mat-mdc-chip-input');
138+
expect(inputNativeElement.classList).toContain('mdc-text-field__input');
139+
});
140+
146141
});
147142

148143
describe('[addOnBlur]', () => {

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,10 @@ let nextUniqueId = 0;
3434
selector: 'input[matChipInputFor]',
3535
exportAs: 'matChipInput, matChipInputFor',
3636
host: {
37-
'class': 'mat-mdc-chip-input mat-input-element',
37+
// TODO: eventually we should remove `mat-input-element` from here since it comes from the
38+
// non-MDC version of the input. It's currently being kept for backwards compatibility, because
39+
// the MDC chips were landed initially with it.
40+
'class': 'mat-mdc-chip-input mat-mdc-input-element mdc-text-field__input mat-input-element',
3841
'(keydown)': '_keydown($event)',
3942
'(blur)': '_blur()',
4043
'(focus)': '_focus()',

src/material-experimental/mdc-chips/chips.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ $mat-mdc-chip-margin: 4px;
108108
margin: -$mat-mdc-chip-margin;
109109

110110
// Keep the mat-chip-grid height the same even when there are no chips.
111-
input.mat-input-element {
111+
input.mat-mdc-chip-input {
112112
margin: $mat-mdc-chip-margin;
113113
}
114114
}

src/material-experimental/mdc-chips/testing/BUILD.bazel

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ ng_test_library(
2929
ng_web_test_suite(
3030
name = "unit_tests",
3131
static_files = [
32+
"@npm//:node_modules/@material/textfield/dist/mdc.textfield.js",
33+
"@npm//:node_modules/@material/line-ripple/dist/mdc.lineRipple.js",
34+
"@npm//:node_modules/@material/notched-outline/dist/mdc.notchedOutline.js",
35+
"@npm//:node_modules/@material/dom/dist/mdc.dom.js",
3236
"@npm//:node_modules/@material/chips/dist/mdc.chips.js",
3337
"@npm//:node_modules/@material/ripple/dist/mdc.ripple.js",
3438
],

src/material/chips/chip-input.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ describe('MatChipInput', () => {
139139
expect(inputNativeElement.getAttribute('aria-required')).toBe('true');
140140
});
141141

142+
it('should set input styling classes', () => {
143+
expect(inputNativeElement.classList).toContain('mat-input-element');
144+
expect(inputNativeElement.classList).toContain('mat-chip-input');
145+
});
146+
142147
});
143148

144149
describe('[addOnBlur]', () => {

0 commit comments

Comments
 (0)