Improve Accessibility of Components
This commit is contained in:
1 parent
102360791f
commit
e430b5b600
5 files changed
+31
-16
No files matched your search
@@ -7,11 +7,12 @@
|
||||
</div>
|
||||
|
||||
@if (isOpen()) {
|
||||
<ul class="dropdown-list" role="listbox">
|
||||
<ul class="dropdown-list" role="listbox" [id]="dropdownId + '-listbox'">
|
||||
@for (option of normalizedOptions(); track option.value; let i = $index) {
|
||||
<li
|
||||
class="dropdown-item"
|
||||
role="option"
|
||||
[id]="dropdownId + '-option-' + i"
|
||||
[class.selected]="option.value === value()"
|
||||
[class.focused]="i === focusedIndex()"
|
||||
[attr.aria-selected]="option.value === value()"
|
||||
|
||||
@@ -17,6 +17,9 @@ export interface DropdownOption {
|
||||
'role': 'combobox',
|
||||
'aria-haspopup': 'listbox',
|
||||
'[attr.aria-expanded]': 'isOpen()',
|
||||
'[attr.aria-controls]': "isOpen() ? dropdownId + '-listbox' : null",
|
||||
'[attr.aria-activedescendant]': "isOpen() && focusedIndex() >= 0 ? dropdownId + '-option-' + focusedIndex() : null",
|
||||
'[attr.aria-label]': 'ariaLabel()',
|
||||
'[class.open]': 'isOpen()',
|
||||
'tabindex': '0',
|
||||
'(click)': 'toggle()',
|
||||
@@ -30,6 +33,7 @@ export interface DropdownOption {
|
||||
export class Dropdown {
|
||||
options = input<Array<DropdownOption | string>>([]);
|
||||
placeholder = input<string>('Select an option');
|
||||
ariaLabel = input<string | undefined>(undefined);
|
||||
icon = input<string>();
|
||||
value = model<any>(null);
|
||||
selectionChange = output<any>();
|
||||
@@ -37,6 +41,9 @@ export class Dropdown {
|
||||
isOpen = signal(false);
|
||||
focusedIndex = signal(-1);
|
||||
|
||||
private static nextId = 0;
|
||||
dropdownId = `dropdown-${Dropdown.nextId++}`;
|
||||
|
||||
constructor(private el: ElementRef) {}
|
||||
|
||||
normalizedOptions = computed(() => {
|
||||
@@ -96,7 +103,10 @@ export class Dropdown {
|
||||
this.toggle();
|
||||
return;
|
||||
}
|
||||
this.focusedIndex.update(i => (i + 1) % this.normalizedOptions().length);
|
||||
this.focusedIndex.update(i => {
|
||||
if (i === -1) return 0;
|
||||
return (i + 1) % this.normalizedOptions().length;
|
||||
});
|
||||
}
|
||||
|
||||
onArrowUp(event: Event) {
|
||||
@@ -105,7 +115,10 @@ export class Dropdown {
|
||||
this.toggle();
|
||||
return;
|
||||
}
|
||||
this.focusedIndex.update(i => (i - 1 + this.normalizedOptions().length) % this.normalizedOptions().length);
|
||||
this.focusedIndex.update(i => {
|
||||
if (i <= 0) return this.normalizedOptions().length - 1;
|
||||
return i - 1;
|
||||
});
|
||||
}
|
||||
|
||||
@HostListener('document:click', ['$event'])
|
||||
|
||||
Reference in new issue
Block a user