mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-01 21:47:46 +00:00
Allow to resize card in the grid with more precision
This commit is contained in:
parent
07e5aa30c6
commit
fde1bb7d6a
@ -14,6 +14,12 @@ import {
|
|||||||
} from "../panels/lovelace/common/compute-card-grid-size";
|
} from "../panels/lovelace/common/compute-card-grid-size";
|
||||||
import { HomeAssistant } from "../types";
|
import { HomeAssistant } from "../types";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HASSDomEvents {
|
||||||
|
"grid-reset": undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@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;
|
||||||
@ -184,12 +190,7 @@ export class HaGridSizeEditor extends LitElement {
|
|||||||
|
|
||||||
private _reset(ev) {
|
private _reset(ev) {
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
fireEvent(this, "value-changed", {
|
fireEvent(this, "grid-reset");
|
||||||
value: {
|
|
||||||
rows: undefined,
|
|
||||||
columns: undefined,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _sliderMoved(ev) {
|
private _sliderMoved(ev) {
|
||||||
|
@ -11,6 +11,8 @@ export type CardGridSize = {
|
|||||||
columns: number | "full";
|
columns: number | "full";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const GRID_COLUMN_MULTIPLIER = 3;
|
||||||
|
|
||||||
export const computeCardGridSize = (
|
export const computeCardGridSize = (
|
||||||
options: LovelaceLayoutOptions
|
options: LovelaceLayoutOptions
|
||||||
): CardGridSize => {
|
): CardGridSize => {
|
||||||
@ -20,14 +22,16 @@ export const computeCardGridSize = (
|
|||||||
const maxRows = options.grid_max_rows;
|
const maxRows = options.grid_max_rows;
|
||||||
const minColumns = options.grid_min_columns;
|
const minColumns = options.grid_min_columns;
|
||||||
const maxColumns = options.grid_max_columns;
|
const maxColumns = options.grid_max_columns;
|
||||||
|
const precisionMode = options.grid_precision_mode;
|
||||||
|
|
||||||
const clampedRows =
|
const clampedRows =
|
||||||
typeof rows === "string" ? rows : conditionalClamp(rows, minRows, maxRows);
|
typeof rows === "string" ? rows : conditionalClamp(rows, minRows, maxRows);
|
||||||
|
|
||||||
const clampedColumns =
|
const clampedColumns =
|
||||||
typeof columns === "string"
|
typeof columns === "string" || precisionMode
|
||||||
? columns
|
? columns
|
||||||
: conditionalClamp(columns, minColumns, maxColumns);
|
: conditionalClamp(columns, minColumns, maxColumns) *
|
||||||
|
GRID_COLUMN_MULTIPLIER;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
rows: clampedRows,
|
rows: clampedRows,
|
||||||
|
@ -26,6 +26,7 @@ import { HuiCard } from "../../cards/hui-card";
|
|||||||
import {
|
import {
|
||||||
CardGridSize,
|
CardGridSize,
|
||||||
computeCardGridSize,
|
computeCardGridSize,
|
||||||
|
GRID_COLUMN_MULTIPLIER,
|
||||||
} from "../../common/compute-card-grid-size";
|
} from "../../common/compute-card-grid-size";
|
||||||
import { LovelaceLayoutOptions } from "../../types";
|
import { LovelaceLayoutOptions } from "../../types";
|
||||||
|
|
||||||
@ -57,11 +58,24 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
private _computeCardGridSize = memoizeOne(computeCardGridSize);
|
private _computeCardGridSize = memoizeOne(
|
||||||
|
(options: LovelaceLayoutOptions) => {
|
||||||
|
const size = computeCardGridSize(options);
|
||||||
|
if (!options.grid_precision_mode) {
|
||||||
|
size.columns =
|
||||||
|
typeof size.columns === "number"
|
||||||
|
? Math.round(size.columns / GRID_COLUMN_MULTIPLIER)
|
||||||
|
: size.columns;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
private _isDefault = memoizeOne(
|
private _isDefault = memoizeOne(
|
||||||
(options?: LovelaceLayoutOptions) =>
|
(options?: LovelaceLayoutOptions) =>
|
||||||
options?.grid_columns === undefined && options?.grid_rows === undefined
|
options?.grid_columns === undefined &&
|
||||||
|
options?.grid_rows === undefined &&
|
||||||
|
options?.grid_precision_mode === undefined
|
||||||
);
|
);
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -74,6 +88,8 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
|
|
||||||
const totalColumns = (this.sectionConfig.column_span ?? 1) * 4;
|
const totalColumns = (this.sectionConfig.column_span ?? 1) * 4;
|
||||||
|
|
||||||
|
const precisionMode = options.grid_precision_mode ?? false;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<p class="intro">
|
<p class="intro">
|
||||||
@ -135,20 +151,39 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
></ha-yaml-editor>
|
></ha-yaml-editor>
|
||||||
`
|
`
|
||||||
: html`
|
: html`
|
||||||
<ha-grid-size-picker
|
${precisionMode
|
||||||
style=${styleMap({
|
? html`
|
||||||
"max-width": `${totalColumns * 45 + 50}px`,
|
<ha-grid-size-picker
|
||||||
})}
|
style=${styleMap({
|
||||||
.columns=${totalColumns}
|
"max-width": `${totalColumns * 50 + 50}px`,
|
||||||
.hass=${this.hass}
|
})}
|
||||||
.value=${value}
|
.columns=${totalColumns * GRID_COLUMN_MULTIPLIER}
|
||||||
.isDefault=${this._isDefault(this.config.layout_options)}
|
.hass=${this.hass}
|
||||||
@value-changed=${this._gridSizeChanged}
|
.value=${value}
|
||||||
.rowMin=${options.grid_min_rows}
|
.isDefault=${this._isDefault(this.config.layout_options)}
|
||||||
.rowMax=${options.grid_max_rows}
|
@grid-reset=${this._reset}
|
||||||
.columnMin=${options.grid_min_columns}
|
@value-changed=${this._gridSizeChanged}
|
||||||
.columnMax=${options.grid_max_columns}
|
.rowMin=${options.grid_min_rows}
|
||||||
></ha-grid-size-picker>
|
.rowMax=${options.grid_max_rows}
|
||||||
|
></ha-grid-size-picker>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<ha-grid-size-picker
|
||||||
|
style=${styleMap({
|
||||||
|
"max-width": `${totalColumns * 50 + 50}px`,
|
||||||
|
})}
|
||||||
|
.columns=${totalColumns}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.value=${value}
|
||||||
|
.isDefault=${this._isDefault(this.config.layout_options)}
|
||||||
|
@grid-reset=${this._reset}
|
||||||
|
@value-changed=${this._gridSizeChanged}
|
||||||
|
.rowMin=${options.grid_min_rows}
|
||||||
|
.rowMax=${options.grid_max_rows}
|
||||||
|
.columnMin=${options.grid_min_columns}
|
||||||
|
.columnMax=${options.grid_max_columns}
|
||||||
|
></ha-grid-size-picker>
|
||||||
|
`}
|
||||||
<ha-settings-row>
|
<ha-settings-row>
|
||||||
<span slot="heading" data-for="full-width">
|
<span slot="heading" data-for="full-width">
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
@ -167,6 +202,24 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
>
|
>
|
||||||
</ha-switch>
|
</ha-switch>
|
||||||
</ha-settings-row>
|
</ha-settings-row>
|
||||||
|
<ha-settings-row>
|
||||||
|
<span slot="heading" data-for="full-width">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.lovelace.editor.edit_card.layout.precision_mode"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<span slot="description" data-for="full-width">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.lovelace.editor.edit_card.layout.precision_mode_helper"
|
||||||
|
)}
|
||||||
|
</span>
|
||||||
|
<ha-switch
|
||||||
|
@change=${this._precisionModeChanged}
|
||||||
|
.checked=${precisionMode}
|
||||||
|
name="full-precision_mode"
|
||||||
|
>
|
||||||
|
</ha-switch>
|
||||||
|
</ha-settings-row>
|
||||||
`}
|
`}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -211,9 +264,6 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
case 1:
|
case 1:
|
||||||
this._yamlMode = true;
|
this._yamlMode = true;
|
||||||
break;
|
break;
|
||||||
case 2:
|
|
||||||
this._reset();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,6 +325,34 @@ export class HuiCardLayoutEditor extends LitElement {
|
|||||||
fireEvent(this, "value-changed", { value: newConfig });
|
fireEvent(this, "value-changed", { value: newConfig });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _precisionModeChanged(ev): void {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const value = ev.target.checked;
|
||||||
|
|
||||||
|
const preciseMode = value;
|
||||||
|
const gridColumns = this.config.layout_options?.grid_columns;
|
||||||
|
|
||||||
|
const newGridColumns =
|
||||||
|
typeof gridColumns === "number"
|
||||||
|
? preciseMode
|
||||||
|
? gridColumns * GRID_COLUMN_MULTIPLIER
|
||||||
|
: Math.round(gridColumns / GRID_COLUMN_MULTIPLIER)
|
||||||
|
: gridColumns;
|
||||||
|
|
||||||
|
const newConfig: LovelaceCardConfig = {
|
||||||
|
...this.config,
|
||||||
|
layout_options: {
|
||||||
|
...this.config.layout_options,
|
||||||
|
grid_columns: newGridColumns,
|
||||||
|
grid_precision_mode: preciseMode || undefined,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (Object.keys(newConfig.layout_options!).length === 0) {
|
||||||
|
delete newConfig.layout_options;
|
||||||
|
}
|
||||||
|
fireEvent(this, "value-changed", { value: newConfig });
|
||||||
|
}
|
||||||
|
|
||||||
static styles = [
|
static styles = [
|
||||||
haStyle,
|
haStyle,
|
||||||
css`
|
css`
|
||||||
|
@ -165,7 +165,7 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
|||||||
haStyle,
|
haStyle,
|
||||||
css`
|
css`
|
||||||
:host {
|
:host {
|
||||||
--base-column-count: 4;
|
--base-column-count: 12;
|
||||||
--row-gap: var(--ha-section-grid-row-gap, 8px);
|
--row-gap: var(--ha-section-grid-row-gap, 8px);
|
||||||
--column-gap: var(--ha-section-grid-column-gap, 8px);
|
--column-gap: var(--ha-section-grid-column-gap, 8px);
|
||||||
--row-height: var(--ha-section-grid-row-height, 56px);
|
--row-height: var(--ha-section-grid-row-height, 56px);
|
||||||
@ -230,8 +230,8 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
|||||||
|
|
||||||
.add {
|
.add {
|
||||||
outline: none;
|
outline: none;
|
||||||
grid-row: span var(--row-size, 1);
|
grid-row: span 1;
|
||||||
grid-column: span var(--column-size, 2);
|
grid-column: span 6;
|
||||||
background: none;
|
background: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: var(--ha-card-border-radius, 12px);
|
border-radius: var(--ha-card-border-radius, 12px);
|
||||||
|
@ -49,6 +49,7 @@ export type LovelaceLayoutOptions = {
|
|||||||
grid_min_columns?: number;
|
grid_min_columns?: number;
|
||||||
grid_min_rows?: number;
|
grid_min_rows?: number;
|
||||||
grid_max_rows?: number;
|
grid_max_rows?: number;
|
||||||
|
grid_precision_mode?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface LovelaceCard extends HTMLElement {
|
export interface LovelaceCard extends HTMLElement {
|
||||||
|
@ -5645,7 +5645,9 @@
|
|||||||
},
|
},
|
||||||
"layout": {
|
"layout": {
|
||||||
"full_width": "Full width card",
|
"full_width": "Full width card",
|
||||||
"full_width_helper": "Take up the full width of the section whatever its size"
|
"full_width_helper": "Take up the full width of the section whatever its size",
|
||||||
|
"precision_mode": "Precision mode",
|
||||||
|
"precision_mode_helper": "Change the card width with precision without limits"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"edit_badge": {
|
"edit_badge": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user