mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Allow a card to span the full width of a section (#21758)
* Limit card size with the grid size * Set full option in YAML * Export card grid size * Add editor * Set full column for map card and iframe by default * Do not set string variable
This commit is contained in:
parent
5a229e3c88
commit
2f68ee0efc
@ -1,24 +1,24 @@
|
|||||||
import { LitElement, css, html, nothing } from "lit";
|
import { LitElement, css, html, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import "./ha-icon-button";
|
|
||||||
import "../panels/lovelace/editor/card-editor/ha-grid-layout-slider";
|
import "../panels/lovelace/editor/card-editor/ha-grid-layout-slider";
|
||||||
|
import "./ha-icon-button";
|
||||||
|
|
||||||
import { mdiRestore } from "@mdi/js";
|
import { mdiRestore } from "@mdi/js";
|
||||||
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { styleMap } from "lit/directives/style-map";
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import { fireEvent } from "../common/dom/fire_event";
|
import { fireEvent } from "../common/dom/fire_event";
|
||||||
import { HomeAssistant } from "../types";
|
|
||||||
import { conditionalClamp } from "../common/number/clamp";
|
import { conditionalClamp } from "../common/number/clamp";
|
||||||
|
import {
|
||||||
type GridSizeValue = {
|
CardGridSize,
|
||||||
rows?: number | "auto";
|
DEFAULT_GRID_SIZE,
|
||||||
columns?: number;
|
} from "../panels/lovelace/common/compute-card-grid-size";
|
||||||
};
|
import { HomeAssistant } from "../types";
|
||||||
|
|
||||||
@customElement("ha-grid-size-picker")
|
@customElement("ha-grid-size-picker")
|
||||||
export class HaGridSizeEditor extends LitElement {
|
export class HaGridSizeEditor extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property({ attribute: false }) public value?: GridSizeValue;
|
@property({ attribute: false }) public value?: CardGridSize;
|
||||||
|
|
||||||
@property({ attribute: false }) public rows = 8;
|
@property({ attribute: false }) public rows = 8;
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ export class HaGridSizeEditor extends LitElement {
|
|||||||
|
|
||||||
@property({ attribute: false }) public isDefault?: boolean;
|
@property({ attribute: false }) public isDefault?: boolean;
|
||||||
|
|
||||||
@state() public _localValue?: GridSizeValue = undefined;
|
@state() public _localValue?: CardGridSize = { rows: 1, columns: 1 };
|
||||||
|
|
||||||
protected willUpdate(changedProperties) {
|
protected willUpdate(changedProperties) {
|
||||||
if (changedProperties.has("value")) {
|
if (changedProperties.has("value")) {
|
||||||
@ -49,6 +49,7 @@ export class HaGridSizeEditor extends LitElement {
|
|||||||
this.rowMin !== undefined && this.rowMin === this.rowMax;
|
this.rowMin !== undefined && this.rowMin === this.rowMax;
|
||||||
|
|
||||||
const autoHeight = this._localValue?.rows === "auto";
|
const autoHeight = this._localValue?.rows === "auto";
|
||||||
|
const fullWidth = this._localValue?.columns === "full";
|
||||||
|
|
||||||
const rowMin = this.rowMin ?? 1;
|
const rowMin = this.rowMin ?? 1;
|
||||||
const rowMax = this.rowMax ?? this.rows;
|
const rowMax = this.rowMax ?? this.rows;
|
||||||
@ -67,7 +68,7 @@ export class HaGridSizeEditor extends LitElement {
|
|||||||
.min=${columnMin}
|
.min=${columnMin}
|
||||||
.max=${columnMax}
|
.max=${columnMax}
|
||||||
.range=${this.columns}
|
.range=${this.columns}
|
||||||
.value=${columnValue}
|
.value=${fullWidth ? this.columns : columnValue}
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
@slider-moved=${this._sliderMoved}
|
@slider-moved=${this._sliderMoved}
|
||||||
.disabled=${disabledColumns}
|
.disabled=${disabledColumns}
|
||||||
@ -104,12 +105,12 @@ export class HaGridSizeEditor extends LitElement {
|
|||||||
`
|
`
|
||||||
: nothing}
|
: nothing}
|
||||||
<div
|
<div
|
||||||
class="preview"
|
class="preview ${classMap({ "full-width": fullWidth })}"
|
||||||
style=${styleMap({
|
style=${styleMap({
|
||||||
"--total-rows": this.rows,
|
"--total-rows": this.rows,
|
||||||
"--total-columns": this.columns,
|
"--total-columns": this.columns,
|
||||||
"--rows": rowValue,
|
"--rows": rowValue,
|
||||||
"--columns": columnValue,
|
"--columns": fullWidth ? this.columns : columnValue,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
@ -140,12 +141,21 @@ export class HaGridSizeEditor extends LitElement {
|
|||||||
const cell = ev.currentTarget as HTMLElement;
|
const cell = ev.currentTarget as HTMLElement;
|
||||||
const rows = Number(cell.getAttribute("data-row"));
|
const rows = Number(cell.getAttribute("data-row"));
|
||||||
const columns = Number(cell.getAttribute("data-column"));
|
const columns = Number(cell.getAttribute("data-column"));
|
||||||
const clampedRow = conditionalClamp(rows, this.rowMin, this.rowMax);
|
const clampedRow: CardGridSize["rows"] = conditionalClamp(
|
||||||
const clampedColumn = conditionalClamp(
|
rows,
|
||||||
|
this.rowMin,
|
||||||
|
this.rowMax
|
||||||
|
);
|
||||||
|
let clampedColumn: CardGridSize["columns"] = conditionalClamp(
|
||||||
columns,
|
columns,
|
||||||
this.columnMin,
|
this.columnMin,
|
||||||
this.columnMax
|
this.columnMax
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const currentSize = this.value ?? DEFAULT_GRID_SIZE;
|
||||||
|
if (currentSize.columns === "full" && clampedColumn === this.columns) {
|
||||||
|
clampedColumn = "full";
|
||||||
|
}
|
||||||
fireEvent(this, "value-changed", {
|
fireEvent(this, "value-changed", {
|
||||||
value: { rows: clampedRow, columns: clampedColumn },
|
value: { rows: clampedRow, columns: clampedColumn },
|
||||||
});
|
});
|
||||||
@ -153,12 +163,23 @@ export class HaGridSizeEditor extends LitElement {
|
|||||||
|
|
||||||
private _valueChanged(ev) {
|
private _valueChanged(ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const key = ev.currentTarget.id;
|
const key = ev.currentTarget.id as "rows" | "columns";
|
||||||
const newValue = {
|
const currentSize = this.value ?? DEFAULT_GRID_SIZE;
|
||||||
...this.value,
|
let value = ev.detail.value as CardGridSize[typeof key];
|
||||||
[key]: ev.detail.value,
|
|
||||||
|
if (
|
||||||
|
key === "columns" &&
|
||||||
|
currentSize.columns === "full" &&
|
||||||
|
value === this.columns
|
||||||
|
) {
|
||||||
|
value = "full";
|
||||||
|
}
|
||||||
|
|
||||||
|
const newSize = {
|
||||||
|
...currentSize,
|
||||||
|
[key]: value,
|
||||||
};
|
};
|
||||||
fireEvent(this, "value-changed", { value: newValue });
|
fireEvent(this, "value-changed", { value: newSize });
|
||||||
}
|
}
|
||||||
|
|
||||||
private _reset(ev) {
|
private _reset(ev) {
|
||||||
@ -173,11 +194,14 @@ export class HaGridSizeEditor extends LitElement {
|
|||||||
|
|
||||||
private _sliderMoved(ev) {
|
private _sliderMoved(ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const key = ev.currentTarget.id;
|
const key = ev.currentTarget.id as "rows" | "columns";
|
||||||
const value = ev.detail.value;
|
const currentSize = this.value ?? DEFAULT_GRID_SIZE;
|
||||||
|
const value = ev.detail.value as CardGridSize[typeof key] | undefined;
|
||||||
|
|
||||||
if (value === undefined) return;
|
if (value === undefined) return;
|
||||||
|
|
||||||
this._localValue = {
|
this._localValue = {
|
||||||
...this.value,
|
...currentSize,
|
||||||
[key]: ev.detail.value,
|
[key]: ev.detail.value,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -231,10 +255,13 @@ export class HaGridSizeEditor extends LitElement {
|
|||||||
}
|
}
|
||||||
.selected .cell {
|
.selected .cell {
|
||||||
background-color: var(--primary-color);
|
background-color: var(--primary-color);
|
||||||
grid-column: 1 / span var(--columns, 0);
|
grid-column: 1 / span min(var(--columns, 0), var(--total-columns));
|
||||||
grid-row: 1 / span var(--rows, 0);
|
grid-row: 1 / span min(var(--rows, 0), var(--total-rows));
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
.preview.full-width .selected .cell {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ export class HuiIframeCard extends LitElement implements LovelaceCard {
|
|||||||
|
|
||||||
public getLayoutOptions(): LovelaceLayoutOptions {
|
public getLayoutOptions(): LovelaceLayoutOptions {
|
||||||
return {
|
return {
|
||||||
grid_columns: 4,
|
grid_columns: "full",
|
||||||
grid_rows: 4,
|
grid_rows: 4,
|
||||||
grid_min_rows: 2,
|
grid_min_rows: 2,
|
||||||
};
|
};
|
||||||
|
@ -426,7 +426,7 @@ class HuiMapCard extends LitElement implements LovelaceCard {
|
|||||||
|
|
||||||
public getLayoutOptions(): LovelaceLayoutOptions {
|
public getLayoutOptions(): LovelaceLayoutOptions {
|
||||||
return {
|
return {
|
||||||
grid_columns: 4,
|
grid_columns: "full",
|
||||||
grid_rows: 4,
|
grid_rows: 4,
|
||||||
grid_min_columns: 2,
|
grid_min_columns: 2,
|
||||||
grid_min_rows: 2,
|
grid_min_rows: 2,
|
||||||
|
36
src/panels/lovelace/common/compute-card-grid-size.ts
Normal file
36
src/panels/lovelace/common/compute-card-grid-size.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { conditionalClamp } from "../../../common/number/clamp";
|
||||||
|
import { LovelaceLayoutOptions } from "../types";
|
||||||
|
|
||||||
|
export const DEFAULT_GRID_SIZE = {
|
||||||
|
columns: 4,
|
||||||
|
rows: "auto",
|
||||||
|
} as CardGridSize;
|
||||||
|
|
||||||
|
export type CardGridSize = {
|
||||||
|
rows: number | "auto";
|
||||||
|
columns: number | "full";
|
||||||
|
};
|
||||||
|
|
||||||
|
export const computeCardGridSize = (
|
||||||
|
options: LovelaceLayoutOptions
|
||||||
|
): CardGridSize => {
|
||||||
|
const rows = options.grid_rows ?? DEFAULT_GRID_SIZE.rows;
|
||||||
|
const columns = options.grid_columns ?? DEFAULT_GRID_SIZE.columns;
|
||||||
|
const minRows = options.grid_min_rows;
|
||||||
|
const maxRows = options.grid_max_rows;
|
||||||
|
const minColumns = options.grid_min_columns;
|
||||||
|
const maxColumns = options.grid_max_columns;
|
||||||
|
|
||||||
|
const clampedRows =
|
||||||
|
typeof rows === "string" ? rows : conditionalClamp(rows, minRows, maxRows);
|
||||||
|
|
||||||
|
const clampedColumns =
|
||||||
|
typeof columns === "string"
|
||||||
|
? columns
|
||||||
|
: conditionalClamp(columns, minColumns, maxColumns);
|
||||||
|
|
||||||
|
return {
|
||||||
|
rows: clampedRows,
|
||||||
|
columns: clampedColumns,
|
||||||
|
};
|
||||||
|
};
|
@ -1,6 +1,6 @@
|
|||||||
import type { ActionDetail } from "@material/mwc-list";
|
import type { ActionDetail } from "@material/mwc-list";
|
||||||
import { mdiCheck, mdiDotsVertical } from "@mdi/js";
|
import { mdiCheck, mdiDotsVertical } from "@mdi/js";
|
||||||
import { LitElement, PropertyValues, css, html, nothing } from "lit";
|
import { css, html, LitElement, nothing, PropertyValues } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
@ -8,6 +8,7 @@ import { preventDefault } from "../../../../common/dom/prevent_default";
|
|||||||
import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
import { stopPropagation } from "../../../../common/dom/stop_propagation";
|
||||||
import "../../../../components/ha-button";
|
import "../../../../components/ha-button";
|
||||||
import "../../../../components/ha-button-menu";
|
import "../../../../components/ha-button-menu";
|
||||||
|
import "../../../../components/ha-formfield";
|
||||||
import "../../../../components/ha-grid-size-picker";
|
import "../../../../components/ha-grid-size-picker";
|
||||||
import "../../../../components/ha-icon-button";
|
import "../../../../components/ha-icon-button";
|
||||||
import "../../../../components/ha-list-item";
|
import "../../../../components/ha-list-item";
|
||||||
@ -21,7 +22,10 @@ import { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
|
|||||||
import { haStyle } from "../../../../resources/styles";
|
import { haStyle } from "../../../../resources/styles";
|
||||||
import { HomeAssistant } from "../../../../types";
|
import { HomeAssistant } from "../../../../types";
|
||||||
import { HuiCard } from "../../cards/hui-card";
|
import { HuiCard } from "../../cards/hui-card";
|
||||||
import { computeSizeOnGrid } from "../../sections/hui-grid-section";
|
import {
|
||||||
|
CardGridSize,
|
||||||
|
computeCardGridSize,
|
||||||
|
} from "../../common/compute-card-grid-size";
|
||||||
import { LovelaceLayoutOptions } from "../../types";
|
import { LovelaceLayoutOptions } from "../../types";
|
||||||
|
|
||||||
@customElement("hui-card-layout-editor")
|
@customElement("hui-card-layout-editor")
|
||||||
@ -50,7 +54,7 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
private _gridSizeValue = memoizeOne(computeSizeOnGrid);
|
private _computeCardGridSize = memoizeOne(computeCardGridSize);
|
||||||
|
|
||||||
private _isDefault = memoizeOne(
|
private _isDefault = memoizeOne(
|
||||||
(options?: LovelaceLayoutOptions) =>
|
(options?: LovelaceLayoutOptions) =>
|
||||||
@ -63,7 +67,7 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
this._defaultLayoutOptions
|
this._defaultLayoutOptions
|
||||||
);
|
);
|
||||||
|
|
||||||
const sizeValue = this._gridSizeValue(options);
|
const value = this._computeCardGridSize(options);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="header">
|
<div class="header">
|
||||||
@ -128,7 +132,7 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
: html`
|
: html`
|
||||||
<ha-grid-size-picker
|
<ha-grid-size-picker
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${sizeValue}
|
.value=${value}
|
||||||
.isDefault=${this._isDefault(this.config.layout_options)}
|
.isDefault=${this._isDefault(this.config.layout_options)}
|
||||||
@value-changed=${this._gridSizeChanged}
|
@value-changed=${this._gridSizeChanged}
|
||||||
.rowMin=${options.grid_min_rows}
|
.rowMin=${options.grid_min_rows}
|
||||||
@ -136,6 +140,24 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
.columnMin=${options.grid_min_columns}
|
.columnMin=${options.grid_min_columns}
|
||||||
.columnMax=${options.grid_max_columns}
|
.columnMax=${options.grid_max_columns}
|
||||||
></ha-grid-size-picker>
|
></ha-grid-size-picker>
|
||||||
|
<ha-settings-row>
|
||||||
|
<span slot="heading" data-for="full-width">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.lovelace.editor.edit_card.layout.full_width"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<span slot="description" data-for="full-width">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.lovelace.editor.edit_card.layout.full_width_helper"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<ha-switch
|
||||||
|
@change=${this._fullWidthChanged}
|
||||||
|
.checked=${value.columns === "full"}
|
||||||
|
name="full-width"
|
||||||
|
>
|
||||||
|
</ha-switch>
|
||||||
|
</ha-settings-row>
|
||||||
`}
|
`}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -195,7 +217,7 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
|
|
||||||
private _gridSizeChanged(ev: CustomEvent): void {
|
private _gridSizeChanged(ev: CustomEvent): void {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const value = ev.detail.value;
|
const value = ev.detail.value as CardGridSize;
|
||||||
|
|
||||||
const newConfig: LovelaceCardConfig = {
|
const newConfig: LovelaceCardConfig = {
|
||||||
...this.config,
|
...this.config,
|
||||||
@ -229,6 +251,21 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
fireEvent(this, "value-changed", { value: newConfig });
|
fireEvent(this, "value-changed", { value: newConfig });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _fullWidthChanged(ev): void {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const value = ev.target.checked;
|
||||||
|
const newConfig: LovelaceCardConfig = {
|
||||||
|
...this.config,
|
||||||
|
layout_options: {
|
||||||
|
...this.config.layout_options,
|
||||||
|
grid_columns: value
|
||||||
|
? "full"
|
||||||
|
: (this._defaultLayoutOptions?.grid_min_columns ?? 1),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
fireEvent(this, "value-changed", { value: newConfig });
|
||||||
|
}
|
||||||
|
|
||||||
static styles = [
|
static styles = [
|
||||||
haStyle,
|
haStyle,
|
||||||
css`
|
css`
|
||||||
@ -262,6 +299,13 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
display: block;
|
display: block;
|
||||||
margin: 16px 0;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
ha-formfield {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
--mdc-typography-body2-font-size: 1em;
|
||||||
|
max-width: 250px;
|
||||||
|
margin: 16px auto;
|
||||||
|
}
|
||||||
`,
|
`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ import type { HomeAssistant } from "../../../types";
|
|||||||
import { HuiCard } from "../cards/hui-card";
|
import { HuiCard } from "../cards/hui-card";
|
||||||
import "../components/hui-card-edit-mode";
|
import "../components/hui-card-edit-mode";
|
||||||
import { moveCard } from "../editor/config-util";
|
import { moveCard } from "../editor/config-util";
|
||||||
import type { Lovelace, LovelaceLayoutOptions } from "../types";
|
import type { Lovelace } from "../types";
|
||||||
import { conditionalClamp } from "../../../common/number/clamp";
|
import { computeCardGridSize } from "../common/compute-card-grid-size";
|
||||||
|
|
||||||
const CARD_SORTABLE_OPTIONS: HaSortableOptions = {
|
const CARD_SORTABLE_OPTIONS: HaSortableOptions = {
|
||||||
delay: 100,
|
delay: 100,
|
||||||
@ -24,43 +24,6 @@ const CARD_SORTABLE_OPTIONS: HaSortableOptions = {
|
|||||||
invertedSwapThreshold: 0.7,
|
invertedSwapThreshold: 0.7,
|
||||||
} as HaSortableOptions;
|
} as HaSortableOptions;
|
||||||
|
|
||||||
export const DEFAULT_GRID_OPTIONS = {
|
|
||||||
grid_columns: 4,
|
|
||||||
grid_rows: "auto",
|
|
||||||
} as const satisfies LovelaceLayoutOptions;
|
|
||||||
|
|
||||||
type GridSizeValue = {
|
|
||||||
rows?: number | "auto";
|
|
||||||
columns?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const computeSizeOnGrid = (
|
|
||||||
options: LovelaceLayoutOptions
|
|
||||||
): GridSizeValue => {
|
|
||||||
const rows =
|
|
||||||
typeof options.grid_rows === "number"
|
|
||||||
? conditionalClamp(
|
|
||||||
options.grid_rows,
|
|
||||||
options.grid_min_rows,
|
|
||||||
options.grid_max_rows
|
|
||||||
)
|
|
||||||
: DEFAULT_GRID_OPTIONS.grid_rows;
|
|
||||||
|
|
||||||
const columns =
|
|
||||||
typeof options.grid_columns === "number"
|
|
||||||
? conditionalClamp(
|
|
||||||
options.grid_columns,
|
|
||||||
options.grid_min_columns,
|
|
||||||
options.grid_max_columns
|
|
||||||
)
|
|
||||||
: DEFAULT_GRID_OPTIONS.grid_columns;
|
|
||||||
|
|
||||||
return {
|
|
||||||
rows,
|
|
||||||
columns,
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
export class GridSection extends LitElement implements LovelaceSectionElement {
|
export class GridSection extends LitElement implements LovelaceSectionElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@ -134,16 +97,18 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
|||||||
card.layout = "grid";
|
card.layout = "grid";
|
||||||
const layoutOptions = card.getLayoutOptions();
|
const layoutOptions = card.getLayoutOptions();
|
||||||
|
|
||||||
const { rows, columns } = computeSizeOnGrid(layoutOptions);
|
const { rows, columns } = computeCardGridSize(layoutOptions);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
style=${styleMap({
|
style=${styleMap({
|
||||||
"--column-size": columns,
|
"--column-size":
|
||||||
"--row-size": rows,
|
typeof columns === "number" ? columns : undefined,
|
||||||
|
"--row-size": typeof rows === "number" ? rows : undefined,
|
||||||
})}
|
})}
|
||||||
class="card ${classMap({
|
class="card ${classMap({
|
||||||
"fit-rows": typeof layoutOptions?.grid_rows === "number",
|
"fit-rows": typeof layoutOptions?.grid_rows === "number",
|
||||||
|
"full-width": columns === "full",
|
||||||
})}"
|
})}"
|
||||||
>
|
>
|
||||||
${editMode
|
${editMode
|
||||||
@ -268,8 +233,8 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
|||||||
.card {
|
.card {
|
||||||
border-radius: var(--ha-card-border-radius, 12px);
|
border-radius: var(--ha-card-border-radius, 12px);
|
||||||
position: relative;
|
position: relative;
|
||||||
grid-row: span var(--row-size);
|
grid-row: span var(--row-size, 1);
|
||||||
grid-column: span var(--column-size);
|
grid-column: span min(var(--column-size, 1), var(--column-count));
|
||||||
}
|
}
|
||||||
|
|
||||||
.card.fit-rows {
|
.card.fit-rows {
|
||||||
@ -280,6 +245,10 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.card.full-width {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
}
|
||||||
|
|
||||||
.card:has(> *) {
|
.card:has(> *) {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ export interface LovelaceBadge extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type LovelaceLayoutOptions = {
|
export type LovelaceLayoutOptions = {
|
||||||
grid_columns?: number;
|
grid_columns?: number | "full";
|
||||||
grid_rows?: number | "auto";
|
grid_rows?: number | "auto";
|
||||||
grid_max_columns?: number;
|
grid_max_columns?: number;
|
||||||
grid_min_columns?: number;
|
grid_min_columns?: number;
|
||||||
|
@ -5588,6 +5588,10 @@
|
|||||||
"tab_layout": "Layout",
|
"tab_layout": "Layout",
|
||||||
"visibility": {
|
"visibility": {
|
||||||
"explanation": "The card will be shown when ALL conditions below are fulfilled. If no conditions are set, the card will always be shown."
|
"explanation": "The card will be shown when ALL conditions below are fulfilled. If no conditions are set, the card will always be shown."
|
||||||
|
},
|
||||||
|
"layout": {
|
||||||
|
"full_width": "Full width card",
|
||||||
|
"full_width_helper": "Take up the full width of the section whatever its size"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"edit_badge": {
|
"edit_badge": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user