From 2b677319061779a39b6bbc0498ab8fcfb616f2e2 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 24 Oct 2023 19:33:15 +0200 Subject: [PATCH] Add resize observer to full calendar, fix missing styles (#18381) --- src/panels/calendar/ha-full-calendar.ts | 33 +++++++++--- .../config/helpers/forms/ha-schedule-form.ts | 54 ++----------------- .../lovelace/cards/hui-calendar-card.ts | 7 +-- 3 files changed, 30 insertions(+), 64 deletions(-) diff --git a/src/panels/calendar/ha-full-calendar.ts b/src/panels/calendar/ha-full-calendar.ts index 30b959b736..14645c5486 100644 --- a/src/panels/calendar/ha-full-calendar.ts +++ b/src/panels/calendar/ha-full-calendar.ts @@ -4,6 +4,7 @@ import allLocales from "@fullcalendar/core/locales-all"; import dayGridPlugin from "@fullcalendar/daygrid"; import interactionPlugin from "@fullcalendar/interaction"; import listPlugin from "@fullcalendar/list"; +import { ResizeController } from "@lit-labs/observers/resize-controller"; import "@material/mwc-button"; import { mdiPlus, @@ -13,11 +14,11 @@ import { mdiViewWeek, } from "@mdi/js"; import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -37,6 +38,7 @@ import type { CalendarEvent, } from "../../data/calendar"; import { CalendarEntityFeature } from "../../data/calendar"; +import { TimeZone } from "../../data/translation"; import { haStyle } from "../../resources/styles"; import type { CalendarViewChanged, @@ -46,7 +48,6 @@ import type { } from "../../types"; import { showCalendarEventDetailDialog } from "./show-dialog-calendar-event-detail"; import { showCalendarEventEditDialog } from "./show-dialog-calendar-event-editor"; -import { TimeZone } from "../../data/translation"; declare global { interface HTMLElementTagNameMap { @@ -63,6 +64,7 @@ const defaultFullCalendarConfig: CalendarOptions = { initialView: "dayGridMonth", dayMaxEventRows: true, height: "parent", + handleWindowResize: false, locales: allLocales, views: { listWeek: { @@ -101,8 +103,23 @@ export class HAFullCalendar extends LitElement { @state() private _activeView = this.initialView; - public updateSize(): void { - this.calendar?.updateSize(); + // @ts-ignore + private _resizeController = new ResizeController(this, { + callback: () => this.calendar?.updateSize(), + }); + + disconnectedCallback(): void { + super.disconnectedCallback(); + this.calendar?.destroy(); + this.calendar = undefined; + this.renderRoot.querySelector("style[data-fullcalendar]")?.remove(); + } + + connectedCallback(): void { + super.connectedCallback(); + if (this.hasUpdated && !this.calendar) { + this._loadCalendar(this._activeView); + } } protected render() { @@ -241,10 +258,10 @@ export class HAFullCalendar extends LitElement { } protected firstUpdated(): void { - this._loadCalendar(); + this._loadCalendar(this.initialView); } - private async _loadCalendar() { + private async _loadCalendar(initialView: FullCalendarView) { const luxonPlugin = this.hass.locale.time_zone === TimeZone.local ? undefined @@ -262,7 +279,7 @@ export class HAFullCalendar extends LitElement { ? "local" : this.hass.config.time_zone, firstDay: firstWeekdayIndex(this.hass.locale), - initialView: this.initialView, + initialView, eventDisplay: this.eventDisplay, eventTimeFormat: { hour: useAmPm(this.hass.locale) ? "numeric" : "2-digit", diff --git a/src/panels/config/helpers/forms/ha-schedule-form.ts b/src/panels/config/helpers/forms/ha-schedule-form.ts index f697073b59..f38c36b3ba 100644 --- a/src/panels/config/helpers/forms/ha-schedule-form.ts +++ b/src/panels/config/helpers/forms/ha-schedule-form.ts @@ -4,11 +4,11 @@ import interactionPlugin from "@fullcalendar/interaction"; import timeGridPlugin from "@fullcalendar/timegrid"; import { addDays, isSameDay, isSameWeek, nextDay } from "date-fns"; import { - css, CSSResultGroup, - html, LitElement, PropertyValues, + css, + html, nothing, } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -16,15 +16,13 @@ import { firstWeekdayIndex } from "../../../../common/datetime/first_weekday"; import { formatTime24h } from "../../../../common/datetime/format_time"; import { useAmPm } from "../../../../common/datetime/use_am_pm"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { debounce } from "../../../../common/util/debounce"; import "../../../../components/ha-icon-picker"; import "../../../../components/ha-textfield"; import { Schedule, ScheduleDay, weekdays } from "../../../../data/schedule"; -import { haStyle } from "../../../../resources/styles"; -import { HomeAssistant } from "../../../../types"; -import { loadPolyfillIfNeeded } from "../../../../resources/resize-observer.polyfill"; import { TimeZone } from "../../../../data/translation"; import { showConfirmationDialog } from "../../../../dialogs/generic/show-dialog-box"; +import { haStyle } from "../../../../resources/styles"; +import { HomeAssistant } from "../../../../types"; const defaultFullCalendarConfig: CalendarOptions = { plugins: [timeGridPlugin, interactionPlugin], @@ -70,8 +68,6 @@ class HaScheduleForm extends LitElement { private _item?: Schedule; - private _resizeObserver?: ResizeObserver; - set item(item: Schedule) { this._item = item; if (item) { @@ -106,41 +102,6 @@ class HaScheduleForm extends LitElement { ); } - public connectedCallback(): void { - super.connectedCallback(); - this.updateComplete.then(() => this._attachObserver()); - } - - public disconnectedCallback(): void { - super.disconnectedCallback(); - if (this._resizeObserver) { - this._resizeObserver.disconnect(); - } - } - - private _measureForm() { - const form = this.shadowRoot!.querySelector(".form"); - if (!form) { - return; - } - - this.calendar?.updateSize(); - } - - private async _attachObserver(): Promise { - if (!this._resizeObserver) { - await loadPolyfillIfNeeded(); - this._resizeObserver = new ResizeObserver( - debounce(() => this._measureForm(), 250, false) - ); - } - const form = this.shadowRoot!.querySelector(".form"); - if (!form) { - return; - } - this._resizeObserver.observe(form); - } - protected render() { if (!this.hass) { return nothing; @@ -233,13 +194,6 @@ class HaScheduleForm extends LitElement { ); this.calendar!.render(); - - // Update size after fully rendered to avoid a bad render in the more info - this.updateComplete.then(() => - window.setTimeout(() => { - this.calendar!.updateSize(); - }, 500) - ); } private get _events() { diff --git a/src/panels/lovelace/cards/hui-calendar-card.ts b/src/panels/lovelace/cards/hui-calendar-card.ts index 3ade43b753..0dce19da97 100644 --- a/src/panels/lovelace/cards/hui-calendar-card.ts +++ b/src/panels/lovelace/cards/hui-calendar-card.ts @@ -6,7 +6,7 @@ import { PropertyValues, nothing, } from "lit"; -import { customElement, property, query, state } from "lit/decorators"; +import { customElement, property, state } from "lit/decorators"; import { getColorByIndex } from "../../../common/color/colors"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import { HASSDomEvent } from "../../../common/dom/fire_event"; @@ -24,7 +24,6 @@ import type { HomeAssistant, } from "../../../types"; import "../../calendar/ha-full-calendar"; -import type { HAFullCalendar } from "../../calendar/ha-full-calendar"; import { findEntities } from "../common/find-entities"; import { loadPolyfillIfNeeded } from "../../../resources/resize-observer.polyfill"; import "../components/hui-warning"; @@ -74,8 +73,6 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard { @state() private _error?: string = undefined; - @query("ha-full-calendar", true) private _calendar?: HAFullCalendar; - private _startDate?: Date; private _endDate?: Date; @@ -210,8 +207,6 @@ export class HuiCalendarCard extends LitElement implements LovelaceCard { } this._narrow = card.offsetWidth < 870; this._veryNarrow = card.offsetWidth < 350; - - this._calendar?.updateSize(); } private async _attachObserver(): Promise {