import type { TemplateResult } from "lit"; import { css, html, LitElement, nothing } from "lit"; import { customElement, property } from "lit/decorators"; import { repeat } from "lit/directives/repeat"; import type { LabelRegistryEntry } from "../../data/label_registry"; import { computeCssColor } from "../../common/color/compute-color"; import { fireEvent } from "../../common/dom/fire_event"; import "../ha-label"; import { stringCompare } from "../../common/string/compare"; import "../chips/ha-chip-set"; import "../ha-button-menu"; import "../ha-icon"; import "../ha-list-item"; @customElement("ha-data-table-labels") class HaDataTableLabels extends LitElement { @property({ attribute: false }) public labels!: LabelRegistryEntry[]; protected render(): TemplateResult { const labels = this.labels.sort((a, b) => stringCompare(a.name, b.name)); return html` ${repeat( labels.slice(0, 2), (label) => label.label_id, (label) => this._renderLabel(label, true) )} ${labels.length > 2 ? html` +${labels.length - 2} ${repeat( labels.slice(2), (label) => label.label_id, (label) => html` ${this._renderLabel(label, false)} ` )} ` : nothing} `; } private _renderLabel(label: LabelRegistryEntry, clickAction: boolean) { const color = label?.color ? computeCssColor(label.color) : undefined; return html` ${label?.icon ? html`` : nothing} ${label.name} `; } private _labelClicked(ev) { ev.stopPropagation(); if (ev.type === "keydown" && ev.key !== "Enter" && ev.key !== " ") { return; } const label = (ev.currentTarget as any).item as LabelRegistryEntry; fireEvent(this, "label-clicked", { label }); } protected _handleIconOverflowMenuOpened(e) { e.stopPropagation(); // If this component is used inside a data table, the z-index of the row // needs to be increased. Otherwise the ha-button-menu would be displayed // underneath the next row in the table. const row = this.closest(".mdc-data-table__row") as HTMLDivElement | null; if (row) { row.style.zIndex = "1"; } } protected _handleIconOverflowMenuClosed() { const row = this.closest(".mdc-data-table__row") as HTMLDivElement | null; if (row) { row.style.zIndex = ""; } } static styles = css` :host { display: block; flex-grow: 1; margin-top: 4px; height: 22px; } ha-chip-set { position: fixed; flex-wrap: nowrap; } ha-label { --ha-label-background-color: var(--color, var(--grey-color)); --ha-label-background-opacity: 0.5; } ha-button-menu { border-radius: 10px; } .plus { --ha-label-background-color: transparent; border: 1px solid var(--divider-color); } `; } declare global { interface HTMLElementTagNameMap { "ha-data-table-labels": HaDataTableLabels; } interface HASSDomEvents { "label-clicked": { label: LabelRegistryEntry }; } }