mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 15:26:36 +00:00
Improve combobox overlay observer (#14463)
This commit is contained in:
parent
aec0eb3c78
commit
4846fa1a74
@ -9,14 +9,7 @@ import type {
|
|||||||
ComboBoxLightValueChangedEvent,
|
ComboBoxLightValueChangedEvent,
|
||||||
} from "@vaadin/combo-box/vaadin-combo-box-light";
|
} from "@vaadin/combo-box/vaadin-combo-box-light";
|
||||||
import { registerStyles } from "@vaadin/vaadin-themable-mixin/register-styles";
|
import { registerStyles } from "@vaadin/vaadin-themable-mixin/register-styles";
|
||||||
import {
|
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
|
||||||
css,
|
|
||||||
CSSResultGroup,
|
|
||||||
html,
|
|
||||||
LitElement,
|
|
||||||
PropertyValues,
|
|
||||||
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 { ifDefined } from "lit/directives/if-defined";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
@ -113,6 +106,8 @@ export class HaComboBox extends LitElement {
|
|||||||
|
|
||||||
private _overlayMutationObserver?: MutationObserver;
|
private _overlayMutationObserver?: MutationObserver;
|
||||||
|
|
||||||
|
private _bodyMutationObserver?: MutationObserver;
|
||||||
|
|
||||||
public async open() {
|
public async open() {
|
||||||
await this.updateComplete;
|
await this.updateComplete;
|
||||||
this._comboBox?.open();
|
this._comboBox?.open();
|
||||||
@ -130,6 +125,10 @@ export class HaComboBox extends LitElement {
|
|||||||
this._overlayMutationObserver.disconnect();
|
this._overlayMutationObserver.disconnect();
|
||||||
this._overlayMutationObserver = undefined;
|
this._overlayMutationObserver = undefined;
|
||||||
}
|
}
|
||||||
|
if (this._bodyMutationObserver) {
|
||||||
|
this._bodyMutationObserver.disconnect();
|
||||||
|
this._bodyMutationObserver = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public get selectedItem() {
|
public get selectedItem() {
|
||||||
@ -227,7 +226,7 @@ export class HaComboBox extends LitElement {
|
|||||||
|
|
||||||
private _openedChanged(ev: ComboBoxLightOpenedChangedEvent) {
|
private _openedChanged(ev: ComboBoxLightOpenedChangedEvent) {
|
||||||
const opened = ev.detail.value;
|
const opened = ev.detail.value;
|
||||||
// delay this so we can handle click event before setting _opened
|
// delay this so we can handle click event for toggle button before setting _opened
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.opened = opened;
|
this.opened = opened;
|
||||||
}, 0);
|
}, 0);
|
||||||
@ -235,36 +234,61 @@ export class HaComboBox extends LitElement {
|
|||||||
fireEvent(this, ev.type, ev.detail);
|
fireEvent(this, ev.type, ev.detail);
|
||||||
|
|
||||||
if (opened) {
|
if (opened) {
|
||||||
this.removeInertOnOverlay();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private removeInertOnOverlay() {
|
|
||||||
if ("MutationObserver" in window && !this._overlayMutationObserver) {
|
|
||||||
const overlay = document.querySelector<HTMLElement>(
|
const overlay = document.querySelector<HTMLElement>(
|
||||||
"vaadin-combo-box-overlay"
|
"vaadin-combo-box-overlay"
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!overlay) {
|
if (overlay) {
|
||||||
return;
|
this._removeInert(overlay);
|
||||||
|
}
|
||||||
|
this._observeBody();
|
||||||
|
} else {
|
||||||
|
this._bodyMutationObserver?.disconnect();
|
||||||
|
this._bodyMutationObserver = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this._overlayMutationObserver = new MutationObserver((mutations) => {
|
private _observeBody() {
|
||||||
|
if ("MutationObserver" in window && !this._bodyMutationObserver) {
|
||||||
|
this._bodyMutationObserver = new MutationObserver((mutations) => {
|
||||||
mutations.forEach((mutation) => {
|
mutations.forEach((mutation) => {
|
||||||
if (
|
mutation.addedNodes.forEach((node) => {
|
||||||
mutation.type === "attributes" &&
|
if (node.nodeName === "VAADIN-COMBO-BOX-OVERLAY") {
|
||||||
mutation.attributeName === "inert"
|
this._removeInert(node as HTMLElement);
|
||||||
) {
|
}
|
||||||
this._overlayMutationObserver?.disconnect();
|
});
|
||||||
this._overlayMutationObserver = undefined;
|
|
||||||
overlay.inert = false;
|
|
||||||
} else if (mutation.type === "childList") {
|
|
||||||
mutation.removedNodes.forEach((node) => {
|
mutation.removedNodes.forEach((node) => {
|
||||||
if (node.nodeName === "VAADIN-COMBO-BOX-OVERLAY") {
|
if (node.nodeName === "VAADIN-COMBO-BOX-OVERLAY") {
|
||||||
this._overlayMutationObserver?.disconnect();
|
this._overlayMutationObserver?.disconnect();
|
||||||
this._overlayMutationObserver = undefined;
|
this._overlayMutationObserver = undefined;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this._bodyMutationObserver.observe(document.body, {
|
||||||
|
childList: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _removeInert(overlay: HTMLElement) {
|
||||||
|
if (overlay.inert) {
|
||||||
|
overlay.inert = false;
|
||||||
|
this._overlayMutationObserver?.disconnect();
|
||||||
|
this._overlayMutationObserver = undefined;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ("MutationObserver" in window && !this._overlayMutationObserver) {
|
||||||
|
this._overlayMutationObserver = new MutationObserver((mutations) => {
|
||||||
|
mutations.forEach((mutation) => {
|
||||||
|
if (mutation.attributeName === "inert") {
|
||||||
|
const target = mutation.target as HTMLElement;
|
||||||
|
if (target.inert) {
|
||||||
|
this._overlayMutationObserver?.disconnect();
|
||||||
|
this._overlayMutationObserver = undefined;
|
||||||
|
target.inert = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -272,19 +296,6 @@ export class HaComboBox extends LitElement {
|
|||||||
this._overlayMutationObserver.observe(overlay, {
|
this._overlayMutationObserver.observe(overlay, {
|
||||||
attributes: true,
|
attributes: true,
|
||||||
});
|
});
|
||||||
this._overlayMutationObserver.observe(document.body, {
|
|
||||||
childList: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updated(changedProps: PropertyValues) {
|
|
||||||
super.updated(changedProps);
|
|
||||||
if (
|
|
||||||
changedProps.has("filteredItems") ||
|
|
||||||
(changedProps.has("items") && this.opened)
|
|
||||||
) {
|
|
||||||
this.removeInertOnOverlay();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user