Skip to content

Commit

Permalink
Add min/max row/columns to resize card editor
Browse files Browse the repository at this point in the history
  • Loading branch information
piitaya committed Jul 1, 2024
1 parent bda61da commit f8e187b
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 39 deletions.
10 changes: 10 additions & 0 deletions src/components/ha-grid-size-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ export class HaGridSizeEditor extends LitElement {
}

protected render() {
const disabledColumns =
this.columnMin !== undefined &&
this.columnMin !== undefined &&
this.columnMin === this.columnMax;
const disabledRows =
this.rowMin !== undefined &&
this.rowMin !== undefined &&
this.rowMin === this.rowMax;
return html`
<div class="grid">
<ha-grid-layout-slider
Expand All @@ -55,6 +63,7 @@ export class HaGridSizeEditor extends LitElement {
.value=${this.value?.columns}
@value-changed=${this._valueChanged}
@slider-moved=${this._sliderMoved}
.disabled=${disabledColumns}
></ha-grid-layout-slider>
<ha-grid-layout-slider
aria-label=${this.hass.localize(
Expand All @@ -68,6 +77,7 @@ export class HaGridSizeEditor extends LitElement {
.value=${this.value?.rows}
@value-changed=${this._valueChanged}
@slider-moved=${this._sliderMoved}
.disabled=${disabledRows}
></ha-grid-layout-slider>
${!this.isDefault
? html`
Expand Down
20 changes: 19 additions & 1 deletion src/panels/lovelace/cards/hui-entity-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ import { findEntities } from "../common/find-entities";
import { hasConfigOrEntityChanged } from "../common/has-changed";
import { createEntityNotFoundWarning } from "../components/hui-warning";
import { createHeaderFooterElement } from "../create-element/create-header-footer-element";
import { LovelaceCard, LovelaceHeaderFooter } from "../types";
import {
LovelaceCard,
LovelaceHeaderFooter,
LovelaceLayoutOptions,
} from "../types";
import { HuiErrorCard } from "./hui-error-card";
import { EntityCardConfig } from "./types";

Expand Down Expand Up @@ -241,6 +245,20 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
fireEvent(this, "hass-more-info", { entityId: this._config!.entity });
}

public getLayoutOptions(): LovelaceLayoutOptions {
if (this._config?.footer) {
return {
grid_columns: 2,
};
}
return {
grid_columns: 2,
grid_rows: 2,
grid_min_rows: 2,
grid_max_rows: 2,
};
}

