diff --git a/src/components/ha-label-picker.ts b/src/components/ha-label-picker.ts index 45219965a2..21f2a98d19 100644 --- a/src/components/ha-label-picker.ts +++ b/src/components/ha-label-picker.ts @@ -1,7 +1,7 @@ import { mdiPlus } from "@mdi/js"; import type { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket"; import type { TemplateResult } from "lit"; -import { LitElement, html } from "lit"; +import { LitElement, html, nothing } from "lit"; import { customElement, property, @@ -9,9 +9,16 @@ import { queryAssignedElements, state, } from "lit/decorators"; +import { styleMap } from "lit/directives/style-map"; +import type { RenderItemFunction } from "@lit-labs/virtualizer/virtualize"; import memoizeOne from "memoize-one"; +import { computeCssColor } from "../common/color/compute-color"; import { fireEvent } from "../common/dom/fire_event"; -import { getLabels, labelComboBoxKeys } from "../data/label/label_picker"; +import { + getLabels, + labelComboBoxKeys, + type LabelComboBoxItem, +} from "../data/label/label_picker"; import { createLabelRegistryEntry, subscribeLabelRegistry, @@ -24,11 +31,26 @@ import type { HomeAssistant, ValueChangedEvent } from "../types"; import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker"; import "./ha-generic-picker"; import type { HaGenericPicker } from "./ha-generic-picker"; -import type { PickerComboBoxItem } from "./ha-picker-combo-box"; +import { + type PickerComboBoxItem, + DEFAULT_ROW_RENDERER_CONTENT, +} from "./ha-picker-combo-box"; import "./ha-svg-icon"; const ADD_NEW_ID = "___ADD_NEW___"; +export const renderLabelColorBadge = (color: string | undefined) => + html`
`; + @customElement("ha-label-picker") export class HaLabelPicker extends SubscribeMixin(LitElement) { @property({ attribute: false }) public hass!: HomeAssistant; @@ -106,6 +128,16 @@ export class HaLabelPicker extends SubscribeMixin(LitElement) { ]; } + private _rowRenderer: RenderItemFunction = (item) => + html` + ${DEFAULT_ROW_RENDERER_CONTENT(item)} + ${item.id !== ADD_NEW_ID + ? html`
+ ${renderLabelColorBadge(item.color)} +
` + : nothing} +
`; + private _getLabelsMemoized = memoizeOne(getLabels); private _getItems = () => @@ -190,6 +222,7 @@ export class HaLabelPicker extends SubscribeMixin(LitElement) { .value=${this.value} .getItems=${this._getItems} .getAdditionalItems=${this._getAdditionalItems} + .rowRenderer=${this._rowRenderer} .searchKeys=${labelComboBoxKeys} @value-changed=${this._valueChanged} > diff --git a/src/components/ha-picker-combo-box.ts b/src/components/ha-picker-combo-box.ts index 2016ba4e6c..36c1eef031 100644 --- a/src/components/ha-picker-combo-box.ts +++ b/src/components/ha-picker-combo-box.ts @@ -59,11 +59,8 @@ export interface PickerComboBoxItem { export const NO_ITEMS_AVAILABLE_ID = "___no_items_available___"; const PADDING_ID = "___padding___"; -const DEFAULT_ROW_RENDERER: RenderItemFunction = ( - item -) => html` - - ${item.icon +export const DEFAULT_ROW_RENDERER_CONTENT = (item: PickerComboBoxItem) => + html` ${item.icon ? html`` : item.icon_path ? html`` @@ -71,9 +68,12 @@ const DEFAULT_ROW_RENDERER: RenderItemFunction = ( ${item.primary} ${item.secondary ? html`${item.secondary}` - : nothing} - -`; + : nothing}`; + +const DEFAULT_ROW_RENDERER: RenderItemFunction = (item) => + html` + ${DEFAULT_ROW_RENDERER_CONTENT(item)} + `; export type PickerComboBoxSearchFn = ( search: string, diff --git a/src/data/label/label_picker.ts b/src/data/label/label_picker.ts index 9a53ade0e8..ba8f3863b4 100644 --- a/src/data/label/label_picker.ts +++ b/src/data/label/label_picker.ts @@ -28,6 +28,10 @@ export const labelComboBoxKeys: FuseWeightedKey[] = [ }, ]; +export interface LabelComboBoxItem extends PickerComboBoxItem { + color?: string; +} + export const getLabels = ( hassStates: HomeAssistant["states"], hassAreas: HomeAssistant["areas"], @@ -41,7 +45,7 @@ export const getLabels = ( entityFilter?: HaEntityPickerEntityFilterFunc, excludeLabels?: string[], idPrefix = "" -): PickerComboBoxItem[] => { +): LabelComboBoxItem[] => { if (!labels || labels.length === 0) { return []; } @@ -194,7 +198,7 @@ export const getLabels = ( ); } - const items = outputLabels.map((label) => ({ + const items = outputLabels.map((label) => ({ id: `${idPrefix}${label.label_id}`, primary: label.name, secondary: label.description ?? "", @@ -206,6 +210,7 @@ export const getLabels = ( description: label.description, id: label.label_id, }, + color: label.color || undefined, })); return items; diff --git a/src/panels/config/labels/ha-config-labels.ts b/src/panels/config/labels/ha-config-labels.ts index e4d8aaef28..edf4fce4df 100644 --- a/src/panels/config/labels/ha-config-labels.ts +++ b/src/panels/config/labels/ha-config-labels.ts @@ -11,9 +11,7 @@ import { import type { PropertyValues } from "lit"; import { LitElement, html, nothing } from "lit"; import { customElement, property, query, state } from "lit/decorators"; -import { styleMap } from "lit/directives/style-map"; import memoizeOne from "memoize-one"; -import { computeCssColor } from "../../../common/color/compute-color"; import { formatShortDateTime } from "../../../common/datetime/format_date_time"; import { storage } from "../../../common/decorators/storage"; import { navigate } from "../../../common/navigate"; @@ -46,6 +44,7 @@ import "../../../layouts/hass-tabs-subpage-data-table"; import type { HomeAssistant, Route } from "../../../types"; import { configSections } from "../ha-panel-config"; import { showLabelDetailDialog } from "./show-dialog-label-detail"; +import { renderLabelColorBadge } from "../../../components/ha-label-picker"; @customElement("ha-config-labels") export class HaConfigLabels extends LitElement { @@ -111,19 +110,7 @@ export class HaConfigLabels extends LitElement { showNarrow: true, label: localize("ui.panel.config.labels.headers.color"), type: "icon", - template: (label) => - html`
`, + template: (label) => renderLabelColorBadge(label.color ?? undefined), }, name: { title: localize("ui.panel.config.labels.headers.name"),