docs: aria listbox examples (#65273)

PR Close #65273
This commit is contained in:
Wagner Maciel 2025-11-16 23:43:09 -05:00 committed by Jessica Janiuk
parent 047b2659b1
commit cb481a549b
85 changed files with 578 additions and 214 deletions

View file

@ -1,4 +1,6 @@
html {
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
font-family: var(--inter-font);
}

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox #combobox="ngCombobox" filterMode="auto-select" class="combobox-container">
<label for="state-input">Select a state:</label>
<div class="input-container">

View file

@ -1,24 +1,26 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
font-family: var(--inter-font);
}
.listbox-container {
width: 200px;
height: 11rem;
padding: 0.5rem;
border-radius: 0.5rem;
background-color: var(--septenary-contrast);
font-size: 0.9rem;
}
[ngListbox] {
gap: 2px;
height: 100%;
display: flex;
overflow: auto;
flex-direction: column;
background: var(--octonary-contrast);
}
[ngCombobox]:has([ngComboboxInput][aria-expanded='false']) .example-popup-container {
max-height: 0;
opacity: 0;
visibility: hidden;
transition:
max-height 150ms ease-in,
visibility 0s 150ms,
opacity 150ms ease-in;
}
[ngCombobox]:has([ngComboboxInput][aria-expanded='true']) [ngListbox] {
display: flex;
}
[ngOption] {
@ -45,20 +47,14 @@
background-color: color-mix(in srgb, var(--hot-pink) 5%, transparent);
}
.example-option-icon {
font-size: 1.25rem;
padding-right: 1rem;
}
[ngOption]:not([aria-selected='true']) .example-option-check {
display: none;
}
.example-option-icon,
.example-option-check {
font-size: 0.9rem;
}
.example-option-text {
flex: 1;
}
}

View file

@ -1,10 +1,10 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngListbox>
@for (option of options; track option) {
<div ngOption [value]="option">
<span class="option-text">{{ option }}</span>
<span class="checkmark-icon material-symbols-outlined">check</span>
<div class="listbox-container">
<div ngListbox value="Option 1">
@for (option of options; track option) {
<div ngOption [value]="option">
<span class="example-option-text">{{ option }}</span>
<span class="example-option-check material-symbols-outlined">check</span>
</div>
}
</div>
}
</div>
</div>

View file

@ -1,13 +1,23 @@
import {Listbox, Option} from '@angular/aria/listbox';
import {Component} from '@angular/core';
import {ChangeDetectionStrategy, Component} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [Listbox, Option],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
/** The options available in the listbox. */
options = ['Option 1', 'Option 2', 'Option 3', 'Option 4'];
options = [
'Option 1',
'Option 2',
'Option 3',
'Option 4',
'Option 5',
'Option 6',
'Option 7',
'Option 8',
];
}

View file

@ -0,0 +1,67 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;
font-family: var(--inter-font);
--primary: var(--hot-pink);
--on-primary: var(--page-background);
}
.docs-light-mode {
--on-primary: #fff;
}
.material-listbox {
width: 200px;
height: 13rem;
padding: 0.5rem;
border-radius: 2rem;
background-color: var(--septenary-contrast);
font-size: 0.9rem;
}
[ngListbox] {
gap: 2px;
padding: 2px;
height: 100%;
display: flex;
overflow: auto;
flex-direction: column;
}
[ngOption] {
display: flex;
cursor: pointer;
align-items: center;
padding: 0 1rem;
min-height: 3rem;
border-radius: 3rem;
}
[ngOption]:hover,
[ngOption][data-active='true'] {
background-color: color-mix(in srgb, var(--primary-contrast) 5%, transparent);
}
[ngOption][data-active='true'] {
outline-offset: -2px;
outline: 2px solid var(--primary);
}
[ngOption][aria-selected='true'] {
color: var(--primary);
background-color: color-mix(in srgb, var(--primary) 10%, transparent);
}
[ngOption]:not([aria-selected='true']) .example-option-check {
display: none;
}
.example-option-check {
font-size: 0.9rem;
}
.example-option-text {
flex: 1;
}

View file

@ -0,0 +1,10 @@
<div class="material-listbox">
<div ngListbox>
@for (option of options; track option) {
<div ngOption [value]="option">
<span class="example-option-text">{{ option }}</span>
<span class="example-option-check material-symbols-outlined">check</span>
</div>
}
</div>
</div>

View file

@ -0,0 +1,23 @@
import {Listbox, Option} from '@angular/aria/listbox';
import {ChangeDetectionStrategy, Component} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [Listbox, Option],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
/** The options available in the listbox. */
options = [
'Option 1',
'Option 2',
'Option 3',
'Option 4',
'Option 5',
'Option 6',
'Option 7',
'Option 8',
];
}

