Change menus to use fixed mode.
This commit is contained in:
+60
-19
@@ -1,6 +1,7 @@
|
||||
import type { Corner, Menu } from '@material/mwc-menu';
|
||||
import { CSSResultGroup, html, LitElement, TemplateResult, unsafeCSS } from 'lit';
|
||||
import { HomeAssistant } from 'custom-card-helpers';
|
||||
import { customElement, property } from 'lit/decorators';
|
||||
import { customElement, property, query } from 'lit/decorators';
|
||||
import { frigateCardHasAction, refreshDynamicStateParameters } from '../common.js';
|
||||
import { ifDefined } from 'lit/directives/if-defined';
|
||||
import { styleMap } from 'lit/directives/style-map';
|
||||
@@ -9,7 +10,6 @@ import { ExtendedHomeAssistant, MenuSubmenu, MenuSubmenuItem } from '../types.js
|
||||
import { actionHandler } from '../action-handler-directive.js';
|
||||
|
||||
import submenuStyle from '../scss/submenu.scss';
|
||||
import type { Corner } from "@material/mwc-menu";
|
||||
|
||||
@customElement('frigate-card-submenu')
|
||||
export class FrigateCardSubmenu extends LitElement {
|
||||
@@ -22,11 +22,13 @@ export class FrigateCardSubmenu extends LitElement {
|
||||
@property({ attribute: false })
|
||||
public corner?: Corner;
|
||||
|
||||
@query('mwc-menu') private _menu?: Menu;
|
||||
|
||||
protected _renderItem(item: MenuSubmenuItem): TemplateResult | void {
|
||||
if (!this.hass) {
|
||||
return;
|
||||
}
|
||||
const stateParameters = refreshDynamicStateParameters(this.hass, {...item});
|
||||
const stateParameters = refreshDynamicStateParameters(this.hass, { ...item });
|
||||
|
||||
return html`
|
||||
<mwc-list-item
|
||||
@@ -59,14 +61,65 @@ export class FrigateCardSubmenu extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the HUI root element for this Lovelace dashboard.
|
||||
* @returns The HUI Root element or null if not found.
|
||||
*/
|
||||
protected getHUIRoot(): Element | null {
|
||||
let n = this as Node | null;
|
||||
while (n) {
|
||||
if (n.nodeType === Node.ELEMENT_NODE && (n as Element).tagName === 'HUI-VIEW') {
|
||||
return n as Element;
|
||||
}
|
||||
n = n.parentNode
|
||||
? n.parentNode
|
||||
: n.nodeType === Node.DOCUMENT_FRAGMENT_NODE
|
||||
? (n as ShadowRoot).host
|
||||
: null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.submenu) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-button-menu
|
||||
corner=${this.corner || "BOTTOM_LEFT"}
|
||||
<ha-icon-button
|
||||
style="${styleMap(this.submenu.style || {})}"
|
||||
class="button"
|
||||
.label=${this.submenu.title || ''}
|
||||
.actionHandler=${actionHandler({
|
||||
hasHold: frigateCardHasAction(this.submenu.hold_action),
|
||||
hasDoubleClick: frigateCardHasAction(this.submenu.double_tap_action),
|
||||
})}
|
||||
@click=${() => {
|
||||
if (this._menu) {
|
||||
// Hack: This insanity is brought about by lack of MWCMenu playing
|
||||
// nicely with the Home Assistant view/sidepanel. The menu must be
|
||||
// rendered in fixed mode in order to allow the menu to render
|
||||
// outside of the card boundaries (card has overflow as hidden).
|
||||
// When in fixed mode, the menu anchoring refuses to get the
|
||||
// placement correct -- it's always off by exactly the dimensions of
|
||||
// the sidebar/header. To work around this we iterate up the DOM to
|
||||
// find the main view (excl. the sidebar) and subtract those
|
||||
// dimensions off wherever the menu believes it should render.
|
||||
this._menu.anchor = this;
|
||||
const root = this.getHUIRoot();
|
||||
if (root) {
|
||||
const rootPosition = root.getBoundingClientRect();
|
||||
this._menu.x = -rootPosition.left;
|
||||
this._menu.y = -rootPosition.top + this.clientHeight;
|
||||
this._menu.show();
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ha-icon icon="${this.submenu.icon}"></ha-icon>
|
||||
</ha-icon-button>
|
||||
<mwc-menu
|
||||
.corner=${this.corner || "BOTTOM_LEFT"}
|
||||
fixed
|
||||
@closed=${
|
||||
// Prevent the submenu closing from closing anything upstream (e.g.
|
||||
// selecting a submenu in the editor dialog should not close the
|
||||
@@ -74,20 +127,8 @@ export class FrigateCardSubmenu extends LitElement {
|
||||
(ev) => ev.stopPropagation()
|
||||
}
|
||||
>
|
||||
<ha-icon-button
|
||||
style="${styleMap(this.submenu.style || {})}"
|
||||
class="button"
|
||||
slot="trigger"
|
||||
.label=${this.submenu.title || ''}
|
||||
.actionHandler=${actionHandler({
|
||||
hasHold: frigateCardHasAction(this.submenu.hold_action),
|
||||
hasDoubleClick: frigateCardHasAction(this.submenu.double_tap_action),
|
||||
})}
|
||||
>
|
||||
<ha-icon icon="${this.submenu.icon}"></ha-icon>
|
||||
</ha-icon-button>
|
||||
${this.submenu.items.map(this._renderItem.bind(this))}
|
||||
</ha-button-menu>
|
||||
</mwc-menu>
|
||||
`;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user