mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-11 10:10:25 +01:00
[CL-439] Improve keyboard and visual a11y for chip select (#11112)
This commit is contained in:
parent
4327fa21f6
commit
eec84d893d
@ -52,10 +52,10 @@
|
|||||||
type="button"
|
type="button"
|
||||||
bitMenuItem
|
bitMenuItem
|
||||||
(click)="viewOption(parent, $event)"
|
(click)="viewOption(parent, $event)"
|
||||||
[title]="parent.label ? ('backTo' | i18n: parent.label) : ('back' | i18n)"
|
[title]="'backTo' | i18n: parent.label ?? placeholderText"
|
||||||
>
|
>
|
||||||
<i slot="start" class="bwi bwi-angle-left" aria-hidden="true"></i>
|
<i slot="start" class="bwi bwi-angle-left" aria-hidden="true"></i>
|
||||||
{{ parent.label ? ("backTo" | i18n: parent.label) : ("back" | i18n) }}
|
{{ "backTo" | i18n: parent.label ?? placeholderText }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
@ -76,6 +76,7 @@
|
|||||||
(click)="option.children?.length ? viewOption(option, $event) : selectOption(option, $event)"
|
(click)="option.children?.length ? viewOption(option, $event) : selectOption(option, $event)"
|
||||||
[disabled]="option.disabled"
|
[disabled]="option.disabled"
|
||||||
[title]="option.label"
|
[title]="option.label"
|
||||||
|
[attr.aria-haspopup]="option.children?.length ? 'menu' : null"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
*ngIf="option.icon"
|
*ngIf="option.icon"
|
||||||
|
@ -1,10 +1,23 @@
|
|||||||
import { Component, HostListener, Input, booleanAttribute, signal } from "@angular/core";
|
import {
|
||||||
|
AfterViewInit,
|
||||||
|
Component,
|
||||||
|
DestroyRef,
|
||||||
|
HostListener,
|
||||||
|
Input,
|
||||||
|
QueryList,
|
||||||
|
ViewChild,
|
||||||
|
ViewChildren,
|
||||||
|
booleanAttribute,
|
||||||
|
inject,
|
||||||
|
signal,
|
||||||
|
} from "@angular/core";
|
||||||
|
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||||
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
|
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
|
||||||
|
|
||||||
import { compareValues } from "../../../common/src/platform/misc/compare-values";
|
import { compareValues } from "../../../common/src/platform/misc/compare-values";
|
||||||
import { ButtonModule } from "../button";
|
import { ButtonModule } from "../button";
|
||||||
import { IconButtonModule } from "../icon-button";
|
import { IconButtonModule } from "../icon-button";
|
||||||
import { MenuModule } from "../menu";
|
import { MenuComponent, MenuItemDirective, MenuModule } from "../menu";
|
||||||
import { Option } from "../select/option";
|
import { Option } from "../select/option";
|
||||||
import { SharedModule } from "../shared";
|
import { SharedModule } from "../shared";
|
||||||
import { TypographyModule } from "../typography";
|
import { TypographyModule } from "../typography";
|
||||||
@ -28,7 +41,10 @@ export type ChipSelectOption<T> = Option<T> & {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class ChipSelectComponent<T = unknown> implements ControlValueAccessor {
|
export class ChipSelectComponent<T = unknown> implements ControlValueAccessor, AfterViewInit {
|
||||||
|
@ViewChild(MenuComponent) menu: MenuComponent;
|
||||||
|
@ViewChildren(MenuItemDirective) menuItems: QueryList<MenuItemDirective>;
|
||||||
|
|
||||||
/** Text to show when there is no selected option */
|
/** Text to show when there is no selected option */
|
||||||
@Input({ required: true }) placeholderText: string;
|
@Input({ required: true }) placeholderText: string;
|
||||||
|
|
||||||
@ -62,6 +78,8 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor {
|
|||||||
this.focusVisibleWithin.set(false);
|
this.focusVisibleWithin.set(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private destroyRef = inject(DestroyRef);
|
||||||
|
|
||||||
/** Tree constructed from `this.options` */
|
/** Tree constructed from `this.options` */
|
||||||
private rootTree: ChipSelectOption<T>;
|
private rootTree: ChipSelectOption<T>;
|
||||||
|
|
||||||
@ -148,6 +166,16 @@ export class ChipSelectComponent<T = unknown> implements ControlValueAccessor {
|
|||||||
this.renderedOptions = this.rootTree;
|
this.renderedOptions = this.rootTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit() {
|
||||||
|
/**
|
||||||
|
* menuItems will change when the user navigates into or out of a submenu. when that happens, we want to
|
||||||
|
* direct their focus to the first item in the new menu
|
||||||
|
*/
|
||||||
|
this.menuItems.changes.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(() => {
|
||||||
|
this.menu.keyManager.setFirstItemActive();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/** Control Value Accessor */
|
/** Control Value Accessor */
|
||||||
|
|
||||||
private notifyOnChange?: (value: T) => void;
|
private notifyOnChange?: (value: T) => void;
|
||||||
|
Loading…
Reference in New Issue
Block a user