2022-05-16 17:10:41 +02:00
|
|
|
import type { Button } from "@material/mwc-button";
|
2020-09-15 08:42:09 +02:00
|
|
|
import "@material/mwc-menu";
|
2022-02-23 11:34:06 +01:00
|
|
|
import type { Corner, Menu, MenuCorner } from "@material/mwc-menu";
|
2021-05-18 16:37:53 +02:00
|
|
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
2022-05-25 16:05:43 +02:00
|
|
|
import { customElement, property, query } from "lit/decorators";
|
2023-11-29 10:17:31 +01:00
|
|
|
import { mainWindow } from "../common/dom/get_main_window";
|
2022-05-16 17:10:41 +02:00
|
|
|
import { FOCUS_TARGET } from "../dialogs/make-dialog-manager";
|
|
|
|
import type { HaIconButton } from "./ha-icon-button";
|
2021-07-15 12:08:04 +02:00
|
|
|
|
2020-05-06 23:22:12 +02:00
|
|
|
@customElement("ha-button-menu")
|
|
|
|
export class HaButtonMenu extends LitElement {
|
2022-05-16 17:10:41 +02:00
|
|
|
protected readonly [FOCUS_TARGET];
|
|
|
|
|
2023-04-05 10:20:21 +02:00
|
|
|
@property() public corner: Corner = "BOTTOM_START";
|
2020-05-08 13:10:24 +02:00
|
|
|
|
2022-02-23 11:34:06 +01:00
|
|
|
@property() public menuCorner: MenuCorner = "START";
|
|
|
|
|
2022-05-16 17:10:41 +02:00
|
|
|
@property({ type: Number }) public x: number | null = null;
|
2022-02-23 11:34:06 +01:00
|
|
|
|
2022-05-16 17:10:41 +02:00
|
|
|
@property({ type: Number }) public y: number | null = null;
|
2022-02-23 11:34:06 +01:00
|
|
|
|
2020-07-21 23:22:19 +02:00
|
|
|
@property({ type: Boolean }) public multi = false;
|
|
|
|
|
|
|
|
@property({ type: Boolean }) public activatable = false;
|
|
|
|
|
2020-09-15 08:42:09 +02:00
|
|
|
@property({ type: Boolean }) public disabled = false;
|
|
|
|
|
2021-05-25 21:29:32 +02:00
|
|
|
@property({ type: Boolean }) public fixed = false;
|
|
|
|
|
2023-10-23 16:13:38 +02:00
|
|
|
@property({ type: Boolean, attribute: "no-anchor" }) public noAnchor = false;
|
|
|
|
|
2020-10-06 15:55:55 +02:00
|
|
|
@query("mwc-menu", true) private _menu?: Menu;
|
2020-05-06 23:22:12 +02:00
|
|
|
|
2020-07-21 23:22:19 +02:00
|
|
|
public get items() {
|
|
|
|
return this._menu?.items;
|
|
|
|
}
|
|
|
|
|
|
|
|
public get selected() {
|
|
|
|
return this._menu?.selected;
|
|
|
|
}
|
|
|
|
|
2022-05-16 17:10:41 +02:00
|
|
|
public override focus() {
|
|
|
|
if (this._menu?.open) {
|
|
|
|
this._menu.focusItemAtIndex(0);
|
|
|
|
} else {
|
2022-05-25 16:05:43 +02:00
|
|
|
this._triggerButton?.focus();
|
2022-05-16 17:10:41 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 23:22:12 +02:00
|
|
|
protected render(): TemplateResult {
|
|
|
|
return html`
|
|
|
|
<div @click=${this._handleClick}>
|
2022-05-25 16:05:43 +02:00
|
|
|
<slot name="trigger" @slotchange=${this._setTriggerAria}></slot>
|
2020-05-06 23:22:12 +02:00
|
|
|
</div>
|
2020-07-21 23:22:19 +02:00
|
|
|
<mwc-menu
|
|
|
|
.corner=${this.corner}
|
2022-02-23 11:34:06 +01:00
|
|
|
.menuCorner=${this.menuCorner}
|
2021-05-25 21:29:32 +02:00
|
|
|
.fixed=${this.fixed}
|
2020-07-21 23:22:19 +02:00
|
|
|
.multi=${this.multi}
|
|
|
|
.activatable=${this.activatable}
|
2022-02-23 11:34:06 +01:00
|
|
|
.y=${this.y}
|
|
|
|
.x=${this.x}
|
2020-07-21 23:22:19 +02:00
|
|
|
>
|
2020-05-06 23:22:12 +02:00
|
|
|
<slot></slot>
|
|
|
|
</mwc-menu>
|
|
|
|
`;
|
|
|
|
}
|
|
|
|
|
2022-05-11 11:01:45 +02:00
|
|
|
protected firstUpdated(changedProps): void {
|
|
|
|
super.firstUpdated(changedProps);
|
|
|
|
|
2023-11-29 10:17:31 +01:00
|
|
|
if (mainWindow.document.dir === "rtl") {
|
2022-05-11 11:01:45 +02:00
|
|
|
this.updateComplete.then(() => {
|
|
|
|
this.querySelectorAll("mwc-list-item").forEach((item) => {
|
|
|
|
const style = document.createElement("style");
|
|
|
|
style.innerHTML =
|
|
|
|
"span.material-icons:first-of-type { margin-left: var(--mdc-list-item-graphic-margin, 32px) !important; margin-right: 0px !important;}";
|
|
|
|
item!.shadowRoot!.appendChild(style);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-05-06 23:22:12 +02:00
|
|
|
private _handleClick(): void {
|
2020-09-15 08:42:09 +02:00
|
|
|
if (this.disabled) {
|
|
|
|
return;
|
|
|
|
}
|
2023-10-23 16:13:38 +02:00
|
|
|
this._menu!.anchor = this.noAnchor ? null : this;
|
2020-05-06 23:22:12 +02:00
|
|
|
this._menu!.show();
|
|
|
|
}
|
|
|
|
|
2022-05-25 16:05:43 +02:00
|
|
|
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";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-07 22:16:14 +02:00
|
|
|
static get styles(): CSSResultGroup {
|
2020-05-08 13:10:24 +02:00
|
|
|
return css`
|
|
|
|
:host {
|
2020-06-09 22:30:36 +02:00
|
|
|
display: inline-block;
|
2020-05-08 13:10:24 +02:00
|
|
|
position: relative;
|
|
|
|
}
|
2020-10-08 16:37:01 +02:00
|
|
|
::slotted([disabled]) {
|
|
|
|
color: var(--disabled-text-color);
|
|
|
|
}
|
2020-05-08 13:10:24 +02:00
|
|
|
`;
|
2020-05-06 23:22:12 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
declare global {
|
|
|
|
interface HTMLElementTagNameMap {
|
|
|
|
"ha-button-menu": HaButtonMenu;
|
|
|
|
}
|
|
|
|
}
|