Skip to content

Commit 064d0dd

Browse files
committed
main - c345614 fix(aria/combobox): several small fixes (#32202)
1 parent e1649cb commit 064d0dd

File tree

20 files changed

+622
-214
lines changed

20 files changed

+622
-214
lines changed

docs-content/examples-highlighted/aria/combobox/combobox-examples-css.html

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
<span class="hljs-selector-class">.example-combobox-container</span> {
22
<span class="hljs-attribute">position</span>: relative;
3-
<span class="hljs-attribute">width</span>: <span class="hljs-number">300px</span>;
3+
<span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
44
<span class="hljs-attribute">display</span>: flex;
55
<span class="hljs-attribute">flex-direction</span>: column;
66
<span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-built_in">var</span>(--mat-sys-outline);
77
<span class="hljs-attribute">border-radius</span>: <span class="hljs-built_in">var</span>(--mat-sys-corner-extra-small);
88
}
99

10+
<span class="hljs-selector-class">.example-combobox-container</span><span class="hljs-selector-pseudo">:has</span>(<span class="hljs-selector-attr">[readonly=<span class="hljs-string">&#x27;true&#x27;</span>]</span>) {
11+
<span class="hljs-attribute">width</span>: <span class="hljs-number">200px</span>;
12+
}
13+
1014
<span class="hljs-selector-class">.example-combobox-input-container</span> {
1115
<span class="hljs-attribute">display</span>: flex;
1216
<span class="hljs-attribute">position</span>: relative;
@@ -78,6 +82,7 @@
7882
<span class="hljs-attribute">overflow</span>: auto;
7983
<span class="hljs-attribute">max-height</span>: <span class="hljs-number">10rem</span>;
8084
<span class="hljs-attribute">padding</span>: <span class="hljs-number">0.5rem</span>;
85+
<span class="hljs-attribute">gap</span>: <span class="hljs-number">4px</span>;
8186
}
8287

8388
<span class="hljs-selector-class">.example-option</span> {
@@ -89,6 +94,26 @@
8994
<span class="hljs-attribute">flex-shrink</span>: <span class="hljs-number">0</span>;
9095
<span class="hljs-attribute">align-items</span>: center;
9196
<span class="hljs-attribute">justify-content</span>: space-between;
97+
<span class="hljs-attribute">gap</span>: <span class="hljs-number">1rem</span>;
98+
}
99+
100+
<span class="hljs-selector-class">.example-option-text</span> {
101+
<span class="hljs-attribute">flex</span>: <span class="hljs-number">1</span>;
102+
}
103+
104+
<span class="hljs-selector-class">.example-checkbox-blank-icon</span>,
105+
<span class="hljs-selector-class">.example-option</span><span class="hljs-selector-attr">[aria-selected=<span class="hljs-string">&#x27;true&#x27;</span>]</span> <span class="hljs-selector-class">.example-checkbox-filled-icon</span> {
106+
<span class="hljs-attribute">display</span>: flex;
107+
<span class="hljs-attribute">align-items</span>: center;
108+
}
109+
110+
<span class="hljs-selector-class">.example-checkbox-filled-icon</span>,
111+
<span class="hljs-selector-class">.example-option</span><span class="hljs-selector-attr">[aria-selected=<span class="hljs-string">&#x27;true&#x27;</span>]</span> <span class="hljs-selector-class">.example-checkbox-blank-icon</span> {
112+
<span class="hljs-attribute">display</span>: none;
113+
}
114+
115+
<span class="hljs-selector-class">.example-checkbox-blank-icon</span> {
116+
<span class="hljs-attribute">opacity</span>: <span class="hljs-number">0.6</span>;
92117
}
93118

94119
<span class="hljs-selector-class">.example-selected-icon</span> {
@@ -99,26 +124,17 @@
99124
<span class="hljs-attribute">visibility</span>: visible;
100125
}
101126

102-
<span class="hljs-selector-class">.example-option</span><span class="hljs-selector-attr">[inert]</span>,
103-
<span class="hljs-selector-class">.example-tree-item</span><span class="hljs-selector-attr">[inert]</span> {
104-
<span class="hljs-attribute">display</span>: none;
127+
<span class="hljs-selector-class">.example-option</span><span class="hljs-selector-attr">[aria-selected=<span class="hljs-string">&#x27;true&#x27;</span>]</span> {
128+
<span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--mat-sys-primary);
129+
<span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">color-mix</span>(in srgb, <span class="hljs-built_in">var</span>(--mat-sys-primary) <span class="hljs-number">10%</span>, transparent);
130+
}
131+
132+
<span class="hljs-selector-class">.example-option</span><span class="hljs-selector-pseudo">:hover</span> {
133+
<span class="hljs-attribute">background-color</span>: <span class="hljs-built_in">color-mix</span>(in srgb, <span class="hljs-built_in">var</span>(--mat-sys-on-surface) <span class="hljs-number">10%</span>, transparent);
105134
}
106135

107136
<span class="hljs-selector-class">.example-combobox-container</span><span class="hljs-selector-pseudo">:focus-within</span> <span class="hljs-selector-attr">[data-active=<span class="hljs-string">&#x27;true&#x27;</span>]</span> {
108-
<span class="hljs-attribute">background</span>: <span class="hljs-built_in">color-mix</span>(
109-
in srgb,
110-
<span class="hljs-built_in">var</span>(--mat-sys-on-surface) <span class="hljs-built_in">calc</span>(<span class="hljs-built_in">var</span>(--mat-sys-focus-state-layer-opacity) * <span class="hljs-number">100%</span>),
111-
transparent
112-
);
113-
}
114-
115-
<span class="hljs-selector-class">.example-combobox-container</span><span class="hljs-selector-pseudo">:focus-within</span> <span class="hljs-selector-attr">[data-active=<span class="hljs-string">&#x27;true&#x27;</span>]</span><span class="hljs-selector-attr">[aria-selected=<span class="hljs-string">&#x27;true&#x27;</span>]</span> {
116-
<span class="hljs-attribute">background</span>: <span class="hljs-built_in">color-mix</span>(
117-
in srgb,
118-
<span class="hljs-built_in">var</span>(--mat-sys-primary) <span class="hljs-built_in">calc</span>(<span class="hljs-built_in">var</span>(--mat-sys-pressed-state-layer-opacity) * <span class="hljs-number">100%</span>),
119-
transparent
120-
);
121-
<span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--mat-sys-primary);
137+
<span class="hljs-attribute">outline</span>: <span class="hljs-number">2px</span> solid <span class="hljs-built_in">color-mix</span>(in srgb, <span class="hljs-built_in">var</span>(--mat-sys-primary) <span class="hljs-number">80%</span>, transparent);
122138
}
123139

124140
<span class="hljs-selector-class">.example-tree</span> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
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>&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>
10+
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
11+
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>
13+
<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">multi</span>]=<span class="hljs-string">&quot;true&quot;</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> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-option&quot;</span> <span class="hljs-attr">ngOption</span> [<span class="hljs-attr">value</span>]=<span class="hljs-string">&quot;option&quot;</span> [<span class="hljs-attr">label</span>]=<span class="hljs-string">&quot;option&quot;</span>&gt;</span>
17+
<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>
18+
<span class="hljs-tag">&lt;<span class="hljs-name">span</span>
19+
<span class="hljs-attr">aria-hidden</span>=<span class="hljs-string">&quot;true&quot;</span>
20+
<span class="hljs-attr">class</span>=<span class="hljs-string">&quot;material-symbols-outlined example-icon example-selected-icon&quot;</span>
21+
&gt;</span>check&lt;/span
22+
&gt;
23+
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
24+
}
25+
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
26+
<span class="hljs-tag">&lt;/<span class="hljs-name">ng-template</span>&gt;</span>
27+
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
28+
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<span class="hljs-comment">/**
2+
* <span class="hljs-doctag">@license</span>
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+
*/</span>
8+
9+
<span class="hljs-keyword">import</span> {
10+
<span class="hljs-title class_">Combobox</span>,
11+
<span class="hljs-title class_">ComboboxInput</span>,
12+
<span class="hljs-title class_">ComboboxPopup</span>,
13+
<span class="hljs-title class_">ComboboxPopupContainer</span>,
14+
} <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;@angular/aria/combobox&#x27;</span>;
15+
<span class="hljs-keyword">import</span> {<span class="hljs-title class_">Listbox</span>, <span class="hljs-title class_">Option</span>} <span class="hljs-keyword">from</span> <span class="hljs-string">&#x27;@angular/aria/listbox&#x27;</span>;
16+
<span class="hljs-keyword">import</span> {
17+
afterRenderEffect,
18+
<span class="hljs-title class_">ChangeDetectionStrategy</span>,
19+
<span class="hljs-title class_">Component</span>,
20+
<span class="hljs-title class_">ElementRef</span>,
21+
signal,
22+
viewChild,
23+
} <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>;
25+
26+
<span class="hljs-comment">/** <span class="hljs-doctag">@title</span> Readonly multiselectable combobox. */</span>
27+
<span class="hljs-meta">@Component</span>({
28+
<span class="hljs-attr">selector</span>: <span class="hljs-string">&#x27;combobox-readonly-multiselect-example&#x27;</span>,
29+
<span class="hljs-attr">templateUrl</span>: <span class="hljs-string">&#x27;combobox-readonly-multiselect-example.html&#x27;</span>,
30+
<span class="hljs-attr">styleUrl</span>: <span class="hljs-string">&#x27;../combobox-examples.css&#x27;</span>,
31+
<span class="hljs-attr">imports</span>: [
32+
<span class="hljs-title class_">Combobox</span>,
33+
<span class="hljs-title class_">ComboboxInput</span>,
34+
<span class="hljs-title class_">ComboboxPopup</span>,
35+
<span class="hljs-title class_">ComboboxPopupContainer</span>,
36+
<span class="hljs-title class_">Listbox</span>,
37+
<span class="hljs-title class_">Option</span>,
38+
<span class="hljs-title class_">FormsModule</span>,
39+
],
40+
<span class="hljs-attr">changeDetection</span>: <span class="hljs-title class_">ChangeDetectionStrategy</span>.<span class="hljs-property">OnPush</span>,
41+
})
42+
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ComboboxReadonlyMultiselectExample</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>);
46+
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>);
49+
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-property">_pattern</span>.<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>();
55+
56+
<span class="hljs-comment">// TODO(wagnermaciel): Make this easier for developers to do.</span>
57+
<span class="hljs-variable language_">this</span>.<span class="hljs-title function_">listbox</span>()?.<span class="hljs-property">_pattern</span>.<span class="hljs-property">inputs</span>.<span class="hljs-title function_">activeItem</span>()?.<span class="hljs-title function_">element</span>()?.<span class="hljs-title function_">scrollIntoView</span>({<span class="hljs-attr">block</span>: <span class="hljs-string">&#x27;nearest&#x27;</span>});
58+
});
59+
}
60+
61+
<span class="hljs-title function_">showPopover</span>(<span class="hljs-params"></span>) {
62+
<span class="hljs-keyword">const</span> popover = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">popover</span>()!;
63+
<span class="hljs-keyword">const</span> combobox = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">combobox</span>()!;
64+
65+
<span class="hljs-keyword">const</span> comboboxRect = combobox.<span class="hljs-property">_pattern</span>.<span class="hljs-property">inputs</span>.<span class="hljs-title function_">inputEl</span>()?.<span class="hljs-title function_">getBoundingClientRect</span>();
66+
<span class="hljs-keyword">const</span> popoverEl = popover.<span class="hljs-property">nativeElement</span>;
67+
68+
<span class="hljs-keyword">if</span> (comboboxRect) {
69+
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>;
70+
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>;
71+
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>;
72+
}
73+
74+
popover.<span class="hljs-property">nativeElement</span>.<span class="hljs-title function_">showPopover</span>();
75+
}
76+
}
77+
78+
<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>];

