Skip to content

Commit 358dc7f

Browse files
committed
refactor(aria/combobox): revert autocomplete examples and move simple-combobox variants
1 parent 15bf0bf commit 358dc7f

25 files changed

Lines changed: 1019 additions & 140 deletions

src/components-examples/aria/autocomplete/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ ng_project(
1313
"//:node_modules/@angular/common",
1414
"//:node_modules/@angular/core",
1515
"//:node_modules/@angular/forms",
16+
"//src/aria/combobox",
1617
"//src/aria/listbox",
17-
"//src/aria/simple-combobox",
1818
"//src/cdk/overlay",
1919
],
2020
)

src/components-examples/aria/autocomplete/autocomplete-auto-select/autocomplete-auto-select-example.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
1-
<div class="example-combobox-container">
1+
<div ngCombobox filterMode="auto-select">
22
<div #origin class="example-autocomplete">
33
<span class="example-search-icon material-symbols-outlined" translate="no">search</span>
44
<input
5-
ngCombobox
6-
#combobox="ngCombobox"
75
aria-label="Label dropdown"
86
placeholder="Select a country"
9-
[(value)]="searchString"
10-
[(expanded)]="popupExpanded"
7+
ngComboboxInput
118
/>
129
<button
1310
class="example-clear-button"
@@ -23,14 +20,17 @@
2320
{{countries().length === 0 ? 'No results found for ' + query() : ''}}
2421
</div>
2522

26-
<ng-template [cdkConnectedOverlay]="{origin, usePopover: 'inline', matchWidth: true}" [cdkConnectedOverlayOpen]="true">
27-
<ng-template ngComboboxPopup [combobox]="combobox">
23+
<ng-template ngComboboxPopupContainer>
24+
<ng-template
25+
[cdkConnectedOverlay]="{origin, usePopover: 'inline', matchWidth: true}"
26+
[cdkConnectedOverlayOpen]="true"
27+
>
2828
<div class="example-popup">
2929
@if (countries().length === 0) {
3030
<div class="example-no-results">No results found</div>
3131
}
3232

