Skip to content

Commit eb69e17

Browse files
committed
refactor(aria/toolbar): Add another example for simple-combobox and toolbar
1 parent bb4f8ec commit eb69e17

22 files changed

Lines changed: 917 additions & 0 deletions
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
load("//tools:defaults.bzl", "ng_project")
2+
3+
package(default_visibility = ["//visibility:public"])
4+
5+
ng_project(
6+
name = "toolbar",
7+
srcs = glob(["**/*.ts"]),
8+
assets = glob([
9+
"**/*.html",
10+
"**/*.css",
11+
]),
12+
deps = [
13+
"//:node_modules/@angular/core",
14+
"//:node_modules/@angular/forms",
15+
"//src/aria/combobox",
16+
"//src/aria/listbox",
17+
"//src/aria/simple-combobox",
18+
"//src/aria/toolbar",
19+
"//src/cdk/a11y",
20+
"//src/material/checkbox",
21+
"//src/material/form-field",
22+
"//src/material/select",
23+
],
24+
)
25+
26+
filegroup(
27+
name = "source-files",
28+
srcs = glob([
29+
"**/*.html",
30+
"**/*.css",
31+
"**/*.ts",
32+
]),
33+
)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export {ToolbarBasicHorizontalExample} from './toolbar-basic-horizontal/toolbar-basic-horizontal-example';
2+
export {ToolbarBasicVerticalExample} from './toolbar-basic-vertical/toolbar-basic-vertical-example';
3+
export {ToolbarConfigurableExample} from './toolbar-configurable/toolbar-configurable-example';
4+
export {ToolbarRtlExample} from './toolbar-rtl/toolbar-rtl-example';
5+
export {ToolbarHardDisabledExample} from './toolbar-hard-disabled/toolbar-hard-disabled-example';
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import {Combobox, ComboboxPopup, ComboboxWidget} from '@angular/aria/simple-combobox';
2+
import {Listbox, Option} from '@angular/aria/listbox';
3+
import {ToolbarWidget} from '@angular/aria/toolbar';
4+
import {Dir, Directionality} from '@angular/cdk/bidi';
5+
import {afterRenderEffect, Component, Directive, inject, signal, viewChild} from '@angular/core';
6+
import {OverlayModule} from '@angular/cdk/overlay';
7+
8+
@Directive({
9+
selector: 'button[toolbar-button]',
10+
standalone: true,
11+
hostDirectives: [{directive: ToolbarWidget, inputs: ['value', 'disabled']}],
12+
host: {
13+
type: 'button',
14+
class: 'example-button material-symbols-outlined',
15+
'[aria-label]': 'widget.value()',
16+
},
17+
})
18+
export class SimpleToolbarButton {
19+
widget = inject(ToolbarWidget);
20+
}
21+
22+
@Directive({
23+
selector: 'button[toolbar-toggle-button]',
24+
standalone: true,
25+
hostDirectives: [{directive: ToolbarWidget, inputs: ['value']}],
26+
host: {
27+
type: 'button',
28+
class: 'example-button material-symbols-outlined',
29+
'[aria-pressed]': 'widget.selected()',
30+
'[aria-label]': 'widget.value()',
31+
},
32+
})
33+
export class SimpleToolbarToggleButton {
34+
widget = inject(ToolbarWidget);
35+
}
36+
37+
@Directive({
38+
selector: 'button[toolbar-radio-button]',
39+
standalone: true,
40+
hostDirectives: [{directive: ToolbarWidget, inputs: ['value', 'disabled']}],
41+
host: {
42+
role: 'radio',
43+
type: 'button',
44+
class: 'example-button material-symbols-outlined',
45+
'[aria-checked]': 'widget.selected()',
46+
'[aria-label]': 'widget.value()',
47+
},
48+
})
49+
export class SimpleToolbarRadioButton {
50+
widget = inject(ToolbarWidget);
51+
}
52+
53+
@Component({
54+
selector: 'combobox',
55+
standalone: true,
56+
imports: [
57+
Dir,
58+
Combobox,
59+
ComboboxPopup,
60+
ComboboxWidget,
61+
Listbox,
62+
Option,
63+
ToolbarWidget,
64+
OverlayModule,
65+
],
66+
styleUrl: 'toolbar-common.css',
67+
host: {class: 'example-combobox-container'},
68+
template: `
69+
<div class="example-combobox" [dir]="dir()">
70+
<div #origin class="example-combobox-input-container"
71+
ngCombobox
72+
#combobox="ngCombobox"
73+
ngToolbarWidget
74+
[(value)]="value"
75+
[(expanded)]="popupExpanded"
76+
(click)="origin.focus()">
77+
<div class="example-combobox-input" style="display: flex; align-items: center;" aria-label="Select a text style">
78+
{{ value() }}
79+
</div>
80+
<span class="material-symbols-outlined example-icon example-arrow-icon"
81+
>arrow_drop_down</span
82+
>
83+
</div>
84+
85+
<ng-template [cdkConnectedOverlay]="{origin, usePopover: 'inline', matchWidth: true}" [cdkConnectedOverlayOpen]="true"
86+
[cdkConnectedOverlayDisableClose]="true">
87+
<ng-template ngComboboxPopup [combobox]="combobox">
88+
<div ngListbox ngComboboxWidget [(value)]="selectedOption" class="example-listbox example-popup" focusMode="activedescendant"
89+
[tabIndex]="-1" selectionMode="explicit" (click)="onCommit()"
90+
(keydown.enter)="onCommit()"
91+
(pointerdown)="$event.preventDefault()">
92+
@for (option of options; track option) {
93+
<div ngOption [value]="option" [label]="option" class="example-option example-selectable example-stateful">
94+
<span>{{option}}</span>
95+
<span aria-hidden="true" class="material-symbols-outlined example-option-icon"
96+
>check</span
97+
>
98+
</div>
99+
}
100+
</div>
101+
</ng-template>
102+
</ng-template>
103+
</div>
104+
`,
105+
})
106+
export class SimpleCombobox {
107+
dir = inject(Directionality).valueSignal;
108+
listbox = viewChild(Listbox);
109+
combobox = viewChild(Combobox);
110+
111+
popupExpanded = signal(false);
112+
selectedOption = signal<string[]>([]);
113+
value = signal('Normal text');
114+
options = ['Normal text', 'Title', 'Subtitle', 'Heading 1', 'Heading 2', 'Heading 3'];
115+
116+
constructor() {
117+
afterRenderEffect(() => {
118+
this.listbox()?.scrollActiveItemIntoView();
119+
});
120+
}
121+
122+
onCommit() {
123+
const selectedOption = this.selectedOption();
124+
if (selectedOption.length > 0) {
125+
this.value.set(selectedOption[0]);
126+
}
127+
this.popupExpanded.set(false);
128+
}
129+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<div class="example-toolbar-container">
2+
<div ngToolbar class="example-toolbar" aria-label="Horizontal Toolbar Text Formatting Tools">
3+
<div class="example-group" aria-label="Undo and Redo options">
4+
<button toolbar-button value="undo">undo</button>
5+
<button toolbar-button value="redo">redo</button>
6+
</div>
7+
8+
<div class="example-separator" role="separator"></div>
9+
10+
<div class="example-group" aria-label="Text formatting options">
11+
<button toolbar-toggle-button value="bold">format_bold</button>
12+
<button toolbar-toggle-button value="italic">format_italic</button>
13+
<button toolbar-toggle-button value="underline">format_underlined</button>
14+
</div>
15+
16+
<div class="example-separator" role="separator"></div>
17+
18+
<combobox />
19+
20+
<div class="example-separator" role="separator"></div>
21+
22+
<div
23+
ngToolbarWidgetGroup
24+
role="radiogroup"
25+
class="example-group"
26+
aria-label="Alignment options"
27+
>
28+
<button toolbar-radio-button value="align left">format_align_left</button>
29+
<button toolbar-radio-button value="align center">format_align_center</button>
30+
<button toolbar-radio-button value="align right">format_align_right</button>
31+
</div>
32+
33+
<div class="example-separator" role="separator"></div>
34+
35+
<div ngToolbarWidgetGroup role="radiogroup" class="example-group" aria-label="List options">
36+
<button toolbar-radio-button value="checklist">checklist</button>
37+
<button toolbar-radio-button value="bullet list">format_list_bulleted</button>
38+
<button toolbar-radio-button value="numbered list">format_list_numbered</button>
39+
</div>
40+
</div>
41+
</div>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import {Component} from '@angular/core';
2+
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
3+
import {
4+
SimpleCombobox,
5+
SimpleToolbarButton,
6+
SimpleToolbarRadioButton,
7+
SimpleToolbarToggleButton,
8+
} from '../simple-toolbar';
9+
10+
/** @title Basic Horizontal Toolbar Example */
11+
@Component({
12+
selector: 'toolbar-basic-horizontal-example',
13+
templateUrl: 'toolbar-basic-horizontal-example.html',
14+
styleUrl: '../toolbar-common.css',
15+
imports: [
16+
Toolbar,
17+
ToolbarWidget,
18+
ToolbarWidgetGroup,
19+
SimpleCombobox,
20+
SimpleToolbarButton,
21+
SimpleToolbarRadioButton,
22+
SimpleToolbarToggleButton,
23+
],
24+
})
25+
export class ToolbarBasicHorizontalExample {}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<div class="example-toolbar-container">
2+
<div
3+
ngToolbar
4+
orientation="vertical"
5+
class="example-toolbar"
6+
aria-label="Vertical Toolbar Text Formatting Tools"
7+
>
8+
<div class="example-group" aria-label="Undo and Redo options">
9+
<button toolbar-button value="undo">undo</button>
10+
<button toolbar-button value="redo">redo</button>
11+
</div>
12+
13+
<div class="example-separator" role="separator"></div>
14+
15+
<div class="example-group" aria-label="Text formatting options">
16+
<button toolbar-toggle-button value="bold">format_bold</button>
17+
<button toolbar-toggle-button value="italic">format_italic</button>
18+
<button toolbar-toggle-button value="underline">format_underlined</button>
19+
</div>
20+
21+
<div class="example-separator" role="separator"></div>
22+
23+
<div
24+
ngToolbarWidgetGroup
25+
role="radiogroup"
26+
class="example-group"
27+
aria-label="Alignment options"
28+
>
29+
<button toolbar-radio-button value="align left">format_align_left</button>
30+
<button toolbar-radio-button value="align center">format_align_center</button>
31+
<button toolbar-radio-button value="align right">format_align_right</button>
32+
</div>
33+
</div>
34+
</div>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import {Component} from '@angular/core';
2+
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
3+
import {
4+
SimpleToolbarButton,
5+
SimpleToolbarRadioButton,
6+
SimpleToolbarToggleButton,
7+
} from '../simple-toolbar';
8+
9+
/** @title Basic Vertical Toolbar Example */
10+
@Component({
11+
selector: 'toolbar-basic-vertical-example',
12+
templateUrl: 'toolbar-basic-vertical-example.html',
13+
styleUrl: '../toolbar-common.css',
14+
imports: [
15+
Toolbar,
16+
ToolbarWidget,
17+
ToolbarWidgetGroup,
18+
SimpleToolbarButton,
19+
SimpleToolbarRadioButton,
20+
SimpleToolbarToggleButton,
21+
],
22+
})
23+
export class ToolbarBasicVerticalExample {}

0 commit comments

Comments
 (0)