1
0
mirror of https://github.com/home-assistant/frontend.git synced 2026-02-14 23:18:21 +00:00

ha-label-picker: add color badges (#28977)

Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
This commit is contained in:
ildar170975
2026-01-22 15:04:17 +03:00
committed by GitHub
parent 0d110cfc7e
commit 3231d46835
4 changed files with 53 additions and 28 deletions

View File

@@ -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`<div
style=${styleMap({
backgroundColor: color ? computeCssColor(color) : undefined,
borderRadius: "var(--ha-border-radius-md)",
border: "1px solid var(--outline-color)",
boxSizing: "border-box",
width: "var(--ha-space-5)",
height: "var(--ha-space-5)",
})}
></div>`;
@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<LabelComboBoxItem> = (item) =>
html`<ha-combo-box-item type="button" compact>
${DEFAULT_ROW_RENDERER_CONTENT(item)}
${item.id !== ADD_NEW_ID
? html`<div slot="trailing-supporting-text">
${renderLabelColorBadge(item.color)}
</div>`
: nothing}
</ha-combo-box-item>`;
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}
>

View File

@@ -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<PickerComboBoxItem> = (
item
) => html`
<ha-combo-box-item type="button" compact>
${item.icon
export const DEFAULT_ROW_RENDERER_CONTENT = (item: PickerComboBoxItem) =>
html` ${item.icon
? html`<ha-icon slot="start" .icon=${item.icon}></ha-icon>`
: item.icon_path
? html`<ha-svg-icon slot="start" .path=${item.icon_path}></ha-svg-icon>`
@@ -71,9 +68,12 @@ const DEFAULT_ROW_RENDERER: RenderItemFunction<PickerComboBoxItem> = (
<span slot="headline">${item.primary}</span>
${item.secondary
? html`<span slot="supporting-text">${item.secondary}</span>`
: nothing}
</ha-combo-box-item>
`;
: nothing}`;
const DEFAULT_ROW_RENDERER: RenderItemFunction<PickerComboBoxItem> = (item) =>
html`<ha-combo-box-item type="button" compact>
${DEFAULT_ROW_RENDERER_CONTENT(item)}
</ha-combo-box-item>`;
export type PickerComboBoxSearchFn<T extends PickerComboBoxItem> = (
search: string,

View File

@@ -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<PickerComboBoxItem>((label) => ({
const items = outputLabels.map<LabelComboBoxItem>((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;

View File

@@ -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`<div
style=${styleMap({
backgroundColor: label.color
? computeCssColor(label.color)
: undefined,
borderRadius: "var(--ha-border-radius-md)",
border: "1px solid var(--outline-color)",
boxSizing: "border-box",
width: "var(--ha-space-5)",
height: "var(--ha-space-5)",
})}
></div>`,
template: (label) => renderLabelColorBadge(label.color ?? undefined),
},
name: {
title: localize("ui.panel.config.labels.headers.name"),