Fix lit warnings (#9204)

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Paulus Schoutsen 2021-05-18 15:01:43 -07:00 committed by GitHub
parent bc92c0b052
commit 1b9286db76
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 161 additions and 129 deletions

View File

@ -129,6 +129,7 @@ const createWebpackConfig = ({
alias: {
"lit/decorators$": "lit/decorators.js",
"lit/directive$": "lit/directive.js",
"lit/polyfill-support$": "lit/polyfill-support.js",
},
},
output: {

View File

@ -1,7 +1,8 @@
// @ts-nocheck
import wrap from "@vue/web-component-wrapper";
import { customElement } from "lit/decorators";
import Vue from "vue";
import DateRangePicker from "vue2-daterange-picker";
// @ts-ignore
import dateRangePickerStyles from "vue2-daterange-picker/dist/vue2-daterange-picker.css";
import { fireEvent } from "../common/dom/fire_event";
import { Constructor } from "../types";
@ -34,22 +35,29 @@ const Component = Vue.extend({
},
},
render(createElement) {
// @ts-ignore
return createElement(DateRangePicker, {
props: {
"time-picker": true,
"auto-apply": false,
opens: "right",
"show-dropdowns": false,
// @ts-ignore
"time-picker24-hour": this.twentyfourHours,
// @ts-ignore
disabled: this.disabled,
// @ts-ignore
ranges: this.ranges ? {} : false,
},
model: {
value: {
// @ts-ignore
startDate: this.startDate,
// @ts-ignore
endDate: this.endDate,
},
callback: (value) => {
// @ts-ignore
fireEvent(this.$el as HTMLElement, "change", value);
},
expression: "dateRange",

View File

@ -80,7 +80,8 @@ export class HaEntityToggle extends LitElement {
this.addEventListener("click", (ev) => ev.stopPropagation());
}
protected updated(changedProps: PropertyValues): void {
public willUpdate(changedProps: PropertyValues): void {
super.willUpdate(changedProps);
if (changedProps.has("stateObj")) {
this._isOn = isOn(this.stateObj);
}

View File

@ -63,7 +63,8 @@ export class StateBadge extends LitElement {
`;
}
protected updated(changedProps: PropertyValues) {
public willUpdate(changedProps: PropertyValues) {
super.willUpdate(changedProps);
if (
!changedProps.has("stateObj") &&
!changedProps.has("overrideImage") &&

View File

@ -55,14 +55,6 @@ export class HaCodeEditor extends ReactiveElement {
public connectedCallback() {
super.connectedCallback();
// Lit 2.0 will create the shadowRoot for us, and adopt the styles, check if it was created
if (!this.shadowRoot) {
this.attachShadow({ mode: "open" }).innerHTML = `<style>
:host(.error-state) div.cm-wrap .cm-gutters {
border-color: var(--error-state-color, red);
}
</style>`;
}
if (!this.codemirror) {
return;
}

View File

@ -49,7 +49,8 @@ export class HaIcon extends LitElement {
@state() private _legacy = false;
protected updated(changedProps: PropertyValues) {
public willUpdate(changedProps: PropertyValues) {
super.willUpdate(changedProps);
if (changedProps.has("icon")) {
this._path = undefined;
this._viewBox = undefined;

View File

@ -93,7 +93,6 @@ class HaMenuButton extends LitElement {
this.style.display = newNarrow || this._alwaysVisible ? "initial" : "none";
if (!newNarrow) {
this._hasNotifications = false;
if (this._unsubNotifications) {
this._unsubNotifications();
this._unsubNotifications = undefined;

View File

@ -27,6 +27,7 @@ import { guard } from "lit/directives/guard";
import memoizeOne from "memoize-one";
import { LocalStorage } from "../common/decorators/local-storage";
import { fireEvent } from "../common/dom/fire_event";
import { toggleAttribute } from "../common/dom/toggle_attribute";
import { computeDomain } from "../common/entity/compute_domain";
import { compare } from "../common/string/compare";
import { computeRTL } from "../common/util/compute_rtl";
@ -165,18 +166,12 @@ class HaSidebar extends LitElement {
@property({ type: Boolean }) public alwaysExpand = false;
@property({ type: Boolean, reflect: true }) public expanded = false;
@property({ type: Boolean }) public editMode = false;
@state() private _externalConfig?: ExternalConfig;
@state() private _notifications?: PersistentNotification[];
// property used only in css
// @ts-ignore
@property({ type: Boolean, reflect: true }) public rtl = false;
@state() private _renderEmptySortable = false;
private _mouseLeaveTimeout?: number;
@ -265,7 +260,7 @@ class HaSidebar extends LitElement {
protected updated(changedProps) {
super.updated(changedProps);
if (changedProps.has("alwaysExpand")) {
this.expanded = this.alwaysExpand;
toggleAttribute(this, "expanded", this.alwaysExpand);
}
if (changedProps.has("editMode")) {
if (this.editMode) {
@ -280,7 +275,7 @@ class HaSidebar extends LitElement {
const oldHass = changedProps.get("hass") as HomeAssistant | undefined;
if (!oldHass || oldHass.locale !== this.hass.locale) {
this.rtl = computeRTL(this.hass);
toggleAttribute(this, "rtl", computeRTL(this.hass));
}
if (!SUPPORT_SCROLL_IF_NEEDED) {
@ -428,7 +423,7 @@ class HaSidebar extends LitElement {
@click=${this._handleShowNotificationDrawer}
>
<ha-svg-icon slot="item-icon" .path=${mdiBell}></ha-svg-icon>
${!this.expanded && notificationCount > 0
${!this.alwaysExpand && notificationCount > 0
? html`
<span class="notification-badge" slot="item-icon">
${notificationCount}
@ -438,7 +433,7 @@ class HaSidebar extends LitElement {
<span class="item-text">
${this.hass.localize("ui.notification_drawer.title")}
</span>
${this.expanded && notificationCount > 0
${this.alwaysExpand && notificationCount > 0
? html` <span class="notification-badge">${notificationCount}</span> `
: ""}
</paper-icon-item>
@ -593,7 +588,7 @@ class HaSidebar extends LitElement {
// for 100ms so that we ignore it when pressing down arrow scrolls the
// sidebar causing the mouse to hover a new icon
if (
this.expanded ||
this.alwaysExpand ||
new Date().getTime() < this._recentKeydownActiveUntil
) {
return;
@ -615,7 +610,7 @@ class HaSidebar extends LitElement {
}
private _listboxFocusIn(ev) {
if (this.expanded || ev.target.nodeName !== "A") {
if (this.alwaysExpand || ev.target.nodeName !== "A") {
return;
}
this._showTooltip(ev.target.querySelector("paper-icon-item"));

View File

@ -50,6 +50,12 @@ export const showDialog = async (
) => {
if (!(dialogTag in LOADED)) {
if (!dialogImport) {
if (__DEV__) {
// eslint-disable-next-line
console.warn(
"Asked to show dialog that's not loaded and can't be imported"
);
}
return;
}
LOADED[dialogTag] = dialogImport().then(() => {

View File

@ -233,7 +233,9 @@ class MoreInfoLight extends LitElement {
`;
}
protected updated(changedProps: PropertyValues<this>) {
public willUpdate(changedProps: PropertyValues<this>) {
super.willUpdate(changedProps);
if (!changedProps.has("stateObj")) {
return;
}

View File

@ -106,8 +106,7 @@ class HassTabsSubpage extends LitElement {
}
);
protected updated(changedProperties: PropertyValues) {
super.updated(changedProperties);
public willUpdate(changedProperties: PropertyValues) {
if (changedProperties.has("route")) {
this._activeTab = this.tabs.find((tab) =>
`${this.route.prefix}${this.route.path}`.includes(tab.path)
@ -121,6 +120,7 @@ class HassTabsSubpage extends LitElement {
this.rtl = computeRTL(this.hass);
}
}
super.willUpdate(changedProperties);
}
protected render(): TemplateResult {

View File

@ -42,19 +42,20 @@ class HomeAssistantMain extends LitElement {
@property() public route?: Route;
@property({ type: Boolean }) public narrow?: boolean;
@property({ type: Boolean }) public narrow!: boolean;
@state() private _sidebarEditMode = false;
constructor() {
super();
listenMediaQuery("(max-width: 870px)", (matches) => {
this.narrow = matches;
});
}
protected render(): TemplateResult {
const hass = this.hass;
if (!hass) {
return html``;
}
const sidebarNarrow = this._sidebarNarrow;
const disableSwipe =
this._sidebarEditMode ||
!sidebarNarrow ||
@ -142,13 +143,9 @@ class HomeAssistantMain extends LitElement {
this.addEventListener("hass-show-notifications", () => {
showNotificationDrawer(this, {
narrow: this.narrow!,
narrow: this.narrow,
});
});
listenMediaQuery("(max-width: 870px)", (matches) => {
this.narrow = matches;
});
}
protected updated(changedProps: PropertyValues) {

View File

@ -15,13 +15,24 @@ import {
import "./ha-init-page";
import "./home-assistant-main";
const useHash = __DEMO__;
const curPath = () =>
window.decodeURIComponent(
useHash ? location.hash.substr(1) : location.pathname
);
const panelUrl = (path: string) => {
const dividerPos = path.indexOf("/", 1);
return dividerPos === -1 ? path.substr(1) : path.substr(1, dividerPos - 1);
};
@customElement("home-assistant")
export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
@state() private _route?: Route;
@state() private _route: Route;
@state() private _error = false;
@state() private _panelUrl?: string;
private _panelUrl: string;
private _haVersion?: string;
@ -29,12 +40,24 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
private _visiblePromiseResolve?: () => void;
constructor() {
super();
const path = curPath();
if (["", "/"].includes(path)) {
navigate(this, `/${getStorageDefaultPanelUrlPath()}`, true);
}
this._route = {
prefix: "",
path,
};
this._panelUrl = panelUrl(path);
}
protected render() {
const hass = this.hass;
return this._panelUrl === undefined || this._route === undefined
? html``
: hass && hass.states && hass.config && hass.services
return hass && hass.states && hass.config && hass.services
? html`
<home-assistant-main
.hass=${this.hass}
@ -56,11 +79,6 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
});
// Navigation
const useHash = __DEMO__;
const curPath = () =>
window.decodeURIComponent(
useHash ? location.hash.substr(1) : location.pathname
);
const updateRoute = (path = curPath()) => {
if (this._route && path === this._route.path) {
return;
@ -69,9 +87,10 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
prefix: "",
path: path,
};
const dividerPos = path.indexOf("/", 1);
this._panelUrl =
dividerPos === -1 ? path.substr(1) : path.substr(1, dividerPos - 1);
this._panelUrl = panelUrl(path);
this.panelUrlChanged(this._panelUrl!);
this._updateHass({ panelUrl: this._panelUrl });
};
window.addEventListener("location-changed", () => updateRoute());
@ -90,21 +109,10 @@ export class HomeAssistantAppEl extends QuickBarMixin(HassElement) {
navigate(this, href);
}
});
// Handle first navigation
if (["", "/"].includes(curPath())) {
navigate(this, `/${getStorageDefaultPanelUrlPath()}`, true);
} else {
updateRoute();
}
}
protected updated(changedProps: PropertyValues): void {
super.updated(changedProps);
if (changedProps.has("_panelUrl")) {
this.panelUrlChanged(this._panelUrl!);
this._updateHass({ panelUrl: this._panelUrl });
}
if (changedProps.has("hass")) {
this.hassChanged(
this.hass!,

View File

@ -65,8 +65,8 @@ class PartialPanelResolver extends HassRouterPage {
document.addEventListener("resume", () => this._checkVisibility());
}
protected updated(changedProps: PropertyValues) {
super.updated(changedProps);
public willUpdate(changedProps: PropertyValues) {
super.willUpdate(changedProps);
if (!changedProps.has("hass")) {
return;

View File

@ -22,8 +22,8 @@ class HuiEntitiesToggle extends LitElement {
@state() private _toggleEntities?: string[];
public updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
public willUpdate(changedProperties: PropertyValues): void {
super.willUpdate(changedProperties);
if (changedProperties.has("entities")) {
this._toggleEntities = this.entities!.filter(
(entityId) =>

View File

@ -83,10 +83,10 @@ export class OriginalStatesStrategy {
info: Parameters<LovelaceDashboardStrategy["generateDashboard"]>[0]
): ReturnType<LovelaceDashboardStrategy["generateDashboard"]> {
return {
title: info.hass.config.location_name,
views: [
{
strategy: { type: "original-states" },
title: info.hass.config.location_name,
},
],
};

View File

@ -23,8 +23,6 @@ import type { HuiErrorCard } from "../cards/hui-error-card";
import { computeCardSize } from "../common/compute-card-size";
import type { Lovelace, LovelaceBadge, LovelaceCard } from "../types";
let editCodeLoaded = false;
// Find column with < 5 size, else smallest column
const getColumnIndex = (columnSizes: number[], size: number) => {
let minIndex = 0;
@ -71,16 +69,26 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
this.addEventListener("iron-resize", (ev: Event) => ev.stopPropagation());
}
public connectedCallback() {
super.connectedCallback();
this._initMqls();
}
public disconnectedCallback() {
super.disconnectedCallback();
this._mqls?.forEach((mql) => {
mql.removeListener(this._updateColumns);
});
this._mqls = undefined;
}
public setConfig(_config: LovelaceViewConfig): void {}
protected render(): TemplateResult {
return html`
<div
id="badges"
style=${this.badges.length > 0 ? "display: block" : "display: none"}
>
${this.badges.map((badge) => html`${badge}`)}
</div>
${this.badges.length > 0
? html` <div class="badges">${this.badges}</div>`
: ""}
<div id="columns"></div>
${this.lovelace?.editMode
? html`
@ -101,31 +109,31 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
`;
}
protected firstUpdated(): void {
private _initMqls() {
this._mqls = [300, 600, 900, 1200].map((width) => {
const mql = window.matchMedia(`(min-width: ${width}px)`);
mql.addListener(() => this._updateColumns());
mql.addListener(this._updateColumns.bind(this));
return mql;
});
this._updateColumns();
}
protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
if (this.lovelace?.editMode && !editCodeLoaded) {
editCodeLoaded = true;
import("./default-view-editable");
private get mqls(): MediaQueryList[] {
if (!this._mqls) {
this._initMqls();
}
return this._mqls!;
}
public willUpdate(changedProperties: PropertyValues) {
super.willUpdate(changedProperties);
if (changedProperties.has("hass")) {
const oldHass = changedProperties.get("hass") as HomeAssistant;
const oldHass = changedProperties.get("hass") as
| HomeAssistant
| undefined;
if (oldHass && this.hass!.dockedSidebar !== oldHass.dockedSidebar) {
if (this.hass!.dockedSidebar !== oldHass?.dockedSidebar) {
this._updateColumns();
}
if (changedProperties.size === 1) {
return;
}
}
@ -133,16 +141,24 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
if (changedProperties.has("narrow")) {
this._updateColumns();
}
}
protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
if (this.lovelace?.editMode) {
import("./default-view-editable");
}
const oldLovelace = changedProperties.get("lovelace") as
| Lovelace
| undefined;
if (
(changedProperties.has("lovelace") &&
(oldLovelace?.config !== this.lovelace?.config ||
oldLovelace?.editMode !== this.lovelace?.editMode)) ||
changedProperties.has("_columns")
changedProperties.has("lovelace") &&
oldLovelace &&
(oldLovelace.config !== this.lovelace?.config ||
oldLovelace.editMode !== this.lovelace?.editMode)
) {
this._createColumns();
}
@ -152,6 +168,17 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
fireEvent(this, "ll-create-card");
}
private _createRootElement(columns: HTMLDivElement[]) {
const root = this.shadowRoot!.getElementById("columns") as HTMLDivElement;
// Remove old columns
while (root.lastChild) {
root.removeChild(root.lastChild);
}
columns.forEach((column) => root.appendChild(column));
}
private async _createColumns() {
if (!this._columns) {
return;
@ -159,12 +186,6 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
this._createColumnsIteration++;
const iteration = this._createColumnsIteration;
const root = this.shadowRoot!.getElementById("columns")!;
// Remove old columns
while (root.lastChild) {
root.removeChild(root.lastChild);
}
// Track the total height of cards in a columns
const columnSizes: number[] = [];
@ -173,11 +194,18 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
for (let i = 0; i < Math.min(this._columns, this.cards.length); i++) {
const columnEl = document.createElement("div");
columnEl.classList.add("column");
root.appendChild(columnEl);
columnSizes.push(0);
columnElements.push(columnEl);
}
if (!this.hasUpdated) {
this.updateComplete.then(() => {
this._createRootElement(columnElements);
});
} else {
this._createRootElement(columnElements);
}
let tillNextRender: Promise<unknown> | undefined;
let start: Date | undefined;
@ -244,19 +272,21 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
}
private _updateColumns() {
if (!this._mqls) {
return;
}
const matchColumns = this._mqls!.reduce(
const matchColumns = this.mqls.reduce(
(cols, mql) => cols + Number(mql.matches),
0
);
// Do -1 column if the menu is docked and open
this._columns = Math.max(
const newColumns = Math.max(
1,
matchColumns -
Number(!this.narrow && this.hass!.dockedSidebar === "docked")
);
if (newColumns === this._columns) {
return;
}
this._columns = newColumns;
this._createColumns();
}
static get styles(): CSSResultGroup {
@ -268,7 +298,7 @@ export class MasonryView extends LitElement implements LovelaceViewElement {
box-sizing: border-box;
}
#badges {
.badges {
margin: 8px 16px;
font-size: 85%;
text-align: center;

View File

@ -40,8 +40,8 @@ export class PanelView extends LitElement implements LovelaceViewElement {
public setConfig(_config: LovelaceViewConfig): void {}
protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
public willUpdate(changedProperties: PropertyValues): void {
super.willUpdate(changedProperties);
if (this.lovelace?.editMode && !editCodeLoaded) {
editCodeLoaded = true;

View File

@ -88,8 +88,8 @@ export class HUIView extends ReactiveElement {
return this;
}
protected updated(changedProperties: PropertyValues): void {
super.updated(changedProperties);
public willUpdate(changedProperties: PropertyValues): void {
super.willUpdate(changedProperties);
/*
We need to handle the following use cases:
@ -112,8 +112,11 @@ export class HUIView extends ReactiveElement {
oldLovelace.config.views[this.index]))
) {
this._initializeConfig();
return;
}
}
protected update(changedProperties) {
super.update(changedProperties);
// If no layout element, we're still creating one
if (this._layoutElement) {

View File

@ -1,6 +1,6 @@
// For localize
import "@formatjs/intl-getcanonicallocales/polyfill";
import "@lit/polyfill-support";
import "lit/polyfill-support";
import "core-js";
// To use comlink under ES5
import "proxy-polyfill";

View File

@ -20,7 +20,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
protected firstUpdated(changedProps) {
super.firstUpdated(changedProps);
// Need to load in advance because when disconnected, can't dynamically load code.
import("../managers/notification-manager");
setTimeout(() => import("../managers/notification-manager"), 5000);
}
updated(changedProperties) {

View File

@ -3,10 +3,6 @@ import { LitElement } from "lit";
import { property } from "lit/decorators";
import { HomeAssistant } from "../types";
// Temporary disable warnings so the dev console is not flooded, we should fix these and then re-enable the warning
if (__DEV__) {
LitElement.disableWarning?.("change-in-update");
}
export class HassBaseEl extends LitElement {
@property({ attribute: false }) public hass?: HomeAssistant;

View File

@ -12,14 +12,6 @@ declare global {
}
}
let moreInfoImportPromise;
const importMoreInfo = () => {
if (!moreInfoImportPromise) {
moreInfoImportPromise = import("../dialogs/more-info/ha-more-info-dialog");
}
return moreInfoImportPromise;
};
export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
class extends superClass {
protected firstUpdated(changedProps: PropertyValues) {
@ -27,7 +19,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
this.addEventListener("hass-more-info", (ev) => this._handleMoreInfo(ev));
// Load it once we are having the initial rendering done.
importMoreInfo();
import("../dialogs/more-info/ha-more-info-dialog");
}
private async _handleMoreInfo(ev: HASSDomEvent<MoreInfoDialogParams>) {
@ -38,7 +30,7 @@ export default <T extends Constructor<HassBaseEl>>(superClass: T) =>
{
entityId: ev.detail.entityId,
},
importMoreInfo
() => import("../dialogs/more-info/ha-more-info-dialog")
);
}
};