33-
<div ngListbox ngComboboxWidget focusMode="activedescendant" [tabIndex]="-1" [(value)]="selectedOption" (click)="onCommit()" (keydown.enter)="onCommit()">
33+
<div ngListbox>
3434
@for (country of countries(); track country) {
3535
<div ngOption [value]="country" [label]="country" [disabled]="country === 'Brazil'">
3636
<span class="example-option-label">{{country}}</span>

src/components-examples/aria/autocomplete/autocomplete-auto-select/autocomplete-auto-select-example.ts

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,20 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {Combobox, ComboboxPopup, ComboboxWidget} from '@angular/aria/simple-combobox';
9+
import {
10+
Combobox,
11+
ComboboxInput,
12+
ComboboxPopup,
13+
ComboboxPopupContainer,
14+
} from '@angular/aria/combobox';
1015
import {Listbox, Option} from '@angular/aria/listbox';
1116
import {
1217
afterRenderEffect,
1318
ChangeDetectionStrategy,
1419
Component,
1520
computed,
16-
signal,
1721
viewChild,
22+
viewChildren,
1823
} from '@angular/core';
1924
import {COUNTRIES} from '../countries';
2025
import {OverlayModule} from '@angular/cdk/overlay';
@@ -25,52 +30,60 @@ import {FormsModule} from '@angular/forms';
2530
selector: 'autocomplete-auto-select-example',
2631
templateUrl: 'autocomplete-auto-select-example.html',
2732
styleUrl: '../autocomplete.css',
28-
imports: [Combobox, ComboboxPopup, ComboboxWidget, Listbox, Option, OverlayModule, FormsModule],
33+
imports: [
34+
Combobox,
35+
ComboboxInput,
36+
ComboboxPopup,
37+
ComboboxPopupContainer,
38+
Listbox,
39+
Option,
40+
OverlayModule,
41+
FormsModule,
42+
],
2943
changeDetection: ChangeDetectionStrategy.OnPush,
3044
})
3145
export class AutocompleteAutoSelectExample {
3246
/** The selected value of the combobox. */
33-
readonly listbox = viewChild(Listbox);
34-
readonly combobox = viewChild(Combobox);
47+
listbox = viewChild<Listbox<string>>(Listbox);
48+
49+
/** The options available in the listbox. */
50+
options = viewChildren<Option<string>>(Option);
51+
52+
/** A reference to the ng aria combobox. */
53+
combobox = viewChild<Combobox<string>>(Combobox);
3554

36-
popupExpanded = signal(false);
37-
searchString = signal('');
38-
selectedOption = signal<string[]>([]);
55+
/** A reference to the ng aria combobox input. */
56+
comboboxInput = viewChild<ComboboxInput>(ComboboxInput);
3957

4058
/** The query string used to filter the list of countries. */
41-
query = computed(() => this.searchString());
59+
query = computed(() => this.comboboxInput()?.value() || '');
4260

4361
/** The list of countries filtered by the query. */
4462
countries = computed(() =>
4563
COUNTRIES.filter(country => country.toLowerCase().startsWith(this.query().toLowerCase())),
4664
);
4765

4866
constructor() {
67+
// Scrolls to the active item when the active option changes.
4968
afterRenderEffect(() => {
50-
this.listbox()?.scrollActiveItemIntoView();
69+
if (this.combobox()?.expanded()) {
70+
const option = this.options().find(opt => opt.active());
71+
option?.element.scrollIntoView({block: 'nearest'});
72+
}
5173
});
5274
}
5375

5476
/** Clears the query and the listbox value. */
5577
clear(): void {
56-
this.searchString.set('');
57-
this.selectedOption.set([]);
58-
}
59-
60-
onCommit() {
61-
const selectedOption = this.selectedOption();
62-
if (selectedOption.length > 0) {
63-
this.searchString.set(selectedOption[0]);
64-
}
65-
this.popupExpanded.set(false);
66-
this.combobox()?.element.focus();
78+
this.comboboxInput()?.value.set('');
79+
this.listbox?.()?.value.set([]);
6780
}
6881

6982
/** Handles keydown events on the clear button. */
7083
onKeydown(event: KeyboardEvent): void {
7184
if (event.key === 'Enter') {
7285
this.clear();
73-
this.popupExpanded.set(false);
86+
this.combobox?.()?.close();
7487
event.stopPropagation();
7588
}
7689
}

src/components-examples/aria/autocomplete/autocomplete-disabled/autocomplete-disabled-example.html

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,24 @@
1-
<div class="example-combobox-container">
1+
<div ngCombobox disabled>
22
<div #origin class="example-autocomplete">
33
<span class="example-search-icon material-symbols-outlined" translate="no">search</span>
44
<input
5-
ngCombobox
6-
#combobox="ngCombobox"
75
aria-label="Label dropdown"
86
placeholder="Select a country"
9-
[(value)]="searchString"
10-
[(expanded)]="popupExpanded"
11-
disabled
12-
readonly
7+
ngComboboxInput
138
/>
149
</div>
1510

16-
<ng-template [cdkConnectedOverlay]="{origin, usePopover: 'inline', matchWidth: true}" [cdkConnectedOverlayOpen]="true">
17-
<ng-template ngComboboxPopup [combobox]="combobox">
11+
<ng-template ngComboboxPopupContainer>
12+
<ng-template
13+
[cdkConnectedOverlay]="{origin, usePopover: 'inline', matchWidth: true}"
14+
[cdkConnectedOverlayOpen]="true"
15+
>
1816
<div class="example-popup">
1917
@if (countries().length === 0) {
2018
<div class="example-no-results">No results found</div>
2119
}
2220

23-
<div ngListbox ngComboboxWidget focusMode="activedescendant" [tabIndex]="-1" [(value)]="selectedOption">
21+
<div ngListbox>
2422
@for (country of countries(); track country) {
2523
<div ngOption [value]="country" [label]="country" [disabled]="country === 'Brazil'">
2624
<span class="example-option-label">{{country}}</span>

src/components-examples/aria/autocomplete/autocomplete-disabled/autocomplete-disabled-example.ts

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@
66
* found in the LICENSE file at https://angular.dev/license
77
*/
88

9-
import {Combobox, ComboboxPopup, ComboboxWidget} from '@angular/aria/simple-combobox';
9+
import {
10+
Combobox,
11+
ComboboxInput,
12+
ComboboxPopup,
13+
ComboboxPopupContainer,
14+
} from '@angular/aria/combobox';
1015
import {Listbox, Option} from '@angular/aria/listbox';
1116
import {
1217
afterRenderEffect,
@@ -15,6 +20,7 @@ import {
1520
computed,
1621
signal,
1722
viewChild,
23+
viewChildren,
1824
} from '@angular/core';
1925
import {COUNTRIES} from '../countries';
2026
import {OverlayModule} from '@angular/cdk/overlay';
@@ -25,29 +31,40 @@ import {FormsModule} from '@angular/forms';
2531
selector: 'autocomplete-disabled-example',
2632
templateUrl: 'autocomplete-disabled-example.html',
2733
styleUrl: '../autocomplete.css',
28-
imports: [Combobox, ComboboxPopup, ComboboxWidget, Listbox, Option, OverlayModule, FormsModule],
34+
imports: [
35+
Combobox,
36+
ComboboxInput,
37+
ComboboxPopup,
38+
ComboboxPopupContainer,
39+
Listbox,
40+
Option,
41+
OverlayModule,
42+
FormsModule,
43+
],
2944
changeDetection: ChangeDetectionStrategy.OnPush,
3045
})
3146
export class AutocompleteDisabledExample {
32-
/** The selected value of the combobox. */
33-
readonly listbox = viewChild(Listbox);
34-
readonly combobox = viewChild(Combobox);
47+
/** The options available in the listbox. */
48+
options = viewChildren<Option<string>>(Option);
3549

36-
popupExpanded = signal(false);
37-
searchString = signal('United States of America');
38-
selectedOption = signal<string[]>([]);
50+
/** A reference to the ng aria combobox. */
51+
combobox = viewChild<Combobox<string>>(Combobox);
3952

4053
/** The query string used to filter the list of countries. */
41-
query = computed(() => this.searchString());
54+
query = signal('United States of America');
4255

4356
/** The list of countries filtered by the query. */
4457
countries = computed(() =>
4558
COUNTRIES.filter(country => country.toLowerCase().startsWith(this.query().toLowerCase())),
4659
);
4760

4861
constructor() {
62+
// Scrolls to the active item when the active option changes.
4963
afterRenderEffect(() => {
50-
this.listbox()?.scrollActiveItemIntoView();
64+
if (this.combobox()?.expanded()) {
65+
const option = this.options().find(opt => opt.active());
66+
option?.element.scrollIntoView({block: 'nearest'});
67+
}
5168
});
5269
}
5370
}

src/components-examples/aria/autocomplete/autocomplete-highlight/autocomplete-highlight-example.html

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
1-
<div class="example-combobox-container">
1+
<div ngCombobox filterMode="highlight">
22
<div #origin class="example-autocomplete">
33
<span class="example-search-icon material-symbols-outlined" translate="no">search</span>
44
<input
5-
ngCombobox
6-
#combobox="ngCombobox"
75
aria-label="Label dropdown"
86
placeholder="Select a country"
9-
[(value)]="searchString"
10-
[(expanded)]="popupExpanded"
11-
[inlineSuggestion]="selectedOption()[0] || countries()[0]"
7+
ngComboboxInput
128
/>
139
<button
1410
class="example-clear-button"
@@ -23,15 +19,18 @@
2319
<div aria-live="polite" class="cdk-visually-hidden">
2420
{{countries().length === 0 ? 'No results found for ' + query() : ''}}
2521
</div>
26-
27-
<ng-template [cdkConnectedOverlay]="{origin, usePopover: 'inline', matchWidth: true}" [cdkConnectedOverlayOpen]="true">
28-
<ng-template ngComboboxPopup [combobox]="combobox">
22+
23+
<ng-template ngComboboxPopupContainer>
24+
<ng-template
25+
[cdkConnectedOverlay]="{origin, usePopover: 'inline', matchWidth: true}"
26+
[cdkConnectedOverlayOpen]="true"
27+
>
2928
<div class="example-popup">
3029
@if (countries().length === 0) {
3130
<div class="example-no-results">No results found</div>
3231
}
3332

34-
<div ngListbox ngComboboxWidget focusMode="activedescendant" [tabIndex]="-1" [(value)]="selectedOption" (click)="onCommit()" (keydown.enter)="onCommit()">
33+
<div ngListbox>
3534
@for (country of countries(); track country) {
3635
<div ngOption [value]="country" [label]="country" [disabled]="country === 'Brazil'">
3736
<span class="example-option-label">{{country}}</span>

0 commit comments

Comments
 (0)