static get styles(): CSSResultGroup {
return [
iconColorCSS,
Expand Down
18 changes: 11 additions & 7 deletions src/panels/lovelace/cards/hui-tile-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,21 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
}

public getLayoutOptions(): LovelaceLayoutOptions {
const options = {
grid_columns: 2,
grid_rows: 1,
};
const grid_columns = 2;
let grid_rows = 1;
if (this._config?.features?.length) {
options.grid_rows += Math.ceil((this._config.features.length * 2) / 3);
grid_rows += Math.ceil((this._config.features.length * 2) / 3);
}
if (this._config?.vertical) {
options.grid_rows++;
grid_rows!++;
}
return options;
return {
grid_columns,
grid_rows,
grid_min_rows: grid_rows,
grid_max_rows: grid_rows,
grid_min_columns: grid_columns,
};
}

private _handleAction(ev: ActionHandlerEvent) {
Expand Down
23 changes: 13 additions & 10 deletions src/panels/lovelace/editor/card-editor/ha-grid-layout-slider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,14 @@ export class HaGridLayoutSlider extends LitElement {
>
<div id="slider" class="slider">
<div class="track">
<div class="background">
<div
class="active"
style=${styleMap({
"--min": `${this.min / this._range}`,
"--max": `${1 - this.max / this._range}`,
})}
></div>
</div>
<div class="background"></div>
<div
class="active"
style=${styleMap({
"--min": `${this.min / this._range}`,
"--max": `${1 - this.max / this._range}`,
})}
></div>
</div>
${this.value !== undefined
? html`<div class="handle"></div>`
Expand Down Expand Up @@ -323,11 +322,12 @@ export class HaGridLayoutSlider extends LitElement {
position: absolute;
inset: 0;
background: var(--disabled-color);
opacity: 0.5;
opacity: 0.2;
}
.active {
position: absolute;
background: grey;
opacity: 0.7;
top: 0;
right: calc(var(--max) * 100%);
bottom: 0;
Expand Down Expand Up @@ -375,6 +375,9 @@ export class HaGridLayoutSlider extends LitElement {
:host(:disabled) .slider {
cursor: not-allowed;
}
:host(:disabled) .handle:after {
background: var(--disabled-color);
}
.pressed .handle {
transition: none;
}
Expand Down
30 changes: 16 additions & 14 deletions src/panels/lovelace/editor/card-editor/hui-card-layout-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { LovelaceCardConfig } from "../../../../data/lovelace/config/card";
import { haStyle } from "../../../../resources/styles";
import { HomeAssistant } from "../../../../types";
import { HuiCard } from "../../cards/hui-card";
import { DEFAULT_GRID_OPTIONS } from "../../sections/hui-grid-section";
import { computeSizeOnGrid } from "../../sections/hui-grid-section";
import { LovelaceLayoutOptions } from "../../types";

@customElement("hui-card-layout-editor")
Expand All @@ -38,28 +38,29 @@ export class HuiCardLayoutEditor extends LitElement {

private _cardElement?: HuiCard;

private _gridSizeValue = memoizeOne(
private _mergedOptions = memoizeOne(
(
options?: LovelaceLayoutOptions,
defaultOptions?: LovelaceLayoutOptions
) => ({
rows:
options?.grid_rows ??
defaultOptions?.grid_rows ??
DEFAULT_GRID_OPTIONS.grid_rows,
columns:
options?.grid_columns ??
defaultOptions?.grid_columns ??
DEFAULT_GRID_OPTIONS.grid_columns,
...defaultOptions,
...options,
})
);

private _gridSizeValue = memoizeOne(computeSizeOnGrid);

private _isDefault = memoizeOne(
(options?: LovelaceLayoutOptions) =>
options?.grid_columns === undefined && options?.grid_rows === undefined
);

render() {
const options = this._mergedOptions(
this.config.layout_options,
this._defaultLayoutOptions
);

return html`
<div class="header">
<p class="intro">
Expand Down Expand Up @@ -123,12 +124,13 @@ export class HuiCardLayoutEditor extends LitElement {
: html`
<ha-grid-size-picker
.hass=${this.hass}
.value=${this._gridSizeValue(
this.config.layout_options,
this._defaultLayoutOptions
)}
.value=${this._gridSizeValue(options)}
.isDefault=${this._isDefault(this.config.layout_options)}
@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>
`}
`;
Expand Down
45 changes: 38 additions & 7 deletions src/panels/lovelace/sections/hui-grid-section.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { HuiCard } from "../cards/hui-card";
import "../components/hui-card-edit-mode";
import { moveCard } from "../editor/config-util";
import type { Lovelace, LovelaceLayoutOptions } from "../types";
import { conditionalClamp } from "../../../common/number/clamp";

const CARD_SORTABLE_OPTIONS: HaSortableOptions = {
delay: 100,
Expand All @@ -23,9 +24,41 @@ const CARD_SORTABLE_OPTIONS: HaSortableOptions = {
invertedSwapThreshold: 0.7,
} as HaSortableOptions;

export const DEFAULT_GRID_OPTIONS: LovelaceLayoutOptions = {
export const DEFAULT_GRID_OPTIONS = {
grid_columns: 4,
grid_rows: 1,
} as const satisfies LovelaceLayoutOptions;

type GridSizeValue = {
rows?: number;
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 {
Expand Down Expand Up @@ -100,15 +133,13 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
const card = this.cards![idx];
const layoutOptions = card.getLayoutOptions();
const columnSize =
layoutOptions.grid_columns ?? DEFAULT_GRID_OPTIONS.grid_columns;
const rowSize =
layoutOptions.grid_rows ?? DEFAULT_GRID_OPTIONS.grid_rows;
const { rows, columns } = computeSizeOnGrid(layoutOptions);
return html`
<div
style=${styleMap({
"--column-size": columnSize,
"--row-size": rowSize,
"--column-size": columns,
"--row-size": rows,
})}
class="card ${classMap({
"fit-rows": typeof layoutOptions?.grid_rows === "number",
Expand Down
4 changes: 4 additions & 0 deletions src/panels/lovelace/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export interface LovelaceBadge extends HTMLElement {
export type LovelaceLayoutOptions = {
grid_columns?: number;
grid_rows?: number;
grid_max_columns?: number;
grid_min_columns?: number;
grid_min_rows?: number;
grid_max_rows?: number;
};

export interface LovelaceCard extends HTMLElement {
Expand Down

0 comments on commit f8e187b

Please sign in to comment.