diff --git a/gallery/src/pages/components/ha-temp-color-picker.markdown b/gallery/src/pages/components/ha-temp-color-picker.markdown
deleted file mode 100644
index 3221e55ee8..0000000000
--- a/gallery/src/pages/components/ha-temp-color-picker.markdown
+++ /dev/null
@@ -1,3 +0,0 @@
----
-title: Temp Color Picker
----
diff --git a/gallery/src/pages/components/ha-temp-color-picker.ts b/gallery/src/pages/components/ha-temp-color-picker.ts
deleted file mode 100644
index d924e745bf..0000000000
--- a/gallery/src/pages/components/ha-temp-color-picker.ts
+++ /dev/null
@@ -1,117 +0,0 @@
-import "../../../../src/components/ha-temp-color-picker";
-
-import { css, html, LitElement, TemplateResult } from "lit";
-import { customElement, state } from "lit/decorators";
-
-import "../../../../src/components/ha-card";
-import "../../../../src/components/ha-slider";
-
-@customElement("demo-components-ha-temp-color-picker")
-export class DemoHaTempColorPicker extends LitElement {
- @state()
- min = 3000;
-
- @state()
- max = 7000;
-
- @state()
- value = 4000;
-
- @state()
- liveValue?: number;
-
- private _minChanged(ev) {
- this.min = Number(ev.target.value);
- }
-
- private _maxChanged(ev) {
- this.max = Number(ev.target.value);
- }
-
- private _valueChanged(ev) {
- this.value = Number(ev.target.value);
- }
-
- private _tempColorCursor(ev) {
- this.liveValue = ev.detail.value;
- }
-
- private _tempColorChanged(ev) {
- this.value = ev.detail.value;
- }
-
- protected render(): TemplateResult {
- return html`
-
-
-
${this.liveValue ?? this.value} K
-
-
Min temp : ${this.min} K
-
-
-
Max temp : ${this.max} K
-
-
-
Value : ${this.value} K
-
-
-
-
- `;
- }
-
- static get styles() {
- return css`
- ha-card {
- max-width: 600px;
- margin: 24px auto;
- }
- .card-content {
- display: flex;
- align-items: center;
- flex-direction: column;
- }
- ha-temp-color-picker {
- width: 400px;
- }
- .value {
- font-size: 22px;
- font-weight: bold;
- margin: 0 0 12px 0;
- }
- `;
- }
-}
-
-declare global {
- interface HTMLElementTagNameMap {
- "demo-components-ha-temp-color-picker": DemoHaTempColorPicker;
- }
-}
diff --git a/package.json b/package.json
index 38d22cf82d..d710f68019 100644
--- a/package.json
+++ b/package.json
@@ -181,12 +181,12 @@
"@types/mocha": "10.0.1",
"@types/qrcode": "1.5.1",
"@types/serve-handler": "6.1.1",
- "@types/sortablejs": "1.15.1",
+ "@types/sortablejs": "1.15.2",
"@types/tar": "6.1.5",
"@types/ua-parser-js": "0.7.36",
"@types/webspeechapi": "0.0.29",
- "@typescript-eslint/eslint-plugin": "6.4.1",
- "@typescript-eslint/parser": "6.4.1",
+ "@typescript-eslint/eslint-plugin": "6.5.0",
+ "@typescript-eslint/parser": "6.5.0",
"@web/dev-server": "0.1.38",
"@web/dev-server-rollup": "0.4.1",
"babel-loader": "9.1.3",
diff --git a/pyproject.toml b/pyproject.toml
index 72d455d5d1..bdc8363051 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "home-assistant-frontend"
-version = "20230831.0"
+version = "20230901.0"
license = {text = "Apache-2.0"}
description = "The Home Assistant frontend"
readme = "README.md"
diff --git a/src/common/number/format_number.ts b/src/common/number/format_number.ts
index dcbcd72d02..ddbe1765d4 100644
--- a/src/common/number/format_number.ts
+++ b/src/common/number/format_number.ts
@@ -108,7 +108,7 @@ export const formatNumber = (
* @returns An `Intl.NumberFormatOptions` object with `maximumFractionDigits` set to 0, or `undefined`
*/
export const getNumberFormatOptions = (
- entityState: HassEntity,
+ entityState?: HassEntity,
entity?: EntityRegistryDisplayEntry
): Intl.NumberFormatOptions | undefined => {
const precision = entity?.display_precision;
@@ -119,8 +119,8 @@ export const getNumberFormatOptions = (
};
}
if (
- Number.isInteger(Number(entityState.attributes?.step)) &&
- Number.isInteger(Number(entityState.state))
+ Number.isInteger(Number(entityState?.attributes?.step)) &&
+ Number.isInteger(Number(entityState?.state))
) {
return { maximumFractionDigits: 0 };
}
diff --git a/src/components/entity/ha-entity-state-picker.ts b/src/components/entity/ha-entity-state-picker.ts
index 688b38e6db..b14cbeaa2f 100644
--- a/src/components/entity/ha-entity-state-picker.ts
+++ b/src/components/entity/ha-entity-state-picker.ts
@@ -1,11 +1,9 @@
import { HassEntity } from "home-assistant-js-websocket";
-import { html, LitElement, PropertyValues, nothing } from "lit";
+import { LitElement, PropertyValues, html, nothing } from "lit";
import { customElement, property, query } from "lit/decorators";
import { fireEvent } from "../../common/dom/fire_event";
-import { computeStateDisplay } from "../../common/entity/compute_state_display";
import { getStates } from "../../common/entity/get_states";
-import { computeAttributeValueDisplay } from "../../common/entity/compute_attribute_display";
-import { ValueChangedEvent, HomeAssistant } from "../../types";
+import { HomeAssistant, ValueChangedEvent } from "../../types";
import "../ha-combo-box";
import type { HaComboBox } from "../ha-combo-box";
@@ -58,20 +56,9 @@ class HaEntityStatePicker extends LitElement {
? getStates(state, this.attribute).map((key) => ({
value: key,
label: !this.attribute
- ? computeStateDisplay(
- this.hass.localize,
+ ? this.hass.formatEntityState(state, key)
+ : this.hass.formatEntityAttributeValue(
state,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
- key
- )
- : computeAttributeValueDisplay(
- this.hass.localize,
- state,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
this.attribute,
key
),
diff --git a/src/components/entity/ha-state-label-badge.ts b/src/components/entity/ha-state-label-badge.ts
index 417ce42024..b340893f06 100644
--- a/src/components/entity/ha-state-label-badge.ts
+++ b/src/components/entity/ha-state-label-badge.ts
@@ -12,7 +12,6 @@ import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { arrayLiteralIncludes } from "../../common/array/literal-includes";
import secondsToDuration from "../../common/datetime/seconds_to_duration";
-import { computeStateDisplay } from "../../common/entity/compute_state_display";
import { computeStateDomain } from "../../common/entity/compute_state_domain";
import { computeStateName } from "../../common/entity/compute_state_name";
import { FIXED_DOMAIN_STATES } from "../../common/entity/get_states";
@@ -192,13 +191,7 @@ export class HaStateLabelBadge extends LitElement {
this.hass!.locale,
getNumberFormatOptions(entityState, entry)
)
- : computeStateDisplay(
- this.hass!.localize,
- entityState,
- this.hass!.locale,
- this.hass!.config,
- this.hass!.entities
- );
+ : this.hass!.formatEntityState(entityState);
}
}
diff --git a/src/components/ha-climate-state.ts b/src/components/ha-climate-state.ts
index 047407f7d3..ca5d3a00e9 100644
--- a/src/components/ha-climate-state.ts
+++ b/src/components/ha-climate-state.ts
@@ -1,9 +1,14 @@
-import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
+import {
+ css,
+ CSSResultGroup,
+ html,
+ LitElement,
+ nothing,
+ TemplateResult,
+} from "lit";
import { customElement, property } from "lit/decorators";
-import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display";
-import { computeStateDisplay } from "../common/entity/compute_state_display";
import { CLIMATE_PRESET_NONE, ClimateEntity } from "../data/climate";
-import { isUnavailableState } from "../data/entity";
+import { isUnavailableState, OFF } from "../data/entity";
import type { HomeAssistant } from "../types";
@customElement("ha-climate-state")
@@ -22,26 +27,24 @@ class HaClimateState extends LitElement {
${this.stateObj.attributes.preset_mode &&
this.stateObj.attributes.preset_mode !== CLIMATE_PRESET_NONE
? html`-
- ${computeAttributeValueDisplay(
- this.hass.localize,
+ ${this.hass.formatEntityAttributeValue(
this.stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
"preset_mode"
)}`
- : ""}
+ : nothing}
@@ -124,12 +125,12 @@ export class HaControlNumberButton extends LitElement {
id="input"
class="value"
role="number-button"
- tabindex="0"
+ .tabIndex=${this.disabled ? "-1" : "0"}
aria-valuenow=${this.value}
aria-valuemin=${this.min}
aria-valuemax=${this.max}
aria-label=${ifDefined(this.label)}
- .disabled=${this.disabled}
+ ?disabled=${this.disabled}
@keydown=${this._handleKeyDown}
>
${displayedValue}
@@ -240,6 +241,7 @@ export class HaControlNumberButton extends LitElement {
.button[disabled] {
opacity: 0.4;
pointer-events: none;
+ cursor: not-allowed;
}
.button.minus {
left: 0;
diff --git a/src/components/ha-control-select.ts b/src/components/ha-control-select.ts
index 855fc338a1..04ff1f9f2c 100644
--- a/src/components/ha-control-select.ts
+++ b/src/components/ha-control-select.ts
@@ -217,6 +217,7 @@ export class HaControlSelect extends LitElement {
transition: box-shadow 180ms ease-in-out;
font-style: normal;
font-weight: 500;
+ color: var(--primary-text-color);
user-select: none;
-webkit-tap-highlight-color: transparent;
}
@@ -267,7 +268,6 @@ export class HaControlSelect extends LitElement {
justify-content: center;
border-radius: var(--control-select-button-border-radius);
overflow: hidden;
- color: var(--primary-text-color);
/* For safari border-radius overflow */
z-index: 0;
}
@@ -331,6 +331,7 @@ export class HaControlSelect extends LitElement {
:host([disabled]) {
--control-select-color: var(--disabled-color);
--control-select-focused-opacity: 0;
+ color: var(--disabled-color);
}
:host([disabled]) .option {
cursor: not-allowed;
diff --git a/src/components/ha-hs-color-picker.ts b/src/components/ha-hs-color-picker.ts
index cef11cfc38..f492be2d7c 100644
--- a/src/components/ha-hs-color-picker.ts
+++ b/src/components/ha-hs-color-picker.ts
@@ -7,6 +7,12 @@ import { hsv2rgb, rgb2hex } from "../common/color/convert-color";
import { rgbw2rgb, rgbww2rgb } from "../common/color/convert-light-color";
import { fireEvent } from "../common/dom/fire_event";
+declare global {
+ interface HASSDomEvents {
+ "cursor-moved": { value?: any };
+ }
+}
+
function xy2polar(x: number, y: number) {
const r = Math.sqrt(x * x + y * y);
const phi = Math.atan2(y, x);
diff --git a/src/components/ha-humidifier-state.ts b/src/components/ha-humidifier-state.ts
index 63fd33037c..a2d6dc740b 100644
--- a/src/components/ha-humidifier-state.ts
+++ b/src/components/ha-humidifier-state.ts
@@ -1,7 +1,5 @@
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
-import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display";
-import { computeStateDisplay } from "../common/entity/compute_state_display";
import { isUnavailableState, OFF } from "../data/entity";
import { HumidifierEntity } from "../data/humidifier";
import type { HomeAssistant } from "../types";
@@ -21,12 +19,8 @@ class HaHumidifierState extends LitElement {
${this._localizeState()}
${this.stateObj.attributes.mode
? html`-
- ${computeAttributeValueDisplay(
- this.hass.localize,
+ ${this.hass.formatEntityAttributeValue(
this.stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
"mode"
)}`
: ""}
@@ -78,24 +72,17 @@ class HaHumidifierState extends LitElement {
return this.hass.localize(`state.default.${this.stateObj.state}`);
}
- const stateString = computeStateDisplay(
- this.hass.localize,
- this.stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities
- );
+ const stateString = this.hass.formatEntityState(this.stateObj);
- return this.stateObj.attributes.action && this.stateObj.state !== OFF
- ? `${computeAttributeValueDisplay(
- this.hass.localize,
- this.stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
- "action"
- )} (${stateString})`
- : stateString;
+ if (this.stateObj.attributes.action && this.stateObj.state !== OFF) {
+ const actionString = this.hass.formatEntityAttributeValue(
+ this.stateObj,
+ "action"
+ );
+ return `${actionString} (${stateString})`;
+ }
+
+ return stateString;
}
static get styles(): CSSResultGroup {
diff --git a/src/components/ha-temp-color-picker.ts b/src/components/ha-temp-color-picker.ts
deleted file mode 100644
index ce471c207f..0000000000
--- a/src/components/ha-temp-color-picker.ts
+++ /dev/null
@@ -1,440 +0,0 @@
-import { DIRECTION_ALL, Manager, Pan, Tap } from "@egjs/hammerjs";
-import { LitElement, PropertyValues, css, html, svg } from "lit";
-import { customElement, property, query, state } from "lit/decorators";
-import { classMap } from "lit/directives/class-map";
-import { styleMap } from "lit/directives/style-map";
-import { rgb2hex } from "../common/color/convert-color";
-import {
- DEFAULT_MAX_KELVIN,
- DEFAULT_MIN_KELVIN,
- temperature2rgb,
-} from "../common/color/convert-light-color";
-import { fireEvent } from "../common/dom/fire_event";
-
-const SAFE_ZONE_FACTOR = 0.9;
-
-declare global {
- interface HASSDomEvents {
- "cursor-moved": { value?: any };
- }
-}
-
-const A11Y_KEY_CODES = new Set([
- "ArrowRight",
- "ArrowUp",
- "ArrowLeft",
- "ArrowDown",
- "PageUp",
- "PageDown",
- "Home",
- "End",
-]);
-
-function xy2polar(x: number, y: number) {
- const r = Math.sqrt(x * x + y * y);
- const phi = Math.atan2(y, x);
- return [r, phi];
-}
-
-function polar2xy(r: number, phi: number) {
- const x = Math.cos(phi) * r;
- const y = Math.sin(phi) * r;
- return [x, y];
-}
-
-function drawColorWheel(
- ctx: CanvasRenderingContext2D,
- minTemp: number,
- maxTemp: number
-) {
- ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
- const radius = ctx.canvas.width / 2;
-
- const min = Math.max(minTemp, 2000);
- const max = Math.min(maxTemp, 40000);
-
- for (let y = -radius; y < radius; y += 1) {
- const x = radius * Math.sqrt(1 - (y / radius) ** 2);
-
- const fraction = (y / (radius * SAFE_ZONE_FACTOR) + 1) / 2;
-
- const temperature = Math.max(
- Math.min(min + fraction * (max - min), max),
- min
- );
-
- const color = rgb2hex(temperature2rgb(temperature));
-
- ctx.fillStyle = color;
- ctx.fillRect(radius - x, radius + y - 0.5, 2 * x, 2);
- ctx.fill();
- }
-}
-
-@customElement("ha-temp-color-picker")
-class HaTempColorPicker extends LitElement {
- @property({ type: Boolean, reflect: true })
- public disabled = false;
-
- @property({ type: Number, attribute: false })
- public renderSize?: number;
-
- @property({ type: Number })
- public value?: number;
-
- @property({ type: Number })
- public min = DEFAULT_MIN_KELVIN;
-
- @property({ type: Number })
- public max = DEFAULT_MAX_KELVIN;
-
- @query("#canvas") private _canvas!: HTMLCanvasElement;
-
- private _mc?: HammerManager;
-
- @state()
- private _pressed?: string;
-
- @state()
- private _cursorPosition?: [number, number];
-
- @state()
- private _localValue?: number;
-
- protected firstUpdated(changedProps: PropertyValues): void {
- super.firstUpdated(changedProps);
- this._setupListeners();
- this._generateColorWheel();
- this.setAttribute("role", "slider");
- this.setAttribute("aria-orientation", "vertical");
- if (!this.hasAttribute("tabindex")) {
- this.setAttribute("tabindex", "0");
- }
- }
-
- private _generateColorWheel() {
- const ctx = this._canvas.getContext("2d")!;
- drawColorWheel(ctx, this.min, this.max);
- }
-
- connectedCallback(): void {
- super.connectedCallback();
- this._setupListeners();
- }
-
- disconnectedCallback(): void {
- super.disconnectedCallback();
- this._destroyListeners();
- }
-
- protected updated(changedProps: PropertyValues): void {
- super.updated(changedProps);
- if (changedProps.has("_localValue")) {
- this.setAttribute("aria-valuenow", this._localValue?.toString() ?? "");
- }
- if (changedProps.has("min") || changedProps.has("max")) {
- this._generateColorWheel();
- this._resetPosition();
- }
- if (changedProps.has("min")) {
- this.setAttribute("aria-valuemin", this.min.toString());
- }
- if (changedProps.has("max")) {
- this.setAttribute("aria-valuemax", this.max.toString());
- }
- if (changedProps.has("value")) {
- if (this._localValue !== this.value) {
- this._resetPosition();
- }
- }
- }
-
- private _setupListeners() {
- if (this._canvas && !this._mc) {
- this._mc = new Manager(this._canvas);
- this._mc.add(
- new Pan({
- direction: DIRECTION_ALL,
- enable: true,
- threshold: 0,
- })
- );
-
- this._mc.add(new Tap({ event: "singletap" }));
-
- let savedPosition;
- this._mc.on("panstart", (e) => {
- if (this.disabled) return;
- this._pressed = e.pointerType;
- savedPosition = this._cursorPosition;
- });
- this._mc.on("pancancel", () => {
- if (this.disabled) return;
- this._pressed = undefined;
- this._cursorPosition = savedPosition;
- });
- this._mc.on("panmove", (e) => {
- if (this.disabled) return;
- this._cursorPosition = this._getPositionFromEvent(e);
- this._localValue = this._getValueFromCoord(...this._cursorPosition);
- fireEvent(this, "cursor-moved", { value: this._localValue });
- });
- this._mc.on("panend", (e) => {
- if (this.disabled) return;
- this._pressed = undefined;
- this._cursorPosition = this._getPositionFromEvent(e);
- this._localValue = this._getValueFromCoord(...this._cursorPosition);
- fireEvent(this, "cursor-moved", { value: undefined });
- fireEvent(this, "value-changed", { value: this._localValue });
- });
-
- this._mc.on("singletap", (e) => {
- if (this.disabled) return;
- this._cursorPosition = this._getPositionFromEvent(e);
- this._localValue = this._getValueFromCoord(...this._cursorPosition);
- fireEvent(this, "value-changed", { value: this._localValue });
- });
-
- this.addEventListener("keydown", this._handleKeyDown);
- this.addEventListener("keyup", this._handleKeyUp);
- }
- }
-
- private _resetPosition() {
- if (this.value === undefined) {
- this._cursorPosition = undefined;
- this._localValue = undefined;
- return;
- }
- const [, y] = this._getCoordsFromValue(this.value);
- const currentX = this._cursorPosition?.[0] ?? 0;
- const x =
- Math.sign(currentX) * Math.min(Math.sqrt(1 - y ** 2), Math.abs(currentX));
- this._cursorPosition = [x, y];
- this._localValue = this.value;
- }
-
- private _getCoordsFromValue = (temperature: number): [number, number] => {
- if (this.value === this.min) {
- return [0, -1];
- }
- if (this.value === this.max) {
- return [0, 1];
- }
- const fraction = (temperature - this.min) / (this.max - this.min);
- const y = (2 * fraction - 1) * SAFE_ZONE_FACTOR;
- return [0, y];
- };
-
- private _getValueFromCoord = (_x: number, y: number): number => {
- const fraction = (y / SAFE_ZONE_FACTOR + 1) / 2;
- const temperature = Math.max(
- Math.min(this.min + fraction * (this.max - this.min), this.max),
- this.min
- );
- return Math.round(temperature);
- };
-
- private _getPositionFromEvent = (e: HammerInput): [number, number] => {
- const x = e.center.x;
- const y = e.center.y;
- const boundingRect = e.target.getBoundingClientRect();
- const offsetX = boundingRect.left;
- const offsetY = boundingRect.top;
- const maxX = e.target.clientWidth;
- const maxY = e.target.clientHeight;
-
- const _x = (2 * (x - offsetX)) / maxX - 1;
- const _y = (2 * (y - offsetY)) / maxY - 1;
-
- const [r, phi] = xy2polar(_x, _y);
- const [__x, __y] = polar2xy(Math.min(1, r), phi);
- return [__x, __y];
- };
-
- private _destroyListeners() {
- if (this._mc) {
- this._mc.destroy();
- this._mc = undefined;
- }
- this.removeEventListener("keydown", this._handleKeyDown);
- this.removeEventListener("keyup", this._handleKeyDown);
- }
-
- _handleKeyDown(e: KeyboardEvent) {
- if (!A11Y_KEY_CODES.has(e.code)) return;
- e.preventDefault();
-
- const step = 1;
- const tenPercentStep = Math.max(step, (this.max - this.min) / 10);
- const currentValue =
- this._localValue ?? Math.round((this.max + this.min) / 2);
- switch (e.code) {
- case "ArrowRight":
- case "ArrowUp":
- this._localValue = Math.round(Math.min(currentValue + step, this.max));
- break;
- case "ArrowLeft":
- case "ArrowDown":
- this._localValue = Math.round(Math.max(currentValue - step, this.min));
- break;
- case "PageUp":
- this._localValue = Math.round(
- Math.min(currentValue + tenPercentStep, this.max)
- );
- break;
- case "PageDown":
- this._localValue = Math.round(
- Math.max(currentValue - tenPercentStep, this.min)
- );
- break;
- case "Home":
- this._localValue = this.min;
- break;
- case "End":
- this._localValue = this.max;
- break;
- }
- if (this._localValue != null) {
- const [_, y] = this._getCoordsFromValue(this._localValue);
- const currentX = this._cursorPosition?.[0] ?? 0;
- const x =
- Math.sign(currentX) *
- Math.min(Math.sqrt(1 - y ** 2), Math.abs(currentX));
- this._cursorPosition = [x, y];
- fireEvent(this, "cursor-moved", { value: this._localValue });
- }
- }
-
- _handleKeyUp(e: KeyboardEvent) {
- if (!A11Y_KEY_CODES.has(e.code)) return;
- e.preventDefault();
- this.value = this._localValue;
- fireEvent(this, "value-changed", { value: this._localValue });
- }
-
- render() {
- const size = this.renderSize || 400;
- const canvasSize = size * window.devicePixelRatio;
-
- const rgb = temperature2rgb(
- this._localValue ?? Math.round((this.max + this.min) / 2)
- );
-
- const [x, y] = this._cursorPosition ?? [0, 0];
-
- const cx = ((x + 1) * size) / 2;
- const cy = ((y + 1) * size) / 2;
-
- const markerPosition = `${cx}px, ${cy}px`;
- const markerScale = this._pressed
- ? this._pressed === "touch"
- ? "2.5"
- : "1.5"
- : "1";
- const markerOffset =
- this._pressed === "touch" ? `0px, -${size / 16}px` : "0px, 0px";
-
- return html`
-
-
-
-
- `;
- }
-
- renderSVGFilter() {
- return svg`
-
-
-
-
- `;
- }
-
- static get styles() {
- return css`
- :host {
- display: block;
- outline: none;
- }
- .container {
- position: relative;
- width: 100%;
- height: 100%;
- display: flex;
- }
- canvas {
- width: 100%;
- height: 100%;
- object-fit: contain;
- border-radius: 50%;
- transition: box-shadow 180ms ease-in-out;
- cursor: pointer;
- }
- :host(:focus-visible) canvas {
- box-shadow: 0 0 0 2px rgb(255, 160, 0);
- }
- svg {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- pointer-events: none;
- }
- circle {
- fill: black;
- stroke: white;
- stroke-width: 2;
- filter: url(#marker-shadow);
- }
- .container:not(.pressed) circle {
- transition:
- transform 100ms ease-in-out,
- fill 100ms ease-in-out;
- }
- .container:not(.pressed) .cursor {
- transition: transform 200ms ease-in-out;
- }
- `;
- }
-}
-
-declare global {
- interface HTMLElementTagNameMap {
- "ha-temp-color-picker": HaTempColorPicker;
- }
-}
diff --git a/src/components/ha-water_heater-state.js b/src/components/ha-water_heater-state.js
index 4f2220fc58..2d768acfd2 100644
--- a/src/components/ha-water_heater-state.js
+++ b/src/components/ha-water_heater-state.js
@@ -1,7 +1,6 @@
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
-import { computeStateDisplay } from "../common/entity/compute_state_display";
import { formatNumber } from "../common/number/format_number";
import LocalizeMixin from "../mixins/localize-mixin";
@@ -84,12 +83,7 @@ class HaWaterHeaterState extends LocalizeMixin(PolymerElement) {
}
_localizeState(stateObj) {
- return computeStateDisplay(
- this.hass.localize,
- stateObj,
- this.hass.locale,
- this.hass.entities
- );
+ return this.hass.formatEntityState(stateObj);
}
}
customElements.define("ha-water_heater-state", HaWaterHeaterState);
diff --git a/src/data/automation_i18n.ts b/src/data/automation_i18n.ts
index f0bf51c55c..244fad1ba3 100644
--- a/src/data/automation_i18n.ts
+++ b/src/data/automation_i18n.ts
@@ -6,11 +6,7 @@ import {
formatTimeWithSeconds,
} from "../common/datetime/format_time";
import secondsToDuration from "../common/datetime/seconds_to_duration";
-import {
- computeAttributeNameDisplay,
- computeAttributeValueDisplay,
-} from "../common/entity/compute_attribute_display";
-import { computeStateDisplay } from "../common/entity/compute_state_display";
+import { computeAttributeNameDisplay } from "../common/entity/compute_attribute_display";
import { computeStateName } from "../common/entity/compute_state_name";
import "../resources/intl-polyfill";
import type { HomeAssistant } from "../types";
@@ -235,23 +231,14 @@ const tryDescribeTrigger = (
for (const state of trigger.from.values()) {
from.push(
trigger.attribute
- ? computeAttributeValueDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- trigger.attribute,
- state
- ).toString()
- : computeStateDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- state
- )
+ ? hass
+ .formatEntityAttributeValue(
+ stateObj,
+ trigger.attribute,
+ state
+ )
+ .toString()
+ : hass.formatEntityState(stateObj, state)
);
}
if (from.length !== 0) {
@@ -261,23 +248,16 @@ const tryDescribeTrigger = (
} else {
base += ` from ${
trigger.attribute
- ? computeAttributeValueDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- trigger.attribute,
- trigger.from
- ).toString()
- : computeStateDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- trigger.from.toString()
- ).toString()
+ ? hass
+ .formatEntityAttributeValue(
+ stateObj,
+ trigger.attribute,
+ trigger.from
+ )
+ .toString()
+ : hass
+ .formatEntityState(stateObj, trigger.from.toString())
+ .toString()
}`;
}
}
@@ -292,23 +272,14 @@ const tryDescribeTrigger = (
for (const state of trigger.to.values()) {
to.push(
trigger.attribute
- ? computeAttributeValueDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- trigger.attribute,
- state
- ).toString()
- : computeStateDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- state
- ).toString()
+ ? hass
+ .formatEntityAttributeValue(
+ stateObj,
+ trigger.attribute,
+ state
+ )
+ .toString()
+ : hass.formatEntityState(stateObj, state).toString()
);
}
if (to.length !== 0) {
@@ -318,23 +289,14 @@ const tryDescribeTrigger = (
} else {
base += ` to ${
trigger.attribute
- ? computeAttributeValueDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- trigger.attribute,
- trigger.to
- ).toString()
- : computeStateDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- trigger.to.toString()
- )
+ ? hass
+ .formatEntityAttributeValue(
+ stateObj,
+ trigger.attribute,
+ trigger.to
+ )
+ .toString()
+ : hass.formatEntityState(stateObj, trigger.to.toString())
}`;
}
}
@@ -822,45 +784,27 @@ const tryDescribeCondition = (
for (const state of condition.state.values()) {
states.push(
condition.attribute
- ? computeAttributeValueDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- condition.attribute,
- state
- ).toString()
- : computeStateDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- state
- )
+ ? hass
+ .formatEntityAttributeValue(
+ stateObj,
+ condition.attribute,
+ state
+ )
+ .toString()
+ : hass.formatEntityState(stateObj, state)
);
}
} else if (condition.state !== "") {
states.push(
condition.attribute
- ? computeAttributeValueDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- condition.attribute,
- condition.state
- ).toString()
- : computeStateDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- condition.state.toString()
- )
+ ? hass
+ .formatEntityAttributeValue(
+ stateObj,
+ condition.attribute,
+ condition.state
+ )
+ .toString()
+ : hass.formatEntityState(stateObj, condition.state.toString())
);
}
diff --git a/src/data/logbook.ts b/src/data/logbook.ts
index e4990da292..8534d548ce 100644
--- a/src/data/logbook.ts
+++ b/src/data/logbook.ts
@@ -5,14 +5,12 @@ import {
DOMAINS_WITH_DYNAMIC_PICTURE,
} from "../common/const";
import { computeDomain } from "../common/entity/compute_domain";
-import { computeStateDisplay } from "../common/entity/compute_state_display";
import { computeStateDomain } from "../common/entity/compute_state_domain";
import { autoCaseNoun } from "../common/translations/auto_case_noun";
import { LocalizeFunc } from "../common/translations/localize";
import { HaEntityPickerEntityFilterFunc } from "../components/entity/ha-entity-picker";
import { HomeAssistant } from "../types";
import { UNAVAILABLE, UNKNOWN } from "./entity";
-import { computeAttributeValueDisplay } from "../common/entity/compute_attribute_display";
const LOGBOOK_LOCALIZE_PATH = "ui.components.logbook.messages";
export const CONTINUOUS_DOMAINS = ["counter", "proximity", "sensor", "zone"];
@@ -339,14 +337,9 @@ export const localizeStateMessage = (
// TODO: This is not working yet, as we don't get historic attribute values
- const event_type = computeAttributeValueDisplay(
- hass!.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- "event_type"
- )?.toString();
+ const event_type = hass
+ .formatEntityAttributeValue(stateObj, "event_type")
+ ?.toString();
if (!event_type) {
return localize(`${LOGBOOK_LOCALIZE_PATH}.detected_unknown_event`);
@@ -392,16 +385,7 @@ export const localizeStateMessage = (
return hass.localize(
`${LOGBOOK_LOCALIZE_PATH}.changed_to_state`,
"state",
- stateObj
- ? computeStateDisplay(
- localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities,
- state
- )
- : state
+ stateObj ? hass.formatEntityState(stateObj, state) : state
);
};
diff --git a/src/data/timer.ts b/src/data/timer.ts
index 5401175d41..7dc4f8e41d 100644
--- a/src/data/timer.ts
+++ b/src/data/timer.ts
@@ -5,7 +5,6 @@ import {
} from "home-assistant-js-websocket";
import durationToSeconds from "../common/datetime/duration_to_seconds";
import secondsToDuration from "../common/datetime/seconds_to_duration";
-import { computeStateDisplay } from "../common/entity/compute_state_display";
import { HomeAssistant } from "../types";
export type TimerEntity = HassEntityBase & {
@@ -90,25 +89,13 @@ export const computeDisplayTimer = (
}
if (stateObj.state === "idle" || timeRemaining === 0) {
- return computeStateDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities
- );
+ return hass.formatEntityState(stateObj);
}
let display = secondsToDuration(timeRemaining || 0);
if (stateObj.state === "paused") {
- display = `${display} (${computeStateDisplay(
- hass.localize,
- stateObj,
- hass.locale,
- hass.config,
- hass.entities
- )})`;
+ display = `${display} (${hass.formatEntityState(stateObj)})`;
}
return display;
diff --git a/src/dialogs/config-flow/previews/entity-preview-row.ts b/src/dialogs/config-flow/previews/entity-preview-row.ts
index 1ca2b10c13..760366c61a 100644
--- a/src/dialogs/config-flow/previews/entity-preview-row.ts
+++ b/src/dialogs/config-flow/previews/entity-preview-row.ts
@@ -1,7 +1,6 @@
import { HassEntity } from "home-assistant-js-websocket";
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
import { customElement, property, state } from "lit/decorators";
-import { computeStateDisplay } from "../../../common/entity/compute_state_display";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { isUnavailableState } from "../../../data/entity";
import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor";
@@ -21,6 +20,7 @@ class EntityPreviewRow extends LitElement {
return html`
${computeStateName(stateObj)}
@@ -35,13 +35,7 @@ class EntityPreviewRow extends LitElement {
capitalize
>
`
- : computeStateDisplay(
- this.hass!.localize,
- stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities
- )}
+ : this.hass.formatEntityState(stateObj)}
`;
}
diff --git a/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts b/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts
index 25a18f810d..f0b1954f55 100644
--- a/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts
+++ b/src/dialogs/more-info/components/climate/ha-more-info-climate-temperature.ts
@@ -11,7 +11,6 @@ import { customElement, property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { styleMap } from "lit/directives/style-map";
import { UNIT_F } from "../../../../common/const";
-import { computeAttributeValueDisplay } from "../../../../common/entity/compute_attribute_display";
import { stateActive } from "../../../../common/entity/state_active";
import { stateColorCss } from "../../../../common/entity/state_color";
import { supportsFeature } from "../../../../common/entity/supports-feature";
@@ -162,14 +161,10 @@ export class HaMoreInfoClimateTemperature extends LitElement {
const action = this.stateObj.attributes.hvac_action;
- const actionLabel = computeAttributeValueDisplay(
- this.hass.localize,
+ const actionLabel = this.hass.formatEntityAttributeValue(
this.stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
"hvac_action"
- ) as string;
+ );
return html`
diff --git a/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts b/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts
index 72333bd2a2..d1a641d6c5 100644
--- a/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts
+++ b/src/dialogs/more-info/components/fan/ha-more-info-fan-speed.ts
@@ -2,7 +2,6 @@ import { css, CSSResultGroup, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators";
import { styleMap } from "lit/directives/style-map";
import { computeAttributeNameDisplay } from "../../../../common/entity/compute_attribute_display";
-import { computeStateDisplay } from "../../../../common/entity/compute_state_display";
import { stateActive } from "../../../../common/entity/state_active";
import { stateColorCss } from "../../../../common/entity/state_color";
import "../../../../components/ha-control-select";
@@ -12,12 +11,12 @@ import { UNAVAILABLE } from "../../../../data/entity";
import {
computeFanSpeedCount,
computeFanSpeedIcon,
+ FAN_SPEED_COUNT_MAX_FOR_BUTTONS,
+ FAN_SPEEDS,
FanEntity,
fanPercentageToSpeed,
FanSpeed,
fanSpeedToPercentage,
- FAN_SPEEDS,
- FAN_SPEED_COUNT_MAX_FOR_BUTTONS,
} from "../../../../data/fan";
import { HomeAssistant } from "../../../../types";
@@ -68,14 +67,7 @@ export class HaMoreInfoFanSpeed extends LitElement {
private _localizeSpeed(speed: FanSpeed) {
if (speed === "on" || speed === "off") {
- return computeStateDisplay(
- this.hass.localize,
- this.stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
- speed
- );
+ return this.hass.formatEntityState(this.stateObj, speed);
}
return (
this.hass.localize(`ui.dialogs.more_info_control.fan.speed.${speed}`) ||
diff --git a/src/dialogs/more-info/components/ha-more-info-state-header.ts b/src/dialogs/more-info/components/ha-more-info-state-header.ts
index 150058e89b..4697868390 100644
--- a/src/dialogs/more-info/components/ha-more-info-state-header.ts
+++ b/src/dialogs/more-info/components/ha-more-info-state-header.ts
@@ -1,7 +1,5 @@
-import { HassEntity } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
-import { computeStateDisplay } from "../../../common/entity/compute_state_display";
import "../../../components/ha-absolute-time";
import "../../../components/ha-relative-time";
import { isUnavailableState } from "../../../data/entity";
@@ -20,30 +18,22 @@ export class HaMoreInfoStateHeader extends LitElement {
@state() private _absoluteTime = false;
- private _computeStateDisplay(stateObj: HassEntity): TemplateResult | string {
+ private _localizeState(): TemplateResult | string {
if (
- stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP &&
- !isUnavailableState(stateObj.state)
+ this.stateObj.attributes.device_class === SENSOR_DEVICE_CLASS_TIMESTAMP &&
+ !isUnavailableState(this.stateObj.state)
) {
return html`
`;
}
- const stateDisplay = computeStateDisplay(
- this.hass!.localize,
- stateObj,
- this.hass!.locale,
- this.hass!.config,
- this.hass!.entities
- );
-
- return stateDisplay;
+ return this.hass.formatEntityState(this.stateObj);
}
private _toggleAbsolute() {
@@ -51,8 +41,7 @@ export class HaMoreInfoStateHeader extends LitElement {
}
protected render(): TemplateResult {
- const stateDisplay =
- this.stateOverride ?? this._computeStateDisplay(this.stateObj);
+ const stateDisplay = this.stateOverride ?? this._localizeState();
return html`
${stateDisplay}
diff --git a/src/dialogs/more-info/components/humidifier/ha-more-info-humidifier-humidity.ts b/src/dialogs/more-info/components/humidifier/ha-more-info-humidifier-humidity.ts
index 1a3db1121c..d93f506f10 100644
--- a/src/dialogs/more-info/components/humidifier/ha-more-info-humidifier-humidity.ts
+++ b/src/dialogs/more-info/components/humidifier/ha-more-info-humidifier-humidity.ts
@@ -2,7 +2,6 @@ import { mdiMinus, mdiPlus } from "@mdi/js";
import { CSSResultGroup, LitElement, PropertyValues, css, html } from "lit";
import { customElement, property, state } from "lit/decorators";
import { styleMap } from "lit/directives/style-map";
-import { computeAttributeValueDisplay } from "../../../../common/entity/compute_attribute_display";
import { stateActive } from "../../../../common/entity/state_active";
import { stateColorCss } from "../../../../common/entity/state_color";
import { clamp } from "../../../../common/number/clamp";
@@ -92,14 +91,10 @@ export class HaMoreInfoHumidifierHumidity extends LitElement {
const action = this.stateObj.attributes.action;
- const actionLabel = computeAttributeValueDisplay(
- this.hass.localize,
+ const actionLabel = this.hass.formatEntityAttributeValue(
this.stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
"action"
- ) as string;
+ );
return html`
diff --git a/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts b/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts
index 90b18f4223..0a66aabcf6 100644
--- a/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts
+++ b/src/dialogs/more-info/components/lights/light-color-rgb-picker.ts
@@ -26,7 +26,6 @@ import "../../../../components/ha-hs-color-picker";
import "../../../../components/ha-icon";
import "../../../../components/ha-icon-button-prev";
import "../../../../components/ha-labeled-slider";
-import "../../../../components/ha-temp-color-picker";
import {
getLightCurrentModeRgbColor,
LightColor,
diff --git a/src/dialogs/more-info/components/lights/light-color-temp-picker.ts b/src/dialogs/more-info/components/lights/light-color-temp-picker.ts
index cd69b7ba7d..0331d24b31 100644
--- a/src/dialogs/more-info/components/lights/light-color-temp-picker.ts
+++ b/src/dialogs/more-info/components/lights/light-color-temp-picker.ts
@@ -1,25 +1,31 @@
import {
- css,
CSSResultGroup,
- html,
LitElement,
- nothing,
PropertyValues,
+ css,
+ html,
+ nothing,
} from "lit";
import { customElement, property, state } from "lit/decorators";
+import { styleMap } from "lit/directives/style-map";
+import memoizeOne from "memoize-one";
+import { rgb2hex } from "../../../../common/color/convert-color";
+import {
+ DEFAULT_MAX_KELVIN,
+ DEFAULT_MIN_KELVIN,
+ temperature2rgb,
+} from "../../../../common/color/convert-light-color";
import { fireEvent } from "../../../../common/dom/fire_event";
+import { stateColorCss } from "../../../../common/entity/state_color";
import { throttle } from "../../../../common/util/throttle";
-import "../../../../components/ha-temp-color-picker";
+import "../../../../components/ha-control-slider";
+import { UNAVAILABLE } from "../../../../data/entity";
import {
LightColor,
LightColorMode,
LightEntity,
} from "../../../../data/light";
import { HomeAssistant } from "../../../../types";
-import {
- DEFAULT_MAX_KELVIN,
- DEFAULT_MIN_KELVIN,
-} from "../../../../common/color/convert-light-color";
declare global {
interface HASSDomEvents {
@@ -28,6 +34,26 @@ declare global {
}
}
+export const generateColorTemperatureGradient = (min: number, max: number) => {
+ const count = 10;
+
+ const gradient: [number, string][] = [];
+
+ const step = (max - min) / count;
+ const percentageStep = 1 / count;
+
+ for (let i = 0; i < count + 1; i++) {
+ const value = min + step * i;
+
+ const hex = rgb2hex(temperature2rgb(value));
+ gradient.push([percentageStep * i, hex]);
+ }
+
+ return gradient
+ .map(([stop, color]) => `${color} ${(stop as number) * 100}%`)
+ .join(", ");
+};
+
@customElement("light-color-temp-picker")
class LightColorTempPicker extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@@ -46,18 +72,36 @@ class LightColorTempPicker extends LitElement {
const maxKelvin =
this.stateObj.attributes.max_color_temp_kelvin ?? DEFAULT_MAX_KELVIN;
+ const gradient = this._generateTemperatureGradient(minKelvin!, maxKelvin);
+ const color = stateColorCss(this.stateObj);
+
return html`
-
-
+
`;
}
+ private _generateTemperatureGradient = memoizeOne(
+ (min: number, max: number) => generateColorTemperatureGradient(min, max)
+ );
+
public _updateSliderValues() {
const stateObj = this.stateObj;
@@ -138,10 +182,18 @@ class LightColorTempPicker extends LitElement {
flex-direction: column;
}
- ha-temp-color-picker {
+ ha-control-slider {
height: 45vh;
max-height: 320px;
min-height: 200px;
+ --control-slider-thickness: 100px;
+ --control-slider-border-radius: 24px;
+ --control-slider-color: var(--primary-color);
+ --control-slider-background: -webkit-linear-gradient(
+ top,
+ var(--gradient)
+ );
+ --control-slider-background-opacity: 1;
}
`,
];
diff --git a/src/dialogs/more-info/controls/more-info-cover.ts b/src/dialogs/more-info/controls/more-info-cover.ts
index d685d1bb63..02b2f2ec5a 100644
--- a/src/dialogs/more-info/controls/more-info-cover.ts
+++ b/src/dialogs/more-info/controls/more-info-cover.ts
@@ -1,22 +1,21 @@
import { mdiMenu, mdiSwapVertical } from "@mdi/js";
import {
- css,
CSSResultGroup,
- html,
LitElement,
- nothing,
PropertyValues,
+ css,
+ html,
+ nothing,
} from "lit";
import { customElement, property, state } from "lit/decorators";
-import { computeStateDisplay } from "../../../common/entity/compute_state_display";
import { supportsFeature } from "../../../common/entity/supports-feature";
import "../../../components/ha-attributes";
import "../../../components/ha-icon-button-group";
import "../../../components/ha-icon-button-toggle";
import {
- computeCoverPositionStateDisplay,
CoverEntity,
CoverEntityFeature,
+ computeCoverPositionStateDisplay,
} from "../../../data/cover";
import type { HomeAssistant } from "../../../types";
import "../components/cover/ha-more-info-cover-buttons";
@@ -83,12 +82,8 @@ class MoreInfoCover extends LitElement {
const forcedState =
liveValue != null ? (liveValue ? "open" : "closed") : undefined;
- const stateDisplay = computeStateDisplay(
- this.hass.localize,
+ const stateDisplay = this.hass.formatEntityState(
this.stateObj!,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
forcedState
);
diff --git a/src/dialogs/more-info/controls/more-info-humidifier.ts b/src/dialogs/more-info/controls/more-info-humidifier.ts
index 74754e25ad..d919753c86 100644
--- a/src/dialogs/more-info/controls/more-info-humidifier.ts
+++ b/src/dialogs/more-info/controls/more-info-humidifier.ts
@@ -10,11 +10,6 @@ import {
import { property, state } from "lit/decorators";
import { fireEvent } from "../../../common/dom/fire_event";
import { stopPropagation } from "../../../common/dom/stop_propagation";
-import {
- computeAttributeNameDisplay,
- computeAttributeValueDisplay,
-} from "../../../common/entity/compute_attribute_display";
-import { computeStateDisplay } from "../../../common/entity/compute_state_display";
import { supportsFeature } from "../../../common/entity/supports-feature";
import "../../../components/ha-control-select-menu";
import "../../../components/ha-list-item";
@@ -58,26 +53,21 @@ class MoreInfoHumidifier extends LitElement {
HumidifierEntityFeature.MODES
);
- const currentHumidity = this.stateObj.attributes.current_humidity as number;
-
return html`
- ${currentHumidity != null
+ ${this.stateObj.attributes.current_humidity != null
? html`
- ${computeAttributeNameDisplay(
- this.hass.localize,
+ ${this.hass.formatEntityAttributeName(
this.stateObj,
- this.hass.entities,
"current_humidity"
)}
${this.hass.formatEntityAttributeValue(
this.stateObj,
- "current_humidity",
- currentHumidity
+ "current_humidity"
)}
@@ -104,24 +94,10 @@ class MoreInfoHumidifier extends LitElement {
>
- ${computeStateDisplay(
- this.hass.localize,
- this.stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
- "off"
- )}
+ ${this.hass.formatEntityState(this.stateObj, "off")}
- ${computeStateDisplay(
- this.hass.localize,
- this.stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
- "on"
- )}
+ ${this.hass.formatEntityState(this.stateObj, "on")}
@@ -144,12 +120,8 @@ class MoreInfoHumidifier extends LitElement {
slot="graphic"
.path=${computeHumidiferModeIcon(mode)}
>
- ${computeAttributeValueDisplay(
- hass.localize,
+ ${this.hass.formatEntityAttributeValue(
stateObj!,
- hass.locale,
- hass.config,
- hass.entities,
"mode",
mode
)}
diff --git a/src/dialogs/more-info/controls/more-info-lawn_mower.ts b/src/dialogs/more-info/controls/more-info-lawn_mower.ts
index b2437bdb45..05a92ce1ce 100644
--- a/src/dialogs/more-info/controls/more-info-lawn_mower.ts
+++ b/src/dialogs/more-info/controls/more-info-lawn_mower.ts
@@ -2,7 +2,6 @@ import { mdiHomeImportOutline, mdiPause, mdiPlay } from "@mdi/js";
import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import memoizeOne from "memoize-one";
-import { computeStateDisplay } from "../../../common/entity/compute_state_display";
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
import { supportsFeature } from "../../../common/entity/supports-feature";
import { blankBeforePercent } from "../../../common/translations/blank_before_percent";
@@ -74,15 +73,7 @@ class MoreInfoLawnMower extends LitElement {
)}:
-
- ${computeStateDisplay(
- this.hass.localize,
- stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities
- )}
-
+ ${this.hass.formatEntityState(stateObj)}
${this._renderBattery()}
diff --git a/src/dialogs/more-info/controls/more-info-media_player.ts b/src/dialogs/more-info/controls/more-info-media_player.ts
index 1d9fcbe0fc..044745d78d 100644
--- a/src/dialogs/more-info/controls/more-info-media_player.ts
+++ b/src/dialogs/more-info/controls/more-info-media_player.ts
@@ -9,24 +9,23 @@ import {
mdiVolumeOff,
mdiVolumePlus,
} from "@mdi/js";
-import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
+import { CSSResultGroup, LitElement, css, html, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import { stopPropagation } from "../../../common/dom/stop_propagation";
-import { computeAttributeValueDisplay } from "../../../common/entity/compute_attribute_display";
+import { stateActive } from "../../../common/entity/state_active";
import { supportsFeature } from "../../../common/entity/supports-feature";
import { computeRTLDirection } from "../../../common/util/compute_rtl";
-import { stateActive } from "../../../common/entity/state_active";
import "../../../components/ha-icon-button";
import "../../../components/ha-select";
import "../../../components/ha-slider";
import "../../../components/ha-svg-icon";
import { showMediaBrowserDialog } from "../../../components/media-player/show-media-browser-dialog";
import {
- computeMediaControls,
- handleMediaControlClick,
MediaPickedEvent,
MediaPlayerEntity,
MediaPlayerEntityFeature,
+ computeMediaControls,
+ handleMediaControlClick,
mediaPlayerPlayMedia,
} from "../../../data/media-player";
import { HomeAssistant } from "../../../types";
@@ -157,24 +156,20 @@ class MoreInfoMediaPlayer extends LitElement {
>
${stateObj.attributes.source_list!.map(
(source) => html`
-
${computeAttributeValueDisplay(
- this.hass.localize,
+
+ ${this.hass.formatEntityAttributeValue(
stateObj,
- this.hass.locale,
- this.hass.config,
- this.hass.entities,
"source",
source
- )}
+ )}
+
`
)}
`
- : ""}
+ : nothing}
${stateActive(stateObj) &&
supportsFeature(stateObj, MediaPlayerEntityFeature.SELECT_SOUND_MODE) &&
stateObj.attributes.sound_mode_list?.length
@@ -191,17 +186,13 @@ class MoreInfoMediaPlayer extends LitElement {
>
${stateObj.attributes.sound_mode_list.map(
(mode) => html`
-