Skip to content

Commit 904893f

Browse files
committed
docs(cdk-experimental/combobox): add component examples
1 parent 8cf7115 commit 904893f

File tree

12 files changed

+601
-164
lines changed

12 files changed

+601
-164
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<div
2+
#combobox="cdkCombobox"
3+
cdkCombobox
4+
class="example-combobox-container"
5+
filterMode="auto-select"
6+
>
7+
<div class="example-combobox-input-container">
8+
<span class="material-symbols-outlined example-icon example-search-icon">search</span>
9+
<input cdkComboboxInput class="example-combobox-input" placeholder="Search..." />
10+
</div>
11+
12+
<div popover="manual" #popover class="example-popover">
13+
<ng-template cdkComboboxPopupContent>
14+
<div cdkListbox class="example-listbox">
15+
@for (state of states; track state) {
16+
<div
17+
class="example-option example-selectable example-stateful"
18+
cdkOption
19+
[value]="state"
20+
[label]="state"
21+
>
22+
<span>{{state}}</span>
23+
<span
24+
aria-hidden="true"
25+
class="material-symbols-outlined example-icon example-selected-icon"
26+
>check</span
27+
>
28+
</div>
29+
}
30+
</div>
31+
</ng-template>
32+
</div>
33+
</div>
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.dev/license
7+
*/
8+
9+
import {
10+
CdkCombobox,
11+
CdkComboboxInput,
12+
CdkComboboxPopup,
13+
CdkComboboxPopupContent,
14+
} from '@angular/cdk-experimental/combobox';
15+
import {CdkListbox, CdkOption} from '@angular/cdk-experimental/listbox';
16+
import {
17+
afterRenderEffect,
18+
ChangeDetectionStrategy,
19+
Component,
20+
ElementRef,
21+
viewChild,
22+
} from '@angular/core';
23+
24+
/** @title Combobox with auto-select filtering. */
25+
@Component({
26+
selector: 'cdk-combobox-auto-select-example',
27+
templateUrl: 'cdk-combobox-auto-select-example.html',
28+
styleUrl: '../cdk-combobox-examples.css',
29+
imports: [
30+
CdkCombobox,
31+
CdkComboboxInput,
32+
CdkComboboxPopup,
33+
CdkComboboxPopupContent,
34+
CdkListbox,
35+
CdkOption,
36+
],
37+
changeDetection: ChangeDetectionStrategy.OnPush,
38+
})
39+
export class CdkComboboxAutoSelectExample {
40+
popover = viewChild<ElementRef>('popover');
41+
listbox = viewChild<CdkListbox<any>>(CdkListbox);
42+
combobox = viewChild<CdkCombobox<any>>(CdkCombobox);
43+
44+
states = [
45+
'Alabama',
46+
'Alaska',
47+
'Arizona',
48+
'Arkansas',
49+
'California',
50+
'Colorado',
51+
'Connecticut',
52+
'Delaware',
53+
'Florida',
54+
'Georgia',
55+
'Hawaii',
56+
'Idaho',
57+
'Illinois',
58+
'Indiana',
59+
'Iowa',
60+
'Kansas',
61+
'Kentucky',
62+
'Louisiana',
63+
'Maine',
64+
'Maryland',
65+
'Massachusetts',
66+
'Michigan',
67+
'Minnesota',
68+
'Mississippi',
69+
'Missouri',
70+
'Montana',
71+
'Nebraska',
72+
'Nevada',
73+
'New Hampshire',
74+
'New Jersey',
75+
'New Mexico',
76+
'New York',
77+
'North Carolina',
78+
'North Dakota',
79+
'Ohio',
80+
'Oklahoma',
81+
'Oregon',
82+
'Pennsylvania',
83+
'Rhode Island',
84+
'South Carolina',
85+
'South Dakota',
86+
'Tennessee',
87+
'Texas',
88+
'Utah',
89+
'Vermont',
90+
'Virginia',
91+
'Washington',
92+
'West Virginia',
93+
'Wisconsin',
94+
'Wyoming',
95+
];
96+
97+
constructor() {
98+
afterRenderEffect(() => {
99+
const popover = this.popover()!;
100+
const combobox = this.combobox()!;
101+
combobox.pattern.expanded() ? this.showPopover() : popover.nativeElement.hidePopover();
102+
103+
// TODO(wagnermaciel): Make this easier for developers to do.
104+
this.listbox()?.pattern.inputs.activeItem()?.element().scrollIntoView({block: 'nearest'});
105+
});
106+
}
107+
108+
showPopover() {
109+
const popover = this.popover()!;
110+
const combobox = this.combobox()!;
111+
112+
const comboboxRect = combobox.pattern.inputs.inputEl()?.getBoundingClientRect();
113+
const popoverEl = popover.nativeElement;
114+
115+
if (comboboxRect) {
116+
popoverEl.style.width = `${comboboxRect.width}px`;
117+
popoverEl.style.top = `${comboboxRect.bottom}px`;
118+
popoverEl.style.left = `${comboboxRect.left - 1}px`;
119+
}
120+
121+
popover.nativeElement.showPopover();
122+
}
123+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
.example-combobox-container {
2+
position: relative;
3+
width: 300px;
4+
display: flex;
5+
overflow: hidden;
6+
flex-direction: column;
7+
border: 1px solid var(--mat-sys-outline);
8+
border-radius: var(--mat-sys-corner-extra-small);
9+
}
10+
11+
.example-combobox-container:has(.example-combobox-input[aria-expanded='true']) {
12+
border-bottom-right-radius: 0;
13+
border-bottom-left-radius: 0;
14+
}
15+
16+
.example-combobox-input-container {
17+
display: flex;
18+
overflow: hidden;
19+
position: relative;
20+
align-items: center;
21+
}
22+
23+
.example-icon {
24+
width: 24px;
25+
height: 24px;
26+
font-size: 20px;
27+
display: grid;
28+
place-items: center;
29+
pointer-events: none;
30+
}
31+
32+
.example-search-icon {
33+
padding: 0 0.5rem;
34+
position: absolute;
35+
opacity: 0.8;
36+
}
37+
38+
.example-combobox-input {
39+
width: 100%;
40+
border: none;
41+
outline: none;
42+
font-size: 1rem;
43+
padding: 0.7rem 1rem 0.7rem 2.5rem;
44+
background-color: var(--mat-sys-surface);
45+
}
46+
47+
.example-popover {
48+
margin: 0;
49+
padding: 0;
50+
border: 1px solid var(--mat-sys-outline);
51+
border-bottom-right-radius: var(--mat-sys-corner-extra-small);
52+
border-bottom-left-radius: var(--mat-sys-corner-extra-small);
53+
background-color: var(--mat-sys-surface);
54+
}
55+
56+
.example-listbox {
57+
display: flex;
58+
flex-direction: column;
59+
overflow: auto;
60+
max-height: 10rem;
61+
padding: 0.5rem;
62+
}
63+
64+
.example-option {
65+
cursor: pointer;
66+
padding: 0.3rem 1rem;
67+
border-radius: var(--mat-sys-corner-extra-small);
68+
display: flex;
69+
overflow: hidden;
70+
flex-shrink: 0;
71+
align-items: center;
72+
justify-content: space-between;
73+
}
74+
75+
.example-selected-icon {
76+
visibility: hidden;
77+
}
78+
79+
.example-option[aria-selected='true'] .example-selected-icon {
80+
visibility: visible;
81+
}
82+
83+
.example-option[inert] {
84+
height: 0;
85+
padding: 0 1rem;
86+
}
87+
88+
.example-combobox-container:focus-within .cdk-active {
89+
background: color-mix(
90+
in srgb,
91+
var(--mat-sys-on-surface) calc(var(--mat-sys-focus-state-layer-opacity) * 100%),
92+
transparent
93+
);
94+
}
95+
96+
.example-combobox-container:focus-within .cdk-active[aria-selected='true'] {
97+
background: color-mix(
98+
in srgb,
99+
var(--mat-sys-primary) calc(var(--mat-sys-pressed-state-layer-opacity) * 100%),
100+
transparent
101+
);
102+
color: var(--mat-sys-primary);
103+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<div #combobox="cdkCombobox" cdkCombobox class="example-combobox-container" filterMode="highlight">
2+
<div class="example-combobox-input-container">
3+
<span class="material-symbols-outlined example-icon example-search-icon">search</span>
4+
<input cdkComboboxInput class="example-combobox-input" placeholder="Search..." />
5+
</div>
6+
7+
<div popover="manual" #popover class="example-popover">
8+
<ng-template cdkComboboxPopupContent>
9+
<div cdkListbox class="example-listbox">
10+
@for (state of states; track state) {
11+
<div
12+
class="example-option example-selectable example-stateful"
13+
cdkOption
14+
[value]="state"
15+
[label]="state"
16+
>
17+
<span>{{state}}</span>
18+
<span
19+
aria-hidden="true"
20+
class="material-symbols-outlined example-icon example-selected-icon"
21+
>check</span
22+
>
23+
</div>
24+
}
25+
</div>
26+
</ng-template>
27+
</div>
28+
</div>

0 commit comments

Comments
 (0)