Skip to content

Commit

Permalink
Add precise resizing mode for card inside section (#22366)
Browse files Browse the repository at this point in the history
* Allow to resize card in the grid with more precision

* Use 12 columns grid

* Fix cursor jump when dragging slider

* Remove precision mode

* Add precise mode switch

* Add switch between regular and precise mode

* Fix prettier

---------

Co-authored-by: Simon Lamon <[email protected]>
  • Loading branch information
piitaya and silamon authored Oct 30, 2024
1 parent 29d9b61 commit c0ca7e4
Show file tree
Hide file tree
Showing 9 changed files with 269 additions and 103 deletions.
4 changes: 2 additions & 2 deletions src/components/ha-grid-size-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export class HaGridSizeEditor extends LitElement {
.min=${columnMin}
.max=${columnMax}
.range=${this.columns}
.value=${fullWidth ? this.columns : columnValue}
.value=${fullWidth ? this.columns : this.value?.columns}
@value-changed=${this._valueChanged}
@slider-moved=${this._sliderMoved}
.disabled=${disabledColumns}
Expand All @@ -81,7 +81,7 @@ export class HaGridSizeEditor extends LitElement {
.max=${rowMax}
.range=${this.rows}
vertical
.value=${rowValue}
.value=${autoHeight ? rowMin : this.value?.rows}
@value-changed=${this._valueChanged}
@slider-moved=${this._sliderMoved}
.disabled=${disabledRows}
Expand Down
7 changes: 6 additions & 1 deletion src/data/lovelace/config/card.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import type { Condition } from "../../../panels/lovelace/common/validate-condition";
import type { LovelaceLayoutOptions } from "../../../panels/lovelace/types";
import type {
LovelaceGridOptions,
LovelaceLayoutOptions,
} from "../../../panels/lovelace/types";

export interface LovelaceCardConfig {
index?: number;
view_index?: number;
view_layout?: any;
/** @deprecated Use `grid_options` instead */
layout_options?: LovelaceLayoutOptions;
grid_options?: LovelaceGridOptions;
type: string;
[key: string]: any;
visibility?: Condition[];
Expand Down
49 changes: 37 additions & 12 deletions src/panels/lovelace/cards/hui-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import type { MediaQueriesListener } from "../../../common/dom/media_query";
import "../../../components/ha-svg-icon";
import type { LovelaceCardConfig } from "../../../data/lovelace/config/card";
import type { HomeAssistant } from "../../../types";
import { migrateLayoutToGridOptions } from "../common/compute-card-grid-size";
import { computeCardSize } from "../common/compute-card-size";
import {
attachConditionMediaQueriesListeners,
checkConditionsMet,
} from "../common/validate-condition";
import { createCardElement } from "../create-element/create-card-element";
import { createErrorCardConfig } from "../create-element/create-element-base";
import type { LovelaceCard, LovelaceLayoutOptions } from "../types";
import type { LovelaceCard, LovelaceGridOptions } from "../types";

declare global {
interface HASSDomEvents {
Expand Down Expand Up @@ -68,20 +69,44 @@ export class HuiCard extends ReactiveElement {
return 1;
}

public getLayoutOptions(): LovelaceLayoutOptions {
const configOptions = this.config?.layout_options ?? {};
if (this._element) {
const cardOptions = this._element.getLayoutOptions?.() ?? {};
return {
...cardOptions,
...configOptions,
};
public getGridOptions(): LovelaceGridOptions {
const elementOptions = this.getElementGridOptions();
const configOptions = this.getConfigGridOptions();
return {
...elementOptions,
...configOptions,
};
}

// options provided by the element
public getElementGridOptions(): LovelaceGridOptions {
if (!this._element) return {};

if (this._element.getGridOptions) {
return this._element.getGridOptions();
}
return configOptions;
if (this._element.getLayoutOptions) {
// eslint-disable-next-line no-console
console.warn(
`This card (${this.config?.type}) is using "getLayoutOptions" and it is deprecated, contact the developer to suggest to use "getGridOptions" instead`
);
const options = migrateLayoutToGridOptions(
this._element.getLayoutOptions()
);
return options;
}
return {};
}

public getElementLayoutOptions(): LovelaceLayoutOptions {
return this._element?.getLayoutOptions?.() ?? {};
// options provided by the config
public getConfigGridOptions(): LovelaceGridOptions {
if (this.config?.grid_options) {
return this.config.grid_options;
}
if (this.config?.layout_options) {
return migrateLayoutToGridOptions(this.config.layout_options);
}
return {};
}

private _updateElement(config: LovelaceCardConfig) {
Expand Down
49 changes: 40 additions & 9 deletions src/panels/lovelace/common/compute-card-grid-size.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,39 @@
import { conditionalClamp } from "../../../common/number/clamp";
import type { LovelaceLayoutOptions } from "../types";
import type { LovelaceGridOptions, LovelaceLayoutOptions } from "../types";

export const GRID_COLUMN_MULTIPLIER = 3;

export const multiplyBy = <T extends number | string | undefined>(
value: T,
multiplier: number
): T => (typeof value === "number" ? ((value * multiplier) as T) : value);

export const divideBy = <T extends number | string | undefined>(
value: T,
divider: number
): T => (typeof value === "number" ? (Math.ceil(value / divider) as T) : value);

export const migrateLayoutToGridOptions = (
options: LovelaceLayoutOptions
): LovelaceGridOptions => {
const gridOptions: LovelaceGridOptions = {
columns: multiplyBy(options.grid_columns, GRID_COLUMN_MULTIPLIER),
max_columns: multiplyBy(options.grid_max_columns, GRID_COLUMN_MULTIPLIER),
min_columns: multiplyBy(options.grid_min_columns, GRID_COLUMN_MULTIPLIER),
rows: options.grid_rows,
max_rows: options.grid_max_rows,
min_rows: options.grid_min_rows,
};
for (const [key, value] of Object.entries(gridOptions)) {
if (value === undefined) {
delete gridOptions[key];
}
}
return gridOptions;
};

export const DEFAULT_GRID_SIZE = {
columns: 4,
columns: 12,
rows: "auto",
} as CardGridSize;

Expand All @@ -12,14 +43,14 @@ export type CardGridSize = {
};

export const computeCardGridSize = (
options: LovelaceLayoutOptions
options: LovelaceGridOptions
): 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 rows = options.rows ?? DEFAULT_GRID_SIZE.rows;
const columns = options.columns ?? DEFAULT_GRID_SIZE.columns;
const minRows = options.min_rows;
const maxRows = options.max_rows;
const minColumns = options.min_columns;
const maxColumns = options.max_columns;

const clampedRows =
typeof rows === "string" ? rows : conditionalClamp(rows, minRows, maxRows);
Expand Down
Loading

0 comments on commit c0ca7e4

Please sign in to comment.