Files
frontend/src/components/ha-md-button-menu.ts
Wendelin 25f25243bd Automation editor: overflow changes and style fixes (#26744)
* Fix for width also for blueprint editor

* Fix overflow menus

* Fix option icons

* Fix iOS bottom sheet flickering and drag handle

* Fix mobile padding

* Fix padding in sidebar

* Fix overflow placement

* Add new a11y sort

* Remove overflow in rows

* Fix a11y select row

* Revert "Fix a11y select row"

This reverts commit 54260c4a37.

* Fix option padding on blueprint

---------

Co-authored-by: Paul Bottein <paul.bottein@gmail.com>
2025-08-28 16:42:45 +00:00

124 lines
3.0 KiB
TypeScript

import type { TemplateResult } from "lit";
import { css, html, LitElement } from "lit";
import { customElement, property, query } from "lit/decorators";
import { fireEvent } from "../common/dom/fire_event";
import { FOCUS_TARGET } from "../dialogs/make-dialog-manager";
import type { HaButton } from "./ha-button";
import type { HaIconButton } from "./ha-icon-button";
import "./ha-md-menu";
import type { HaMdMenu } from "./ha-md-menu";
@customElement("ha-md-button-menu")
export class HaMdButtonMenu extends LitElement {
protected readonly [FOCUS_TARGET];
@property({ type: Boolean }) public disabled = false;
@property() public positioning?: "fixed" | "absolute" | "popover";
@property({ attribute: "anchor-corner" }) public anchorCorner:
| "start-start"
| "start-end"
| "end-start"
| "end-end" = "end-start";
@property({ attribute: "menu-corner" }) public menuCorner:
| "start-start"
| "start-end"
| "end-start"
| "end-end" = "start-start";
@property({ type: Boolean, attribute: "has-overflow" }) public hasOverflow =
false;
@property({ type: Boolean }) public quick = false;
@query("ha-md-menu", true) private _menu!: HaMdMenu;
public get items() {
return this._menu.items;
}
public override focus() {
if (this._menu.open) {
this._menu.focus();
} else {
this._triggerButton?.focus();
}
}
protected render(): TemplateResult {
return html`
<div @click=${this._handleClick}>
<slot name="trigger" @slotchange=${this._setTriggerAria}></slot>
</div>
<ha-md-menu
.quick=${this.quick}
.positioning=${this.positioning}
.hasOverflow=${this.hasOverflow}
.anchorCorner=${this.anchorCorner}
.menuCorner=${this.menuCorner}
@opening=${this._handleOpening}
@closing=${this._handleClosing}
>
<slot></slot>
</ha-md-menu>
`;
}
private _handleOpening(): void {
fireEvent(this, "opening", undefined, { composed: false });
}
private _handleClosing(): void {
fireEvent(this, "closing", undefined, { composed: false });
}
private _handleClick(): void {
if (this.disabled) {
return;
}
this._menu.anchorElement = this;
if (this._menu.open) {
this._menu.close();
} else {
this._menu.show();
}
}
private get _triggerButton() {
return this.querySelector(
'ha-icon-button[slot="trigger"], ha-button[slot="trigger"], ha-assist-chip[slot="trigger"]'
) as HaIconButton | HaButton | null;
}
private _setTriggerAria() {
if (this._triggerButton) {
this._triggerButton.ariaHasPopup = "menu";
}
}
static styles = css`
:host {
display: inline-block;
position: relative;
}
::slotted([disabled]) {
color: var(--disabled-text-color);
}
`;
}
declare global {
interface HTMLElementTagNameMap {
"ha-md-button-menu": HaMdButtonMenu;
}
}
declare global {
interface HASSDomEvents {
opening: undefined;
closing: undefined;
}
}