A container for grouping related controls and actions with keyboard navigation, commonly used for text formatting, toolbars, and command panels.
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div ngToolbarWidgetGroup role="radiogroup" class="group" aria-label="Text alignment options">
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
}
[ngToolbar] {
gap: 1.5rem;
display: flex;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
background-color: var(--septenary-contrast);
}
.group {
gap: 0.5rem;
display: flex;
}
.separator {
width: 1px;
align-self: center;
height: calc(100% - 1rem);
background-color: var(--quinary-contrast);
}
[ngToolbarWidget] {
border: none;
cursor: pointer;
padding: 0.5rem;
border-radius: 4px;
font-size: 1.25rem;
background-color: transparent;
color: var(--primary-contrast);
}
[ngToolbarWidget]:hover {
background-color: color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngToolbarWidget]:active {
background-color: color-mix(in srgb, var(--primary-contrast) 15%, transparent);
}
[ngToolbarWidget]:focus {
outline-offset: -1px;
outline: 1px solid color-mix(in srgb, var(--hot-pink) 60%, transparent);
}
[ngToolbarWidget][aria-pressed="true"],
[ngToolbarWidget][aria-checked="true"] {
color: color-mix(in srgb, var(--hot-pink) 80%, var(--primary-contrast));
background-color: color-mix(in srgb, var(--hot-pink) 10%, transparent);
}
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar class="material-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div ngToolbarWidgetGroup role="radiogroup" class="group" aria-label="Text alignment options">
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
}
[ngToolbar] {
display: flex;
}
[ngToolbarWidget] {
border: none;
outline: none;
cursor: pointer;
width: 3rem;
height: 3rem;
font-size: 1.25rem;
border-radius: 2rem;
color: color-mix(in srgb, var(--vivid-pink) 70%, var(--full-contrast));
background-color: color-mix(in srgb, var(--vivid-pink) 20%, transparent);
transition:
width 0.2s ease-in-out,
background-color 0.15s ease-in-out,
color 0.15s ease-in-out;
}
[ngToolbarWidget]:focus {
outline-offset: 2px;
outline: 2px solid var(--vivid-pink);
}
[ngToolbarWidget]:active,
[ngToolbarWidget][aria-pressed='true'],
[ngToolbarWidget][aria-checked='true'] {
background-color: color-mix(in srgb, var(--vivid-pink) 80%, var(--full-contrast));
color: var(--page-background);
}
[ngToolbarWidget][aria-checked='true'] {
width: 4.5rem;
}
.group {
display: flex;
gap: 0.5rem;
}
.separator {
width: 1px;
margin: 0 1rem;
height: calc(100% - 2rem);
background-color: var(--quinary-contrast);
}
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar class="retro-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div ngToolbarWidgetGroup role="radiogroup" class="group" aria-label="Text alignment options">
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
font-family: 'Press Start 2P';
--retro-button-color: color-mix(in srgb, var(--vivid-pink) 80%, var(--page-background));
--retro-shadow-light: color-mix(in srgb, var(--retro-button-color) 90%, #fff);
--retro-shadow-dark: color-mix(in srgb, var(--retro-button-color) 90%, #000);
--retro-elevated-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast);
--retro-flat-shadow:
4px 0px 0px 0px var(--tertiary-contrast), 0px 4px 0px 0px var(--tertiary-contrast),
-4px 0px 0px 0px var(--tertiary-contrast), 0px -4px 0px 0px var(--tertiary-contrast);
--retro-clickable-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast), 8px 8px 0px 0px var(--tertiary-contrast);
--retro-pressed-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-dark),
inset -4px -4px 0px 0px var(--retro-shadow-light), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast), 0px 0px 0px 0px var(--tertiary-contrast);
}
[ngToolbar] {
gap: 1.5rem;
display: flex;
padding: 1rem;
}
.group {
gap: 1rem;
display: flex;
}
.separator {
width: 1px;
align-self: center;
height: calc(100% - 1rem);
background-color: var(--quinary-contrast);
}
[ngToolbarWidget] {
border: none;
outline: none;
cursor: pointer;
padding: 0.5rem;
font-size: 1.25rem;
color: var(--page-background);
background-color: var(--retro-button-color);
box-shadow: var(--retro-clickable-shadow);
transition:
transform 0.1s,
box-shadow 0.1s;
}
[ngToolbarWidget]:focus,
[ngToolbarWidget]:hover {
transform: translate(1px, 1px);
}
[ngToolbarWidget]:active,
[ngToolbarWidget][aria-pressed='true'],
[ngToolbarWidget][aria-checked='true'] {
transform: translate(4px, 4px);
box-shadow: var(--retro-pressed-shadow);
background-color: color-mix(in srgb, var(--retro-button-color) 60%, var(--gray-50));
}
[ngToolbarWidget]:focus {
outline-offset: 4px;
outline: 4px dashed var(--retro-button-color);
}
Toolbar works best for grouping related controls that users access frequently. Consider using toolbar when:
Avoid toolbar when:
Angular's toolbar provides a fully accessible toolbar implementation with:
Horizontal toolbars organize controls from left to right, matching the common pattern in text editors and design tools. Arrow keys navigate between widgets, maintaining focus within the toolbar until users press Tab to move to the next page element.
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div ngToolbarWidgetGroup role="radiogroup" class="group" aria-label="Text alignment options">
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
}
[ngToolbar] {
gap: 1.5rem;
display: flex;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
background-color: var(--septenary-contrast);
}
.group {
gap: 0.5rem;
display: flex;
}
.separator {
width: 1px;
align-self: center;
height: calc(100% - 1rem);
background-color: var(--quinary-contrast);
}
[ngToolbarWidget] {
border: none;
cursor: pointer;
padding: 0.5rem;
border-radius: 4px;
font-size: 1.25rem;
background-color: transparent;
color: var(--primary-contrast);
}
[ngToolbarWidget]:hover {
background-color: color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngToolbarWidget]:active {
background-color: color-mix(in srgb, var(--primary-contrast) 15%, transparent);
}
[ngToolbarWidget]:focus {
outline-offset: -1px;
outline: 1px solid color-mix(in srgb, var(--hot-pink) 60%, transparent);
}
[ngToolbarWidget][aria-pressed="true"],
[ngToolbarWidget][aria-checked="true"] {
color: color-mix(in srgb, var(--hot-pink) 80%, var(--primary-contrast));
background-color: color-mix(in srgb, var(--hot-pink) 10%, transparent);
}
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar class="material-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div ngToolbarWidgetGroup role="radiogroup" class="group" aria-label="Text alignment options">
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
}
[ngToolbar] {
display: flex;
}
[ngToolbarWidget] {
border: none;
outline: none;
cursor: pointer;
width: 3rem;
height: 3rem;
font-size: 1.25rem;
border-radius: 2rem;
color: color-mix(in srgb, var(--vivid-pink) 70%, var(--full-contrast));
background-color: color-mix(in srgb, var(--vivid-pink) 20%, transparent);
transition:
width 0.2s ease-in-out,
background-color 0.15s ease-in-out,
color 0.15s ease-in-out;
}
[ngToolbarWidget]:focus {
outline-offset: 2px;
outline: 2px solid var(--vivid-pink);
}
[ngToolbarWidget]:active,
[ngToolbarWidget][aria-pressed='true'],
[ngToolbarWidget][aria-checked='true'] {
background-color: color-mix(in srgb, var(--vivid-pink) 80%, var(--full-contrast));
color: var(--page-background);
}
[ngToolbarWidget][aria-checked='true'] {
width: 4.5rem;
}
.group {
display: flex;
gap: 0.5rem;
}
.separator {
width: 1px;
margin: 0 1rem;
height: calc(100% - 2rem);
background-color: var(--quinary-contrast);
}
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar class="retro-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div ngToolbarWidgetGroup role="radiogroup" class="group" aria-label="Text alignment options">
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
font-family: 'Press Start 2P';
--retro-button-color: color-mix(in srgb, var(--vivid-pink) 80%, var(--page-background));
--retro-shadow-light: color-mix(in srgb, var(--retro-button-color) 90%, #fff);
--retro-shadow-dark: color-mix(in srgb, var(--retro-button-color) 90%, #000);
--retro-elevated-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast);
--retro-flat-shadow:
4px 0px 0px 0px var(--tertiary-contrast), 0px 4px 0px 0px var(--tertiary-contrast),
-4px 0px 0px 0px var(--tertiary-contrast), 0px -4px 0px 0px var(--tertiary-contrast);
--retro-clickable-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast), 8px 8px 0px 0px var(--tertiary-contrast);
--retro-pressed-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-dark),
inset -4px -4px 0px 0px var(--retro-shadow-light), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast), 0px 0px 0px 0px var(--tertiary-contrast);
}
[ngToolbar] {
gap: 1.5rem;
display: flex;
padding: 1rem;
}
.group {
gap: 1rem;
display: flex;
}
.separator {
width: 1px;
align-self: center;
height: calc(100% - 1rem);
background-color: var(--quinary-contrast);
}
[ngToolbarWidget] {
border: none;
outline: none;
cursor: pointer;
padding: 0.5rem;
font-size: 1.25rem;
color: var(--page-background);
background-color: var(--retro-button-color);
box-shadow: var(--retro-clickable-shadow);
transition:
transform 0.1s,
box-shadow 0.1s;
}
[ngToolbarWidget]:focus,
[ngToolbarWidget]:hover {
transform: translate(1px, 1px);
}
[ngToolbarWidget]:active,
[ngToolbarWidget][aria-pressed='true'],
[ngToolbarWidget][aria-checked='true'] {
transform: translate(4px, 4px);
box-shadow: var(--retro-pressed-shadow);
background-color: color-mix(in srgb, var(--retro-button-color) 60%, var(--gray-50));
}
[ngToolbarWidget]:focus {
outline-offset: 4px;
outline: 4px dashed var(--retro-button-color);
}
Vertical toolbars stack controls top to bottom, useful for side panels or vertical command palettes. Up and down arrow keys navigate between widgets.
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget],
})
export class App {}
<div ngToolbar orientation="vertical" aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: flex-start;
}
[ngToolbar] {
gap: 1.5rem;
display: flex;
flex-direction: column;
padding: 1rem 0.5rem;
border-radius: 0.5rem;
background-color: var(--septenary-contrast);
}
.group {
gap: 0.5rem;
display: flex;
flex-direction: column;
}
.separator {
height: 1px;
align-self: center;
width: calc(100% - 1rem);
background-color: var(--quinary-contrast);
}
[ngToolbarWidget] {
border: none;
cursor: pointer;
padding: 0.5rem;
border-radius: 4px;
font-size: 1.25rem;
background-color: transparent;
color: var(--primary-contrast);
}
[ngToolbarWidget]:hover {
background-color: color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngToolbarWidget]:active {
background-color: color-mix(in srgb, var(--primary-contrast) 15%, transparent);
}
[ngToolbarWidget]:focus {
outline-offset: -1px;
outline: 1px solid color-mix(in srgb, var(--hot-pink) 60%, transparent);
}
[ngToolbarWidget][aria-pressed="true"],
[ngToolbarWidget][aria-checked="true"] {
color: color-mix(in srgb, var(--hot-pink) 80%, var(--primary-contrast));
background-color: color-mix(in srgb, var(--hot-pink) 10%, transparent);
}
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget],
})
export class App {}
<div
ngToolbar
orientation="vertical"
class="vertical-material-toolbar"
aria-label="Text Formatting Tools"
>
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: flex-start;
}
[ngToolbar] {
display: flex;
flex-direction: column;
}
[ngToolbarWidget] {
border: none;
outline: none;
cursor: pointer;
width: 3rem;
height: 3rem;
font-size: 1.25rem;
border-radius: 2rem;
color: color-mix(in srgb, var(--vivid-pink) 70%, var(--full-contrast));
background-color: color-mix(in srgb, var(--vivid-pink) 20%, transparent);
transition:
height 0.2s ease-in-out,
background-color 0.15s ease-in-out,
color 0.15s ease-in-out;
}
[ngToolbarWidget]:focus {
outline-offset: 2px;
outline: 2px solid var(--vivid-pink);
}
[ngToolbarWidget]:active,
[ngToolbarWidget][aria-pressed='true'],
[ngToolbarWidget][aria-checked='true'] {
background-color: var(--vivid-pink);
color: var(--page-background);
}
[ngToolbarWidget][aria-checked='true'] {
height: 4.5rem;
}
.group {
gap: 0.5rem;
display: flex;
flex-direction: column;
}
.separator {
width: 1px;
margin: 1rem 0;
height: calc(100% - 2rem);
background-color: var(--quinary-contrast);
}
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget],
})
export class App {}
<div ngToolbar orientation="vertical" class="retro-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: flex-start;
font-family: 'Press Start 2P';
--retro-button-color: color-mix(in srgb, var(--vivid-pink) 80%, var(--page-background));
--retro-shadow-light: color-mix(in srgb, var(--retro-button-color) 90%, #fff);
--retro-shadow-dark: color-mix(in srgb, var(--retro-button-color) 90%, #000);
--retro-elevated-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast);
--retro-flat-shadow:
4px 0px 0px 0px var(--tertiary-contrast), 0px 4px 0px 0px var(--tertiary-contrast),
-4px 0px 0px 0px var(--tertiary-contrast), 0px -4px 0px 0px var(--tertiary-contrast);
--retro-clickable-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast), 8px 8px 0px 0px var(--tertiary-contrast);
--retro-pressed-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-dark),
inset -4px -4px 0px 0px var(--retro-shadow-light), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast), 0px 0px 0px 0px var(--tertiary-contrast);
}
[ngToolbar] {
gap: 1.5rem;
display: flex;
padding: 1rem;
flex-direction: column;
}
.group {
gap: 1rem;
display: flex;
flex-direction: column;
}
.separator {
width: 1px;
align-self: center;
height: calc(100% - 1rem);
background-color: var(--quinary-contrast);
}
[ngToolbarWidget] {
border: none;
outline: none;
cursor: pointer;
padding: 0.5rem;
font-size: 1.25rem;
color: var(--page-background);
background-color: var(--retro-button-color);
box-shadow: var(--retro-clickable-shadow);
transition:
transform 0.1s,
box-shadow 0.1s;
}
[ngToolbarWidget]:focus,
[ngToolbarWidget]:hover {
transform: translate(1px, 1px);
}
[ngToolbarWidget]:active,
[ngToolbarWidget][aria-pressed='true'],
[ngToolbarWidget][aria-checked='true'] {
transform: translate(4px, 4px);
box-shadow: var(--retro-pressed-shadow);
background-color: color-mix(in srgb, var(--retro-button-color) 60%, var(--gray-50));
}
[ngToolbarWidget]:focus {
outline-offset: 4px;
outline: 4px dashed var(--retro-button-color);
}
Widget groups contain related controls that work together, like text alignment options or list formatting choices. Groups maintain their own internal state while participating in toolbar navigation.
In the examples above, the alignment buttons are wrapped in ngToolbarWidgetGroup with role="radiogroup" to create a mutually exclusive selection group.
The multi input controls whether multiple widgets within a group can be selected simultaneously:
<!-- Single selection (radio group) --> <div ngToolbarWidgetGroup role="radiogroup" aria-label="Alignment"> <button ngToolbarWidget value="left">Left</button> <button ngToolbarWidget value="center">Center</button> <button ngToolbarWidget value="right">Right</button> </div> <!-- Multiple selection (toggle group) --> <div ngToolbarWidgetGroup [multi]="true" aria-label="Formatting"> <button ngToolbarWidget value="bold">Bold</button> <button ngToolbarWidget value="italic">Italic</button> <button ngToolbarWidget value="underline">Underline</button> </div>
Toolbars support two disabled modes:
By default, softDisabled is true, which allows disabled widgets to still receive focus. If you want to enable hard-disabled mode, set [softDisabled]="false" on the toolbar.
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
disabled
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div
ngToolbarWidgetGroup
role="radiogroup"
class="group"
aria-label="Text alignment options"
disabled
>
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
}
[ngToolbar] {
gap: 1.5rem;
display: flex;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
background-color: var(--septenary-contrast);
}
.group {
gap: 0.5rem;
display: flex;
}
.separator {
width: 1px;
align-self: center;
height: calc(100% - 1rem);
background-color: var(--quinary-contrast);
}
[ngToolbarWidget] {
border: none;
cursor: pointer;
padding: 0.5rem;
border-radius: 4px;
font-size: 1.25rem;
background-color: transparent;
color: var(--primary-contrast);
}
[ngToolbarWidget]:hover {
background-color: color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngToolbarWidget]:active {
background-color: color-mix(in srgb, var(--primary-contrast) 15%, transparent);
}
[ngToolbarWidget]:focus {
outline-offset: -1px;
outline: 1px solid color-mix(in srgb, var(--hot-pink) 60%, transparent);
}
[ngToolbarWidget][aria-pressed="true"],
[ngToolbarWidget][aria-checked="true"] {
color: color-mix(in srgb, var(--hot-pink) 80%, var(--primary-contrast));
background-color: color-mix(in srgb, var(--hot-pink) 10%, transparent);
}
[ngToolbarWidget][aria-disabled="true"] {
cursor: default;
opacity: 0.45;
}
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar class="disabled-material-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
disabled
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div
ngToolbarWidgetGroup
role="radiogroup"
class="group"
aria-label="Text alignment options"
disabled
>
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
}
[ngToolbar] {
display: flex;
}
[ngToolbarWidget] {
border: none;
outline: none;
cursor: pointer;
width: 3rem;
height: 3rem;
font-size: 1.25rem;
border-radius: 2rem;
color: color-mix(in srgb, var(--vivid-pink) 70%, var(--full-contrast));
background-color: color-mix(in srgb, var(--vivid-pink) 20%, transparent);
transition:
width 0.2s ease-in-out,
background-color 0.15s ease-in-out,
color 0.15s ease-in-out;
}
[ngToolbarWidget]:focus {
outline-offset: 2px;
outline: 2px solid var(--vivid-pink);
}
[ngToolbarWidget]:active,
[ngToolbarWidget][aria-pressed='true'],
[ngToolbarWidget][aria-checked='true'] {
background-color: color-mix(in srgb, var(--vivid-pink) 80%, var(--full-contrast));
color: var(--page-background);
}
[ngToolbarWidget][aria-checked='true'] {
width: 4.5rem;
}
.group {
display: flex;
gap: 0.5rem;
}
.separator {
width: 1px;
margin: 0 1rem;
height: calc(100% - 2rem);
background-color: var(--quinary-contrast);
}
[ngToolbarWidget][aria-disabled="true"] {
cursor: default;
opacity: 0.45;
}
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar class="retro-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
disabled
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div
ngToolbarWidgetGroup
role="radiogroup"
class="group"
aria-label="Text alignment options"
disabled
>
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
font-family: 'Press Start 2P';
--retro-button-color: color-mix(in srgb, var(--vivid-pink) 80%, var(--page-background));
--retro-shadow-light: color-mix(in srgb, var(--retro-button-color) 90%, #fff);
--retro-shadow-dark: color-mix(in srgb, var(--retro-button-color) 90%, #000);
--retro-elevated-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast);
--retro-flat-shadow:
4px 0px 0px 0px var(--tertiary-contrast), 0px 4px 0px 0px var(--tertiary-contrast),
-4px 0px 0px 0px var(--tertiary-contrast), 0px -4px 0px 0px var(--tertiary-contrast);
--retro-clickable-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast), 8px 8px 0px 0px var(--tertiary-contrast);
--retro-pressed-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-dark),
inset -4px -4px 0px 0px var(--retro-shadow-light), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast), 0px 0px 0px 0px var(--tertiary-contrast);
}
[ngToolbar] {
gap: 1.5rem;
display: flex;
padding: 1rem;
}
.group {
gap: 1rem;
display: flex;
}
.separator {
width: 1px;
align-self: center;
height: calc(100% - 1rem);
background-color: var(--quinary-contrast);
}
[ngToolbarWidget] {
border: none;
outline: none;
cursor: pointer;
padding: 0.5rem;
font-size: 1.25rem;
color: var(--page-background);
background-color: var(--retro-button-color);
box-shadow: var(--retro-clickable-shadow);
transition:
transform 0.1s,
box-shadow 0.1s;
}
[ngToolbarWidget]:focus,
[ngToolbarWidget]:hover {
transform: translate(1px, 1px);
}
[ngToolbarWidget]:active,
[ngToolbarWidget][aria-pressed='true'],
[ngToolbarWidget][aria-checked='true'] {
transform: translate(4px, 4px);
box-shadow: var(--retro-pressed-shadow);
background-color: color-mix(in srgb, var(--retro-button-color) 60%, var(--gray-50));
}
[ngToolbarWidget]:focus {
outline-offset: 4px;
outline: 4px dashed var(--retro-button-color);
}
[ngToolbarWidget][aria-disabled='true'] {
cursor: default;
opacity: 0.45;
}
Toolbars automatically support right-to-left languages. Wrap the toolbar in a container with dir="rtl" to reverse the layout and keyboard navigation direction. Arrow key navigation adjusts automatically: left arrow moves to the next widget, right arrow to the previous.
import {Dir} from '@angular/cdk/bidi';
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Dir, Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar dir="rtl" aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div ngToolbarWidgetGroup role="radiogroup" class="group" aria-label="Text alignment options">
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
}
[ngToolbar] {
gap: 1.5rem;
display: flex;
padding: 0.5rem 1rem;
border-radius: 0.5rem;
background-color: var(--septenary-contrast);
}
.group {
gap: 0.5rem;
display: flex;
}
.separator {
width: 1px;
align-self: center;
height: calc(100% - 1rem);
background-color: var(--quinary-contrast);
}
[ngToolbarWidget] {
border: none;
cursor: pointer;
padding: 0.5rem;
border-radius: 4px;
font-size: 1.25rem;
background-color: transparent;
color: var(--primary-contrast);
}
[ngToolbarWidget]:hover {
background-color: color-mix(in srgb, var(--primary-contrast) 10%, transparent);
}
[ngToolbarWidget]:active {
background-color: color-mix(in srgb, var(--primary-contrast) 15%, transparent);
}
[ngToolbarWidget]:focus {
outline-offset: -1px;
outline: 1px solid color-mix(in srgb, var(--hot-pink) 60%, transparent);
}
[ngToolbarWidget][aria-pressed="true"],
[ngToolbarWidget][aria-checked="true"] {
color: color-mix(in srgb, var(--hot-pink) 80%, var(--primary-contrast));
background-color: color-mix(in srgb, var(--hot-pink) 10%, transparent);
}
import {Dir} from '@angular/cdk/bidi';
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Dir, Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar dir="rtl" class="rtl-material-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div ngToolbarWidgetGroup role="radiogroup" class="group" aria-label="Text alignment options">
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
}
[ngToolbar] {
display: flex;
}
[ngToolbarWidget] {
border: none;
outline: none;
cursor: pointer;
width: 3rem;
height: 3rem;
font-size: 1.25rem;
border-radius: 2rem;
color: color-mix(in srgb, var(--vivid-pink) 70%, var(--full-contrast));
background-color: color-mix(in srgb, var(--vivid-pink) 20%, transparent);
transition:
width 0.2s ease-in-out,
background-color 0.15s ease-in-out,
color 0.15s ease-in-out;
}
[ngToolbarWidget]:focus {
outline-offset: 2px;
outline: 2px solid var(--vivid-pink);
}
[ngToolbarWidget]:active,
[ngToolbarWidget][aria-pressed='true'],
[ngToolbarWidget][aria-checked='true'] {
background-color: var(--vivid-pink);
color: var(--page-background);
}
[ngToolbarWidget][aria-checked='true'] {
width: 4.5rem;
}
.group {
display: flex;
gap: 0.5rem;
}
.separator {
width: 1px;
margin: 0 1rem;
height: calc(100% - 2rem);
background-color: var(--quinary-contrast);
}
import {Dir} from '@angular/cdk/bidi';
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Dir, Toolbar, ToolbarWidget, ToolbarWidgetGroup],
})
export class App {}
<div ngToolbar dir="rtl" class="rtl-retro-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button
ngToolbarWidget
value="undo"
type="button"
aria-label="undo"
class="material-symbols-outlined"
translate="no"
>
undo
</button>
<button
ngToolbarWidget
value="redo"
type="button"
aria-label="redo"
class="material-symbols-outlined"
translate="no"
>
redo
</button>
</div>
<div class="separator" role="separator"></div>
<div class="group">
<button
ngToolbarWidget
value="bold"
type="button"
aria-label="bold"
#bold="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="bold.selected()"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
#italic="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="italic.selected()"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
#underlined="ngToolbarWidget"
class="material-symbols-outlined"
[aria-pressed]="underlined.selected()"
translate="no"
>
format_underlined
</button>
</div>
<div class="separator" role="separator"></div>
<div ngToolbarWidgetGroup role="radiogroup" class="group" aria-label="Text alignment options">
<button
ngToolbarWidget
role="radio"
type="button"
value="align left"
aria-label="align left"
#leftAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="leftAlign.selected()"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
#centerAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="centerAlign.selected()"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
#rightAlign="ngToolbarWidget"
class="material-symbols-outlined"
[aria-checked]="rightAlign.selected()"
translate="no"
>
format_align_right
</button>
</div>
</div>
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
font-family: 'Press Start 2P';
--retro-button-color: color-mix(in srgb, var(--vivid-pink) 80%, var(--page-background));
--retro-shadow-light: color-mix(in srgb, var(--retro-button-color) 90%, #fff);
--retro-shadow-dark: color-mix(in srgb, var(--retro-button-color) 90%, #000);
--retro-elevated-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast);
--retro-flat-shadow:
4px 0px 0px 0px var(--tertiary-contrast), 0px 4px 0px 0px var(--tertiary-contrast),
-4px 0px 0px 0px var(--tertiary-contrast), 0px -4px 0px 0px var(--tertiary-contrast);
--retro-clickable-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-light),
inset -4px -4px 0px 0px var(--retro-shadow-dark), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast), 8px 8px 0px 0px var(--tertiary-contrast);
--retro-pressed-shadow:
inset 4px 4px 0px 0px var(--retro-shadow-dark),
inset -4px -4px 0px 0px var(--retro-shadow-light), 4px 0px 0px 0px var(--tertiary-contrast),
0px 4px 0px 0px var(--tertiary-contrast), -4px 0px 0px 0px var(--tertiary-contrast),
0px -4px 0px 0px var(--tertiary-contrast), 0px 0px 0px 0px var(--tertiary-contrast);
}
[ngToolbar] {
gap: 1.5rem;
display: flex;
padding: 1rem;
}
.group {
gap: 1rem;
display: flex;
}
.separator {
width: 1px;
align-self: center;
height: calc(100% - 1rem);
background-color: var(--quinary-contrast);
}
[ngToolbarWidget] {
border: none;
outline: none;
cursor: pointer;
padding: 0.5rem;
font-size: 1.25rem;
color: var(--page-background);
background-color: var(--retro-button-color);
box-shadow: var(--retro-clickable-shadow);
transition:
transform 0.1s,
box-shadow 0.1s;
}
[ngToolbarWidget]:focus,
[ngToolbarWidget]:hover {
transform: translate(1px, 1px);
}
[ngToolbarWidget]:active,
[ngToolbarWidget][aria-pressed='true'],
[ngToolbarWidget][aria-checked='true'] {
transform: translate(4px, 4px);
box-shadow: var(--retro-pressed-shadow);
background-color: color-mix(in srgb, var(--retro-button-color) 60%, var(--gray-50));
}
[ngToolbarWidget]:focus {
outline-offset: 4px;
outline: 4px dashed var(--retro-button-color);
}
The ngToolbar directive provides the container for toolbar functionality.
| Property | Type | Default | Description |
|---|---|---|---|
orientation |
'vertical' | 'horizontal'
| 'horizontal' | Whether toolbar is vertically or horizontally oriented |
disabled | boolean | false | Disables the entire toolbar |
softDisabled | boolean | true | Whether disabled items can receive focus |
wrap | boolean | true | Whether focus should wrap at the edges |
The ngToolbarWidget directive marks an element as a navigable widget within the toolbar.
| Property | Type | Default | Description |
|---|---|---|---|
id | string | auto | Unique identifier for the widget |
disabled | boolean | false | Disables the widget |
value | V | - | The value associated with the widget (required) |
| Property | Type | Description |
|---|---|---|
active | Signal<boolean> | Whether the widget is currently focused |
selected | Signal<boolean> | Whether the widget is selected (in a group) |
The ngToolbarWidgetGroup directive groups related widgets together.
| Property | Type | Default | Description |
|---|---|---|---|
disabled | boolean | false | Disables all widgets in the group |
multi | boolean | false | Whether multiple widgets can be selected |
Toolbar can contain various widget types including buttons, trees, and comboboxes. See individual component documentation for specific widget implementations.
Super-powered by Google ©2010–2025.
Code licensed under an MIT-style License. Documentation licensed under CC BY 4.0.
https://angular.dev/guide/aria/toolbar