import { DrawerBase } from "@material/mwc-drawer/mwc-drawer-base"; import { styles } from "@material/mwc-drawer/mwc-drawer.css"; import { css, PropertyValues } from "lit"; import { customElement, property } from "lit/decorators"; import { fireEvent } from "../common/dom/fire_event"; const blockingElements = (document as any).$blockingElements; @customElement("ha-drawer") export class HaDrawer extends DrawerBase { @property() public direction: "ltr" | "rtl" = "ltr"; private _mc?: HammerManager; private _rtlStyle?: HTMLElement; protected createAdapter() { return { ...super.createAdapter(), trapFocus: () => { blockingElements.push(this); this.appContent.inert = true; document.body.style.overflow = "hidden"; }, releaseFocus: () => { blockingElements.remove(this); this.appContent.inert = false; document.body.style.overflow = ""; }, }; } protected updated(changedProps: PropertyValues) { super.updated(changedProps); if (changedProps.has("direction")) { this.mdcRoot.dir = this.direction; if (this.direction === "rtl") { this._rtlStyle = document.createElement("style"); this._rtlStyle.innerHTML = ` .mdc-drawer--animate { transform: translateX(100%); } .mdc-drawer--opening { transform: translateX(0); } .mdc-drawer--closing { transform: translateX(100%); } `; this.shadowRoot!.appendChild(this._rtlStyle); } else if (this._rtlStyle) { this.shadowRoot!.removeChild(this._rtlStyle); } } if (changedProps.has("open") && this.open && this.type === "modal") { this._setupSwipe(); } else if (this._mc) { this._mc.destroy(); this._mc = undefined; } } private async _setupSwipe() { const hammer = await import("../resources/hammer"); this._mc = new hammer.Manager(document, { touchAction: "pan-y", }); this._mc.add( new hammer.Swipe({ direction: this.direction === "rtl" ? hammer.DIRECTION_RIGHT : hammer.DIRECTION_LEFT, }) ); this._mc.on("swipeleft swiperight", () => { fireEvent(this, "hass-toggle-menu", { open: false }); }); } static override styles = [ styles, css` .mdc-drawer { position: fixed; top: 0; border-color: var(--divider-color, rgba(0, 0, 0, 0.12)); inset-inline-start: 0 !important; inset-inline-end: initial !important; } .mdc-drawer.mdc-drawer--modal.mdc-drawer--open { z-index: 200; } .mdc-drawer-app-content { overflow: unset; flex: none; padding-left: var(--mdc-drawer-width); padding-inline-start: var(--mdc-drawer-width); padding-inline-end: initial; direction: var(--direction); width: 100%; box-sizing: border-box; } `, ]; } declare global { interface HTMLElementTagNameMap { "ha-drawer": HaDrawer; } }