Add aria-haspopup to button menus (#12758)

Co-authored-by: Zack Barett <zackbarett@hey.com>
This commit is contained in:
Steve Repsher 2022-05-25 10:05:43 -04:00 committed by GitHub
parent f8303bff76
commit b35ba4d673
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 18 deletions

View File

@ -2,12 +2,7 @@ import type { Button } from "@material/mwc-button";
import "@material/mwc-menu";
import type { Corner, Menu, MenuCorner } from "@material/mwc-menu";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import {
customElement,
property,
query,
queryAssignedElements,
} from "lit/decorators";
import { customElement, property, query } from "lit/decorators";
import { FOCUS_TARGET } from "../dialogs/make-dialog-manager";
import type { HaIconButton } from "./ha-icon-button";
@ -33,12 +28,6 @@ export class HaButtonMenu extends LitElement {
@query("mwc-menu", true) private _menu?: Menu;
@queryAssignedElements({
slot: "trigger",
selector: "ha-icon-button, mwc-button",
})
private _triggerButton!: Array<HaIconButton | Button>;
public get items() {
return this._menu?.items;
}
@ -51,14 +40,14 @@ export class HaButtonMenu extends LitElement {
if (this._menu?.open) {
this._menu.focusItemAtIndex(0);
} else {
this._triggerButton[0]?.focus();
this._triggerButton?.focus();
}
}
protected render(): TemplateResult {
return html`
<div @click=${this._handleClick}>
<slot name="trigger"></slot>
<slot name="trigger" @slotchange=${this._setTriggerAria}></slot>
</div>
<mwc-menu
.corner=${this.corner}
@ -97,6 +86,18 @@ export class HaButtonMenu extends LitElement {
this._menu!.show();
}
private get _triggerButton() {
return this.querySelector(
'ha-icon-button[slot="trigger"], mwc-button[slot="trigger"]'
) as HaIconButton | Button | null;
}
private _setTriggerAria() {
if (this._triggerButton) {
this._triggerButton.ariaHasPopup = "menu";
}
}
static get styles(): CSSResultGroup {
return css`
:host {

View File

@ -2,6 +2,7 @@ import "@material/mwc-icon-button";
import type { IconButton } from "@material/mwc-icon-button";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, query } from "lit/decorators";
import { ifDefined } from "lit/directives/if-defined";
import "./ha-svg-icon";
@customElement("ha-icon-button")
@ -12,7 +13,12 @@ export class HaIconButton extends LitElement {
@property({ type: String }) path?: string;
// Label that is used for ARIA support and as tooltip
@property({ type: String }) label = "";
@property({ type: String }) label?: string;
// These should always be set as properties, not attributes,
// so that only the <button> element gets the attribute
@property({ type: String, attribute: "aria-haspopup" })
override ariaHasPopup!: IconButton["ariaHasPopup"];
@property({ type: Boolean }) hideTitle = false;
@ -28,11 +34,11 @@ export class HaIconButton extends LitElement {
};
protected render(): TemplateResult {
// Note: `ariaLabel` required despite the `mwc-icon-button` docs saying `label` should be enough
return html`
<mwc-icon-button
.ariaLabel=${this.label}
.title=${this.hideTitle ? "" : this.label}
aria-label=${ifDefined(this.label)}
title=${ifDefined(this.hideTitle ? undefined : this.label)}
aria-haspopup=${ifDefined(this.ariaHasPopup)}
.disabled=${this.disabled}
>
${this.path