Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
load("//tools:defaults.bzl", "ng_project")

package(default_visibility = ["//visibility:public"])

ng_project(
name = "toolbar",
srcs = glob(["**/*.ts"]),
assets = glob([
"**/*.html",
"**/*.css",
]),
deps = [
"//:node_modules/@angular/core",
"//:node_modules/@angular/forms",
"//src/aria/combobox",
"//src/aria/listbox",
"//src/aria/simple-combobox",
"//src/aria/toolbar",
"//src/cdk/a11y",
"//src/material/checkbox",
"//src/material/form-field",
"//src/material/select",
],
)

filegroup(
name = "source-files",
srcs = glob([
"**/*.html",
"**/*.css",
"**/*.ts",
]),
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export {ToolbarBasicHorizontalExample} from './toolbar-basic-horizontal/toolbar-basic-horizontal-example';
export {ToolbarBasicVerticalExample} from './toolbar-basic-vertical/toolbar-basic-vertical-example';
export {ToolbarConfigurableExample} from './toolbar-configurable/toolbar-configurable-example';
export {ToolbarRtlExample} from './toolbar-rtl/toolbar-rtl-example';
export {ToolbarHardDisabledExample} from './toolbar-hard-disabled/toolbar-hard-disabled-example';
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import {Combobox, ComboboxPopup, ComboboxWidget} from '@angular/aria/simple-combobox';
import {Listbox, Option} from '@angular/aria/listbox';
import {ToolbarWidget} from '@angular/aria/toolbar';
import {Dir, Directionality} from '@angular/cdk/bidi';
import {afterRenderEffect, Component, Directive, inject, signal, viewChild} from '@angular/core';
import {OverlayModule} from '@angular/cdk/overlay';

@Directive({
selector: 'button[toolbar-button]',
standalone: true,
hostDirectives: [{directive: ToolbarWidget, inputs: ['value', 'disabled']}],
host: {
type: 'button',
class: 'example-button material-symbols-outlined',
'[aria-label]': 'widget.value()',
},
})
export class SimpleToolbarButton {
widget = inject(ToolbarWidget);
}

@Directive({
selector: 'button[toolbar-toggle-button]',
standalone: true,
hostDirectives: [{directive: ToolbarWidget, inputs: ['value']}],
host: {
type: 'button',
class: 'example-button material-symbols-outlined',
'[aria-pressed]': 'widget.selected()',
'[aria-label]': 'widget.value()',
},
})
export class SimpleToolbarToggleButton {
widget = inject(ToolbarWidget);
}

@Directive({
selector: 'button[toolbar-radio-button]',
standalone: true,
hostDirectives: [{directive: ToolbarWidget, inputs: ['value', 'disabled']}],
host: {
role: 'radio',
type: 'button',
class: 'example-button material-symbols-outlined',
'[aria-checked]': 'widget.selected()',
'[aria-label]': 'widget.value()',
},
})
export class SimpleToolbarRadioButton {
widget = inject(ToolbarWidget);
}

@Component({
selector: 'combobox',
standalone: true,
imports: [
Dir,
Combobox,
ComboboxPopup,
ComboboxWidget,
Listbox,
Option,
ToolbarWidget,
OverlayModule,
],
styleUrl: 'toolbar-common.css',
host: {class: 'example-combobox-container'},
template: `
<div class="example-combobox" [dir]="dir()">
<div #origin class="example-combobox-input-container"
ngCombobox
#combobox="ngCombobox"
ngToolbarWidget
[(value)]="value"
[(expanded)]="popupExpanded"
(click)="origin.focus()">
<div class="example-combobox-input" style="display: flex; align-items: center;" aria-label="Select a text style">
{{ value() }}
</div>
<span class="material-symbols-outlined example-icon example-arrow-icon"
>arrow_drop_down</span
>
</div>

<ng-template [cdkConnectedOverlay]="{origin, usePopover: 'inline', matchWidth: true}" [cdkConnectedOverlayOpen]="true"
[cdkConnectedOverlayDisableClose]="true">
<ng-template ngComboboxPopup [combobox]="combobox">
<div ngListbox ngComboboxWidget [(value)]="selectedOption" class="example-listbox example-popup" focusMode="activedescendant"
[tabIndex]="-1" selectionMode="explicit" (click)="onCommit()"
(keydown.enter)="onCommit()"
(pointerdown)="$event.preventDefault()">
@for (option of options; track option) {
<div ngOption [value]="option" [label]="option" class="example-option example-selectable example-stateful">
<span>{{option}}</span>
<span aria-hidden="true" class="material-symbols-outlined example-option-icon"
>check</span
>
</div>
}
</div>
</ng-template>
</ng-template>
</div>
`,
})
export class SimpleCombobox {
dir = inject(Directionality).valueSignal;
listbox = viewChild(Listbox);
combobox = viewChild(Combobox);

popupExpanded = signal(false);
selectedOption = signal<string[]>([]);
value = signal('Normal text');
options = ['Normal text', 'Title', 'Subtitle', 'Heading 1', 'Heading 2', 'Heading 3'];

constructor() {
afterRenderEffect(() => {
this.listbox()?.scrollActiveItemIntoView();
});
}

onCommit() {
const selectedOption = this.selectedOption();
if (selectedOption.length > 0) {
this.value.set(selectedOption[0]);
}
this.popupExpanded.set(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<div class="example-toolbar-container">
<div ngToolbar class="example-toolbar" aria-label="Horizontal Toolbar Text Formatting Tools">
<div class="example-group" aria-label="Undo and Redo options">
<button toolbar-button value="undo">undo</button>
<button toolbar-button value="redo">redo</button>
</div>

<div class="example-separator" role="separator"></div>

<div class="example-group" aria-label="Text formatting options">
<button toolbar-toggle-button value="bold">format_bold</button>
<button toolbar-toggle-button value="italic">format_italic</button>
<button toolbar-toggle-button value="underline">format_underlined</button>
</div>

<div class="example-separator" role="separator"></div>

<combobox />

<div class="example-separator" role="separator"></div>

<div
ngToolbarWidgetGroup
role="radiogroup"
class="example-group"
aria-label="Alignment options"
>
<button toolbar-radio-button value="align left">format_align_left</button>
<button toolbar-radio-button value="align center">format_align_center</button>
<button toolbar-radio-button value="align right">format_align_right</button>
</div>

<div class="example-separator" role="separator"></div>

<div ngToolbarWidgetGroup role="radiogroup" class="example-group" aria-label="List options">
<button toolbar-radio-button value="checklist">checklist</button>
<button toolbar-radio-button value="bullet list">format_list_bulleted</button>
<button toolbar-radio-button value="numbered list">format_list_numbered</button>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
import {
SimpleCombobox,
SimpleToolbarButton,
SimpleToolbarRadioButton,
SimpleToolbarToggleButton,
} from '../simple-toolbar';

/** @title Basic Horizontal Toolbar Example */
@Component({
selector: 'toolbar-basic-horizontal-example',
templateUrl: 'toolbar-basic-horizontal-example.html',
styleUrl: '../toolbar-common.css',
imports: [
Toolbar,
ToolbarWidget,
ToolbarWidgetGroup,
SimpleCombobox,
SimpleToolbarButton,
SimpleToolbarRadioButton,
SimpleToolbarToggleButton,
],
})
export class ToolbarBasicHorizontalExample {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<div class="example-toolbar-container">
<div
ngToolbar
orientation="vertical"
class="example-toolbar"
aria-label="Vertical Toolbar Text Formatting Tools"
>
<div class="example-group" aria-label="Undo and Redo options">
<button toolbar-button value="undo">undo</button>
<button toolbar-button value="redo">redo</button>
</div>

<div class="example-separator" role="separator"></div>

<div class="example-group" aria-label="Text formatting options">
<button toolbar-toggle-button value="bold">format_bold</button>
<button toolbar-toggle-button value="italic">format_italic</button>
<button toolbar-toggle-button value="underline">format_underlined</button>
</div>

<div class="example-separator" role="separator"></div>

<div
ngToolbarWidgetGroup
role="radiogroup"
class="example-group"
aria-label="Alignment options"
>
<button toolbar-radio-button value="align left">format_align_left</button>
<button toolbar-radio-button value="align center">format_align_center</button>
<button toolbar-radio-button value="align right">format_align_right</button>
</div>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
import {
SimpleToolbarButton,
SimpleToolbarRadioButton,
SimpleToolbarToggleButton,
} from '../simple-toolbar';

/** @title Basic Vertical Toolbar Example */
@Component({
selector: 'toolbar-basic-vertical-example',
templateUrl: 'toolbar-basic-vertical-example.html',
styleUrl: '../toolbar-common.css',
imports: [
Toolbar,
ToolbarWidget,
ToolbarWidgetGroup,
SimpleToolbarButton,
SimpleToolbarRadioButton,
SimpleToolbarToggleButton,
],
})
export class ToolbarBasicVerticalExample {}
Loading
Loading