diff --git a/src/panels/lovelace/common/compute-card-grid-size.ts b/src/panels/lovelace/common/compute-card-grid-size.ts index e7991a877169..635d43ef53a1 100644 --- a/src/panels/lovelace/common/compute-card-grid-size.ts +++ b/src/panels/lovelace/common/compute-card-grid-size.ts @@ -1,13 +1,18 @@ import { conditionalClamp } from "../../../common/number/clamp"; import { LovelaceGridOptions, LovelaceLayoutOptions } from "../types"; -const GRID_COLUMN_MULTIPLIER = 3; +export const GRID_COLUMN_MULTIPLIER = 3; -const multiplyBy = ( +export const multiplyBy = ( value: T, multiplier: number ): T => (typeof value === "number" ? ((value * multiplier) as T) : value); +export const divideBy = ( + value: T, + divider: number +): T => (typeof value === "number" ? (Math.ceil(value / divider) as T) : value); + export const migrateLayoutToGridOptions = ( options: LovelaceLayoutOptions ): LovelaceGridOptions => { diff --git a/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts b/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts index 07913a502146..d144c80f7d9c 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts @@ -25,7 +25,10 @@ import { HuiCard } from "../../cards/hui-card"; import { CardGridSize, computeCardGridSize, + divideBy, + GRID_COLUMN_MULTIPLIER, migrateLayoutToGridOptions, + multiplyBy, } from "../../common/compute-card-grid-size"; import { LovelaceGridOptions } from "../../types"; @@ -59,6 +62,22 @@ export class HuiCardLayoutEditor extends LitElement { private _computeCardGridSize = memoizeOne(computeCardGridSize); + private _simplifyOptions = ( + options: LovelaceGridOptions + ): LovelaceGridOptions => ({ + ...options, + columns: divideBy(options.columns, GRID_COLUMN_MULTIPLIER), + max_columns: divideBy(options.max_columns, GRID_COLUMN_MULTIPLIER), + min_columns: divideBy(options.min_columns, GRID_COLUMN_MULTIPLIER), + }); + + private _standardizeOptions = (options: LovelaceGridOptions) => ({ + ...options, + columns: multiplyBy(options.columns, GRID_COLUMN_MULTIPLIER), + max_columns: multiplyBy(options.max_columns, GRID_COLUMN_MULTIPLIER), + min_columns: multiplyBy(options.min_columns, GRID_COLUMN_MULTIPLIER), + }); + private _isDefault = memoizeOne( (options?: LovelaceGridOptions) => options?.columns === undefined && options?.rows === undefined @@ -75,15 +94,20 @@ export class HuiCardLayoutEditor extends LitElement { }; render() { - const configGridOptions = this._configGridOptions(this.config); + const configOptions = this._configGridOptions(this.config); const options = this._mergedOptions( - configGridOptions, + configOptions, this._defaultGridOptions ); - const value = this._computeCardGridSize(options); + const gridOptions = this._preciseMode + ? options + : this._simplifyOptions(options); + const gridValue = this._computeCardGridSize(gridOptions); - const totalColumns = (this.sectionConfig.column_span ?? 1) * 12; + const columnSpan = this.sectionConfig.column_span ?? 1; + const gridTotalColumns = + (12 * columnSpan) / (this._preciseMode ? 1 : GRID_COLUMN_MULTIPLIER); return html`
@@ -141,24 +165,24 @@ export class HuiCardLayoutEditor extends LitElement { ? html` ` : html` @@ -173,7 +197,7 @@ export class HuiCardLayoutEditor extends LitElement { @@ -271,60 +295,73 @@ export class HuiCardLayoutEditor extends LitElement { ev.stopPropagation(); const value = ev.detail.value as CardGridSize; - const newConfig: LovelaceCardConfig = { - ...this.config, - grid_options: { - ...this.config.grid_options, - columns: value.columns, - rows: value.rows, - }, + const gridOptions = { + columns: value.columns, + rows: value.rows, }; - this._updateValue(newConfig); - } + const newOptions = this._preciseMode + ? gridOptions + : this._standardizeOptions(gridOptions); - private _updateValue(value: LovelaceCardConfig): void { - if (value.grid_options!.columns === undefined) { - delete value.grid_options!.columns; - } - if (value.grid_options!.rows === undefined) { - delete value.grid_options!.rows; - } - if (Object.keys(value.grid_options!).length === 0) { - delete value.grid_options; - } - if (value.layout_options) { - delete value.layout_options; - } - fireEvent(this, "value-changed", { value }); + this._updateGridOptions({ + ...this.config.grid_options, + ...newOptions, + }); } - private _valueChanged(ev: CustomEvent): void { + private _yamlChanged(ev: CustomEvent): void { ev.stopPropagation(); const options = ev.detail.value as LovelaceGridOptions; - const newConfig: LovelaceCardConfig = { - ...this.config, - grid_options: options, - }; - this._updateValue(newConfig); + this._updateGridOptions(options); } private _fullWidthChanged(ev): void { ev.stopPropagation(); const value = ev.target.checked; - const newConfig: LovelaceCardConfig = { - ...this.config, - grid_options: { - ...this.config.grid_options, - columns: value ? "full" : (this._defaultGridOptions?.min_columns ?? 1), - }, - }; - this._updateValue(newConfig); + this._updateGridOptions({ + ...this.config.grid_options, + columns: value ? "full" : (this._defaultGridOptions?.min_columns ?? 1), + }); } private _preciseModeChanged(ev): void { ev.stopPropagation(); this._preciseMode = ev.target.checked; + if (this._preciseMode) return; + + const newOptions = this._standardizeOptions( + this._simplifyOptions(this.config.grid_options ?? {}) + ); + if (newOptions.columns !== this.config.grid_options?.columns) { + this._updateGridOptions({ + ...this.config.grid_options, + columns: newOptions.columns, + }); + } + } + + private _updateGridOptions(options: LovelaceGridOptions): void { + const value: LovelaceCardConfig = { + ...this.config, + grid_options: { + ...options, + }, + }; + if (value.grid_options) { + for (const [k, v] of Object.entries(value.grid_options)) { + if (v === undefined) { + delete value.grid_options[k]; + } + } + if (Object.keys(value.grid_options).length === 0) { + delete value.grid_options; + } + } + if (value.layout_options) { + delete value.layout_options; + } + fireEvent(this, "value-changed", { value }); } static styles = [