mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-22 08:46:35 +00:00
Improve grid size editor (#22697)
* Use table instead of grid * Add animation * Change size * Simplify precideMode logic * Add tooltip and improve slider style * Improve size * Back to default instead of min * Limit number of cells for the grid when more than 24 cells
This commit is contained in:
parent
1990b8fa84
commit
23b55484c3
@ -2,9 +2,7 @@ import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import "../panels/lovelace/editor/card-editor/ha-grid-layout-slider";
|
||||
import "./ha-icon-button";
|
||||
|
||||
import { mdiRestore } from "@mdi/js";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { conditionalClamp } from "../common/number/clamp";
|
||||
@ -20,7 +18,7 @@ export class HaGridSizeEditor extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public rows = 8;
|
||||
|
||||
@property({ attribute: false }) public columns = 4;
|
||||
@property({ attribute: false }) public columns = 12;
|
||||
|
||||
@property({ attribute: false }) public rowMin?: number;
|
||||
|
||||
@ -32,6 +30,8 @@ export class HaGridSizeEditor extends LitElement {
|
||||
|
||||
@property({ attribute: false }) public isDefault?: boolean;
|
||||
|
||||
@property({ attribute: false }) public step: number = 1;
|
||||
|
||||
@state() public _localValue?: CardGridSize = { rows: 1, columns: 1 };
|
||||
|
||||
protected willUpdate(changedProperties) {
|
||||
@ -51,8 +51,9 @@ export class HaGridSizeEditor extends LitElement {
|
||||
|
||||
const rowMin = this.rowMin ?? 1;
|
||||
const rowMax = this.rowMax ?? this.rows;
|
||||
const columnMin = this.columnMin ?? 1;
|
||||
const columnMax = this.columnMax ?? this.columns;
|
||||
const columnMin = Math.ceil((this.columnMin ?? 1) / this.step) * this.step;
|
||||
const columnMax =
|
||||
Math.ceil((this.columnMax ?? this.columns) / this.step) * this.step;
|
||||
const rowValue = autoHeight ? rowMin : this._localValue?.rows;
|
||||
const columnValue = this._localValue?.columns;
|
||||
|
||||
@ -67,9 +68,11 @@ export class HaGridSizeEditor extends LitElement {
|
||||
.max=${columnMax}
|
||||
.range=${this.columns}
|
||||
.value=${fullWidth ? this.columns : this.value?.columns}
|
||||
.step=${this.step}
|
||||
@value-changed=${this._valueChanged}
|
||||
@slider-moved=${this._sliderMoved}
|
||||
.disabled=${disabledColumns}
|
||||
tooltip-mode="always"
|
||||
></ha-grid-layout-slider>
|
||||
|
||||
<ha-grid-layout-slider
|
||||
@ -85,6 +88,7 @@ export class HaGridSizeEditor extends LitElement {
|
||||
@value-changed=${this._valueChanged}
|
||||
@slider-moved=${this._sliderMoved}
|
||||
.disabled=${disabledRows}
|
||||
tooltip-mode="always"
|
||||
></ha-grid-layout-slider>
|
||||
${!this.isDefault
|
||||
? html`
|
||||
@ -102,34 +106,44 @@ export class HaGridSizeEditor extends LitElement {
|
||||
</ha-icon-button>
|
||||
`
|
||||
: nothing}
|
||||
<div
|
||||
class="preview ${classMap({ "full-width": fullWidth })}"
|
||||
style=${styleMap({
|
||||
"--total-rows": this.rows,
|
||||
"--total-columns": this.columns,
|
||||
"--rows": rowValue,
|
||||
"--columns": fullWidth ? this.columns : columnValue,
|
||||
})}
|
||||
>
|
||||
<div>
|
||||
${Array(this.rows * this.columns)
|
||||
<div class="preview">
|
||||
<table>
|
||||
${Array(this.rows)
|
||||
.fill(0)
|
||||
.map((_, index) => {
|
||||
const row = Math.floor(index / this.columns) + 1;
|
||||
const column = (index % this.columns) + 1;
|
||||
const row = index + 1;
|
||||
return html`
|
||||
<div
|
||||
class="cell"
|
||||
data-row=${row}
|
||||
data-column=${column}
|
||||
@click=${this._cellClick}
|
||||
></div>
|
||||
<tr>
|
||||
${Array(this.columns)
|
||||
.fill(0)
|
||||
.map((__, columnIndex) => {
|
||||
const column = columnIndex + 1;
|
||||
if (
|
||||
column % this.step !== 0 ||
|
||||
(this.columns > 24 && column % 3 !== 0)
|
||||
) {
|
||||
return nothing;
|
||||
}
|
||||
return html`
|
||||
<td
|
||||
data-row=${row}
|
||||
data-column=${column}
|
||||
@click=${this._cellClick}
|
||||
></td>
|
||||
`;
|
||||
})}
|
||||
</tr>
|
||||
`;
|
||||
})}
|
||||
</div>
|
||||
<div class="selected">
|
||||
<div class="cell"></div>
|
||||
</div>
|
||||
</table>
|
||||
<div
|
||||
class="preview-card"
|
||||
style=${styleMap({
|
||||
"--rows": rowValue,
|
||||
"--columns": fullWidth ? this.columns : columnValue,
|
||||
"--total-columns": this.columns,
|
||||
})}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -223,42 +237,40 @@ export class HaGridSizeEditor extends LitElement {
|
||||
}
|
||||
.reset {
|
||||
grid-area: reset;
|
||||
--mdc-icon-button-size: 36px;
|
||||
}
|
||||
.preview {
|
||||
position: relative;
|
||||
grid-area: preview;
|
||||
}
|
||||
.preview > div {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--total-columns), 1fr);
|
||||
grid-template-rows: repeat(var(--total-rows), 25px);
|
||||
gap: 4px;
|
||||
.preview table,
|
||||
.preview tr,
|
||||
.preview td {
|
||||
border: 2px dotted var(--divider-color);
|
||||
border-collapse: collapse;
|
||||
}
|
||||
.preview .cell {
|
||||
background-color: var(--disabled-color);
|
||||
grid-column: span 1;
|
||||
grid-row: span 1;
|
||||
border-radius: 4px;
|
||||
opacity: 0.2;
|
||||
cursor: pointer;
|
||||
}
|
||||
.preview .selected {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
.preview table {
|
||||
width: 100%;
|
||||
}
|
||||
.selected .cell {
|
||||
background-color: var(--primary-color);
|
||||
grid-column: 1 / span min(var(--columns, 0), var(--total-columns));
|
||||
grid-row: 1 / span min(var(--rows, 0), var(--total-rows));
|
||||
opacity: 0.5;
|
||||
.preview tr {
|
||||
height: 30px;
|
||||
}
|
||||
.preview.full-width .selected .cell {
|
||||
grid-column: 1 / -1;
|
||||
.preview td {
|
||||
cursor: pointer;
|
||||
}
|
||||
.preview-card {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: var(--primary-color);
|
||||
opacity: 0.3;
|
||||
border-radius: 8px;
|
||||
height: calc(var(--rows, 1) * 30px);
|
||||
width: calc(var(--columns, 1) * 100% / var(--total-columns, 12));
|
||||
pointer-events: none;
|
||||
transition:
|
||||
width ease-in-out 180ms,
|
||||
height ease-in-out 180ms;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
@ -3,16 +3,11 @@ import type { LovelaceGridOptions, LovelaceLayoutOptions } from "../types";
|
||||
|
||||
export const GRID_COLUMN_MULTIPLIER = 3;
|
||||
|
||||
export const multiplyBy = <T extends number | string | undefined>(
|
||||
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 => {
|
||||
@ -42,6 +37,9 @@ export type CardGridSize = {
|
||||
columns: number | "full";
|
||||
};
|
||||
|
||||
export const isPreciseMode = (options: LovelaceGridOptions) =>
|
||||
typeof options.columns === "number" && options.columns % 3 !== 0;
|
||||
|
||||
export const computeCardGridSize = (
|
||||
options: LovelaceGridOptions
|
||||
): CardGridSize => {
|
||||
|
@ -23,6 +23,8 @@ const A11Y_KEY_CODES = new Set([
|
||||
"End",
|
||||
]);
|
||||
|
||||
type TooltipMode = "never" | "always" | "interaction";
|
||||
|
||||
@customElement("ha-grid-layout-slider")
|
||||
export class HaGridLayoutSlider extends LitElement {
|
||||
@property({ type: Boolean, reflect: true })
|
||||
@ -34,6 +36,9 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
@property({ attribute: "touch-action" })
|
||||
public touchAction?: string;
|
||||
|
||||
@property({ attribute: "tooltip-mode" })
|
||||
public tooltipMode: TooltipMode = "interaction";
|
||||
|
||||
@property({ type: Number })
|
||||
public value?: number;
|
||||
|
||||
@ -52,6 +57,9 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
@state()
|
||||
public pressed = false;
|
||||
|
||||
@state()
|
||||
public tooltipVisible = false;
|
||||
|
||||
private _mc?: HammerManager;
|
||||
|
||||
private get _range() {
|
||||
@ -135,11 +143,13 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
this._mc.on("panstart", () => {
|
||||
if (this.disabled) return;
|
||||
this.pressed = true;
|
||||
this._showTooltip();
|
||||
savedValue = this.value;
|
||||
});
|
||||
this._mc.on("pancancel", () => {
|
||||
if (this.disabled) return;
|
||||
this.pressed = false;
|
||||
this._hideTooltip();
|
||||
this.value = savedValue;
|
||||
});
|
||||
this._mc.on("panmove", (e) => {
|
||||
@ -152,6 +162,7 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
this._mc.on("panend", (e) => {
|
||||
if (this.disabled) return;
|
||||
this.pressed = false;
|
||||
this._hideTooltip();
|
||||
const percentage = this._getPercentageFromEvent(e);
|
||||
const value = this._percentageToValue(percentage);
|
||||
this.value = this._steppedValue(this._boundedValue(value));
|
||||
@ -223,6 +234,23 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
fireEvent(this, "value-changed", { value: this.value });
|
||||
}
|
||||
|
||||
private _tooltipTimeout?: number;
|
||||
|
||||
_showTooltip() {
|
||||
if (this._tooltipTimeout != null) window.clearTimeout(this._tooltipTimeout);
|
||||
this.tooltipVisible = true;
|
||||
}
|
||||
|
||||
_hideTooltip(delay?: number) {
|
||||
if (!delay) {
|
||||
this.tooltipVisible = false;
|
||||
return;
|
||||
}
|
||||
this._tooltipTimeout = window.setTimeout(() => {
|
||||
this.tooltipVisible = false;
|
||||
}, delay);
|
||||
}
|
||||
|
||||
private _getPercentageFromEvent = (e: HammerInput) => {
|
||||
if (this.vertical) {
|
||||
const y = e.center.y;
|
||||
@ -236,6 +264,30 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
return Math.max(Math.min(1, (x - offset) / total), 0);
|
||||
};
|
||||
|
||||
private _renderTooltip() {
|
||||
if (this.tooltipMode === "never") return nothing;
|
||||
|
||||
const position = this.vertical ? "left" : "top";
|
||||
|
||||
const visible =
|
||||
this.tooltipMode === "always" ||
|
||||
(this.tooltipVisible && this.tooltipMode === "interaction");
|
||||
|
||||
const value = this._boundedValue(this._steppedValue(this.value ?? 0));
|
||||
|
||||
return html`
|
||||
<span
|
||||
aria-hidden="true"
|
||||
class="tooltip ${classMap({
|
||||
visible,
|
||||
[position]: true,
|
||||
})}"
|
||||
>
|
||||
${value}
|
||||
</span>
|
||||
`;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
<div
|
||||
@ -257,9 +309,29 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
})}
|
||||
></div>
|
||||
</div>
|
||||
|
||||
${Array(this._range / this.step)
|
||||
.fill(0)
|
||||
.map((_, i) => {
|
||||
const percentage = i / (this._range / this.step);
|
||||
const disabled =
|
||||
this.min >= i * this.step || i * this.step > this.max;
|
||||
if (disabled) {
|
||||
return nothing;
|
||||
}
|
||||
return html`
|
||||
<div
|
||||
class="dot"
|
||||
style=${styleMap({
|
||||
"--value": `${percentage}`,
|
||||
})}
|
||||
></div>
|
||||
`;
|
||||
})}
|
||||
${this.value !== undefined
|
||||
? html`<div class="handle"></div>`
|
||||
: nothing}
|
||||
${this._renderTooltip()}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -269,7 +341,7 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
return css`
|
||||
:host {
|
||||
display: block;
|
||||
--grid-layout-slider: 48px;
|
||||
--grid-layout-slider: 36px;
|
||||
height: var(--grid-layout-slider);
|
||||
width: 100%;
|
||||
outline: none;
|
||||
@ -297,6 +369,7 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
}
|
||||
.slider * {
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
}
|
||||
.track {
|
||||
position: absolute;
|
||||
@ -315,12 +388,11 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: var(--disabled-color);
|
||||
opacity: 0.2;
|
||||
opacity: 0.4;
|
||||
}
|
||||
.active {
|
||||
position: absolute;
|
||||
background: grey;
|
||||
opacity: 0.7;
|
||||
background: var(--primary-color);
|
||||
top: 0;
|
||||
right: calc(var(--max) * 100%);
|
||||
bottom: 0;
|
||||
@ -351,6 +423,27 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
height: 16px;
|
||||
width: 100%;
|
||||
}
|
||||
.dot {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
opacity: 0.6;
|
||||
margin: auto;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
flex-shrink: 0;
|
||||
transform: translate(-50%, 0);
|
||||
background: var(--card-background-color);
|
||||
left: calc(var(--value, 0%) * 100%);
|
||||
border-radius: 2px;
|
||||
}
|
||||
:host([vertical]) .dot {
|
||||
transform: translate(0, -50%);
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: inherit;
|
||||
top: calc(var(--value, 0%) * 100%);
|
||||
}
|
||||
.handle::after {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
@ -358,7 +451,7 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
border-radius: 2px;
|
||||
height: 100%;
|
||||
margin: auto;
|
||||
background: grey;
|
||||
background: var(--primary-color);
|
||||
content: "";
|
||||
}
|
||||
:host([vertical]) .handle::after {
|
||||
@ -374,9 +467,88 @@ export class HaGridLayoutSlider extends LitElement {
|
||||
:host(:disabled) .active {
|
||||
background: var(--disabled-color);
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
position: absolute;
|
||||
background-color: var(--clear-background-color);
|
||||
color: var(--primary-text-color);
|
||||
font-size: var(--control-slider-tooltip-font-size);
|
||||
border-radius: 0.8em;
|
||||
padding: 0.2em 0.4em;
|
||||
opacity: 0;
|
||||
white-space: nowrap;
|
||||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||
transition:
|
||||
opacity 180ms ease-in-out,
|
||||
left 180ms ease-in-out,
|
||||
bottom 180ms ease-in-out;
|
||||
--handle-spacing: calc(2 * var(--handle-margin) + var(--handle-size));
|
||||
--slider-tooltip-margin: 0px;
|
||||
--slider-tooltip-range: 100%;
|
||||
--slider-tooltip-offset: 0px;
|
||||
--slider-tooltip-position: calc(
|
||||
min(
|
||||
max(
|
||||
var(--value) * var(--slider-tooltip-range) +
|
||||
var(--slider-tooltip-offset),
|
||||
0%
|
||||
),
|
||||
100%
|
||||
)
|
||||
);
|
||||
}
|
||||
.tooltip.start {
|
||||
--slider-tooltip-offset: calc(-0.5 * (var(--handle-spacing)));
|
||||
}
|
||||
.tooltip.end {
|
||||
--slider-tooltip-offset: calc(0.5 * (var(--handle-spacing)));
|
||||
}
|
||||
.tooltip.cursor {
|
||||
--slider-tooltip-range: calc(100% - var(--handle-spacing));
|
||||
--slider-tooltip-offset: calc(0.5 * (var(--handle-spacing)));
|
||||
}
|
||||
.tooltip.show-handle {
|
||||
--slider-tooltip-range: calc(100% - var(--handle-spacing));
|
||||
--slider-tooltip-offset: calc(0.5 * (var(--handle-spacing)));
|
||||
}
|
||||
.tooltip.visible {
|
||||
opacity: 1;
|
||||
}
|
||||
.tooltip.top {
|
||||
transform: translate3d(-50%, -100%, 0);
|
||||
top: var(--slider-tooltip-margin);
|
||||
left: 50%;
|
||||
}
|
||||
.tooltip.bottom {
|
||||
transform: translate3d(-50%, 100%, 0);
|
||||
bottom: var(--slider-tooltip-margin);
|
||||
left: 50%;
|
||||
}
|
||||
.tooltip.left {
|
||||
transform: translate3d(-100%, -50%, 0);
|
||||
top: 50%;
|
||||
left: var(--slider-tooltip-margin);
|
||||
}
|
||||
.tooltip.right {
|
||||
transform: translate3d(100%, -50%, 0);
|
||||
top: 50%;
|
||||
right: var(--slider-tooltip-margin);
|
||||
}
|
||||
:host(:not([vertical])) .tooltip.top,
|
||||
:host(:not([vertical])) .tooltip.bottom {
|
||||
left: var(--slider-tooltip-position);
|
||||
}
|
||||
:host([vertical]) .tooltip.right,
|
||||
:host([vertical]) .tooltip.left {
|
||||
top: var(--slider-tooltip-position);
|
||||
}
|
||||
|
||||
.pressed .handle {
|
||||
transition: none;
|
||||
}
|
||||
.pressed .tooltip {
|
||||
transition: opacity 180ms ease-in-out;
|
||||
}
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
@ -26,16 +26,12 @@ import type { HuiCard } from "../../cards/hui-card";
|
||||
import type { CardGridSize } from "../../common/compute-card-grid-size";
|
||||
import {
|
||||
computeCardGridSize,
|
||||
divideBy,
|
||||
GRID_COLUMN_MULTIPLIER,
|
||||
isPreciseMode,
|
||||
migrateLayoutToGridOptions,
|
||||
multiplyBy,
|
||||
} from "../../common/compute-card-grid-size";
|
||||
import type { LovelaceGridOptions } from "../../types";
|
||||
|
||||
const computePreciseMode = (columns?: number | string) =>
|
||||
typeof columns === "number" && columns % 3 !== 0;
|
||||
|
||||
@customElement("hui-card-layout-editor")
|
||||
export class HuiCardLayoutEditor extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@ -63,22 +59,6 @@ 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
|
||||
@ -101,14 +81,11 @@ export class HuiCardLayoutEditor extends LitElement {
|
||||
this._defaultGridOptions
|
||||
);
|
||||
|
||||
const gridOptions = this._preciseMode
|
||||
? options
|
||||
: this._simplifyOptions(options);
|
||||
const gridOptions = options;
|
||||
const gridValue = this._computeCardGridSize(gridOptions);
|
||||
|
||||
const columnSpan = this.sectionConfig.column_span ?? 1;
|
||||
const gridTotalColumns =
|
||||
(12 * columnSpan) / (this._preciseMode ? 1 : GRID_COLUMN_MULTIPLIER);
|
||||
const gridTotalColumns = 12 * columnSpan;
|
||||
|
||||
return html`
|
||||
<div class="header">
|
||||
@ -173,7 +150,7 @@ export class HuiCardLayoutEditor extends LitElement {
|
||||
: html`
|
||||
<ha-grid-size-picker
|
||||
style=${styleMap({
|
||||
"max-width": `${(this.sectionConfig.column_span ?? 1) * 200 + 50}px`,
|
||||
"max-width": `${(this.sectionConfig.column_span ?? 1) * 250 + 40}px`,
|
||||
})}
|
||||
.columns=${gridTotalColumns}
|
||||
.hass=${this.hass}
|
||||
@ -184,6 +161,7 @@ export class HuiCardLayoutEditor extends LitElement {
|
||||
.rowMax=${gridOptions.max_rows}
|
||||
.columnMin=${gridOptions.min_columns}
|
||||
.columnMax=${gridOptions.max_columns}
|
||||
.step=${this._preciseMode ? 1 : GRID_COLUMN_MULTIPLIER}
|
||||
></ha-grid-size-picker>
|
||||
<ha-settings-row>
|
||||
<span slot="heading" data-for="full-width">
|
||||
@ -267,17 +245,21 @@ export class HuiCardLayoutEditor extends LitElement {
|
||||
protected willUpdate(changedProps: PropertyValues<this>): void {
|
||||
super.willUpdate(changedProps);
|
||||
if (changedProps.has("config")) {
|
||||
const columns = this.config.grid_options?.columns;
|
||||
const preciseMode = computePreciseMode(columns);
|
||||
const options = this.config.grid_options;
|
||||
|
||||
// Reset precise mode when grid options config is reset
|
||||
if (!options) {
|
||||
this._preciseMode = this._defaultGridOptions
|
||||
? isPreciseMode(this._defaultGridOptions)
|
||||
: false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Force precise mode if columns count is not a multiple of 3
|
||||
const preciseMode = isPreciseMode(options);
|
||||
if (!this._preciseMode && preciseMode) {
|
||||
this._preciseMode = preciseMode;
|
||||
}
|
||||
// Reset precise mode when grid options config is reset
|
||||
if (columns === undefined) {
|
||||
const defaultColumns = this._defaultGridOptions?.columns;
|
||||
this._preciseMode = computePreciseMode(defaultColumns);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,18 +278,10 @@ export class HuiCardLayoutEditor extends LitElement {
|
||||
ev.stopPropagation();
|
||||
const value = ev.detail.value as CardGridSize;
|
||||
|
||||
const gridOptions = {
|
||||
columns: value.columns,
|
||||
rows: value.rows,
|
||||
};
|
||||
|
||||
const newOptions = this._preciseMode
|
||||
? gridOptions
|
||||
: this._standardizeOptions(gridOptions);
|
||||
|
||||
this._updateGridOptions({
|
||||
...this.config.grid_options,
|
||||
...newOptions,
|
||||
columns: value.columns,
|
||||
rows: value.rows,
|
||||
});
|
||||
}
|
||||
|
||||
@ -322,7 +296,7 @@ export class HuiCardLayoutEditor extends LitElement {
|
||||
const value = ev.target.checked;
|
||||
this._updateGridOptions({
|
||||
...this.config.grid_options,
|
||||
columns: value ? "full" : (this._defaultGridOptions?.min_columns ?? 1),
|
||||
columns: value ? "full" : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
@ -331,13 +305,14 @@ export class HuiCardLayoutEditor extends LitElement {
|
||||
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) {
|
||||
const columns = this.config.grid_options?.columns;
|
||||
|
||||
if (typeof columns === "number" && columns % GRID_COLUMN_MULTIPLIER !== 0) {
|
||||
const newColumns =
|
||||
Math.ceil(columns / GRID_COLUMN_MULTIPLIER) * GRID_COLUMN_MULTIPLIER;
|
||||
this._updateGridOptions({
|
||||
...this.config.grid_options,
|
||||
columns: newOptions.columns,
|
||||
columns: newColumns,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user