View file

@ -0,0 +1,68 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
:host {
display: flex;
justify-content: center;
font-size: 0.8rem;
font-family: 'Press Start 2P';
--retro-button-color: color-mix(in srgb, var(--hot-pink) 80%, var(--gray-1000));
--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-flat-shadow:
4px 0px 0px 0px var(--gray-700), 0px 4px 0px 0px var(--gray-700),
-4px 0px 0px 0px var(--gray-700), 0px -4px 0px 0px var(--gray-700);
}
.retro-listbox {
width: 200px;
height: 11rem;
padding: 0.5rem;
box-shadow: var(--retro-flat-shadow);
background-color: var(--septenary-contrast);
}
[ngListbox] {
gap: 2px;
height: 100%;
display: flex;
overflow: auto;
flex-direction: column;
}
[ngOption] {
display: flex;
cursor: pointer;
align-items: center;
padding: 0 1rem;
font-size: 0.6rem;
min-height: 2.25rem;
}
[ngOption]:hover {
background-color: color-mix(in srgb, var(--primary-contrast) 5%, transparent);
}
[ngOption][data-active='true'] {
outline-offset: -2px;
outline: 2px dashed var(--hot-pink);
}
[ngOption][aria-selected='true'] {
color: var(--hot-pink);
background-color: color-mix(in srgb, var(--hot-pink) 5%, transparent);
}
[ngOption]:not([aria-selected='true']) .example-option-check {
display: none;
}
.example-option-icon,
.example-option-check {
font-size: 0.9rem;
}
.example-option-text {
flex: 1;
}

View file

@ -0,0 +1,10 @@
<div class="retro-listbox">
<div ngListbox>
@for (option of options; track option) {
<div ngOption [value]="option">
<span class="example-option-text">{{ option }}</span>
<span class="example-option-check material-symbols-outlined">check</span>
</div>
}
</div>
</div>

View file

@ -0,0 +1,23 @@
import {Listbox, Option} from '@angular/aria/listbox';
import {ChangeDetectionStrategy, Component} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [Listbox, Option],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
/** The options available in the listbox. */
options = [
'Option 1',
'Option 2',
'Option 3',
'Option 4',
'Option 5',
'Option 6',
'Option 7',
'Option 8',
];
}

View file

@ -1,9 +1,35 @@
h1 {
background: #1e1e1e;
color: #e0e0e0;
padding: 2rem;
margin: 0;
font-family: system-ui, -apple-system, sans-serif;
font-size: 2rem;
text-align: center;
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
font-size: 0.8rem;
font-family: var(--inter-font);
}
[ngListbox] {
gap: 0.5rem;
display: flex;
flex-wrap: wrap;
}
[ngOption] {
cursor: pointer;
border-radius: 1rem;
padding: 0.3rem 1rem;
color: var(--hot-pink);
border: 1px solid var(--hot-pink);
background-color: color-mix(in srgb, var(--hot-pink) 5%, transparent);
}
[ngOption]:focus {
outline: 2px solid var(--hot-pink);
outline-offset: 2px;
}
[ngOption]:hover {
background-color: color-mix(in srgb, var(--hot-pink) 15%, transparent);
}
[ngOption][aria-selected='true'] {
color: var(--page-background);
background-color: var(--hot-pink);
}

View file

@ -1 +1,7 @@
<h1>PLACEHOLDER</h1>
<div ngListbox aria-label="Amenities" orientation="horizontal" selectionMode="explicit" multi>
@for (amenity of amenities; track amenity) {
<div ngOption [value]="amenity" [label]="amenity">
<span class="option-label">{{ amenity }}</span>
</div>
}
</div>

View file

@ -1,8 +1,14 @@
import {Component} from '@angular/core';
import {Listbox, Option} from '@angular/aria/listbox';
import {ChangeDetectionStrategy, Component} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [Listbox, Option],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {}
export class App {
/** The options available in the listbox. */
amenities = ['Washer / Dryer', 'Ramp access', 'Garden', 'Cats OK', 'Dogs OK', 'Smoke-free'];
}

View file

@ -0,0 +1,51 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
font-size: 0.8rem;
font-family: var(--inter-font);
}
[ngListbox] {
gap: 0.5rem;
display: flex;
flex-wrap: wrap;
}
[ngOption] {
display: flex;
cursor: pointer;
align-items: center;
border-radius: 0.3rem;
padding: 0.3rem 0.5rem;
color: var(--hot-pink);
border: 1px solid var(--hot-pink);
background-color: color-mix(in srgb, var(--hot-pink) 5%, transparent);
}
[ngOption]:focus {
outline: 2px solid var(--hot-pink);
outline-offset: 2px;
}
[ngOption]:hover {
background-color: color-mix(in srgb, var(--hot-pink) 15%, transparent);
}
[ngOption][aria-selected='true'] {
color: var(--page-background);
background-color: var(--hot-pink);
}
.check-icon {
width: 0;
font-size: 1.25rem;
overflow: hidden;
transition:
width 0.2s ease-in-out,
padding-right 0.2s ease-in-out;
}
[ngOption][aria-selected='true'] .check-icon {
width: 1.5rem;
padding-right: 0.2rem;
}

