mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-03 14:37:47 +00:00
Use listeners
This commit is contained in:
parent
3de4dffa02
commit
79f3dfdfce
@ -33,6 +33,7 @@ export interface LovelaceSectionElement extends HTMLElement {
|
|||||||
lovelace?: Lovelace;
|
lovelace?: Lovelace;
|
||||||
preview?: boolean;
|
preview?: boolean;
|
||||||
viewIndex?: number;
|
viewIndex?: number;
|
||||||
|
columnSpan?: number;
|
||||||
index?: number;
|
index?: number;
|
||||||
cards?: HuiCard[];
|
cards?: HuiCard[];
|
||||||
isStrategy: boolean;
|
isStrategy: boolean;
|
||||||
|
@ -35,6 +35,8 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public isStrategy = false;
|
@property({ type: Boolean }) public isStrategy = false;
|
||||||
|
|
||||||
|
@property({ type: Number, attribute: "column_span" }) public columnSpan = 1;
|
||||||
|
|
||||||
@property({ attribute: false }) public cards: HuiCard[] = [];
|
@property({ attribute: false }) public cards: HuiCard[] = [];
|
||||||
|
|
||||||
@state() _config?: LovelaceSectionConfig;
|
@state() _config?: LovelaceSectionConfig;
|
||||||
@ -77,7 +79,12 @@ export class GridSection extends LitElement implements LovelaceSectionElement {
|
|||||||
.options=${CARD_SORTABLE_OPTIONS}
|
.options=${CARD_SORTABLE_OPTIONS}
|
||||||
invert-swap
|
invert-swap
|
||||||
>
|
>
|
||||||
<div class="container ${classMap({ "edit-mode": editMode })}">
|
<div
|
||||||
|
class="container ${classMap({ "edit-mode": editMode })}"
|
||||||
|
style=${styleMap({
|
||||||
|
"--column-span": this.columnSpan,
|
||||||
|
})}
|
||||||
|
>
|
||||||
${repeat(
|
${repeat(
|
||||||
cardsConfig,
|
cardsConfig,
|
||||||
(cardConfig) => this._getKey(cardConfig),
|
(cardConfig) => this._getKey(cardConfig),
|
||||||
|
@ -47,6 +47,8 @@ export class HuiSection extends ReactiveElement {
|
|||||||
|
|
||||||
@property({ type: Number }) public viewIndex!: number;
|
@property({ type: Number }) public viewIndex!: number;
|
||||||
|
|
||||||
|
@property({ type: Number }) public columnSpan!: number;
|
||||||
|
|
||||||
@state() private _cards: HuiCard[] = [];
|
@state() private _cards: HuiCard[] = [];
|
||||||
|
|
||||||
private _layoutElementType?: string;
|
private _layoutElementType?: string;
|
||||||
@ -131,6 +133,9 @@ export class HuiSection extends ReactiveElement {
|
|||||||
if (changedProperties.has("_cards")) {
|
if (changedProperties.has("_cards")) {
|
||||||
this._layoutElement.cards = this._cards;
|
this._layoutElement.cards = this._cards;
|
||||||
}
|
}
|
||||||
|
if (changedProperties.has("columnSpan")) {
|
||||||
|
this._layoutElement.columnSpan = this.columnSpan;
|
||||||
|
}
|
||||||
if (changedProperties.has("hass") || changedProperties.has("preview")) {
|
if (changedProperties.has("hass") || changedProperties.has("preview")) {
|
||||||
this._updateElement();
|
this._updateElement();
|
||||||
}
|
}
|
||||||
@ -195,6 +200,7 @@ export class HuiSection extends ReactiveElement {
|
|||||||
this._layoutElement!.lovelace = this.lovelace;
|
this._layoutElement!.lovelace = this.lovelace;
|
||||||
this._layoutElement!.index = this.index;
|
this._layoutElement!.index = this.index;
|
||||||
this._layoutElement!.viewIndex = this.viewIndex;
|
this._layoutElement!.viewIndex = this.viewIndex;
|
||||||
|
this._layoutElement!.columnSpan = this.columnSpan;
|
||||||
this._layoutElement!.cards = this._cards;
|
this._layoutElement!.cards = this._cards;
|
||||||
|
|
||||||
if (addLayoutElement) {
|
if (addLayoutElement) {
|
||||||
|
@ -27,12 +27,15 @@ import { findLovelaceContainer } from "../editor/lovelace-path";
|
|||||||
import { showEditSectionDialog } from "../editor/section-editor/show-edit-section-dialog";
|
import { showEditSectionDialog } from "../editor/section-editor/show-edit-section-dialog";
|
||||||
import { HuiSection } from "../sections/hui-section";
|
import { HuiSection } from "../sections/hui-section";
|
||||||
import type { Lovelace } from "../types";
|
import type { Lovelace } from "../types";
|
||||||
|
import { listenMediaQuery } from "../../../common/dom/media_query";
|
||||||
|
|
||||||
export const DEFAULT_MAX_COLUMNS = 4;
|
export const DEFAULT_MAX_COLUMNS = 4;
|
||||||
|
|
||||||
const parsePx = (value: string) => parseInt(value.replace("px", ""));
|
const parsePx = (value: string) => parseInt(value.replace("px", ""));
|
||||||
|
|
||||||
export const BREAKPOINTS: Record<string, number> = {
|
type Breakpoints = Record<string, number>;
|
||||||
|
|
||||||
|
export const DEFAULT_BREAKPOINTS: Breakpoints = {
|
||||||
"0": 1,
|
"0": 1,
|
||||||
"768": 2,
|
"768": 2,
|
||||||
"1280": 3,
|
"1280": 3,
|
||||||
@ -41,6 +44,16 @@ export const BREAKPOINTS: Record<string, number> = {
|
|||||||
"2560": 6,
|
"2560": 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const buildMediaQueries = (breakpoints: Breakpoints) =>
|
||||||
|
Object.keys(breakpoints).map((breakpoint, index, array) => {
|
||||||
|
const nextBreakpoint = array[index + 1] as string | undefined;
|
||||||
|
let mediaQuery = `(min-width: ${breakpoint}px)`;
|
||||||
|
if (nextBreakpoint) {
|
||||||
|
mediaQuery += ` and (max-width: ${parseInt(nextBreakpoint) - 1}px)`;
|
||||||
|
}
|
||||||
|
return mediaQuery;
|
||||||
|
});
|
||||||
|
|
||||||
@customElement("hui-sections-view")
|
@customElement("hui-sections-view")
|
||||||
export class SectionsView extends LitElement implements LovelaceViewElement {
|
export class SectionsView extends LitElement implements LovelaceViewElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
@ -85,8 +98,13 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
private _listeners: Array<() => void> = [];
|
||||||
|
|
||||||
|
@state() private _columns: number = 1;
|
||||||
|
|
||||||
public setConfig(config: LovelaceViewConfig): void {
|
public setConfig(config: LovelaceViewConfig): void {
|
||||||
this._config = config;
|
this._config = config;
|
||||||
|
this._attachMediaQueriesListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _sectionConfigKeys = new WeakMap<HuiSection, string>();
|
private _sectionConfigKeys = new WeakMap<HuiSection, string>();
|
||||||
@ -109,12 +127,32 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
|||||||
this._computeSectionsCount();
|
this._computeSectionsCount();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private _attachMediaQueriesListeners() {
|
||||||
|
this._detachMediaQueriesListeners();
|
||||||
|
const breakpoints = this._config?.column_breakpoints || DEFAULT_BREAKPOINTS;
|
||||||
|
const mediaQueries = buildMediaQueries(breakpoints);
|
||||||
|
this._listeners = mediaQueries.map((mediaQuery, index) =>
|
||||||
|
listenMediaQuery(mediaQuery, (matches) => {
|
||||||
|
if (matches) {
|
||||||
|
this._columns = Object.values(breakpoints)[index];
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _detachMediaQueriesListeners() {
|
||||||
|
while (this._listeners.length) {
|
||||||
|
this._listeners.pop()!();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
connectedCallback(): void {
|
connectedCallback(): void {
|
||||||
super.connectedCallback();
|
super.connectedCallback();
|
||||||
this.addEventListener(
|
this.addEventListener(
|
||||||
"section-visibility-changed",
|
"section-visibility-changed",
|
||||||
this._sectionVisibilityChanged
|
this._sectionVisibilityChanged
|
||||||
);
|
);
|
||||||
|
this._attachMediaQueriesListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback(): void {
|
disconnectedCallback(): void {
|
||||||
@ -123,6 +161,7 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
|||||||
"section-visibility-changed",
|
"section-visibility-changed",
|
||||||
this._sectionVisibilityChanged
|
this._sectionVisibilityChanged
|
||||||
);
|
);
|
||||||
|
this._detachMediaQueriesListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
willUpdate(changedProperties: PropertyValues<typeof this>): void {
|
willUpdate(changedProperties: PropertyValues<typeof this>): void {
|
||||||
@ -170,14 +209,12 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
|||||||
(section) => this._getSectionKey(section),
|
(section) => this._getSectionKey(section),
|
||||||
(section, idx) => {
|
(section, idx) => {
|
||||||
const sectionConfig = this._config?.sections?.[idx];
|
const sectionConfig = this._config?.sections?.[idx];
|
||||||
const columnSpan = Math.min(
|
const columnSpan = Math.min(sectionConfig?.column_span || 1);
|
||||||
sectionConfig?.column_span || 1,
|
|
||||||
maxColumnCount
|
|
||||||
);
|
|
||||||
|
|
||||||
const rowSpan = sectionConfig?.row_span || 1;
|
const rowSpan = sectionConfig?.row_span || 1;
|
||||||
|
|
||||||
(section as any).itemPath = [idx];
|
(section as any).itemPath = [idx];
|
||||||
|
(section as any).columnSpan = columnSpan;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
@ -331,49 +368,19 @@ export class SectionsView extends LitElement implements LovelaceViewElement {
|
|||||||
--row-height: var(--ha-view-sections-row-height, 56px);
|
--row-height: var(--ha-view-sections-row-height, 56px);
|
||||||
--row-gap: var(--ha-view-sections-row-gap, 8px);
|
--row-gap: var(--ha-view-sections-row-gap, 8px);
|
||||||
--column-gap: var(--ha-view-sections-column-gap, 24px);
|
--column-gap: var(--ha-view-sections-column-gap, 24px);
|
||||||
--column-max-width: var(--ha-view-sections-column-max-width, 500px);
|
|
||||||
--column-min-width: var(--ha-view-sections-column-min-width, 320px);
|
--column-min-width: var(--ha-view-sections-column-min-width, 320px);
|
||||||
|
--column-max-width: var(--ha-view-sections-column-max-width, 500px);
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host {
|
|
||||||
--column-count: 1;
|
|
||||||
}
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
:host {
|
|
||||||
--column-count: 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (min-width: 1280px) {
|
|
||||||
:host {
|
|
||||||
--column-count: 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (min-width: 1600px) {
|
|
||||||
:host {
|
|
||||||
--column-count: 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (min-width: 1920px) {
|
|
||||||
:host {
|
|
||||||
--column-count: 5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media (min-width: 2560px) {
|
|
||||||
:host {
|
|
||||||
--column-count: 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.container > * {
|
.container > * {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section {
|
.section {
|
||||||
--section-column-span: min(var(--column-span, 1), var(--column-count));
|
|
||||||
border-radius: var(--ha-card-border-radius, 12px);
|
border-radius: var(--ha-card-border-radius, 12px);
|
||||||
grid-column: span var(--section-column-span);
|
grid-column: span var(--column-span);
|
||||||
grid-row: span var(--row-span);
|
grid-row: span var(--row-span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user