Compare commits

..

1 Commits

Author SHA1 Message Date
Wendelin
402dd5c71b Use filter-chips for target picker 2025-10-15 17:20:35 +02:00
5 changed files with 33 additions and 69 deletions

View File

@@ -288,10 +288,7 @@ export class HaEntityNamePicker extends LitElement {
private _toItems = memoizeOne((value?: typeof this.value) => {
if (typeof value === "string") {
if (value === "") {
return [];
}
return [{ type: "text", text: value } satisfies EntityNameItem];
return [{ type: "text", text: value } as const];
}
return value ? ensureArray(value) : [];
});
@@ -299,7 +296,7 @@ export class HaEntityNamePicker extends LitElement {
private _toValue = memoizeOne(
(items: EntityNameItem[]): typeof this.value => {
if (items.length === 0) {
return "";
return [];
}
if (items.length === 1) {
const item = items[0];

View File

@@ -1,6 +1,6 @@
import type { LitVirtualizer } from "@lit-labs/virtualizer";
import { consume } from "@lit/context";
import { mdiCheck, mdiPlus, mdiTextureBox } from "@mdi/js";
import { mdiPlus, mdiTextureBox } from "@mdi/js";
import Fuse from "fuse.js";
import type { HassServiceTarget } from "home-assistant-js-websocket";
import { css, html, LitElement, nothing, type PropertyValues } from "lit";
@@ -43,9 +43,9 @@ import { haStyleScrollbar } from "../../resources/styles";
import { loadVirtualizer } from "../../resources/virtualizer";
import type { HomeAssistant } from "../../types";
import { brandsUrl } from "../../util/brands-url";
import "../chips/ha-filter-chip";
import type { HaDevicePickerDeviceFilterFunc } from "../device/ha-device-picker";
import "../entity/state-badge";
import "../ha-button";
import "../ha-combo-box-item";
import "../ha-floor-icon";
import "../ha-md-list";
@@ -430,21 +430,15 @@ export class HaTargetPickerSelector extends LitElement {
const selected = this.filterTypes.includes(filterType);
return html`
<ha-button
<ha-filter-chip
@click=${this._toggleFilter}
.type=${filterType}
size="small"
.variant=${selected ? "brand" : "neutral"}
appearance="filled"
no-shrink
>
${selected
? html`<ha-svg-icon slot="start" .path=${mdiCheck}></ha-svg-icon>`
: nothing}
${this.hass.localize(
.selected=${selected}
.label=${this.hass.localize(
`ui.components.target-picker.type.${filterType === "entity" ? "entities" : `${filterType}s`}` as LocalizeKeys
)}
</ha-button>
>
</ha-filter-chip>
`;
});
}
@@ -944,6 +938,7 @@ export class HaTargetPickerSelector extends LitElement {
}
private _toggleFilter(ev: any) {
ev.stopPropagation();
this._resetSelectedItem();
this._filterHeader = undefined;
const type = ev.target.type as TargetTypeFloorless;
@@ -997,15 +992,18 @@ export class HaTargetPickerSelector extends LitElement {
gap: var(--ha-space-2);
padding: var(--ha-space-3) var(--ha-space-3);
overflow: auto;
--ha-button-border-radius: var(--ha-border-radius-md);
}
:host([mode="dialog"]) .filter {
padding: var(--ha-space-3) var(--ha-space-4);
}
.filter ha-button {
.filter ha-filter-chip {
flex-shrink: 0;
--md-filter-chip-selected-container-color: var(
--ha-color-fill-primary-normal-hover
);
color: var(--primary-color);
}
.filter .separator {

View File

@@ -244,8 +244,7 @@ class HaConfigBackupSettings extends LitElement {
`
: nothing}
</div>
${!this.cloudStatus?.logged_in &&
isComponentLoaded(this.hass, "cloud")
${!this.cloudStatus?.logged_in
? html`<ha-card class="cloud-info">
<div class="cloud-header">
<img
@@ -280,10 +279,7 @@ class HaConfigBackupSettings extends LitElement {
"ui.panel.config.voice_assistants.assistants.cloud.sign_in"
)}
</ha-button>
<ha-button
href="/config/cloud/register"
appearance="filled"
>
<ha-button href="/config/cloud/register">
${this.hass.localize(
"ui.panel.config.voice_assistants.assistants.cloud.try_one_month"
)}

View File

@@ -11,6 +11,7 @@ import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
import { stateActive } from "../../../common/entity/state_active";
import { stateColorCss } from "../../../common/entity/state_color";
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
import "../../../components/ha-badge";
import "../../../components/ha-ripple";
import "../../../components/ha-state-icon";
@@ -19,7 +20,6 @@ import { cameraUrlWithWidthHeight } from "../../../data/camera";
import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
import type { HomeAssistant } from "../../../types";
import { actionHandler } from "../common/directives/action-handler-directive";
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
import { findEntities } from "../common/find-entities";
import { handleAction } from "../common/handle-action";
import { hasAction } from "../common/has-action";
@@ -162,7 +162,11 @@ export class HuiEntityBadge extends LitElement implements LovelaceBadge {
if (!stateObj) {
return html`
<ha-badge .label=${entityId} class="error">
<ha-svg-icon slot="icon" .path=${mdiAlertCircle}></ha-svg-icon>
<ha-svg-icon
slot="icon"
.hass=${this.hass}
.path=${mdiAlertCircle}
></ha-svg-icon>
${this.hass.localize("ui.badge.entity.not_found")}
</ha-badge>
`;
@@ -175,22 +179,22 @@ export class HuiEntityBadge extends LitElement implements LovelaceBadge {
"--badge-color": color,
};
const name = computeLovelaceEntityName(
this.hass,
stateObj,
this._config.name
);
const stateDisplay = html`
<state-display
.stateObj=${stateObj}
.hass=${this.hass}
.content=${this._config.state_content}
.name=${name}
.name=${this._config.name}
>
</state-display>
`;
const name = computeLovelaceEntityName(
this.hass,
stateObj,
this._config.name
);
const showState = this._config.show_state;
const showName = this._config.show_name;
const showIcon = this._config.show_icon;

View File

@@ -1,12 +1,8 @@
import { css, LitElement, nothing } from "lit";
import type { PropertyValues } from "lit";
import { customElement, property, state } from "lit/decorators";
import { customElement, property } from "lit/decorators";
import type { HomeAssistant } from "../../../types";
import type { LovelaceViewBackgroundConfig } from "../../../data/lovelace/config/view";
import {
isMediaSourceContentId,
resolveMediaSource,
} from "../../../data/media_source";
@customElement("hui-view-background")
export class HUIViewBackground extends LitElement {
@@ -17,27 +13,10 @@ export class HUIViewBackground extends LitElement {
| LovelaceViewBackgroundConfig
| undefined;
@state({ attribute: false }) resolvedImage?: string;
protected render() {
return nothing;
}
private _fetchMedia() {
const backgroundImage =
typeof this.background === "string"
? this.background
: this.background?.image;
if (backgroundImage && isMediaSourceContentId(backgroundImage)) {
resolveMediaSource(this.hass, backgroundImage).then((result) => {
this.resolvedImage = result.url;
});
} else {
this.resolvedImage = undefined;
}
}
private _applyTheme() {
const computedStyles = getComputedStyle(this);
const themeBackground = computedStyles.getPropertyValue(
@@ -73,19 +52,13 @@ export class HUIViewBackground extends LitElement {
background?: string | LovelaceViewBackgroundConfig
) {
if (typeof background === "object" && background.image) {
if (isMediaSourceContentId(background.image) && !this.resolvedImage) {
return null;
}
const alignment = background.alignment ?? "center";
const size = background.size ?? "cover";
const repeat = background.repeat ?? "no-repeat";
return `${alignment} / ${size} ${repeat} url('${this.hass.hassUrl(this.resolvedImage || background.image)}')`;
return `${alignment} / ${size} ${repeat} url('${this.hass.hassUrl(background.image)}')`;
}
if (typeof background === "string") {
if (isMediaSourceContentId(background) && !this.resolvedImage) {
return null;
}
return this.resolvedImage || background;
return background;
}
return null;
}
@@ -117,10 +90,6 @@ export class HUIViewBackground extends LitElement {
if (changedProperties.has("background")) {
this._applyTheme();
this._fetchMedia();
}
if (changedProperties.has("resolvedImage")) {
this._applyTheme();
}
}