View file

@ -0,0 +1,15 @@
<div
ngListbox
class="material-listbox"
aria-label="Amenities"
orientation="horizontal"
selectionMode="explicit"
multi
>
@for (amenity of amenities; track amenity) {
<div ngOption [value]="amenity" [label]="amenity">
<span class="check-icon material-symbols-outlined">check</span>
<span class="option-label">{{ amenity }}</span>
</div>
}
</div>

View file

@ -0,0 +1,14 @@
import {Listbox, Option} from '@angular/aria/listbox';
import {ChangeDetectionStrategy, Component} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [Listbox, Option],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
/** The options available in the listbox. */
amenities = ['Washer / Dryer', 'Ramp access', 'Garden', 'Cats OK', 'Dogs OK', 'Smoke-free'];
}

View file

@ -0,0 +1,62 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
:host {
display: flex;
justify-content: center;
font-size: 0.8rem;
font-family: 'Press Start 2P';
--retro-button-color: color-mix(in srgb, var(--hot-pink) 80%, var(--gray-1000));
--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-flat-shadow:
4px 0px 0px 0px var(--gray-700), 0px 4px 0px 0px var(--gray-700),
-4px 0px 0px 0px var(--gray-700), 0px -4px 0px 0px var(--gray-700);
--retro-flat-shadow-small:
2px 0px 0px 0px var(--gray-700), 0px 2px 0px 0px var(--gray-700),
-2px 0px 0px 0px var(--gray-700), 0px -2px 0px 0px var(--gray-700);
}
.retro-listbox {
gap: 0.5rem;
display: flex;
flex-wrap: wrap;
padding: 0.5rem;
box-shadow: var(--retro-flat-shadow);
background-color: var(--septenary-contrast);
}
[ngOption] {
display: flex;
cursor: pointer;
align-items: center;
padding: 0.3rem 0.5rem;
font-size: 0.6rem;
box-shadow: var(--retro-flat-shadow-small);
}
[ngOption]:hover {
background-color: color-mix(in srgb, var(--primary-contrast) 5%, transparent);
}
[ngOption][data-active='true'] {
outline-offset: -2px;
outline: 2px dashed var(--hot-pink);
}
[ngOption][aria-selected='true'] {
color: var(--hot-pink);
background-color: color-mix(in srgb, var(--hot-pink) 5%, transparent);
}
.check-icon {
width: 0;
font-size: 0.9rem;
overflow: hidden;
transition: width 0.2s ease-in-out;
}
[ngOption][aria-selected='true'] .check-icon {
width: 1.2rem;
}

View file

@ -0,0 +1,8 @@
<div ngListbox class="retro-listbox" aria-label="Amenities" orientation="horizontal" selectionMode="explicit" multi>
@for (amenity of amenities; track amenity) {
<div ngOption [value]="amenity" [label]="amenity">
<span class="check-icon material-symbols-outlined">check</span>
<span class="option-label">{{ amenity }}</span>
</div>
}
</div>

View file

