diff --git a/src/panels/lovelace/badges/hui-view-badges.ts b/src/panels/lovelace/badges/hui-view-badges.ts new file mode 100644 index 000000000000..2c0cee46fa08 --- /dev/null +++ b/src/panels/lovelace/badges/hui-view-badges.ts @@ -0,0 +1,173 @@ +import { mdiPlus } from "@mdi/js"; +import { css, CSSResultGroup, html, LitElement, nothing } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import { repeat } from "lit/directives/repeat"; +import { fireEvent } from "../../../common/dom/fire_event"; +import "../../../components/ha-sortable"; +import type { HaSortableOptions } from "../../../components/ha-sortable"; +import "../../../components/ha-svg-icon"; +import { HomeAssistant } from "../../../types"; +import "../components/hui-badge-edit-mode"; +import { moveBadge } from "../editor/config-util"; +import { Lovelace } from "../types"; +import { HuiBadge } from "./hui-badge"; + +const BADGE_SORTABLE_OPTIONS: HaSortableOptions = { + delay: 100, + delayOnTouchOnly: true, + direction: "horizontal", + invertedSwapThreshold: 0.7, +} as HaSortableOptions; + +@customElement("hui-view-badges") +export class HuiStateLabelBadge extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property({ attribute: false }) public lovelace!: Lovelace; + + @property({ attribute: false }) public badges: HuiBadge[] = []; + + @property({ attribute: false }) public viewIndex!: number; + + @state() _dragging = false; + + private _badgeConfigKeys = new WeakMap(); + + private _getBadgeKey(badge: HuiBadge) { + if (!this._badgeConfigKeys.has(badge)) { + this._badgeConfigKeys.set(badge, Math.random().toString()); + } + return this._badgeConfigKeys.get(badge)!; + } + + private _badgeMoved(ev) { + ev.stopPropagation(); + const { oldIndex, newIndex, oldPath, newPath } = ev.detail; + const newConfig = moveBadge( + this.lovelace!.config, + [...oldPath, oldIndex] as [number, number, number], + [...newPath, newIndex] as [number, number, number] + ); + this.lovelace!.saveConfig(newConfig); + } + + private _dragStart() { + this._dragging = true; + } + + private _dragEnd() { + this._dragging = false; + } + + private _addBadge() { + fireEvent(this, "ll-create-badge"); + } + + render() { + if (!this.lovelace) return nothing; + + const editMode = this.lovelace.editMode; + + const badges = this.badges; + + return html` + ${badges?.length > 0 || editMode + ? html` + +
+ ${repeat( + badges, + (badge) => this._getBadgeKey(badge), + (badge, idx) => html` +
+ ${editMode + ? html` + + ${badge} + + ` + : badge} +
+ ` + )} + ${editMode + ? html` + + ` + : nothing} +
+
+ ` + : nothing} + `; + } + + static get styles(): CSSResultGroup { + return css` + .badges { + display: flex; + align-items: flex-start; + flex-wrap: wrap; + justify-content: center; + gap: 8px; + margin: 0; + } + + .badge { + display: block; + position: relative; + } + + .add { + position: relative; + display: flex; + flex-direction: row; + align-items: center; + gap: 8px; + height: 36px; + padding: 6px 20px 6px 20px; + box-sizing: border-box; + width: auto; + border-radius: 18px; + background-color: transparent; + border-width: 2px; + border-style: dashed; + border-color: var(--primary-color); + --mdc-icon-size: 18px; + cursor: pointer; + color: var(--primary-text-color); + } + .add:focus { + border-style: solid; + } + `; + } +} diff --git a/src/panels/lovelace/views/hui-masonry-view.ts b/src/panels/lovelace/views/hui-masonry-view.ts index 3edf99193f8e..500bc441cf56 100644 --- a/src/panels/lovelace/views/hui-masonry-view.ts +++ b/src/panels/lovelace/views/hui-masonry-view.ts @@ -16,6 +16,7 @@ import type { LovelaceViewElement } from "../../../data/lovelace"; import type { LovelaceViewConfig } from "../../../data/lovelace/config/view"; import type { HomeAssistant } from "../../../types"; import { HuiBadge } from "../badges/hui-badge"; +import "../badges/hui-view-badges"; import { HuiCard } from "../cards/hui-card"; import { computeCardSize } from "../common/compute-card-size"; import type { Lovelace } from "../types"; @@ -79,9 +80,12 @@ export class MasonryView extends LitElement implements LovelaceViewElement { protected render(): TemplateResult { return html` - ${this.badges.length > 0 - ? html`
${this.badges}
` - : ""} +
(); - private _badgeConfigKeys = new WeakMap(); - - private _getBadgeKey(badge: HuiBadge) { - if (!this._badgeConfigKeys.has(badge)) { - this._badgeConfigKeys.set(badge, Math.random().toString()); - } - return this._badgeConfigKeys.get(badge)!; - } - private _getSectionKey(section: HuiSection) { if (!this._sectionConfigKeys.has(section)) { this._sectionConfigKeys.set(section, Math.random().toString()); @@ -115,65 +87,13 @@ export class SectionsView extends LitElement implements LovelaceViewElement { const maxColumnsCount = this._config?.max_columns; - const badges = this.badges; - return html` - ${badges?.length > 0 || editMode - ? html` - -
- ${repeat( - badges, - (badge) => this._getBadgeKey(badge), - (badge, idx) => html` -
- ${editMode - ? html` - - ${badge} - - ` - : badge} -
- ` - )} - ${editMode - ? html` - - ` - : nothing} -
-
- ` - : nothing} + * { position: relative; max-width: var(--column-max-width); @@ -455,27 +334,10 @@ export class SectionsView extends LitElement implements LovelaceViewElement { border-radius: var(--ha-card-border-radius, 12px); } - .add-badge { - position: relative; - display: flex; - flex-direction: row; - align-items: center; - gap: 8px; - height: 36px; - padding: 6px 20px 6px 20px; - box-sizing: border-box; - width: auto; - border-radius: 18px; - background-color: transparent; - border-width: 2px; - border-style: dashed; - border-color: var(--primary-color); - --mdc-icon-size: 18px; - cursor: pointer; - color: var(--primary-text-color); - } - .add-badge:focus { - border-style: solid; + hui-view-badges { + display: block; + margin: 16px 32px; + text-align: center; } `; }