Ignore aspect ratio in grid section (#21248)

* Ignore aspect ratio in grid section

* Feedback
This commit is contained in:
Paul Bottein 2024-07-02 18:50:42 +02:00 committed by GitHub
parent 7d432cd11a
commit 09accb3071
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 72 additions and 22 deletions

View File

@ -55,7 +55,11 @@ import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import { HomeAssistant } from "../../../types"; import { HomeAssistant } from "../../../types";
import "../components/hui-image"; import "../components/hui-image";
import "../components/hui-warning"; import "../components/hui-warning";
import { LovelaceCard, LovelaceCardEditor } from "../types"; import {
LovelaceCard,
LovelaceCardEditor,
LovelaceLayoutOptions,
} from "../types";
import { AreaCardConfig } from "./types"; import { AreaCardConfig } from "./types";
export const DEFAULT_ASPECT_RATIO = "16:9"; export const DEFAULT_ASPECT_RATIO = "16:9";
@ -102,6 +106,9 @@ export class HuiAreaCard
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false })
public layout?: string;
@state() private _config?: AreaCardConfig; @state() private _config?: AreaCardConfig;
@state() private _entities?: EntityRegistryEntry[]; @state() private _entities?: EntityRegistryEntry[];
@ -405,13 +412,17 @@ export class HuiAreaCard
if (this._config.show_camera && "camera" in entitiesByDomain) { if (this._config.show_camera && "camera" in entitiesByDomain) {
cameraEntityId = entitiesByDomain.camera[0].entity_id; cameraEntityId = entitiesByDomain.camera[0].entity_id;
} }
cameraEntityId = "camera.demo_camera";
const imageClass = area.picture || cameraEntityId; const imageClass = area.picture || cameraEntityId;
const ignoreAspectRatio = imageClass || this.layout === "grid";
return html` return html`
<ha-card <ha-card
class=${imageClass ? "image" : ""} class=${imageClass ? "image" : ""}
style=${styleMap({ style=${styleMap({
paddingBottom: imageClass paddingBottom: ignoreAspectRatio
? "0" ? "0"
: `${((100 * this._ratio!.h) / this._ratio!.w).toFixed(2)}%`, : `${((100 * this._ratio!.h) / this._ratio!.w).toFixed(2)}%`,
})} })}
@ -534,12 +545,20 @@ export class HuiAreaCard
forwardHaptic("light"); forwardHaptic("light");
} }
getLayoutOptions(): LovelaceLayoutOptions {
return {
grid_columns: 4,
grid_rows: 3,
};
}
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return css` return css`
ha-card { ha-card {
overflow: hidden; overflow: hidden;
position: relative; position: relative;
background-size: cover; background-size: cover;
height: 100%;
} }
.container { .container {

View File

@ -23,14 +23,16 @@ declare global {
@customElement("hui-card") @customElement("hui-card")
export class HuiCard extends ReactiveElement { export class HuiCard extends ReactiveElement {
@property({ type: Boolean }) public preview = false; @property({ attribute: false }) public preview = false;
@property({ type: Boolean }) public isPanel = false; @property({ attribute: false }) public isPanel = false;
@property({ attribute: false }) public config?: LovelaceCardConfig; @property({ attribute: false }) public config?: LovelaceCardConfig;
@property({ attribute: false }) public hass?: HomeAssistant; @property({ attribute: false }) public hass?: HomeAssistant;
@property({ attribute: false }) public layout?: string;
private _elementConfig?: LovelaceCardConfig; private _elementConfig?: LovelaceCardConfig;
public load() { public load() {
@ -98,6 +100,7 @@ export class HuiCard extends ReactiveElement {
if (this.hass) { if (this.hass) {
this._element.hass = this.hass; this._element.hass = this.hass;
} }
this._element.layout = this.layout;
this._element.preview = this.preview; this._element.preview = this.preview;
// For backwards compatibility // For backwards compatibility
(this._element as any).editMode = this.preview; (this._element as any).editMode = this.preview;
@ -176,6 +179,9 @@ export class HuiCard extends ReactiveElement {
if (changedProps.has("isPanel")) { if (changedProps.has("isPanel")) {
this._element.isPanel = this.isPanel; this._element.isPanel = this.isPanel;
} }
if (changedProps.has("layout")) {
this._element.layout = this.layout;
}
} }
if (changedProps.has("hass") || changedProps.has("preview")) { if (changedProps.has("hass") || changedProps.has("preview")) {

View File

@ -7,7 +7,11 @@ import "../../../components/ha-alert";
import "../../../components/ha-card"; import "../../../components/ha-card";
import type { HomeAssistant } from "../../../types"; import type { HomeAssistant } from "../../../types";
import { IFRAME_SANDBOX } from "../../../util/iframe"; import { IFRAME_SANDBOX } from "../../../util/iframe";
import { LovelaceCard, LovelaceCardEditor } from "../types"; import {
LovelaceCard,
LovelaceCardEditor,
LovelaceLayoutOptions,
} from "../types";
import { IframeCardConfig } from "./types"; import { IframeCardConfig } from "./types";
@customElement("hui-iframe-card") @customElement("hui-iframe-card")
@ -28,6 +32,9 @@ export class HuiIframeCard extends LitElement implements LovelaceCard {
@property({ type: Boolean, reflect: true }) @property({ type: Boolean, reflect: true })
public isPanel = false; public isPanel = false;
@property({ attribute: false })
public layout?: string;
@property({ attribute: false }) public hass?: HomeAssistant; @property({ attribute: false }) public hass?: HomeAssistant;
@state() protected _config?: IframeCardConfig; @state() protected _config?: IframeCardConfig;
@ -56,13 +63,16 @@ export class HuiIframeCard extends LitElement implements LovelaceCard {
} }
let padding = ""; let padding = "";
if (!this.isPanel && this._config.aspect_ratio) { const ignoreAspectRatio = this.isPanel || this.layout === "grid";
const ratio = parseAspectRatio(this._config.aspect_ratio); if (!ignoreAspectRatio) {
if (ratio && ratio.w > 0 && ratio.h > 0) { if (this._config.aspect_ratio) {
padding = `${((100 * ratio.h) / ratio.w).toFixed(2)}%`; const ratio = parseAspectRatio(this._config.aspect_ratio);
if (ratio && ratio.w > 0 && ratio.h > 0) {
padding = `${((100 * ratio.h) / ratio.w).toFixed(2)}%`;
}
} else {
padding = "50%";
} }
} else if (!this.isPanel) {
padding = "50%";
} }
const target_protocol = new URL(this._config.url, location.toString()) const target_protocol = new URL(this._config.url, location.toString())
@ -105,24 +115,25 @@ export class HuiIframeCard extends LitElement implements LovelaceCard {
`; `;
} }
public getLayoutOptions(): LovelaceLayoutOptions {
return {
grid_columns: 4,
grid_rows: 4,
};
}
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return css` return css`
:host([ispanel]) ha-card {
width: 100%;
height: 100%;
}
ha-card { ha-card {
overflow: hidden; overflow: hidden;
width: 100%;
height: 100%;
} }
#root { #root {
width: 100%; width: 100%;
position: relative;
}
:host([ispanel]) #root {
height: 100%; height: 100%;
position: relative;
} }
iframe { iframe {

View File

@ -39,7 +39,7 @@ import { HomeAssistant } from "../../../types";
import { findEntities } from "../common/find-entities"; import { findEntities } from "../common/find-entities";
import { processConfigEntities } from "../common/process-config-entities"; import { processConfigEntities } from "../common/process-config-entities";
import { EntityConfig } from "../entity-rows/types"; import { EntityConfig } from "../entity-rows/types";
import { LovelaceCard } from "../types"; import { LovelaceCard, LovelaceLayoutOptions } from "../types";
import { MapCardConfig } from "./types"; import { MapCardConfig } from "./types";
export const DEFAULT_HOURS_TO_SHOW = 0; export const DEFAULT_HOURS_TO_SHOW = 0;
@ -57,6 +57,9 @@ class HuiMapCard extends LitElement implements LovelaceCard {
@property({ type: Boolean, reflect: true }) @property({ type: Boolean, reflect: true })
public isPanel = false; public isPanel = false;
@property({ attribute: false })
public layout?: string;
@state() private _stateHistory?: HistoryStates; @state() private _stateHistory?: HistoryStates;
@state() @state()
@ -297,7 +300,9 @@ class HuiMapCard extends LitElement implements LovelaceCard {
private _computePadding(): void { private _computePadding(): void {
const root = this.shadowRoot!.getElementById("root"); const root = this.shadowRoot!.getElementById("root");
if (!this._config || this.isPanel || !root) {
const ignoreAspectRatio = this.isPanel || this.layout === "grid";
if (!this._config || ignoreAspectRatio || !root) {
return; return;
} }
@ -423,6 +428,13 @@ class HuiMapCard extends LitElement implements LovelaceCard {
} }
); );
public getLayoutOptions(): LovelaceLayoutOptions {
return {
grid_columns: 4,
grid_rows: 4,
};
}
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return css` return css`
ha-card { ha-card {

View File

@ -98,6 +98,7 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
(cardConfig) => this._getKey(cardConfig), (cardConfig) => this._getKey(cardConfig),
(_cardConfig, idx) => { (_cardConfig, idx) => {
const card = this.cards![idx]; const card = this.cards![idx];
card.layout = "grid";
const layoutOptions = card.getLayoutOptions(); const layoutOptions = card.getLayoutOptions();
const columnSize = const columnSize =

View File

@ -49,6 +49,7 @@ export interface LovelaceCard extends HTMLElement {
hass?: HomeAssistant; hass?: HomeAssistant;
isPanel?: boolean; isPanel?: boolean;
preview?: boolean; preview?: boolean;
layout?: string;
getCardSize(): number | Promise<number>; getCardSize(): number | Promise<number>;
getLayoutOptions?(): LovelaceLayoutOptions; getLayoutOptions?(): LovelaceLayoutOptions;
setConfig(config: LovelaceCardConfig): void; setConfig(config: LovelaceCardConfig): void;