Skip to content

Commit

Permalink
feat(cdk-experimental/combobox): added additional open actions and a …
Browse files Browse the repository at this point in the history
…combobox-popup directive (#20306)

Combobox open actions

* build: Added required files to listbox directory.

* build: added listbox option directive and renamed listbox directive files.

* build: Added required files to listbox directory.

* build: added listbox option directive and renamed listbox directive files.

* build: Added required files to listbox directory.

* build: added listbox option directive and renamed listbox directive files.

* build: Added required files to listbox directory.

* build: added listbox option directive and renamed listbox directive files.

* feat(dev-app/listbox): added cdk listbox example to the dev-app.

* fix(listbox): removed duplicate dep in dev-app build file.

* fix(listbox): deleted unused files.

* refactor(combobox): changed names and made coerceOpenActionProperty simpler for this PR.

* fix(combobox): updated syntax for casting.

* refactor(combobox): changed casting syntax back.

* fix(combobox): fixed trailing whitespace.

* refactor(combobox): improved coerceOpenActions function to handle whitespace separated strings as input.

* fix(combobox): split the coerceOpenActions on comma or space.

* feat(combobox): added aria-expanded and aria-owns traits.

* refactor(combobox): minor refactor.

* feat(combobox): added logic to close popup on click outside of combobox.

* test(combobox): added many tests for combobox open action features.

* test(combobox): added back two failing tests, focus and sending input value to combobox.

* refactor(combobox): further tests on focus.

* refactor(combobox): added tabindex to allow focusing on content, and fixed the setTextContent function.

* fix(combobox): removed separate coerceArray import.

* fix(combobox): lint errors.

* refactor(combobox): only throw error in coercing open action in dev mode, condense click and focus handlers into one.

* nit(combobox): removed whitespace.

* fix(combobox): removed unused imports.

* feat(combobox): added combobox popup directive to handle registering panel content with panel.

* nit(combobox): changed double quotes to single quotes.

* nit(combobox): changed class names and parameter types.

* fix(combobox): changed import to relative import.
  • Loading branch information
nielsr98 committed Aug 14, 2020
1 parent 004afa1 commit 809f157
Show file tree
Hide file tree
Showing 7 changed files with 484 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/cdk-experimental/combobox/BUILD.bazel
Expand Up @@ -25,6 +25,7 @@ ng_test_library(
),
deps = [
":combobox",
"//src/cdk/keycodes",
"//src/cdk/testing/private",
"@npm//@angular/platform-browser",
],
Expand Down
3 changes: 2 additions & 1 deletion src/cdk-experimental/combobox/combobox-module.ts
Expand Up @@ -10,8 +10,9 @@ import {NgModule} from '@angular/core';
import {OverlayModule} from '@angular/cdk/overlay';
import {CdkCombobox} from './combobox';
import {CdkComboboxPanel} from './combobox-panel';
import {CdkComboboxPopup} from './combobox-popup';

const EXPORTED_DECLARATIONS = [CdkCombobox, CdkComboboxPanel];
const EXPORTED_DECLARATIONS = [CdkCombobox, CdkComboboxPanel, CdkComboboxPopup];
@NgModule({
imports: [OverlayModule],
exports: EXPORTED_DECLARATIONS,
Expand Down
15 changes: 13 additions & 2 deletions src/cdk-experimental/combobox/combobox-panel.ts
Expand Up @@ -12,6 +12,9 @@ import {Directive, TemplateRef} from '@angular/core';
import {Subject} from 'rxjs';

@Directive({
host: {
'class': 'cdk-combobox-panel'
},
selector: 'ng-template[cdkComboboxPanel]',
exportAs: 'cdkComboboxPanel',
})
Expand All @@ -24,13 +27,21 @@ export class CdkComboboxPanel<T = unknown> {
contentId: string = '';
contentType: AriaHasPopupValue;

constructor(readonly _templateRef: TemplateRef<unknown>) {}
constructor(
readonly _templateRef: TemplateRef<unknown>
) {}

/** Tells the parent combobox to closet he panel and sends back the content value. */
/** Tells the parent combobox to close the panel and sends back the content value. */
closePanel(data?: T) {
this.valueUpdated.next(data);
}

// TODO: instead of using a focus function, potentially use cdk/a11y focus trapping
focusContent() {
// TODO: Use an injected document here
document.getElementById(this.contentId)?.focus();
}

/** Registers the content's id and the content type with the panel. */
_registerContent(contentId: string, contentType: AriaHasPopupValue) {
this.contentId = contentId;
Expand Down
55 changes: 55 additions & 0 deletions src/cdk-experimental/combobox/combobox-popup.ts
@@ -0,0 +1,55 @@
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {Directive, Inject, InjectionToken, Input, OnInit, Optional} from '@angular/core';
import {AriaHasPopupValue, CdkComboboxPanel} from './combobox-panel';

export const PANEL = new InjectionToken<CdkComboboxPanel>('CdkComboboxPanel');

let nextId = 0;

@Directive({
selector: '[cdkComboboxPopup]',
exportAs: 'cdkComboboxPopup',
host: {
'class': 'cdk-combobox-popup',
'[attr.role]': 'role',
'[id]': 'id',
'tabindex': '-1'
}
})
export class CdkComboboxPopup<T = unknown> implements OnInit {
@Input()
get role(): AriaHasPopupValue {
return this._role;
}
set role(value: AriaHasPopupValue) {
this._role = value;
}
private _role: AriaHasPopupValue = 'dialog';

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

@Input('parentPanel') private readonly _explicitPanel: CdkComboboxPanel;

constructor(
@Optional() @Inject(PANEL) readonly _parentPanel?: CdkComboboxPanel<T>,
) { }

ngOnInit() {
this.registerWithPanel();
}

registerWithPanel(): void {
if (this._parentPanel === null || this._parentPanel === undefined) {
this._explicitPanel._registerContent(this.id, this._role);
} else {
this._parentPanel._registerContent(this.id, this._role);
}
}
}

0 comments on commit 809f157

Please sign in to comment.