Skip to content

Commit c176670

Browse files
authored
feat(cdk-experimental/combobox): glue together combobox and listbox with DI instead of a panel directive (#24637)
* feat(cdk-experimental/combobox): glue together combobox and listbox with DI instead of a panel directive * fixup! feat(cdk-experimental/combobox): glue together combobox and listbox with DI instead of a panel directive * fixup! feat(cdk-experimental/combobox): glue together combobox and listbox with DI instead of a panel directive
1 parent b4058d7 commit c176670

File tree

11 files changed

+110
-281
lines changed

11 files changed

+110
-281
lines changed

src/cdk-experimental/combobox/combobox-module.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@
99
import {NgModule} from '@angular/core';
1010
import {OverlayModule} from '@angular/cdk/overlay';
1111
import {CdkCombobox} from './combobox';
12-
import {CdkComboboxPanel} from './combobox-panel';
1312
import {CdkComboboxPopup} from './combobox-popup';
1413

15-
const EXPORTED_DECLARATIONS = [CdkCombobox, CdkComboboxPanel, CdkComboboxPopup];
14+
const EXPORTED_DECLARATIONS = [CdkCombobox, CdkComboboxPopup];
1615
@NgModule({
1716
imports: [OverlayModule],
1817
exports: EXPORTED_DECLARATIONS,

src/cdk-experimental/combobox/combobox-panel.ts

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

src/cdk-experimental/combobox/combobox-popup.ts

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

9-
import {
10-
Directive,
11-
ElementRef,
12-
Inject,
13-
InjectionToken,
14-
Input,
15-
OnInit,
16-
Optional,
17-
} from '@angular/core';
18-
import {AriaHasPopupValue, CdkComboboxPanel} from './combobox-panel';
19-
20-
export const PANEL = new InjectionToken<CdkComboboxPanel>('CdkComboboxPanel');
9+
import {Directive, ElementRef, Inject, Input, OnInit} from '@angular/core';
10+
import {AriaHasPopupValue, CDK_COMBOBOX, CdkCombobox} from './combobox';
2111

2212
let nextId = 0;
2313

@@ -53,23 +43,17 @@ export class CdkComboboxPopup<T = unknown> implements OnInit {
5343

5444
@Input() id = `cdk-combobox-popup-${nextId++}`;
5545

56-
@Input('parentPanel') private readonly _explicitPanel: CdkComboboxPanel;
57-
5846
constructor(
5947
private readonly _elementRef: ElementRef<HTMLElement>,
60-
@Optional() @Inject(PANEL) readonly _parentPanel?: CdkComboboxPanel<T>,
48+
@Inject(CDK_COMBOBOX) private readonly _combobox: CdkCombobox,
6149
) {}
6250

6351
ngOnInit() {
6452
this.registerWithPanel();
6553
}
6654

6755
registerWithPanel(): void {
68-
if (this._parentPanel === null || this._parentPanel === undefined) {
69-
this._explicitPanel._registerContent(this.id, this._role);
70-
} else {
71-
this._parentPanel._registerContent(this.id, this._role);
72-
}
56+
this._combobox._registerContent(this.id, this._role);
7357
}
7458

7559
focusFirstElement() {

src/cdk-experimental/combobox/combobox.spec.ts

Lines changed: 20 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,23 @@
1-
import {
2-
Component,
3-
DebugElement,
4-
Directive,
5-
ElementRef,
6-
Inject,
7-
InjectionToken,
8-
Input,
9-
OnInit,
10-
Optional,
11-
ViewChild,
12-
} from '@angular/core';
1+
import {Component, DebugElement, ElementRef, ViewChild} from '@angular/core';
132
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
143
import {By} from '@angular/platform-browser';
154
import {CdkComboboxModule} from './combobox-module';
165
import {CdkCombobox} from './combobox';
176
import {dispatchKeyboardEvent, dispatchMouseEvent} from '../../cdk/testing/private';
18-
import {
19-
AriaHasPopupValue,
20-
CdkComboboxPanel,
21-
} from '@angular/cdk-experimental/combobox/combobox-panel';
227
import {DOWN_ARROW, ESCAPE} from '@angular/cdk/keycodes';
8+
import {CdkComboboxPopup} from '@angular/cdk-experimental/combobox/combobox-popup';
239

2410
describe('Combobox', () => {
2511
describe('with a basic toggle trigger', () => {
2612
let fixture: ComponentFixture<ComboboxToggle>;
2713
let testComponent: ComboboxToggle;
2814

2915
let combobox: DebugElement;
30-
let comboboxInstance: CdkCombobox<unknown>;
16+
let comboboxInstance: CdkCombobox;
3117
let comboboxElement: HTMLElement;
3218

3319
let dialog: DebugElement;
34-
let dialogInstance: FakeDialogContent<unknown>;
20+
let dialogInstance: CdkComboboxPopup;
3521
let dialogElement: HTMLElement;
3622

3723
let applyButton: DebugElement;
@@ -41,7 +27,7 @@ describe('Combobox', () => {
4127
waitForAsync(() => {
4228
TestBed.configureTestingModule({
4329
imports: [CdkComboboxModule],
44-
declarations: [ComboboxToggle, FakeDialogContent],
30+
declarations: [ComboboxToggle],
4531
}).compileComponents();
4632
}),
4733
);
@@ -53,7 +39,7 @@ describe('Combobox', () => {
5339
testComponent = fixture.debugElement.componentInstance;
5440

5541
combobox = fixture.debugElement.query(By.directive(CdkCombobox));
56-
comboboxInstance = combobox.injector.get<CdkCombobox<unknown>>(CdkCombobox);
42+
comboboxInstance = combobox.injector.get<CdkCombobox>(CdkCombobox);
5743
comboboxElement = combobox.nativeElement;
5844
});
5945

@@ -77,10 +63,10 @@ describe('Combobox', () => {
7763
dispatchMouseEvent(comboboxElement, 'click');
7864
fixture.detectChanges();
7965

80-
dialog = fixture.debugElement.query(By.directive(FakeDialogContent));
81-
dialogInstance = dialog.injector.get<FakeDialogContent<unknown>>(FakeDialogContent);
66+
dialog = fixture.debugElement.query(By.directive(CdkComboboxPopup));
67+
dialogInstance = dialog.injector.get<CdkComboboxPopup>(CdkComboboxPopup);
8268

83-
expect(comboboxElement.getAttribute('aria-owns')).toBe(dialogInstance.dialogId);
69+
expect(comboboxElement.getAttribute('aria-owns')).toBe(dialogInstance.id);
8470
expect(comboboxElement.getAttribute('aria-haspopup')).toBe('dialog');
8571
});
8672

@@ -110,7 +96,7 @@ describe('Combobox', () => {
11096

11197
expect(comboboxInstance.isOpen()).toBeTrue();
11298

113-
dialog = fixture.debugElement.query(By.directive(FakeDialogContent));
99+
dialog = fixture.debugElement.query(By.directive(CdkComboboxPopup));
114100
dialogElement = dialog.nativeElement;
115101

116102
expect(document.activeElement).toBe(dialogElement);
@@ -201,13 +187,13 @@ describe('Combobox', () => {
201187
let testComponent: ComboboxToggle;
202188

203189
let combobox: DebugElement;
204-
let comboboxInstance: CdkCombobox<unknown>;
190+
let comboboxInstance: CdkCombobox;
205191

206192
beforeEach(
207193
waitForAsync(() => {
208194
TestBed.configureTestingModule({
209195
imports: [CdkComboboxModule],
210-
declarations: [ComboboxToggle, FakeDialogContent],
196+
declarations: [ComboboxToggle],
211197
}).compileComponents();
212198
}),
213199
);
@@ -219,7 +205,7 @@ describe('Combobox', () => {
219205
testComponent = fixture.debugElement.componentInstance;
220206

221207
combobox = fixture.debugElement.query(By.directive(CdkCombobox));
222-
comboboxInstance = combobox.injector.get<CdkCombobox<unknown>>(CdkCombobox);
208+
comboboxInstance = combobox.injector.get<CdkCombobox>(CdkCombobox);
223209
});
224210

225211
it('should coerce single string into open action', () => {
@@ -273,14 +259,14 @@ describe('Combobox', () => {
273259
let testComponent: ComboboxToggle;
274260

275261
let combobox: DebugElement;
276-
let comboboxInstance: CdkCombobox<unknown>;
262+
let comboboxInstance: CdkCombobox;
277263
let comboboxElement: HTMLElement;
278264

279265
beforeEach(
280266
waitForAsync(() => {
281267
TestBed.configureTestingModule({
282268
imports: [CdkComboboxModule],
283-
declarations: [ComboboxToggle, FakeDialogContent],
269+
declarations: [ComboboxToggle],
284270
}).compileComponents();
285271
}),
286272
);
@@ -292,7 +278,7 @@ describe('Combobox', () => {
292278
testComponent = fixture.debugElement.componentInstance;
293279

294280
combobox = fixture.debugElement.query(By.directive(CdkCombobox));
295-
comboboxInstance = combobox.injector.get<CdkCombobox<unknown>>(CdkCombobox);
281+
comboboxInstance = combobox.injector.get<CdkCombobox>(CdkCombobox);
296282
comboboxElement = combobox.nativeElement;
297283
});
298284

@@ -392,17 +378,17 @@ describe('Combobox', () => {
392378

393379
@Component({
394380
template: `
395-
<button cdkCombobox #toggleCombobox class="example-combobox"
381+
<button cdkCombobox #toggleCombobox="cdkCombobox" class="example-combobox"
396382
[cdkComboboxTriggerFor]="panel"
397383
[openActions]="actions">
398384
No Value
399385
</button>
400386
<div id="other-content"></div>
401387
402-
<ng-template cdkComboboxPanel #panel="cdkComboboxPanel">
403-
<div dialogContent #dialog="dialogContent" [parentPanel]="panel">
388+
<ng-template #panel>
389+
<div #dialog cdkComboboxPopup>
404390
<input #input>
405-
<button id="applyButton" (click)="panel.closePanel(input.value)">Apply</button>
391+
<button id="applyButton" (click)="toggleCombobox.updateAndClose(input.value)">Apply</button>
406392
</div>
407393
</ng-template>`,
408394
})
@@ -411,37 +397,3 @@ class ComboboxToggle {
411397

412398
actions: string = 'click';
413399
}
414-
415-
export const PANEL = new InjectionToken<CdkComboboxPanel>('CdkComboboxPanel');
416-
417-
let id = 0;
418-
419-
@Directive({
420-
selector: '[dialogContent]',
421-
exportAs: 'dialogContent',
422-
host: {
423-
'[attr.role]': 'role',
424-
'[id]': 'dialogId',
425-
'tabIndex': '-1',
426-
},
427-
})
428-
export class FakeDialogContent<V> implements OnInit {
429-
dialogId = `dialog-${id++}`;
430-
role = 'dialog';
431-
432-
@Input('parentPanel') private readonly _explicitPanel: CdkComboboxPanel;
433-
434-
constructor(@Optional() @Inject(PANEL) readonly _parentPanel?: CdkComboboxPanel<V>) {}
435-
436-
ngOnInit() {
437-
this.registerWithPanel();
438-
}
439-
440-
registerWithPanel(): void {
441-
if (this._parentPanel === null || this._parentPanel === undefined) {
442-
this._explicitPanel._registerContent(this.dialogId, this.role as AriaHasPopupValue);
443-
} else {
444-
this._parentPanel._registerContent(this.dialogId, this.role as AriaHasPopupValue);
445-
}
446-
}
447-
}

0 commit comments

Comments
 (0)