@ -0,0 +1,14 @@
import {Listbox, Option} from '@angular/aria/listbox';
import {ChangeDetectionStrategy, Component} from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.html',
styleUrl: './app.css',
imports: [Listbox, Option],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class App {
/** The options available in the listbox. */
amenities = ['Washer / Dryer', 'Ramp access', 'Garden', 'Cats OK', 'Dogs OK', 'Smoke-free'];
}

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox class="material-select" readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,6 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
:host {
display: flex;
justify-content: center;

View file

@ -1,6 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet" />
<div ngCombobox class="retro-select" readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox class="material-select" readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,6 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
:host {
display: flex;
justify-content: center;

View file

@ -1,6 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet" />
<div ngCombobox class="retro-select" readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox class="material-select" readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,6 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
:host {
display: flex;
justify-content: center;

View file

@ -1,6 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet" />
<div ngCombobox class="retro-select" readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox class="material-select" readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,6 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
:host {
display: flex;
justify-content: center;

View file

@ -1,6 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet" />
<div ngCombobox class="retro-select" readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox readonly disabled>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox class="material-select" readonly disabled>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,6 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
:host {
display: flex;
justify-content: center;

View file

@ -1,6 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet" />
<div ngCombobox class="retro-select" readonly disabled>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngCombobox class="material-select" readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,6 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
@import url('https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap');
:host {
display: flex;
justify-content: center;

View file

@ -1,6 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap" rel="stylesheet" />
<div ngCombobox class="retro-select" readonly>
<div #origin class="select">
<span class="combobox-label">

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar aria-label="Text Formatting Tools">
<div class="group">
<button

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar class="material-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar class="retro-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar aria-label="Text Formatting Tools">
<div class="group">
<button

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar class="disabled-material-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar class="disabled-material-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar class="retro-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar dir="rtl" aria-label="Text Formatting Tools">
<div class="group">
<button

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar dir="rtl" class="rtl-material-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: center;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar dir="rtl" class="rtl-retro-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: flex-start;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar orientation="vertical" aria-label="Text Formatting Tools">
<div class="group">
<button

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: flex-start;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar orientation="vertical" class="vertical-material-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button
@ -62,47 +60,4 @@
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()"
>
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()"
>
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()"
>
format_align_right
</button>
</div>
</div>

View file

@ -1,10 +1,10 @@
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
import {Toolbar, ToolbarWidget} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
imports: [Toolbar, ToolbarWidget],
})
export class App {}

View file

@ -1,3 +1,5 @@
@import url('https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined');
:host {
display: flex;
justify-content: flex-start;

View file

@ -1,5 +1,3 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Symbols+Outlined" rel="stylesheet" />
<div ngToolbar orientation="vertical" class="retro-toolbar" aria-label="Text Formatting Tools">
<div class="group">
<button
@ -62,47 +60,4 @@
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()"
>
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()"
>
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()"
>
format_align_right
</button>
</div>
</div>

View file

@ -1,10 +1,10 @@
import {Component} from '@angular/core';
import {Toolbar, ToolbarWidget, ToolbarWidgetGroup} from '@angular/aria/toolbar';
import {Toolbar, ToolbarWidget} from '@angular/aria/toolbar';
@Component({
selector: 'app-root',
templateUrl: 'app.html',
styleUrl: 'app.css',
imports: [Toolbar, ToolbarWidget, ToolbarWidgetGroup],
imports: [Toolbar, ToolbarWidget],
})
export class App {}

View file

@ -5,11 +5,31 @@
A directive that displays a list of options for users to select from, supporting keyboard navigation, single or multiple selection, and screen reader support.
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/listbox/src/basic/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/listbox/src/basic/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/listbox/src/basic/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/listbox/src/basic/app/app.css"/>
</docs-code-multifile>
<docs-tab-group>
<docs-tab label="Basic">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/listbox/src/basic/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/listbox/src/basic/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/listbox/src/basic/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/listbox/src/basic/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Material">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/listbox/src/basic/material/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/listbox/src/basic/material/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/listbox/src/basic/material/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/listbox/src/basic/material/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Retro">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/listbox/src/basic/retro/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/listbox/src/basic/retro/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/listbox/src/basic/retro/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/listbox/src/basic/retro/app/app.css"/>
</docs-code-multifile>
</docs-tab>
</docs-tab-group>
## Usage
@ -53,10 +73,31 @@ The `values` model signal provides two-way binding to the selected items. With `
Lists sometimes work better horizontally, such as toolbar-like interfaces or tab-style selections. The `orientation` attribute changes both the layout and keyboard navigation direction.
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/listbox/src/horizontal/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/listbox/src/horizontal/app/app.ts" />
<docs-code header="app.html" path="adev/src/content/examples/aria/listbox/src/horizontal/app/app.html" />
</docs-code-multifile>
<docs-tab-group>
<docs-tab label="Basic">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/listbox/src/horizontal/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/listbox/src/horizontal/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/listbox/src/horizontal/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/listbox/src/horizontal/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Material">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/listbox/src/horizontal/material/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/listbox/src/horizontal/material/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/listbox/src/horizontal/material/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/listbox/src/horizontal/material/app/app.css"/>
</docs-code-multifile>
</docs-tab>
<docs-tab label="Retro">
<docs-code-multifile preview hideCode path="adev/src/content/examples/aria/listbox/src/horizontal/retro/app/app.ts">
<docs-code header="app.ts" path="adev/src/content/examples/aria/listbox/src/horizontal/retro/app/app.ts"/>
<docs-code header="app.html" path="adev/src/content/examples/aria/listbox/src/horizontal/retro/app/app.html"/>
<docs-code header="app.css" path="adev/src/content/examples/aria/listbox/src/horizontal/retro/app/app.css"/>
</docs-code-multifile>
</docs-tab>
</docs-tab-group>
With `orientation="horizontal"`, left and right arrow keys navigate between options instead of up and down. The listbox automatically handles right-to-left (RTL) languages by reversing navigation direction.