From 5a8339753932fcbc02eda42441be2fe71d1df24b Mon Sep 17 00:00:00 2001 From: karwosts Date: Sun, 3 Nov 2024 05:57:39 -0800 Subject: [PATCH 01/23] Support tiled view backgrounds --- src/data/lovelace/config/view.ts | 1 + .../view-editor/hui-view-background-editor.ts | 59 +++++++++++++++---- .../lovelace/views/hui-view-container.ts | 3 + src/translations/en.json | 4 +- 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/src/data/lovelace/config/view.ts b/src/data/lovelace/config/view.ts index dd784c628a1e..4d7799561a95 100644 --- a/src/data/lovelace/config/view.ts +++ b/src/data/lovelace/config/view.ts @@ -9,6 +9,7 @@ export interface ShowViewConfig { interface LovelaceViewBackgroundConfig { image?: string; + tile?: boolean; } export interface LovelaceBaseViewConfig { diff --git a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts index 1ab7e5fe1181..69b9f16e14e3 100644 --- a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts +++ b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts @@ -3,11 +3,30 @@ import type { CSSResultGroup } from "lit"; import { LitElement, css, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; +import "../../../../components/ha-form/ha-form"; +import type { SchemaUnion } from "../../../../components/ha-form/types"; import "../../../../components/ha-selector/ha-selector-image"; import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view"; -import type { HomeAssistant, ValueChangedEvent } from "../../../../types"; +import type { HomeAssistant } from "../../../../types"; -const SELECTOR = { image: { original: true } }; +const SCHEMA = [ + { + name: "backgroundUrl", + selector: { image: { original: true } }, + }, + { + name: "settings", + flatten: true, + expanded: true, + type: "expandable" as const, + schema: [ + { + name: "tile", + selector: { boolean: {} }, + }, + ], + }, +]; @customElement("hui-view-background-editor") export class HuiViewBackgroundEditor extends LitElement { @@ -30,21 +49,23 @@ export class HuiViewBackgroundEditor extends LitElement { ? background.match(/url\(['"]?([^'"]+)['"]?\)/)?.[1] : background?.image; + const tile = typeof background === "string" ? false : background?.tile; + + const data = { backgroundUrl, tile }; + return html` - + .data=${data} + .schema=${SCHEMA} + .computeLabel=${this._computeLabelCallback} + @value-changed=${this._valueChanged} + > `; } - private _backgroundChanged(ev: ValueChangedEvent) { - const backgroundUrl = ev.detail.value; + private _valueChanged(ev: CustomEvent): void { + const backgroundUrl = ev.detail.value.backgroundUrl; const config = { ...this._config, background: { @@ -52,11 +73,25 @@ export class HuiViewBackgroundEditor extends LitElement { ? {} : this._config.background), image: backgroundUrl || undefined, + tile: ev.detail.value.tile, }, }; fireEvent(this, "view-config-changed", { config }); } + private _computeLabelCallback = (schema: SchemaUnion) => { + switch (schema.name) { + case "backgroundUrl": + return this.hass.localize( + "ui.panel.lovelace.editor.edit_view.background.image" + ); + default: + return this.hass.localize( + `ui.panel.lovelace.editor.edit_view.background.${schema.name}` + ); + } + }; + static get styles(): CSSResultGroup { return css` :host { diff --git a/src/panels/lovelace/views/hui-view-container.ts b/src/panels/lovelace/views/hui-view-container.ts index bf74f55dc654..c25bb78fff6f 100644 --- a/src/panels/lovelace/views/hui-view-container.ts +++ b/src/panels/lovelace/views/hui-view-container.ts @@ -54,6 +54,9 @@ class HuiViewContainer extends LitElement { private _computeBackgroundProperty(background?: BackgroundConfig) { if (typeof background === "object" && background.image) { + if (background.tile) { + return `top / auto repeat url('${background.image}')`; + } return `center / cover no-repeat url('${background.image}')`; } if (typeof background === "string") { diff --git a/src/translations/en.json b/src/translations/en.json index 8a78108a97c7..85ab59d0c72f 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5926,7 +5926,9 @@ "header_name": "{name} View Configuration", "add": "Add view", "background": { - "title": "Add a background to the view" + "settings": "Background settings", + "image": "Background image", + "tile": "Tile background" }, "edit": "Edit view", "delete": "Delete view", From f991f8da60a5459d30fe67cdafe3229049131d74 Mon Sep 17 00:00:00 2001 From: karwosts Date: Sun, 3 Nov 2024 06:58:17 -0800 Subject: [PATCH 02/23] dynamic settings --- .../view-editor/hui-view-background-editor.ts | 53 +++++++++++-------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts index 69b9f16e14e3..4f63aa535404 100644 --- a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts +++ b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts @@ -1,5 +1,6 @@ import "@material/mwc-list/mwc-list-item"; import type { CSSResultGroup } from "lit"; +import memoizeOne from "memoize-one"; import { LitElement, css, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { fireEvent } from "../../../../common/dom/fire_event"; @@ -9,25 +10,6 @@ import "../../../../components/ha-selector/ha-selector-image"; import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view"; import type { HomeAssistant } from "../../../../types"; -const SCHEMA = [ - { - name: "backgroundUrl", - selector: { image: { original: true } }, - }, - { - name: "settings", - flatten: true, - expanded: true, - type: "expandable" as const, - schema: [ - { - name: "tile", - selector: { boolean: {} }, - }, - ], - }, -]; - @customElement("hui-view-background-editor") export class HuiViewBackgroundEditor extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -38,6 +20,29 @@ export class HuiViewBackgroundEditor extends LitElement { this._config = config; } + private _schema = memoizeOne((showSettings: boolean) => [ + { + name: "backgroundUrl", + selector: { image: { original: true } }, + }, + ...(showSettings + ? ([ + { + name: "settings", + flatten: true, + expanded: true, + type: "expandable" as const, + schema: [ + { + name: "tile", + selector: { boolean: {} }, + }, + ], + }, + ] as const) + : []), + ]); + protected render() { if (!this.hass) { return nothing; @@ -57,7 +62,7 @@ export class HuiViewBackgroundEditor extends LitElement { @@ -73,13 +78,17 @@ export class HuiViewBackgroundEditor extends LitElement { ? {} : this._config.background), image: backgroundUrl || undefined, - tile: ev.detail.value.tile, + ...(backgroundUrl + ? { tile: ev.detail.value.tile } + : { tile: undefined }), }, }; fireEvent(this, "view-config-changed", { config }); } - private _computeLabelCallback = (schema: SchemaUnion) => { + private _computeLabelCallback = ( + schema: SchemaUnion> + ) => { switch (schema.name) { case "backgroundUrl": return this.hass.localize( From 2b22540cb6ecef837c12872f0d4b53c682e93935 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Tue, 26 Nov 2024 17:34:13 +0000 Subject: [PATCH 03/23] continue work --- src/data/lovelace/config/view.ts | 12 ++++ .../view-editor/hui-view-background-editor.ts | 55 +++++++++++++++++++ .../lovelace/views/hui-view-container.ts | 38 ++++++++++++- src/translations/en.json | 25 ++++++++- 4 files changed, 128 insertions(+), 2 deletions(-) diff --git a/src/data/lovelace/config/view.ts b/src/data/lovelace/config/view.ts index 4d7799561a95..f38c26b8be00 100644 --- a/src/data/lovelace/config/view.ts +++ b/src/data/lovelace/config/view.ts @@ -9,6 +9,18 @@ export interface ShowViewConfig { interface LovelaceViewBackgroundConfig { image?: string; + transparency: number; + size: "original" | "fill_view" | "fit_view"; + alignment: + | "top_left" + | "top_center" + | "top_right" + | "center_left" + | "center" + | "center_right" + | "bottom_left" + | "bottom_center" + | "bottom_right"; tile?: boolean; } diff --git a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts index 4f63aa535404..eaa1b09e5e59 100644 --- a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts +++ b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts @@ -20,6 +20,9 @@ export class HuiViewBackgroundEditor extends LitElement { this._config = config; } + private _localizeValueCallback = (key: string) => + this.hass.localize(key as any); + private _schema = memoizeOne((showSettings: boolean) => [ { name: "backgroundUrl", @@ -33,6 +36,44 @@ export class HuiViewBackgroundEditor extends LitElement { expanded: true, type: "expandable" as const, schema: [ + { + name: "transparency", + selector: { + number: { min: 1, max: 100, mode: "box" }, + }, + }, + { + name: "size", + selector: { + select: { + translation_key: + "ui.panel.lovelace.editor.edit_view.background.size", + default: "original", + options: ["original", "fill_view", "fit_view"], + }, + }, + }, + { + name: "alignment", + selector: { + select: { + translation_key: + "ui.panel.lovelace.editor.edit_view.background.alignment", + default: "center", + options: [ + "top_left", + "top_center", + "top_right", + "center_left", + "center", + "center_right", + "bottom_left", + "bottom_center", + "bottom_right", + ], + }, + }, + }, { name: "tile", selector: { boolean: {} }, @@ -65,6 +106,7 @@ export class HuiViewBackgroundEditor extends LitElement { .schema=${this._schema(!!backgroundUrl)} .computeLabel=${this._computeLabelCallback} @value-changed=${this._valueChanged} + .localizeValue=${this._localizeValueCallback} > `; } @@ -89,11 +131,24 @@ export class HuiViewBackgroundEditor extends LitElement { private _computeLabelCallback = ( schema: SchemaUnion> ) => { + console.log(schema.name); switch (schema.name) { case "backgroundUrl": return this.hass.localize( "ui.panel.lovelace.editor.edit_view.background.image" ); + case "transparency": + return this.hass.localize( + "ui.panel.lovelace.editor.edit_view.background.transparency" + ); + case "alignment": + return this.hass.localize( + "ui.panel.lovelace.editor.edit_view.background.alignment.name" + ); + case "size": + return this.hass.localize( + "ui.panel.lovelace.editor.edit_view.background.size.name" + ); default: return this.hass.localize( `ui.panel.lovelace.editor.edit_view.background.${schema.name}` diff --git a/src/panels/lovelace/views/hui-view-container.ts b/src/panels/lovelace/views/hui-view-container.ts index c25bb78fff6f..84fcbaaa4f77 100644 --- a/src/panels/lovelace/views/hui-view-container.ts +++ b/src/panels/lovelace/views/hui-view-container.ts @@ -57,7 +57,28 @@ class HuiViewContainer extends LitElement { if (background.tile) { return `top / auto repeat url('${background.image}')`; } - return `center / cover no-repeat url('${background.image}')`; + let size = "auto"; + if (background.size in ["original", "fill_view", "fit_view"]) { + size = background.size; + } + let alignment = "center"; + if ( + background.size in + [ + "top_left", + "top_center", + "top_right", + "center_left", + "center", + "center_right", + "bottom_left", + "bottom_center", + "bottom_right", + ] + ) { + alignment = background.alignment; + } + return `${alignment} / ${size} no-repeat url('${background.image}')`; } if (typeof background === "string") { return background; @@ -65,6 +86,15 @@ class HuiViewContainer extends LitElement { return null; } + private _computeBackgroundOpacityProperty(background?: BackgroundConfig) { + if (typeof background === "object" && background.image) { + if (background.transparency) { + return `${background.transparency}%`; + } + } + return null; + } + protected willUpdate(changedProperties: PropertyValues) { super.willUpdate(changedProperties); if (changedProperties.has("hass") && this.hass) { @@ -104,6 +134,11 @@ class HuiViewContainer extends LitElement { const viewBackground = this._computeBackgroundProperty(this.background); this.toggleAttribute("fixed-background", fixedBackground); this.style.setProperty("--view-background", viewBackground); + + const viewBackgroundOpacity = this._computeBackgroundOpacityProperty( + this.background + ); + this.style.setProperty("--view-background-opacity", viewBackgroundOpacity); } static get styles(): CSSResultGroup { @@ -127,6 +162,7 @@ class HuiViewContainer extends LitElement { --view-background, var(--lovelace-background, var(--primary-background-color)) ); + opacity: var(--view-background-opacity) background-attachment: scroll !important; } :host(:not([fixed-background])) { diff --git a/src/translations/en.json b/src/translations/en.json index 85ab59d0c72f..eeecc75322ba 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5928,6 +5928,29 @@ "background": { "settings": "Background settings", "image": "Background image", + "size": { + "name": "Background size", + "options": { + "top_left": "Top left", + "top_center": "Top center", + "top_right": "Top right", + "center_left": "Center left", + "center": "Center", + "center_right": "Center right", + "bottom_left": "Bottom left", + "bottom_center": "Bottom center", + "bottom_right": "Bottom right" + } + }, + "alignment": { + "name": "Background alignment", + "options": { + "original": "Original", + "fill_view": "Fill view", + "fit_view": "Fit view" + } + }, + "transparency": "Background transparency", "tile": "Tile background" }, "edit": "Edit view", @@ -8315,4 +8338,4 @@ } } } -} +} \ No newline at end of file From 44e431032d18a5f647dfeeee556bdb89323b374b Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Sun, 1 Dec 2024 13:05:50 +0000 Subject: [PATCH 04/23] Decouple background from container for opacity --- cast/src/receiver/layout/hc-lovelace.ts | 8 +- src/data/lovelace/config/view.ts | 2 +- src/panels/lovelace/hui-root.ts | 3 +- src/panels/lovelace/views/hui-background.ts | 137 ++++++++++++++++++ .../lovelace/views/hui-view-container.ts | 111 -------------- 5 files changed, 143 insertions(+), 118 deletions(-) create mode 100644 src/panels/lovelace/views/hui-background.ts diff --git a/cast/src/receiver/layout/hc-lovelace.ts b/cast/src/receiver/layout/hc-lovelace.ts index 87cc165d9774..69dad25a95fe 100644 --- a/cast/src/receiver/layout/hc-lovelace.ts +++ b/cast/src/receiver/layout/hc-lovelace.ts @@ -14,6 +14,7 @@ import "../../../../src/panels/lovelace/views/hui-view"; import "../../../../src/panels/lovelace/views/hui-view-container"; import type { HomeAssistant } from "../../../../src/types"; import "./hc-launch-screen"; +import "../../../../src/panels/lovelace/views/hui-background"; (window as any).loadCardHelpers = () => import("../../../../src/panels/lovelace/custom-card-helpers"); @@ -57,11 +58,8 @@ class HcLovelace extends LitElement { const background = viewConfig.background || this.lovelaceConfig.background; return html` - + + + `; diff --git a/src/panels/lovelace/views/hui-background.ts b/src/panels/lovelace/views/hui-background.ts new file mode 100644 index 000000000000..63804a77c886 --- /dev/null +++ b/src/panels/lovelace/views/hui-background.ts @@ -0,0 +1,137 @@ +import { css, html, LitElement, nothing } from "lit"; +import type { CSSResultGroup, PropertyValues } from "lit"; +import { customElement, property } from "lit/decorators"; +import type { HomeAssistant } from "../../../types"; +import type { LovelaceViewBackgroundConfig } from "../../../data/lovelace/config/view"; + +@customElement("hui-background") +export class HUIBackground extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) background?: + | string + | LovelaceViewBackgroundConfig + | undefined; + + protected render() { + return nothing; + } + + private _applyTheme() { + const computedStyles = getComputedStyle(this); + const themeBackground = computedStyles.getPropertyValue( + "--lovelace-background" + ); + + const fixedBackground = this._isFixedBackground( + this.background || themeBackground + ); + const viewBackground = this._computeBackgroundProperty(this.background); + this.toggleAttribute("fixed-background", fixedBackground); + this.style.setProperty("--view-background", viewBackground); + + const viewBackgroundOpacity = this._computeBackgroundOpacityProperty( + this.background + ); + this.style.setProperty("--view-background-opacity", viewBackgroundOpacity); + } + + private _isFixedBackground( + background?: string | LovelaceViewBackgroundConfig + ) { + if (typeof background === "string") { + return background.includes(" fixed"); + } + return false; + } + + private _computeBackgroundProperty( + background?: string | LovelaceViewBackgroundConfig + ) { + if (typeof background === "object" && background.image) { + if (background.tile) { + return `top / auto repeat url('${background.image}')`; + } + let size = "auto"; + if (background.size in ["original", "fill_view", "fit_view"]) { + size = background.size; + } + let alignment = "center"; + if ( + background.size in + [ + "top_left", + "top_center", + "top_right", + "center_left", + "center", + "center_right", + "bottom_left", + "bottom_center", + "bottom_right", + ] + ) { + alignment = background.alignment; + } + return `${alignment} / ${size} no-repeat url('${background.image}')`; + } + if (typeof background === "string") { + return background; + } + return null; + } + + private _computeBackgroundOpacityProperty( + background?: string | LovelaceViewBackgroundConfig + ) { + console.log("ongoing"); + if (typeof background === "object" && background.image) { + if (background.transparency) { + return `${background.transparency}%`; + } + } + return null; + } + + protected willUpdate(changedProperties: PropertyValues) { + super.willUpdate(changedProperties); + if (changedProperties.has("hass") && this.hass) { + const oldHass = changedProperties.get("hass"); + if ( + !oldHass || + this.hass.themes !== oldHass.themes || + this.hass.selectedTheme !== oldHass.selectedTheme + ) { + this._applyTheme(); + return; + } + } + + if (changedProperties.has("background")) { + this._applyTheme(); + } + } + + static get styles(): CSSResultGroup { + return css` + :host { + z-index: -1; + position: fixed; + height: 100%; + width: 100%; + background: var( + --view-background, + var(--lovelace-background, var(--primary-background-color)) + ); + opacity: var(--view-background-opacity); + background-attachment: scroll !important; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-background": HUIBackground; + } +} diff --git a/src/panels/lovelace/views/hui-view-container.ts b/src/panels/lovelace/views/hui-view-container.ts index 84fcbaaa4f77..7822a65b7eda 100644 --- a/src/panels/lovelace/views/hui-view-container.ts +++ b/src/panels/lovelace/views/hui-view-container.ts @@ -45,75 +45,6 @@ class HuiViewContainer extends LitElement { ); } - private _isFixedBackground(background?: BackgroundConfig) { - if (typeof background === "string") { - return background.split(" ").includes("fixed"); - } - return false; - } - - private _computeBackgroundProperty(background?: BackgroundConfig) { - if (typeof background === "object" && background.image) { - if (background.tile) { - return `top / auto repeat url('${background.image}')`; - } - let size = "auto"; - if (background.size in ["original", "fill_view", "fit_view"]) { - size = background.size; - } - let alignment = "center"; - if ( - background.size in - [ - "top_left", - "top_center", - "top_right", - "center_left", - "center", - "center_right", - "bottom_left", - "bottom_center", - "bottom_right", - ] - ) { - alignment = background.alignment; - } - return `${alignment} / ${size} no-repeat url('${background.image}')`; - } - if (typeof background === "string") { - return background; - } - return null; - } - - private _computeBackgroundOpacityProperty(background?: BackgroundConfig) { - if (typeof background === "object" && background.image) { - if (background.transparency) { - return `${background.transparency}%`; - } - } - return null; - } - - protected willUpdate(changedProperties: PropertyValues) { - super.willUpdate(changedProperties); - if (changedProperties.has("hass") && this.hass) { - const oldHass = changedProperties.get("hass"); - if ( - !oldHass || - this.hass.themes !== oldHass.themes || - this.hass.selectedTheme !== oldHass.selectedTheme - ) { - this._applyTheme(); - return; - } - } - - if (changedProperties.has("theme") || changedProperties.has("background")) { - this._applyTheme(); - } - } - render() { return html``; } @@ -122,23 +53,6 @@ class HuiViewContainer extends LitElement { if (this.hass) { applyThemesOnElement(this, this.hass?.themes, this.theme); } - - const computedStyles = getComputedStyle(this); - const themeBackground = computedStyles.getPropertyValue( - "--lovelace-background" - ); - - const fixedBackground = this._isFixedBackground( - this.background || themeBackground - ); - const viewBackground = this._computeBackgroundProperty(this.background); - this.toggleAttribute("fixed-background", fixedBackground); - this.style.setProperty("--view-background", viewBackground); - - const viewBackgroundOpacity = this._computeBackgroundOpacityProperty( - this.background - ); - this.style.setProperty("--view-background-opacity", viewBackgroundOpacity); } static get styles(): CSSResultGroup { @@ -146,31 +60,6 @@ class HuiViewContainer extends LitElement { :host { display: relative; } - /* Fixed background hack for Safari iOS */ - :host([fixed-background]) ::slotted(*):before { - display: block; - content: ""; - z-index: -1; - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; - height: 100%; - width: 100%; - background: var( - --view-background, - var(--lovelace-background, var(--primary-background-color)) - ); - opacity: var(--view-background-opacity) - background-attachment: scroll !important; - } - :host(:not([fixed-background])) { - background: var( - --view-background, - var(--lovelace-background, var(--primary-background-color)) - ); - } `; } } From 3d291b4365fb8cd306341bac61eaf4eb3ecaac64 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Sun, 1 Dec 2024 14:28:10 +0000 Subject: [PATCH 05/23] Experiment further, break more things --- src/data/lovelace/config/view.ts | 6 +- .../view-editor/hui-view-background-editor.ts | 56 +++++++++---------- src/panels/lovelace/views/hui-background.ts | 1 - 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/data/lovelace/config/view.ts b/src/data/lovelace/config/view.ts index c78603474a45..22cf9193fb14 100644 --- a/src/data/lovelace/config/view.ts +++ b/src/data/lovelace/config/view.ts @@ -9,9 +9,9 @@ export interface ShowViewConfig { export interface LovelaceViewBackgroundConfig { image?: string; - transparency: number; - size: "original" | "fill_view" | "fit_view"; - alignment: + transparency?: number; + size?: "original" | "fill_view" | "fit_view"; + alignment?: | "top_left" | "top_center" | "top_right" diff --git a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts index eaa1b09e5e59..e15984143f98 100644 --- a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts +++ b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts @@ -7,7 +7,10 @@ import { fireEvent } from "../../../../common/dom/fire_event"; import "../../../../components/ha-form/ha-form"; import type { SchemaUnion } from "../../../../components/ha-form/types"; import "../../../../components/ha-selector/ha-selector-image"; -import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view"; +import type { + LovelaceViewBackgroundConfig, + LovelaceViewConfig, +} from "../../../../data/lovelace/config/view"; import type { HomeAssistant } from "../../../../types"; @customElement("hui-view-background-editor") @@ -48,17 +51,6 @@ export class HuiViewBackgroundEditor extends LitElement { select: { translation_key: "ui.panel.lovelace.editor.edit_view.background.size", - default: "original", - options: ["original", "fill_view", "fit_view"], - }, - }, - }, - { - name: "alignment", - selector: { - select: { - translation_key: - "ui.panel.lovelace.editor.edit_view.background.alignment", default: "center", options: [ "top_left", @@ -74,6 +66,17 @@ export class HuiViewBackgroundEditor extends LitElement { }, }, }, + { + name: "alignment", + selector: { + select: { + translation_key: + "ui.panel.lovelace.editor.edit_view.background.alignment", + default: "original", + options: ["original", "fill_view", "fit_view"], + }, + }, + }, { name: "tile", selector: { boolean: {} }, @@ -90,20 +93,22 @@ export class HuiViewBackgroundEditor extends LitElement { } const background = this._config?.background; - const backgroundUrl = - typeof background === "string" - ? background.match(/url\(['"]?([^'"]+)['"]?\)/)?.[1] - : background?.image; - - const tile = typeof background === "string" ? false : background?.tile; + let data: LovelaceViewBackgroundConfig = {}; + if (typeof background === "string") { + const backgroundUrl = background.match(/url\(['"]?([^'"]+)['"]?\)/)?.[1]; - const data = { backgroundUrl, tile }; + data = { + image: backgroundUrl, + }; + } else if (background) { + data = background; + } return html` Date: Sun, 1 Dec 2024 15:21:15 +0000 Subject: [PATCH 06/23] Fixing things --- .../view-editor/hui-view-background-editor.ts | 29 +++++++++---------- src/panels/lovelace/views/hui-background.ts | 22 +++++++++----- src/translations/en.json | 16 +++++----- 3 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts index e15984143f98..cd806a5815e9 100644 --- a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts +++ b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts @@ -28,7 +28,7 @@ export class HuiViewBackgroundEditor extends LitElement { private _schema = memoizeOne((showSettings: boolean) => [ { - name: "backgroundUrl", + name: "image", selector: { image: { original: true } }, }, ...(showSettings @@ -42,7 +42,7 @@ export class HuiViewBackgroundEditor extends LitElement { { name: "transparency", selector: { - number: { min: 1, max: 100, mode: "box" }, + number: { min: 1, max: 100, mode: "slider" }, }, }, { @@ -51,6 +51,17 @@ export class HuiViewBackgroundEditor extends LitElement { select: { translation_key: "ui.panel.lovelace.editor.edit_view.background.size", + default: "original", + options: ["original", "fill_view", "fit_view"], + }, + }, + }, + { + name: "alignment", + selector: { + select: { + translation_key: + "ui.panel.lovelace.editor.edit_view.background.alignment", default: "center", options: [ "top_left", @@ -66,17 +77,6 @@ export class HuiViewBackgroundEditor extends LitElement { }, }, }, - { - name: "alignment", - selector: { - select: { - translation_key: - "ui.panel.lovelace.editor.edit_view.background.alignment", - default: "original", - options: ["original", "fill_view", "fit_view"], - }, - }, - }, { name: "tile", selector: { boolean: {} }, @@ -127,9 +127,8 @@ export class HuiViewBackgroundEditor extends LitElement { private _computeLabelCallback = ( schema: SchemaUnion> ) => { - console.log(schema.name); switch (schema.name) { - case "backgroundUrl": + case "image": return this.hass.localize( "ui.panel.lovelace.editor.edit_view.background.image" ); diff --git a/src/panels/lovelace/views/hui-background.ts b/src/panels/lovelace/views/hui-background.ts index 1c4c1316599d..8fedadffb50a 100644 --- a/src/panels/lovelace/views/hui-background.ts +++ b/src/panels/lovelace/views/hui-background.ts @@ -1,4 +1,4 @@ -import { css, html, LitElement, nothing } from "lit"; +import { css, LitElement, nothing } from "lit"; import type { CSSResultGroup, PropertyValues } from "lit"; import { customElement, property } from "lit/decorators"; import type { HomeAssistant } from "../../../types"; @@ -53,12 +53,20 @@ export class HUIBackground extends LitElement { return `top / auto repeat url('${background.image}')`; } let size = "auto"; - if (background.size in ["original", "fill_view", "fit_view"]) { - size = background.size; + if ( + background.size && + ["original", "fill_view", "fit_view"].includes(background.size) + ) { + size = + background.size === "fill_view" + ? "cover" + : background.size === "fit_view" + ? "contain" + : "auto"; } let alignment = "center"; if ( - background.size in + background.alignment && [ "top_left", "top_center", @@ -69,9 +77,9 @@ export class HUIBackground extends LitElement { "bottom_left", "bottom_center", "bottom_right", - ] + ].includes(background.alignment) ) { - alignment = background.alignment; + alignment = background.alignment.replace("_", " "); } return `${alignment} / ${size} no-repeat url('${background.image}')`; } @@ -115,7 +123,7 @@ export class HUIBackground extends LitElement { return css` :host { z-index: -1; - position: fixed; + position: absolute; height: 100%; width: 100%; background: var( diff --git a/src/translations/en.json b/src/translations/en.json index eeecc75322ba..fa68f0580d99 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5930,6 +5930,14 @@ "image": "Background image", "size": { "name": "Background size", + "options": { + "original": "Original", + "fill_view": "Fill view", + "fit_view": "Fit view" + } + }, + "alignment": { + "name": "Background alignment", "options": { "top_left": "Top left", "top_center": "Top center", @@ -5942,14 +5950,6 @@ "bottom_right": "Bottom right" } }, - "alignment": { - "name": "Background alignment", - "options": { - "original": "Original", - "fill_view": "Fill view", - "fit_view": "Fit view" - } - }, "transparency": "Background transparency", "tile": "Tile background" }, From 1f759dab1c212a1d6bca0e8e06e6aa43118aba6e Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Wed, 4 Dec 2024 11:48:26 +0000 Subject: [PATCH 07/23] Cleanup things --- cast/src/receiver/layout/hc-lovelace.ts | 4 ++-- .../view-editor/hui-view-background-editor.ts | 20 ++++++++++--------- src/panels/lovelace/hui-root.ts | 4 ++-- ...i-background.ts => hui-view-background.ts} | 17 ++++++++-------- .../lovelace/views/hui-view-container.ts | 19 ++++++++++++++++++ 5 files changed, 42 insertions(+), 22 deletions(-) rename src/panels/lovelace/views/{hui-background.ts => hui-view-background.ts} (92%) diff --git a/cast/src/receiver/layout/hc-lovelace.ts b/cast/src/receiver/layout/hc-lovelace.ts index 69dad25a95fe..0cf3d5121d45 100644 --- a/cast/src/receiver/layout/hc-lovelace.ts +++ b/cast/src/receiver/layout/hc-lovelace.ts @@ -14,7 +14,7 @@ import "../../../../src/panels/lovelace/views/hui-view"; import "../../../../src/panels/lovelace/views/hui-view-container"; import type { HomeAssistant } from "../../../../src/types"; import "./hc-launch-screen"; -import "../../../../src/panels/lovelace/views/hui-background"; +import "../../../../src/panels/lovelace/views/hui-view-background"; (window as any).loadCardHelpers = () => import("../../../../src/panels/lovelace/custom-card-helpers"); @@ -59,7 +59,7 @@ class HcLovelace extends LitElement { return html` - + - + `; diff --git a/src/panels/lovelace/views/hui-background.ts b/src/panels/lovelace/views/hui-view-background.ts similarity index 92% rename from src/panels/lovelace/views/hui-background.ts rename to src/panels/lovelace/views/hui-view-background.ts index 8fedadffb50a..7327f2dbcf7d 100644 --- a/src/panels/lovelace/views/hui-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -4,8 +4,8 @@ import { customElement, property } from "lit/decorators"; import type { HomeAssistant } from "../../../types"; import type { LovelaceViewBackgroundConfig } from "../../../data/lovelace/config/view"; -@customElement("hui-background") -export class HUIBackground extends LitElement { +@customElement("hui-view-background") +export class HUIViewBackground extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) background?: @@ -57,12 +57,11 @@ export class HUIBackground extends LitElement { background.size && ["original", "fill_view", "fit_view"].includes(background.size) ) { - size = - background.size === "fill_view" - ? "cover" - : background.size === "fit_view" - ? "contain" - : "auto"; + size = { + fill_view: "cover", + fit_view: "contain", + original: "auto", + }[background.size]; } let alignment = "center"; if ( @@ -139,6 +138,6 @@ export class HUIBackground extends LitElement { declare global { interface HTMLElementTagNameMap { - "hui-background": HUIBackground; + "hui-view-background": HUIViewBackground; } } diff --git a/src/panels/lovelace/views/hui-view-container.ts b/src/panels/lovelace/views/hui-view-container.ts index 7822a65b7eda..5a344b93b280 100644 --- a/src/panels/lovelace/views/hui-view-container.ts +++ b/src/panels/lovelace/views/hui-view-container.ts @@ -45,6 +45,25 @@ class HuiViewContainer extends LitElement { ); } + protected willUpdate(changedProperties: PropertyValues) { + super.willUpdate(changedProperties); + if (changedProperties.has("hass") && this.hass) { + const oldHass = changedProperties.get("hass"); + if ( + !oldHass || + this.hass.themes !== oldHass.themes || + this.hass.selectedTheme !== oldHass.selectedTheme + ) { + this._applyTheme(); + return; + } + } + + if (changedProperties.has("theme")) { + this._applyTheme(); + } + } + render() { return html``; } From 3fc75dd30bc139fc0841c3fa7b36c24228cc7820 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Wed, 11 Dec 2024 09:48:12 +0000 Subject: [PATCH 08/23] feedback / ci --- .../editor/view-editor/hui-view-background-editor.ts | 5 +---- src/panels/lovelace/views/hui-view-background.ts | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts index c6cc63afcb7b..befca49ed541 100644 --- a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts +++ b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts @@ -7,10 +7,7 @@ import { fireEvent } from "../../../../common/dom/fire_event"; import "../../../../components/ha-form/ha-form"; import type { SchemaUnion } from "../../../../components/ha-form/types"; import "../../../../components/ha-selector/ha-selector-image"; -import type { - LovelaceViewBackgroundConfig, - LovelaceViewConfig, -} from "../../../../data/lovelace/config/view"; +import type { LovelaceViewConfig } from "../../../../data/lovelace/config/view"; import type { HomeAssistant } from "../../../../types"; @customElement("hui-view-background-editor") diff --git a/src/panels/lovelace/views/hui-view-background.ts b/src/panels/lovelace/views/hui-view-background.ts index 7327f2dbcf7d..c8f300db9972 100644 --- a/src/panels/lovelace/views/hui-view-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -49,9 +49,6 @@ export class HUIViewBackground extends LitElement { background?: string | LovelaceViewBackgroundConfig ) { if (typeof background === "object" && background.image) { - if (background.tile) { - return `top / auto repeat url('${background.image}')`; - } let size = "auto"; if ( background.size && @@ -80,7 +77,7 @@ export class HUIViewBackground extends LitElement { ) { alignment = background.alignment.replace("_", " "); } - return `${alignment} / ${size} no-repeat url('${background.image}')`; + return `${alignment} / ${size} ${background.tile ? "repeat" : "no-repeat"} url('${background.image}')`; } if (typeof background === "string") { return background; From 08c15127c95ee7e910c4cb78b6e2410f41152b32 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Wed, 11 Dec 2024 09:56:48 +0000 Subject: [PATCH 09/23] ci --- src/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations/en.json b/src/translations/en.json index fa68f0580d99..17353926c4bc 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -8338,4 +8338,4 @@ } } } -} \ No newline at end of file +} From a83d293c268d8a5fe5bbe369f3dff8bce0223dde Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Wed, 11 Dec 2024 17:28:44 +0000 Subject: [PATCH 10/23] align options to the css values --- src/data/lovelace/config/view.ts | 20 +++++------ .../view-editor/hui-view-background-editor.ts | 35 ++++++++++++------- .../lovelace/views/hui-view-background.ts | 33 +++-------------- src/translations/en.json | 32 ++++++++++------- 4 files changed, 56 insertions(+), 64 deletions(-) diff --git a/src/data/lovelace/config/view.ts b/src/data/lovelace/config/view.ts index 22cf9193fb14..f5724a45a741 100644 --- a/src/data/lovelace/config/view.ts +++ b/src/data/lovelace/config/view.ts @@ -10,18 +10,18 @@ export interface ShowViewConfig { export interface LovelaceViewBackgroundConfig { image?: string; transparency?: number; - size?: "original" | "fill_view" | "fit_view"; + size?: "auto" | "cover" | "contain"; alignment?: - | "top_left" - | "top_center" - | "top_right" - | "center_left" + | "top left" + | "top center" + | "top right" + | "center left" | "center" - | "center_right" - | "bottom_left" - | "bottom_center" - | "bottom_right"; - tile?: boolean; + | "center right" + | "bottom left" + | "bottom center" + | "bottom right"; + repeat?: "repeat" | "no-repeat"; } export interface LovelaceBaseViewConfig { diff --git a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts index befca49ed541..6abd294d0c35 100644 --- a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts +++ b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts @@ -48,7 +48,7 @@ export class HuiViewBackgroundEditor extends LitElement { select: { translation_key: "ui.panel.lovelace.editor.edit_view.background.size", - options: ["original", "fill_view", "fit_view"], + options: ["auto", "cover", "contain"], }, }, }, @@ -59,22 +59,28 @@ export class HuiViewBackgroundEditor extends LitElement { translation_key: "ui.panel.lovelace.editor.edit_view.background.alignment", options: [ - "top_left", - "top_center", - "top_right", - "center_left", + "top left", + "top center", + "top right", + "center left", "center", - "center_right", - "bottom_left", - "bottom_center", - "bottom_right", + "center right", + "bottom left", + "bottom center", + "bottom right", ], }, }, }, { - name: "tile", - selector: { boolean: {} }, + name: "repeat", + selector: { + select: { + translation_key: + "ui.panel.lovelace.editor.edit_view.background.repeat", + options: ["repeat", "no-repeat"], + }, + }, }, ], }, @@ -99,7 +105,8 @@ export class HuiViewBackgroundEditor extends LitElement { background = { transparency: 100, alignment: "center", - size: "original", + size: "auto", + repeat: "repeat", ...background, }; @@ -143,6 +150,10 @@ export class HuiViewBackgroundEditor extends LitElement { return this.hass.localize( "ui.panel.lovelace.editor.edit_view.background.size.name" ); + case "repeat": + return this.hass.localize( + "ui.panel.lovelace.editor.edit_view.background.repeat.name" + ); default: return this.hass.localize( `ui.panel.lovelace.editor.edit_view.background.${schema.name}` diff --git a/src/panels/lovelace/views/hui-view-background.ts b/src/panels/lovelace/views/hui-view-background.ts index c8f300db9972..66a84da5862a 100644 --- a/src/panels/lovelace/views/hui-view-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -49,35 +49,10 @@ export class HUIViewBackground extends LitElement { background?: string | LovelaceViewBackgroundConfig ) { if (typeof background === "object" && background.image) { - let size = "auto"; - if ( - background.size && - ["original", "fill_view", "fit_view"].includes(background.size) - ) { - size = { - fill_view: "cover", - fit_view: "contain", - original: "auto", - }[background.size]; - } - let alignment = "center"; - if ( - background.alignment && - [ - "top_left", - "top_center", - "top_right", - "center_left", - "center", - "center_right", - "bottom_left", - "bottom_center", - "bottom_right", - ].includes(background.alignment) - ) { - alignment = background.alignment.replace("_", " "); - } - return `${alignment} / ${size} ${background.tile ? "repeat" : "no-repeat"} url('${background.image}')`; + let size = background.size ?? "auto"; + let alignment = background.alignment ?? "center"; + let repeat = background.repeat ?? "repeat"; + return `${alignment} / ${size} ${repeat} url('${background.image}')`; } if (typeof background === "string") { return background; diff --git a/src/translations/en.json b/src/translations/en.json index 17353926c4bc..f618b3ea3936 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5931,27 +5931,33 @@ "size": { "name": "Background size", "options": { - "original": "Original", - "fill_view": "Fill view", - "fit_view": "Fit view" + "auto": "Original", + "cover": "Fill view", + "contain": "Fit view" } }, "alignment": { "name": "Background alignment", "options": { - "top_left": "Top left", - "top_center": "Top center", - "top_right": "Top right", - "center_left": "Center left", + "top left": "Top left", + "top center": "Top center", + "top right": "Top right", + "center left": "Center left", "center": "Center", - "center_right": "Center right", - "bottom_left": "Bottom left", - "bottom_center": "Bottom center", - "bottom_right": "Bottom right" + "center right": "Center right", + "bottom left": "Bottom left", + "bottom center": "Bottom center", + "bottom right": "Bottom right" } }, "transparency": "Background transparency", - "tile": "Tile background" + "repeat": { + "name": "Background repeat", + "options": { + "repeat": "Repeat (tile)", + "no-repeat": "No repeat" + } + } }, "edit": "Edit view", "delete": "Delete view", @@ -8338,4 +8344,4 @@ } } } -} +} \ No newline at end of file From 44e065a0061ff2dc8bd371bab85993faf2911f74 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Wed, 11 Dec 2024 17:32:38 +0000 Subject: [PATCH 11/23] ci --- src/panels/lovelace/views/hui-view-background.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/panels/lovelace/views/hui-view-background.ts b/src/panels/lovelace/views/hui-view-background.ts index 66a84da5862a..da125539ff3b 100644 --- a/src/panels/lovelace/views/hui-view-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -49,9 +49,9 @@ export class HUIViewBackground extends LitElement { background?: string | LovelaceViewBackgroundConfig ) { if (typeof background === "object" && background.image) { - let size = background.size ?? "auto"; - let alignment = background.alignment ?? "center"; - let repeat = background.repeat ?? "repeat"; + const size = background.size ?? "auto"; + const alignment = background.alignment ?? "center"; + const repeat = background.repeat ?? "repeat"; return `${alignment} / ${size} ${repeat} url('${background.image}')`; } if (typeof background === "string") { From 710b057a152cf223c2c766435d4ad17feb555ead Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Wed, 11 Dec 2024 17:51:14 +0000 Subject: [PATCH 12/23] ci --- src/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations/en.json b/src/translations/en.json index f618b3ea3936..c1a00c421859 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -8344,4 +8344,4 @@ } } } -} \ No newline at end of file +} From f712bd2b8a699d46f65032b4821e668b40753aac Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Fri, 13 Dec 2024 18:23:15 +0000 Subject: [PATCH 13/23] fix rendering --- .../lovelace/views/hui-view-background.ts | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/panels/lovelace/views/hui-view-background.ts b/src/panels/lovelace/views/hui-view-background.ts index da125539ff3b..350fad28b938 100644 --- a/src/panels/lovelace/views/hui-view-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -23,11 +23,7 @@ export class HUIViewBackground extends LitElement { "--lovelace-background" ); - const fixedBackground = this._isFixedBackground( - this.background || themeBackground - ); const viewBackground = this._computeBackgroundProperty(this.background); - this.toggleAttribute("fixed-background", fixedBackground); this.style.setProperty("--view-background", viewBackground); const viewBackgroundOpacity = this._computeBackgroundOpacityProperty( @@ -36,15 +32,6 @@ export class HUIViewBackground extends LitElement { this.style.setProperty("--view-background-opacity", viewBackgroundOpacity); } - private _isFixedBackground( - background?: string | LovelaceViewBackgroundConfig - ) { - if (typeof background === "string") { - return background.includes(" fixed"); - } - return false; - } - private _computeBackgroundProperty( background?: string | LovelaceViewBackgroundConfig ) { @@ -95,6 +82,10 @@ export class HUIViewBackground extends LitElement { :host { z-index: -1; position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; height: 100%; width: 100%; background: var( @@ -102,7 +93,6 @@ export class HUIViewBackground extends LitElement { var(--lovelace-background, var(--primary-background-color)) ); opacity: var(--view-background-opacity); - background-attachment: scroll !important; } `; } From 262057231dfb89b1d6871dc488a4594db2af6a75 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Fri, 13 Dec 2024 18:45:08 +0000 Subject: [PATCH 14/23] fixed hack --- .../lovelace/views/hui-view-background.ts | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/panels/lovelace/views/hui-view-background.ts b/src/panels/lovelace/views/hui-view-background.ts index 350fad28b938..fea954cb7e1d 100644 --- a/src/panels/lovelace/views/hui-view-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -23,7 +23,11 @@ export class HUIViewBackground extends LitElement { "--lovelace-background" ); + const fixedBackground = this._isFixedBackground( + this.background || themeBackground + ); const viewBackground = this._computeBackgroundProperty(this.background); + this.toggleAttribute("fixed-background", fixedBackground); this.style.setProperty("--view-background", viewBackground); const viewBackgroundOpacity = this._computeBackgroundOpacityProperty( @@ -32,6 +36,15 @@ export class HUIViewBackground extends LitElement { this.style.setProperty("--view-background-opacity", viewBackgroundOpacity); } + private _isFixedBackground( + background?: string | LovelaceViewBackgroundConfig + ) { + if (typeof background === "string") { + return background.includes(" fixed"); + } + return false; + } + private _computeBackgroundProperty( background?: string | LovelaceViewBackgroundConfig ) { @@ -79,9 +92,18 @@ export class HUIViewBackground extends LitElement { static get styles(): CSSResultGroup { return css` - :host { + /* Fixed background hack for Safari iOS */ + :host([fixed-background]) { + display: block; + z-index: -1; + position: fixed; + background-attachment: scroll !important; + } + :host(:not(fixed-background)) { z-index: -1; position: absolute; + } + :host { top: 0; left: 0; right: 0; From b33db9d985e8c908dd1793ee7810d504a8439ffd Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Fri, 13 Dec 2024 19:48:41 +0100 Subject: [PATCH 15/23] Update hui-view-background.ts --- src/panels/lovelace/views/hui-view-background.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/lovelace/views/hui-view-background.ts b/src/panels/lovelace/views/hui-view-background.ts index fea954cb7e1d..950047862499 100644 --- a/src/panels/lovelace/views/hui-view-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -40,7 +40,7 @@ export class HUIViewBackground extends LitElement { background?: string | LovelaceViewBackgroundConfig ) { if (typeof background === "string") { - return background.includes(" fixed"); + return background.split(" ").includes("fixed"); } return false; } From cac197608f2cab9e36dcc571e956a888195b079e Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:59:49 +0000 Subject: [PATCH 16/23] Fixed background + change repeat to no-repeat as default --- src/data/lovelace/config/view.ts | 1 + .../editor/view-editor/hui-view-background-editor.ts | 11 ++++++++++- src/panels/lovelace/views/hui-view-background.ts | 5 ++++- src/translations/en.json | 5 ++++- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/data/lovelace/config/view.ts b/src/data/lovelace/config/view.ts index f5724a45a741..37ad8d5593ad 100644 --- a/src/data/lovelace/config/view.ts +++ b/src/data/lovelace/config/view.ts @@ -22,6 +22,7 @@ export interface LovelaceViewBackgroundConfig { | "bottom center" | "bottom right"; repeat?: "repeat" | "no-repeat"; + fixed?: boolean; } export interface LovelaceBaseViewConfig { diff --git a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts index 6abd294d0c35..9433ba457836 100644 --- a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts +++ b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts @@ -82,6 +82,10 @@ export class HuiViewBackgroundEditor extends LitElement { }, }, }, + { + name: "fixed", + selector: { boolean: {} }, + }, ], }, ] as const) @@ -106,7 +110,8 @@ export class HuiViewBackgroundEditor extends LitElement { transparency: 100, alignment: "center", size: "auto", - repeat: "repeat", + repeat: "no-repeat", + fixed: false, ...background, }; @@ -154,6 +159,10 @@ export class HuiViewBackgroundEditor extends LitElement { return this.hass.localize( "ui.panel.lovelace.editor.edit_view.background.repeat.name" ); + case "fixed": + return this.hass.localize( + "ui.panel.lovelace.editor.edit_view.background.fixed.name" + ); default: return this.hass.localize( `ui.panel.lovelace.editor.edit_view.background.${schema.name}` diff --git a/src/panels/lovelace/views/hui-view-background.ts b/src/panels/lovelace/views/hui-view-background.ts index 950047862499..7037430cbdb0 100644 --- a/src/panels/lovelace/views/hui-view-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -42,6 +42,9 @@ export class HUIViewBackground extends LitElement { if (typeof background === "string") { return background.split(" ").includes("fixed"); } + if (typeof background === "object" && background.fixed) { + return true; + } return false; } @@ -51,7 +54,7 @@ export class HUIViewBackground extends LitElement { if (typeof background === "object" && background.image) { const size = background.size ?? "auto"; const alignment = background.alignment ?? "center"; - const repeat = background.repeat ?? "repeat"; + const repeat = background.repeat ?? "no-repeat"; return `${alignment} / ${size} ${repeat} url('${background.image}')`; } if (typeof background === "string") { diff --git a/src/translations/en.json b/src/translations/en.json index c1a00c421859..e683347ce77d 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5957,6 +5957,9 @@ "repeat": "Repeat (tile)", "no-repeat": "No repeat" } + }, + "fixed": { + "name": "Fixed background" } }, "edit": "Edit view", @@ -8344,4 +8347,4 @@ } } } -} +} \ No newline at end of file From 38e993fda4c039da86a30c84c69ade6f5db4bc60 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Mon, 16 Dec 2024 16:03:10 +0100 Subject: [PATCH 17/23] Prettier --- src/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations/en.json b/src/translations/en.json index e683347ce77d..be2ca9fb6a09 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -8347,4 +8347,4 @@ } } } -} \ No newline at end of file +} From 34b7ca1b1c82ca52f054bd1d113b6135a3085c0a Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Tue, 17 Dec 2024 20:11:46 +0000 Subject: [PATCH 18/23] Add a new button toggle selector and use in background form --- .../ha-selector/ha-selector-button-toggle.ts | 98 +++++++++++++++++++ src/components/ha-selector/ha-selector.ts | 2 + src/data/lovelace/config/view.ts | 2 +- src/data/selector.ts | 8 ++ .../view-editor/hui-view-background-editor.ts | 20 ++-- .../lovelace/views/hui-view-background.ts | 2 +- src/translations/en.json | 10 +- 7 files changed, 130 insertions(+), 12 deletions(-) create mode 100644 src/components/ha-selector/ha-selector-button-toggle.ts diff --git a/src/components/ha-selector/ha-selector-button-toggle.ts b/src/components/ha-selector/ha-selector-button-toggle.ts new file mode 100644 index 000000000000..6578cee61ff2 --- /dev/null +++ b/src/components/ha-selector/ha-selector-button-toggle.ts @@ -0,0 +1,98 @@ +import "@material/mwc-list/mwc-list-item"; +import { LitElement, css, html } from "lit"; +import { customElement, property } from "lit/decorators"; +import { fireEvent } from "../../common/dom/fire_event"; +import { caseInsensitiveStringCompare } from "../../common/string/compare"; +import type { ButtonToggleSelector, SelectOption } from "../../data/selector"; +import type { HomeAssistant, ToggleButton } from "../../types"; +import "../ha-button-toggle-group"; + +@customElement("ha-selector-button_toggle") +export class HaButtonToggleSelector extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public selector!: ButtonToggleSelector; + + @property() public value?: string; + + @property() public label?: string; + + @property() public helper?: string; + + @property({ attribute: false }) + public localizeValue?: (key: string) => string; + + @property({ type: Boolean }) public disabled = false; + + @property({ type: Boolean }) public required = true; + + protected render() { + const options = + this.selector.button_toggle?.options?.map((option) => + typeof option === "object" + ? (option as SelectOption) + : ({ value: option, label: option } as SelectOption) + ) || []; + + const translationKey = this.selector.button_toggle?.translation_key; + + if (this.localizeValue && translationKey) { + options.forEach((option) => { + const localizedLabel = this.localizeValue!( + `${translationKey}.options.${option.value}` + ); + if (localizedLabel) { + option.label = localizedLabel; + } + }); + } + + if (this.selector.button_toggle?.sort) { + options.sort((a, b) => + caseInsensitiveStringCompare( + a.label, + b.label, + this.hass.locale.language + ) + ); + } + + const toggleButtons: ToggleButton[] = options.map((item: SelectOption) => ({ + label: item.label, + value: item.value, + })); + + return html` + ${this.label} + + `; + } + + private _valueChanged(ev) { + ev.stopPropagation(); + + const value = ev.detail?.value || ev.target.value; + if (this.disabled || value === undefined || value === (this.value ?? "")) { + return; + } + fireEvent(this, "value-changed", { + value: value, + }); + } + + static styles = css` + :host { + position: relative; + } + `; +} + +declare global { + interface HTMLElementTagNameMap { + "ha-selector-button_toggle": HaButtonToggleSelector; + } +} diff --git a/src/components/ha-selector/ha-selector.ts b/src/components/ha-selector/ha-selector.ts index a41b602b4d64..456b02a67c2c 100644 --- a/src/components/ha-selector/ha-selector.ts +++ b/src/components/ha-selector/ha-selector.ts @@ -51,6 +51,7 @@ const LOAD_ELEMENTS = { icon: () => import("./ha-selector-icon"), media: () => import("./ha-selector-media"), theme: () => import("./ha-selector-theme"), + button_toggle: () => import("./ha-selector-button-toggle"), trigger: () => import("./ha-selector-trigger"), tts: () => import("./ha-selector-tts"), tts_voice: () => import("./ha-selector-tts-voice"), @@ -123,6 +124,7 @@ export class HaSelector extends LitElement { protected render() { return html` + ${this._type} ${dynamicElement(`ha-selector-${this._type}`, { hass: this.hass, name: this.name, diff --git a/src/data/lovelace/config/view.ts b/src/data/lovelace/config/view.ts index 37ad8d5593ad..89a96b1a54f9 100644 --- a/src/data/lovelace/config/view.ts +++ b/src/data/lovelace/config/view.ts @@ -22,7 +22,7 @@ export interface LovelaceViewBackgroundConfig { | "bottom center" | "bottom right"; repeat?: "repeat" | "no-repeat"; - fixed?: boolean; + attachment?: "scroll" | "fixed"; } export interface LovelaceBaseViewConfig { diff --git a/src/data/selector.ts b/src/data/selector.ts index 7228624d70d4..8f28048a4914 100644 --- a/src/data/selector.ts +++ b/src/data/selector.ts @@ -108,6 +108,14 @@ export interface BooleanSelector { boolean: {} | null; } +export interface ButtonToggleSelector { + button_toggle: { + options: readonly string[] | readonly SelectOption[]; + translation_key?: string; + sort?: boolean; + } | null; +} + export interface ColorRGBSelector { // eslint-disable-next-line @typescript-eslint/ban-types color_rgb: {} | null; diff --git a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts index 9433ba457836..794e78e5a552 100644 --- a/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts +++ b/src/panels/lovelace/editor/view-editor/hui-view-background-editor.ts @@ -42,6 +42,16 @@ export class HuiViewBackgroundEditor extends LitElement { number: { min: 1, max: 100, mode: "slider" }, }, }, + { + name: "attachment", + selector: { + button_toggle: { + translation_key: + "ui.panel.lovelace.editor.edit_view.background.attachment", + options: ["scroll", "fixed"], + }, + }, + }, { name: "size", selector: { @@ -82,10 +92,6 @@ export class HuiViewBackgroundEditor extends LitElement { }, }, }, - { - name: "fixed", - selector: { boolean: {} }, - }, ], }, ] as const) @@ -111,7 +117,7 @@ export class HuiViewBackgroundEditor extends LitElement { alignment: "center", size: "auto", repeat: "no-repeat", - fixed: false, + attachment: "scroll", ...background, }; @@ -159,9 +165,9 @@ export class HuiViewBackgroundEditor extends LitElement { return this.hass.localize( "ui.panel.lovelace.editor.edit_view.background.repeat.name" ); - case "fixed": + case "attachment": return this.hass.localize( - "ui.panel.lovelace.editor.edit_view.background.fixed.name" + "ui.panel.lovelace.editor.edit_view.background.attachment.name" ); default: return this.hass.localize( diff --git a/src/panels/lovelace/views/hui-view-background.ts b/src/panels/lovelace/views/hui-view-background.ts index 7037430cbdb0..fdb7c87f76db 100644 --- a/src/panels/lovelace/views/hui-view-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -42,7 +42,7 @@ export class HUIViewBackground extends LitElement { if (typeof background === "string") { return background.split(" ").includes("fixed"); } - if (typeof background === "object" && background.fixed) { + if (typeof background === "object" && background.attachment == "fixed") { return true; } return false; diff --git a/src/translations/en.json b/src/translations/en.json index be2ca9fb6a09..d819b7ff2e82 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5958,8 +5958,12 @@ "no-repeat": "No repeat" } }, - "fixed": { - "name": "Fixed background" + "attachment": { + "name": "Background attachment", + "options": { + "scroll": "Scroll", + "fixed": "Fixed" + } } }, "edit": "Edit view", @@ -8347,4 +8351,4 @@ } } } -} +} \ No newline at end of file From cf34c2d65d6a313f75c70b00dee66ddf6b9eb712 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Tue, 17 Dec 2024 20:13:35 +0000 Subject: [PATCH 19/23] remove debug code --- src/components/ha-selector/ha-selector.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/ha-selector/ha-selector.ts b/src/components/ha-selector/ha-selector.ts index 456b02a67c2c..6b50b9329f89 100644 --- a/src/components/ha-selector/ha-selector.ts +++ b/src/components/ha-selector/ha-selector.ts @@ -124,7 +124,6 @@ export class HaSelector extends LitElement { protected render() { return html` - ${this._type} ${dynamicElement(`ha-selector-${this._type}`, { hass: this.hass, name: this.name, From 7b9b9e0daa2d0b2a9dcb3f051850df5fbc869129 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Tue, 17 Dec 2024 20:15:01 +0000 Subject: [PATCH 20/23] ci --- src/panels/lovelace/views/hui-view-background.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/lovelace/views/hui-view-background.ts b/src/panels/lovelace/views/hui-view-background.ts index fdb7c87f76db..2914af1c1ab2 100644 --- a/src/panels/lovelace/views/hui-view-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -42,7 +42,7 @@ export class HUIViewBackground extends LitElement { if (typeof background === "string") { return background.split(" ").includes("fixed"); } - if (typeof background === "object" && background.attachment == "fixed") { + if (typeof background === "object" && background.attachment === "fixed") { return true; } return false; From d7fc18953ed53382deec20bffee1f0d4e2656136 Mon Sep 17 00:00:00 2001 From: Simon Lamon <32477463+silamon@users.noreply.github.com> Date: Fri, 20 Dec 2024 13:42:09 +0000 Subject: [PATCH 21/23] ci fix --- src/data/selector.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/data/selector.ts b/src/data/selector.ts index 8f28048a4914..40fb7e36ce1a 100644 --- a/src/data/selector.ts +++ b/src/data/selector.ts @@ -26,6 +26,7 @@ export type Selector = | AreaFilterSelector | AttributeSelector | BooleanSelector + | ButtonToggleSelector | ColorRGBSelector | ColorTempSelector | ConditionSelector From 0097f809274c3e5e6e828bb67d023921f70ea457 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Sun, 22 Dec 2024 17:08:40 +0100 Subject: [PATCH 22/23] Update en.json --- src/translations/en.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/translations/en.json b/src/translations/en.json index d819b7ff2e82..48c93626d205 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -8351,4 +8351,4 @@ } } } -} \ No newline at end of file +} From 9f9179a20028ea9b132ba3a0708542a694160fc8 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Sun, 22 Dec 2024 17:13:16 +0100 Subject: [PATCH 23/23] Update hui-view-background.ts --- src/panels/lovelace/views/hui-view-background.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/panels/lovelace/views/hui-view-background.ts b/src/panels/lovelace/views/hui-view-background.ts index 2914af1c1ab2..bf322b4170ba 100644 --- a/src/panels/lovelace/views/hui-view-background.ts +++ b/src/panels/lovelace/views/hui-view-background.ts @@ -102,7 +102,7 @@ export class HUIViewBackground extends LitElement { position: fixed; background-attachment: scroll !important; } - :host(:not(fixed-background)) { + :host(:not([fixed-background])) { z-index: -1; position: absolute; }