Skip to content

Commit d2be70e

Browse files
committed
main - ea25472 docs(aria/combobox): material select demo (#32336)
1 parent 4359346 commit d2be70e

20 files changed

+891
-477
lines changed
Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,26 @@
1-
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ngCombobox</span> #<span class="hljs-attr">combobox</span>=<span class="hljs-string">&quot;ngCombobox&quot;</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-combobox-container&quot;</span> [<span class="hljs-attr">readonly</span>]=<span class="hljs-string">&quot;true&quot;</span> [<span class="hljs-attr">disabled</span>]=<span class="hljs-string">&quot;true&quot;</span>&gt;</span>
2-
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-combobox-input-container&quot;</span>&gt;</span>
3-
<span class="hljs-tag">&lt;<span class="hljs-name">input</span>
4-
<span class="hljs-attr">ngComboboxInput</span>
5-
<span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-combobox-input&quot;</span>
6-
<span class="hljs-attr">placeholder</span>=<span class="hljs-string">&quot;Search...&quot;</span>
7-
[(<span class="hljs-attr">value</span>)]=<span class="hljs-string">&quot;searchString&quot;</span>
8-
/&gt;</span>
9-
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;material-symbols-outlined example-icon example-arrow-icon&quot;</span>&gt;</span>arrow_drop_down<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
1+
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ngCombobox</span> <span class="hljs-attr">readonly</span> <span class="hljs-attr">disabled</span>&gt;</span>
2+
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> #<span class="hljs-attr">origin</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-select&quot;</span>&gt;</span>
3+
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-combobox-text&quot;</span>&gt;</span>{{ displayValue() }}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
4+
<span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">aria-label</span>=<span class="hljs-string">&quot;Label dropdown&quot;</span> <span class="hljs-attr">placeholder</span>=<span class="hljs-string">&quot;Select a label&quot;</span> <span class="hljs-attr">ngComboboxInput</span> /&gt;</span>
5+
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-arrow material-symbols-outlined&quot;</span>&gt;</span>arrow_drop_down<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
106
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
117

12-
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">popover</span>=<span class="hljs-string">&quot;manual&quot;</span> #<span class="hljs-attr">popover</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-popover&quot;</span>&gt;</span>
8+
<span class="hljs-tag">&lt;<span class="hljs-name">ng-template</span>
9+
[<span class="hljs-attr">cdkConnectedOverlay</span>]=<span class="hljs-string">&quot;{origin, usePopover: &#x27;inline&#x27;, matchWidth: true}&quot;</span>
10+
[<span class="hljs-attr">cdkConnectedOverlayOpen</span>]=<span class="hljs-string">&quot;true&quot;</span>
11+
&gt;</span>
1312
<span class="hljs-tag">&lt;<span class="hljs-name">ng-template</span> <span class="hljs-attr">ngComboboxPopupContainer</span>&gt;</span>
14-
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ngListbox</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-listbox&quot;</span>&gt;</span>
15-
@for (option of options(); track option) {
16-
<span class="hljs-tag">&lt;<span class="hljs-name">div</span>
17-
<span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-option example-selectable example-stateful&quot;</span>
18-
<span class="hljs-attr">ngOption</span>
19-
[<span class="hljs-attr">value</span>]=<span class="hljs-string">&quot;option&quot;</span>
20-
[<span class="hljs-attr">label</span>]=<span class="hljs-string">&quot;option&quot;</span>
21-
&gt;</span>
22-
<span class="hljs-tag">&lt;<span class="hljs-name">span</span>&gt;</span>{{option}}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
23-
<span class="hljs-tag">&lt;<span class="hljs-name">span</span>
24-
<span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">&quot;true&quot;</span>
25-
<span class="hljs-attr">class</span>=<span class="hljs-string">&quot;material-symbols-outlined example-icon example-selected-icon&quot;</span>
26-
&gt;</span>check&lt;/span
27-
&gt;
28-
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
29-
}
13+
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-popup-container&quot;</span>&gt;</span>
14+
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ngListbox</span>&gt;</span>
15+
@for (label of labels; track label.value) {
16+
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">ngOption</span> [<span class="hljs-attr">value</span>]=<span class="hljs-string">&quot;label.value&quot;</span> [<span class="hljs-attr">label</span>]=<span class="hljs-string">&quot;label.value&quot;</span>&gt;</span>
17+
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-option-icon material-symbols-outlined&quot;</span>&gt;</span>{{label.icon}}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
18+
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-option-text&quot;</span>&gt;</span>{{label.value}}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
19+
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-option-check material-symbols-outlined&quot;</span>&gt;</span>check<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
20+
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
21+
}
22+
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
3023
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
3124
<span class="hljs-tag">&lt;/<span class="hljs-name">ng-template</span>&gt;</span>
32-
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
25+
<span class="hljs-tag">&lt;/<span class="hljs-name">ng-template</span>&gt;</span>
3326
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

docs-content/examples-highlighted/aria/combobox/combobox-readonly-disabled/combobox-readonly-disabled-example-ts.html

Lines changed: 47 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,61 +17,78 @@
1717
afterRenderEffect,
1818
<span class="hljs-title class_">ChangeDetectionStrategy</span>,
1919
<span class="hljs-title class_">Component</span>,
20-
<span class="hljs-title class_">ElementRef</span>,
2120
signal,
2221
viewChild,
22+
viewChildren,
2323
} <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;@angular/core&#x27;</span>;
24-
<span class="hljs-keyword">import</span> {<span class="hljs-title class_">FormsModule</span>} <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;@angular/forms&#x27;</span>;
24+
<span class="hljs-keyword">import</span> {<span class="hljs-title class_">OverlayModule</span>} <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;@angular/cdk/overlay&#x27;</span>;
2525

2626
<span class="hljs-comment">/** <span class="hljs-doctag">@title</span> Disabled readonly combobox. */</span>
2727
<span class="hljs-meta">@Component</span>({
2828
<span class="hljs-attr">selector</span>: <span class="hljs-string">&#x27;combobox-readonly-disabled-example&#x27;</span>,
2929
<span class="hljs-attr">templateUrl</span>: <span class="hljs-string">&#x27;combobox-readonly-disabled-example.html&#x27;</span>,
30-
<span class="hljs-attr">styleUrl</span>: <span class="hljs-string">&#x27;../combobox-examples.css&#x27;</span>,
30+
<span class="hljs-attr">styleUrl</span>: <span class="hljs-string">&#x27;../select-examples.css&#x27;</span>,
3131
<span class="hljs-attr">imports</span>: [
3232
<span class="hljs-title class_">Combobox</span>,
3333
<span class="hljs-title class_">ComboboxInput</span>,
3434
<span class="hljs-title class_">ComboboxPopup</span>,
3535
<span class="hljs-title class_">ComboboxPopupContainer</span>,
3636
<span class="hljs-title class_">Listbox</span>,
3737
<span class="hljs-title class_">Option</span>,
38-
<span class="hljs-title class_">FormsModule</span>,
38+
<span class="hljs-title class_">OverlayModule</span>,
3939
],
4040
<span class="hljs-attr">changeDetection</span>: <span class="hljs-title class_">ChangeDetectionStrategy</span>.<span class="hljs-property">OnPush</span>,
4141
})
4242
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ComboboxReadonlyDisabledExample</span> {
43-
popover = viewChild&lt;<span class="hljs-title class_">ElementRef</span>&gt;(<span class="hljs-string">&#x27;popover&#x27;</span>);
44-
listbox = viewChild&lt;<span class="hljs-title class_">Listbox</span>&lt;<span class="hljs-built_in">any</span>&gt;&gt;(<span class="hljs-title class_">Listbox</span>);
45-
combobox = viewChild&lt;<span class="hljs-title class_">Combobox</span>&lt;<span class="hljs-built_in">any</span>&gt;&gt;(<span class="hljs-title class_">Combobox</span>);
43+
<span class="hljs-comment">/** The string that is displayed in the combobox. */</span>
44+
displayValue = <span class="hljs-title function_">signal</span>(<span class="hljs-string">&#x27;&#x27;</span>);
4645

47-
options = <span class="hljs-function">() =&gt;</span> states;
48-
searchString = <span class="hljs-title function_">signal</span>(<span class="hljs-string">&#x27;&#x27;</span>);
46+
<span class="hljs-comment">/** The combobox listbox popup. */</span>
47+
listbox = viewChild&lt;<span class="hljs-title class_">Listbox</span>&lt;<span class="hljs-built_in">string</span>&gt;&gt;(<span class="hljs-title class_">Listbox</span>);
4948

50-
<span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span>) {
51-
<span class="hljs-title function_">afterRenderEffect</span>(<span class="hljs-function">() =&gt;</span> {
52-
<span class="hljs-keyword">const</span> popover = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">popover</span>()!;
53-
<span class="hljs-keyword">const</span> combobox = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">combobox</span>()!;
54-
combobox.<span class="hljs-title function_">expanded</span>() ? <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">showPopover</span>() : popover.<span class="hljs-property">nativeElement</span>.<span class="hljs-title function_">hidePopover</span>();
49+
<span class="hljs-comment">/** The options available in the listbox. */</span>
50+
options = viewChildren&lt;<span class="hljs-title class_">Option</span>&lt;<span class="hljs-built_in">string</span>&gt;&gt;(<span class="hljs-title class_">Option</span>);
5551

56-
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">listbox</span>()?.<span class="hljs-title function_">scrollActiveItemIntoView</span>();
57-
});
58-
}
52+
<span class="hljs-comment">/** A reference to the ng aria combobox. */</span>
53+
combobox = viewChild&lt;<span class="hljs-title class_">Combobox</span>&lt;<span class="hljs-built_in">string</span>&gt;&gt;(<span class="hljs-title class_">Combobox</span>);
5954

60-
<span class="hljs-title function_">showPopover</span>(<span class="hljs-params"></span>) {
61-
<span class="hljs-keyword">const</span> popover = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">popover</span>()!;
62-
<span class="hljs-keyword">const</span> combobox = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">combobox</span>()!;
55+
<span class="hljs-comment">/** The labels that are available for selection. */</span>
56+
labels = [
57+
{<span class="hljs-attr">value</span>: <span class="hljs-string">&#x27;Important&#x27;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&#x27;label&#x27;</span>},
58+
{<span class="hljs-attr">value</span>: <span class="hljs-string">&#x27;Starred&#x27;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&#x27;star&#x27;</span>},
59+
{<span class="hljs-attr">value</span>: <span class="hljs-string">&#x27;Work&#x27;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&#x27;work&#x27;</span>},
60+
{<span class="hljs-attr">value</span>: <span class="hljs-string">&#x27;Personal&#x27;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&#x27;person&#x27;</span>},
61+
{<span class="hljs-attr">value</span>: <span class="hljs-string">&#x27;To Do&#x27;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&#x27;checklist&#x27;</span>},
62+
{<span class="hljs-attr">value</span>: <span class="hljs-string">&#x27;Later&#x27;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&#x27;schedule&#x27;</span>},
63+
{<span class="hljs-attr">value</span>: <span class="hljs-string">&#x27;Read&#x27;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&#x27;menu_book&#x27;</span>},
64+
{<span class="hljs-attr">value</span>: <span class="hljs-string">&#x27;Travel&#x27;</span>, <span class="hljs-attr">icon</span>: <span class="hljs-string">&#x27;flight&#x27;</span>},
65+
];
6366

64-
<span class="hljs-keyword">const</span> comboboxRect = combobox.<span class="hljs-title function_">inputElement</span>()?.<span class="hljs-title function_">getBoundingClientRect</span>();
65-
<span class="hljs-keyword">const</span> popoverEl = popover.<span class="hljs-property">nativeElement</span>;
67+
<span class="hljs-title function_">constructor</span>(<span class="hljs-params"></span>) {
68+
<span class="hljs-comment">// Updates the display value when the listbox values change.</span>
69+
<span class="hljs-title function_">afterRenderEffect</span>(<span class="hljs-function">() =&gt;</span> {
70+
<span class="hljs-keyword">const</span> values = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">listbox</span>()?.<span class="hljs-title function_">values</span>() || [];
71+
<span class="hljs-keyword">if</span> (values.<span class="hljs-property">length</span> === <span class="hljs-number">0</span>) {
72+
<span class="hljs-variable language_">this</span>.<span class="hljs-property">displayValue</span>.<span class="hljs-title function_">set</span>(<span class="hljs-string">&#x27;Select a label&#x27;</span>);
73+
} <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (values.<span class="hljs-property">length</span> === <span class="hljs-number">1</span>) {
74+
<span class="hljs-variable language_">this</span>.<span class="hljs-property">displayValue</span>.<span class="hljs-title function_">set</span>(values[<span class="hljs-number">0</span>]);
75+
} <span class="hljs-keyword">else</span> {
76+
<span class="hljs-variable language_">this</span>.<span class="hljs-property">displayValue</span>.<span class="hljs-title function_">set</span>(<span class="hljs-string">`<span class="hljs-subst">${values[<span class="hljs-number">0</span>]}</span> + <span class="hljs-subst">${values.length - <span class="hljs-number">1</span>}</span> more`</span>);
77+
}
78+
});
6679

67-
<span class="hljs-keyword">if</span> (comboboxRect) {
68-
popoverEl.<span class="hljs-property">style</span>.<span class="hljs-property">width</span> = <span class="hljs-string">`<span class="hljs-subst">${comboboxRect.width}</span>px`</span>;
69-
popoverEl.<span class="hljs-property">style</span>.<span class="hljs-property">top</span> = <span class="hljs-string">`<span class="hljs-subst">${comboboxRect.bottom + <span class="hljs-number">4</span>}</span>px`</span>;
70-
popoverEl.<span class="hljs-property">style</span>.<span class="hljs-property">left</span> = <span class="hljs-string">`<span class="hljs-subst">${comboboxRect.left - <span class="hljs-number">1</span>}</span>px`</span>;
71-
}
80+
<span class="hljs-comment">// Scrolls to the active item when the active option changes.</span>
81+
<span class="hljs-comment">// The slight delay here is to ensure animations are done before scrolling.</span>
82+
<span class="hljs-title function_">afterRenderEffect</span>(<span class="hljs-function">() =&gt;</span> {
83+
<span class="hljs-keyword">const</span> option = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">options</span>().<span class="hljs-title function_">find</span>(<span class="hljs-function"><span class="hljs-params">opt</span> =&gt;</span> opt.<span class="hljs-title function_">active</span>());
84+
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> option?.<span class="hljs-property">element</span>.<span class="hljs-title function_">scrollIntoView</span>({<span class="hljs-attr">block</span>: <span class="hljs-string">&#x27;nearest&#x27;</span>}), <span class="hljs-number">50</span>);
85+
});
7286

73-
popover.<span class="hljs-property">nativeElement</span>.<span class="hljs-title function_">showPopover</span>();
87+
<span class="hljs-comment">// Resets the listbox scroll position when the combobox is closed.</span>
88+
<span class="hljs-title function_">afterRenderEffect</span>(<span class="hljs-function">() =&gt;</span> {
89+
<span class="hljs-keyword">if</span> (!<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">combobox</span>()?.<span class="hljs-title function_">expanded</span>()) {
90+
<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">listbox</span>()?.<span class="hljs-property">element</span>.<span class="hljs-title function_">scrollTo</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>), <span class="hljs-number">150</span>);
91+
}
92+
});
7493
}
7594
}
76-
77-
<span class="hljs-keyword">const</span> states = [<span class="hljs-string">&#x27;Option 1&#x27;</span>, <span class="hljs-string">&#x27;Option 2&#x27;</span>, <span class="hljs-string">&#x27;Option 3&#x27;</span>];

0 commit comments

Comments
 (0)