docs-content/examples-highlighted/aria/combobox/combobox-tree-auto-select/combobox-tree-auto-select-example-html.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
[<span class="hljs-attr">parent</span>]=<span class="hljs-string">&quot;parent&quot;</span>
3535
[<span class="hljs-attr">value</span>]=<span class="hljs-string">&quot;node.name&quot;</span>
3636
[<span class="hljs-attr">label</span>]=<span class="hljs-string">&quot;node.name&quot;</span>
37+
[<span class="hljs-attr">selectable</span>]=<span class="hljs-string">&quot;!node.children&quot;</span>
3738
#<span class="hljs-attr">treeItem</span>=<span class="hljs-string">&quot;ngTreeItem&quot;</span>
3839
<span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-tree-item example-selectable example-stateful&quot;</span>
3940
&gt;</span>

docs-content/examples-highlighted/aria/combobox/combobox-tree-highlight/combobox-tree-highlight-example-html.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
[<span class="hljs-attr">parent</span>]=<span class="hljs-string">&quot;parent&quot;</span>
3535
[<span class="hljs-attr">value</span>]=<span class="hljs-string">&quot;node.name&quot;</span>
3636
[<span class="hljs-attr">label</span>]=<span class="hljs-string">&quot;node.name&quot;</span>
37+
[<span class="hljs-attr">selectable</span>]=<span class="hljs-string">&quot;!node.children&quot;</span>
3738
#<span class="hljs-attr">treeItem</span>=<span class="hljs-string">&quot;ngTreeItem&quot;</span>
3839
<span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-tree-item example-selectable example-stateful&quot;</span>
3940
&gt;</span>

docs-content/examples-highlighted/aria/combobox/combobox-tree-manual/combobox-tree-manual-example-html.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
[<span class="hljs-attr">parent</span>]=<span class="hljs-string">&quot;parent&quot;</span>
3535
[<span class="hljs-attr">value</span>]=<span class="hljs-string">&quot;node.name&quot;</span>
3636
[<span class="hljs-attr">label</span>]=<span class="hljs-string">&quot;node.name&quot;</span>
37+
[<span class="hljs-attr">selectable</span>]=<span class="hljs-string">&quot;!node.children&quot;</span>
3738
#<span class="hljs-attr">treeItem</span>=<span class="hljs-string">&quot;ngTreeItem&quot;</span>
3839
<span class="hljs-attr">class</span>=<span class="hljs-string">&quot;example-tree-item example-selectable example-stateful&quot;</span>
3940
&gt;</span>

0 commit comments

Comments
 (0)