Genel Bakış
Klavye navigasyonu ile ilgili kontrolleri ve eylemleri gruplamak için kullanılan bir kapsayıcı; genellikle metin biçimlendirme, araç çubukları ve komut panelleri için kullanılır.
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
(click)="alignment.set('left')"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
(click)="alignment.set('center')"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
(click)="alignment.set('right')"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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);
}
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
(click)="alignment.set('left')"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
(click)="alignment.set('center')"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
(click)="alignment.set('right')"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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);
}
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
(click)="alignment.set('left')"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
(click)="alignment.set('center')"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
(click)="alignment.set('right')"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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-pressed-tint: #fbfbfb;
--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);
}
:host-context(.docs-dark-mode) {
--retro-pressed-tint: #151417;
}
[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(--retro-pressed-tint));
}
[ngToolbarWidget]:focus {
outline-offset: 4px;
outline: 4px dashed var(--retro-button-color);
}
Kullanım
Toolbar, kullanıcıların sık eriştiği ilgili kontrolleri gruplamak için en iyi şekilde çalışır. Şu durumlarda toolbar kullanmayı düşünün:
- Birden fazla ilgili eylem - İlgili işlevleri gerçekleştiren birkaç kontrolünüz var (metin biçimlendirme düğmeleri gibi)
- Klavye verimliliği önemli - Kullanıcılar ok tuşları aracılığıyla hızlı klavye navigasyonundan faydalanır
- Gruplanmış kontroller - Kontrolleri ayırıcılarla mantıksal bölümlere organize etmeniz gerekiyor
- Sık erişim - Kontroller bir iş akışı içinde tekrar tekrar kullanılıyor
Şu durumlarda toolbar'dan kaçının:
- Basit bir düğme grubu yeterliyse - Sadece 2-3 ilgisiz eylem için ayrı düğmeler daha iyi çalışır
- Kontroller ilişkili değilse - Toolbar mantıksal bir gruplama ima eder; ilgisiz kontroller kullanıcıları karıştırır
- Karmaşık iç içe navigasyon - Derin hiyerarşiler menüler veya navigasyon bileşenleri tarafından daha iyi karşılanır
Özellikler
Angular'ın toolbar'ı tam erişilebilir bir araç çubuğu uygulaması sağlar:
- Klavye Navigasyonu - Roving tabindex kullanarak ok tuşları, Home ve End ile widget'lar arasında gezinin; kontroller yerel etkinleştirme davranışlarını korur
- Ekran Okuyucu Desteği - Yardımcı teknolojiler için yerleşik ARIA öznitelikleri
- Widget Grupları - Radyo düğmesi grupları veya geçiş düğmesi grupları gibi ilgili widget'ları organize edin
- Esnek Yönelim - Otomatik klavye navigasyonu ile yatay veya dikey düzenler
- Sinyal Tabanlı Reaktivite - Angular sinyalleri kullanarak reaktif durum yönetimi
- Çift Yönlü Metin Desteği - Sağdan sola (RTL) dilleri otomatik olarak yönetir
- Yapılandırılabilir Odak - Kenarlarda sarmalama navigasyonu veya sert duraklar arasında seçim yapın
Örnekler
Temel yatay araç çubuğu
Yatay araç çubukları kontrolleri soldan sağa düzenler ve metin editörleri ve tasarım araçlarındaki yaygın kalıba uyar. Ok tuşları widget'lar arasında gezinir ve kullanıcılar bir sonraki sayfa öğesine geçmek için Tab'a basana kadar odağı araç çubuğu içinde tutar.
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
(click)="alignment.set('left')"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
(click)="alignment.set('center')"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
(click)="alignment.set('right')"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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);
}
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
(click)="alignment.set('left')"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
(click)="alignment.set('center')"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
(click)="alignment.set('right')"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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);
}
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
(click)="alignment.set('left')"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
(click)="alignment.set('center')"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
(click)="alignment.set('right')"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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-pressed-tint: #fbfbfb;
--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);
}
:host-context(.docs-dark-mode) {
--retro-pressed-tint: #151417;
}
[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(--retro-pressed-tint));
}
[ngToolbarWidget]:focus {
outline-offset: 4px;
outline: 4px dashed var(--retro-button-color);
}
Dikey araç çubuğu
Dikey araç çubukları kontrolleri yukarıdan aşağıya yığar; yan paneller veya dikey komut paletleri için kullanışlıdır. Yukarı ve aşağı ok tuşları widget'lar arasında gezinir.
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
translate="no"
>
format_underlined
</button>
</div>
</div>
app.css
@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);
}
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
translate="no"
>
format_underlined
</button>
</div>
</div>
app.css
@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);
}
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
translate="no"
>
format_underlined
</button>
</div>
</div>
app.css
@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-pressed-tint: #fbfbfb;
--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);
}
:host-context(.docs-dark-mode) {
--retro-pressed-tint: #151417;
}
[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(--retro-pressed-tint));
}
[ngToolbarWidget]:focus {
outline-offset: 4px;
outline: 4px dashed var(--retro-button-color);
}
Widget grupları
Widget grupları, metin hizalama seçenekleri veya biçimlendirme geçişleri gibi birlikte çalışan ilgili kontrolleri organize eder. Gruplar, yardımcı teknolojilere uygun semantik yapıyı sunarken roving tabindex navigasyonunu korur.
Yukarıdaki örneklerde hizalama düğmeleri, role="radiogroup" ile ngToolbarWidgetGroup içine sarılmıştır. Seçim, araç çubuğu kapsayıcısından ayrıştırılmıştır; bu sayede durumu Angular sinyalleri veya özel direktifler kullanarak yönetebilirsiniz:
<!-- Mutually exclusive radio group -->
<div ngToolbarWidgetGroup role="radiogroup" aria-label="Alignment">
<button
ngToolbarWidget
role="radio"
type="button"
[attr.aria-checked]="alignment() === 'left'"
(click)="alignment.set('left')"
>
Left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
[attr.aria-checked]="alignment() === 'center'"
(click)="alignment.set('center')"
>
Center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
[attr.aria-checked]="alignment() === 'right'"
(click)="alignment.set('right')"
>
Right
</button>
</div>
<!-- Toggle button group -->
<div class="group" role="group" aria-label="Text styling">
<button ngToolbarWidget type="button" [attr.aria-pressed]="bold()" (click)="bold.set(!bold())">
Bold
</button>
<button
ngToolbarWidget
type="button"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
>
Italic
</button>
</div>
Devre dışı widget'lar
Araç çubukları iki devre dışı bırakma modunu destekler:
- Yumuşak devre dışı widget'lar odaklanılabilir kalır ancak görsel olarak kullanılamaz olduklarını gösterir
- Sert devre dışı widget'lar klavye navigasyonundan tamamen kaldırılır.
Varsayılan olarak softDisabled true'dur, bu da devre dışı widget'ların hala odak almasına izin verir. Sert devre dışı modunu etkinleştirmek istiyorsanız, araç çubuğunda [softDisabled]="false" ayarlayın.
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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;
}
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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;
}
app.ts
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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-pressed-tint: #fbfbfb;
--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);
}
:host-context(.docs-dark-mode) {
--retro-pressed-tint: #151417;
}
[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(--retro-pressed-tint));
}
[ngToolbarWidget]:focus {
outline-offset: 4px;
outline: 4px dashed var(--retro-button-color);
}
[ngToolbarWidget][aria-disabled='true'] {
cursor: default;
opacity: 0.45;
}
Sağdan sola (RTL) desteği
Araç çubukları sağdan sola dilleri otomatik olarak destekler. Düzeni ve klavye navigasyon yönünü tersine çevirmek için araç çubuğunu dir="rtl" içeren bir kapsayıcı ile sarın. Ok tuşu navigasyonu otomatik olarak ayarlanır: sol ok sonraki widget'a, sağ ok önceki widget'a hareket eder.
app.ts
import {Dir} from '@angular/cdk/bidi';
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
(click)="alignment.set('left')"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
(click)="alignment.set('center')"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
(click)="alignment.set('right')"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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);
}
app.ts
import {Dir} from '@angular/cdk/bidi';
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
(click)="alignment.set('left')"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
(click)="alignment.set('center')"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
(click)="alignment.set('right')"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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);
}
app.ts
import {Dir} from '@angular/cdk/bidi';
import {Component, signal} 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 {
readonly bold = signal(false);
readonly italic = signal(false);
readonly underlined = signal(false);
readonly alignment = signal<'left' | 'center' | 'right'>('left');
}
app.html
<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"
class="material-symbols-outlined"
[attr.aria-pressed]="bold()"
(click)="bold.set(!bold())"
translate="no"
>
format_bold
</button>
<button
ngToolbarWidget
value="italic"
type="button"
aria-label="italic"
class="material-symbols-outlined"
[attr.aria-pressed]="italic()"
(click)="italic.set(!italic())"
translate="no"
>
format_italic
</button>
<button
ngToolbarWidget
value="underlined"
type="button"
aria-label="underlined"
class="material-symbols-outlined"
[attr.aria-pressed]="underlined()"
(click)="underlined.set(!underlined())"
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"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'left'"
(click)="alignment.set('left')"
translate="no"
>
format_align_left
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align center"
aria-label="align center"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'center'"
(click)="alignment.set('center')"
translate="no"
>
format_align_center
</button>
<button
ngToolbarWidget
role="radio"
type="button"
value="align right"
aria-label="align right"
class="material-symbols-outlined"
[attr.aria-checked]="alignment() === 'right'"
(click)="alignment.set('right')"
translate="no"
>
format_align_right
</button>
</div>
</div>
app.css
@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-pressed-tint: #fbfbfb;
--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);
}
:host-context(.docs-dark-mode) {
--retro-pressed-tint: #151417;
}
[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(--retro-pressed-tint));
}
[ngToolbarWidget]:focus {
outline-offset: 4px;
outline: 4px dashed var(--retro-button-color);
}
Test etme
Angular Aria, araç çubuğu bileşenlerini test etmek için bileşen harness'leri sağlar. Bir bileşen testinde harness'lerin nasıl kullanılacağına dair bir örnek:
import {ComponentFixture, TestBed} from '@angular/core/testing';
import {HarnessLoader} from '@angular/cdk/testing';
import {TestbedHarnessEnvironment} from '@angular/cdk/testing/testbed';
import {ToolbarHarness} from '@angular/aria/toolbar/testing';
import {MyToolbarComponent} from './my-toolbar'; // Bileşeniniz
describe('MyToolbarComponent', () => {
let fixture: ComponentFixture<MyToolbarComponent>;
let loader: HarnessLoader;
beforeEach(async () => {
TestBed.configureTestingModule({
imports: [MyToolbarComponent],
});
fixture = TestBed.createComponent(MyToolbarComponent);
await fixture.whenStable();
loader = TestbedHarnessEnvironment.loader(fixture);
});
it('should have widgets and update toggle state on click', async () => {
// Araç çubuğu harness'ini yükle
const toolbar = await loader.getHarness(ToolbarHarness);
// Tüm widget'ları al
const widgets = await toolbar.getWidgets();
expect(widgets.length).toBe(3);
// İlk widget'a tıkla
await widgets[0].click();
// Basılı durumun tıklama işleyicisi aracılığıyla güncellendiğini doğrula
expect(await widgets[0].isSelected()).toBe(true);
});
});
API referansı
Ayrıntılı API belgeleri için aşağıdaki API referanslarını inceleyin: