mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-08 18:06:36 +00:00
Add aria-haspopup to button menus (#12758)
Co-authored-by: Zack Barett <zackbarett@hey.com>
This commit is contained in:
parent
f8303bff76
commit
b35ba4d673
@ -2,12 +2,7 @@ import type { Button } from "@material/mwc-button";
|
|||||||
import "@material/mwc-menu";
|
import "@material/mwc-menu";
|
||||||
import type { Corner, Menu, MenuCorner } from "@material/mwc-menu";
|
import type { Corner, Menu, MenuCorner } from "@material/mwc-menu";
|
||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import {
|
import { customElement, property, query } from "lit/decorators";
|
||||||
customElement,
|
|
||||||
property,
|
|
||||||
query,
|
|
||||||
queryAssignedElements,
|
|
||||||
} from "lit/decorators";
|
|
||||||
import { FOCUS_TARGET } from "../dialogs/make-dialog-manager";
|
import { FOCUS_TARGET } from "../dialogs/make-dialog-manager";
|
||||||
import type { HaIconButton } from "./ha-icon-button";
|
import type { HaIconButton } from "./ha-icon-button";
|
||||||
|
|
||||||
@ -33,12 +28,6 @@ export class HaButtonMenu extends LitElement {
|
|||||||
|
|
||||||
@query("mwc-menu", true) private _menu?: Menu;
|
@query("mwc-menu", true) private _menu?: Menu;
|
||||||
|
|
||||||
@queryAssignedElements({
|
|
||||||
slot: "trigger",
|
|
||||||
selector: "ha-icon-button, mwc-button",
|
|
||||||
})
|
|
||||||
private _triggerButton!: Array<HaIconButton | Button>;
|
|
||||||
|
|
||||||
public get items() {
|
public get items() {
|
||||||
return this._menu?.items;
|
return this._menu?.items;
|
||||||
}
|
}
|
||||||
@ -51,14 +40,14 @@ export class HaButtonMenu extends LitElement {
|
|||||||
if (this._menu?.open) {
|
if (this._menu?.open) {
|
||||||
this._menu.focusItemAtIndex(0);
|
this._menu.focusItemAtIndex(0);
|
||||||
} else {
|
} else {
|
||||||
this._triggerButton[0]?.focus();
|
this._triggerButton?.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
return html`
|
return html`
|
||||||
<div @click=${this._handleClick}>
|
<div @click=${this._handleClick}>
|
||||||
<slot name="trigger"></slot>
|
<slot name="trigger" @slotchange=${this._setTriggerAria}></slot>
|
||||||
</div>
|
</div>
|
||||||
<mwc-menu
|
<mwc-menu
|
||||||
.corner=${this.corner}
|
.corner=${this.corner}
|
||||||
@ -97,6 +86,18 @@ export class HaButtonMenu extends LitElement {
|
|||||||
this._menu!.show();
|
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 {
|
static get styles(): CSSResultGroup {
|
||||||
return css`
|
return css`
|
||||||
:host {
|
:host {
|
||||||
|
@ -2,6 +2,7 @@ import "@material/mwc-icon-button";
|
|||||||
import type { IconButton } from "@material/mwc-icon-button";
|
import type { IconButton } from "@material/mwc-icon-button";
|
||||||
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
import { customElement, property, query } from "lit/decorators";
|
import { customElement, property, query } from "lit/decorators";
|
||||||
|
import { ifDefined } from "lit/directives/if-defined";
|
||||||
import "./ha-svg-icon";
|
import "./ha-svg-icon";
|
||||||
|
|
||||||
@customElement("ha-icon-button")
|
@customElement("ha-icon-button")
|
||||||
@ -12,7 +13,12 @@ export class HaIconButton extends LitElement {
|
|||||||
@property({ type: String }) path?: string;
|
@property({ type: String }) path?: string;
|
||||||
|
|
||||||
// Label that is used for ARIA support and as tooltip
|
// 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;
|
@property({ type: Boolean }) hideTitle = false;
|
||||||
|
|
||||||
@ -28,11 +34,11 @@ export class HaIconButton extends LitElement {
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
// Note: `ariaLabel` required despite the `mwc-icon-button` docs saying `label` should be enough
|
|
||||||
return html`
|
return html`
|
||||||
<mwc-icon-button
|
<mwc-icon-button
|
||||||
.ariaLabel=${this.label}
|
aria-label=${ifDefined(this.label)}
|
||||||
.title=${this.hideTitle ? "" : this.label}
|
title=${ifDefined(this.hideTitle ? undefined : this.label)}
|
||||||
|
aria-haspopup=${ifDefined(this.ariaHasPopup)}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
>
|
>
|
||||||
${this.path
|
${this.path
|
||||||
|
Loading…
x
Reference in New Issue
Block a user