Convert default state icons (#10223)

* Convert default state icons

* update

* Update cast/src/launcher/layout/hc-cast.ts

Co-authored-by: Philip Allgaier <mail@spacegaier.de>

* Update ha-config-core.js

* Update

* Finish

* Add siren icon

* FIx

* Add curtain icons

Co-authored-by: Philip Allgaier <mail@spacegaier.de>
pull/10339/head
Bram Kragten 2021-10-20 11:10:16 +02:00 committed by GitHub
parent b760e543b0
commit 667fd39147
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
75 changed files with 829 additions and 573 deletions

View File

@ -1,4 +1,5 @@
import "@material/mwc-button/mwc-button";
import { mdiCast, mdiCastConnected } from "@mdi/js";
import "@polymer/paper-item/paper-icon-item";
import "@polymer/paper-listbox/paper-listbox";
import { Auth, Connection } from "home-assistant-js-websocket";
@ -17,6 +18,7 @@ import {
import { atLeastVersion } from "../../../../src/common/config/version";
import { toggleAttribute } from "../../../../src/common/dom/toggle_attribute";
import "../../../../src/components/ha-icon";
import "../../../../src/components/ha-svg-icon";
import {
getLegacyLovelaceCollection,
getLovelaceCollection,
@ -73,7 +75,7 @@ class HcCast extends LitElement {
? html`
<p class="center-item">
<mwc-button raised @click=${this._handleLaunch}>
<ha-icon icon="hass:cast"></ha-icon>
<ha-svg-icon .path=${mdiCast}></ha-svg-icon>
Start Casting
</mwc-button>
</p>
@ -111,7 +113,7 @@ class HcCast extends LitElement {
${this.castManager.status
? html`
<mwc-button @click=${this._handleLaunch}>
<ha-icon icon="hass:cast-connected"></ha-icon>
<ha-svg-icon .path=${mdiCastConnected}></ha-svg-icon>
Manage
</mwc-button>
`
@ -233,7 +235,7 @@ class HcCast extends LitElement {
color: var(--secondary-text-color);
}
mwc-button ha-icon {
mwc-button ha-svg-icon {
margin-right: 8px;
height: 18px;
}

View File

@ -1,4 +1,5 @@
import "@material/mwc-button";
import { mdiCastConnected, mdiCast } from "@mdi/js";
import "@polymer/paper-input/paper-input";
import {
Auth,
@ -19,7 +20,7 @@ import {
loadTokens,
saveTokens,
} from "../../../../src/common/auth/token_storage";
import "../../../../src/components/ha-icon";
import "../../../../src/components/ha-svg-icon";
import "../../../../src/layouts/hass-loading-screen";
import { registerServiceWorker } from "../../../../src/util/register-service-worker";
import "./hc-layout";
@ -127,11 +128,11 @@ export class HcConnect extends LitElement {
<div class="card-actions">
<mwc-button @click=${this._handleDemo}>
Show Demo
<ha-icon
.icon=${this.castManager.castState === "CONNECTED"
? "hass:cast-connected"
: "hass:cast"}
></ha-icon>
<ha-svg-icon
.path=${this.castManager.castState === "CONNECTED"
? mdiCastConnected
: mdiCast}
></ha-svg-icon>
</mwc-button>
<div class="spacer"></div>
<mwc-button @click=${this._handleConnect}>Authorize</mwc-button>
@ -307,7 +308,7 @@ export class HcConnect extends LitElement {
color: darkred;
}
mwc-button ha-icon {
mwc-button ha-svg-icon {
margin-left: 8px;
}

View File

@ -1,3 +1,4 @@
import { mdiTelevision } from "@mdi/js";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, state } from "lit/decorators";
import { CastManager } from "../../../src/cast/cast_manager";
@ -27,7 +28,7 @@ class CastDemoRow extends LitElement implements LovelaceRow {
return html``;
}
return html`
<ha-icon icon="hademo:television"></ha-icon>
<ha-svg-icon .path=${mdiTelevision}></ha-svg-icon>
<div class="flex">
<div class="name">Show Chromecast interface</div>
<google-cast-launcher></google-cast-launcher>
@ -72,7 +73,7 @@ class CastDemoRow extends LitElement implements LovelaceRow {
display: flex;
align-items: center;
}
ha-icon {
ha-svg-icon {
padding: 8px;
color: var(--paper-item-icon-color);
}

View File

@ -1,88 +1,146 @@
/** Constants to be used in the frontend. */
import {
mdiAccount,
mdiAirFilter,
mdiAlert,
mdiAngleAcute,
mdiAppleSafari,
mdiBell,
mdiBookmark,
mdiBrightness5,
mdiBullhorn,
mdiCalendar,
mdiCalendarClock,
mdiCash,
mdiClock,
mdiCloudUpload,
mdiCog,
mdiCommentAlert,
mdiCounter,
mdiCurrentAc,
mdiEye,
mdiFan,
mdiFlash,
mdiFlower,
mdiFormatListBulleted,
mdiFormTextbox,
mdiGasCylinder,
mdiGauge,
mdiGoogleAssistant,
mdiGoogleCirclesCommunities,
mdiHomeAssistant,
mdiHomeAutomation,
mdiImageFilterFrames,
mdiLightbulb,
mdiLightningBolt,
mdiMailbox,
mdiMapMarkerRadius,
mdiMolecule,
mdiMoleculeCo,
mdiMoleculeCo2,
mdiPalette,
mdiRayVertex,
mdiRemote,
mdiRobot,
mdiRobotVacuum,
mdiScriptText,
mdiSineWave,
mdiTextToSpeech,
mdiThermometer,
mdiThermostat,
mdiTimerOutline,
mdiToggleSwitchOutline,
mdiVideo,
mdiWaterPercent,
mdiWeatherCloudy,
mdiWhiteBalanceSunny,
mdiWifi,
} from "@mdi/js";
// Constants should be alphabetically sorted by name.
// Arrays with values should be alphabetically sorted if order doesn't matter.
// Each constant should have a description what it is supposed to be used for.
/** Icon to use when no icon specified for domain. */
export const DEFAULT_DOMAIN_ICON = "hass:bookmark";
export const DEFAULT_DOMAIN_ICON = mdiBookmark;
/** Icons for each domain */
export const FIXED_DOMAIN_ICONS = {
alert: "hass:alert",
alexa: "hass:amazon-alexa",
air_quality: "hass:air-filter",
automation: "hass:robot",
calendar: "hass:calendar",
camera: "hass:video",
climate: "hass:thermostat",
configurator: "hass:cog",
conversation: "hass:text-to-speech",
counter: "hass:counter",
device_tracker: "hass:account",
fan: "hass:fan",
google_assistant: "hass:google-assistant",
group: "hass:google-circles-communities",
homeassistant: "hass:home-assistant",
homekit: "hass:home-automation",
image_processing: "hass:image-filter-frames",
input_boolean: "hass:toggle-switch-outline",
input_datetime: "hass:calendar-clock",
input_number: "hass:ray-vertex",
input_select: "hass:format-list-bulleted",
input_text: "hass:form-textbox",
light: "hass:lightbulb",
mailbox: "hass:mailbox",
notify: "hass:comment-alert",
number: "hass:ray-vertex",
persistent_notification: "hass:bell",
person: "hass:account",
plant: "hass:flower",
proximity: "hass:apple-safari",
remote: "hass:remote",
scene: "hass:palette",
script: "hass:script-text",
select: "hass:format-list-bulleted",
sensor: "hass:eye",
simple_alarm: "hass:bell",
sun: "hass:white-balance-sunny",
switch: "hass:flash",
timer: "hass:timer-outline",
updater: "hass:cloud-upload",
vacuum: "hass:robot-vacuum",
water_heater: "hass:thermometer",
weather: "hass:weather-cloudy",
zone: "hass:map-marker-radius",
alert: mdiAlert,
air_quality: mdiAirFilter,
automation: mdiRobot,
calendar: mdiCalendar,
camera: mdiVideo,
climate: mdiThermostat,
configurator: mdiCog,
conversation: mdiTextToSpeech,
counter: mdiCounter,
device_tracker: mdiAccount,
fan: mdiFan,
google_assistant: mdiGoogleAssistant,
group: mdiGoogleCirclesCommunities,
homeassistant: mdiHomeAssistant,
homekit: mdiHomeAutomation,
image_processing: mdiImageFilterFrames,
input_boolean: mdiToggleSwitchOutline,
input_datetime: mdiCalendarClock,
input_number: mdiRayVertex,
input_select: mdiFormatListBulleted,
input_text: mdiFormTextbox,
light: mdiLightbulb,
mailbox: mdiMailbox,
notify: mdiCommentAlert,
number: mdiRayVertex,
persistent_notification: mdiBell,
person: mdiAccount,
plant: mdiFlower,
proximity: mdiAppleSafari,
remote: mdiRemote,
scene: mdiPalette,
script: mdiScriptText,
select: mdiFormatListBulleted,
sensor: mdiEye,
siren: mdiBullhorn,
simple_alarm: mdiBell,
sun: mdiWhiteBalanceSunny,
switch: mdiFlash,
timer: mdiTimerOutline,
updater: mdiCloudUpload,
vacuum: mdiRobotVacuum,
water_heater: mdiThermometer,
weather: mdiWeatherCloudy,
zone: mdiMapMarkerRadius,
};
export const FIXED_DEVICE_CLASS_ICONS = {
aqi: "hass:air-filter",
// battery: "hass:battery", => not included by design since `sensorIcon()` will dynamically determine the icon
carbon_dioxide: "mdi:molecule-co2",
carbon_monoxide: "mdi:molecule-co",
current: "hass:current-ac",
date: "hass:calendar",
energy: "hass:lightning-bolt",
gas: "hass:gas-cylinder",
humidity: "hass:water-percent",
illuminance: "hass:brightness-5",
monetary: "mdi:cash",
nitrogen_dioxide: "mdi:molecule",
nitrogen_monoxide: "mdi:molecule",
nitrous_oxide: "mdi:molecule",
ozone: "mdi:molecule",
pm1: "mdi:molecule",
pm10: "mdi:molecule",
pm25: "mdi:molecule",
power: "hass:flash",
power_factor: "hass:angle-acute",
pressure: "hass:gauge",
signal_strength: "hass:wifi",
sulphur_dioxide: "mdi:molecule",
temperature: "hass:thermometer",
timestamp: "hass:clock",
volatile_organic_compounds: "mdi:molecule",
voltage: "hass:sine-wave",
aqi: mdiAirFilter,
// battery: mdiBattery, => not included by design since `sensorIcon()` will dynamically determine the icon
carbon_dioxide: mdiMoleculeCo2,
carbon_monoxide: mdiMoleculeCo,
current: mdiCurrentAc,
date: mdiCalendar,
energy: mdiLightningBolt,
gas: mdiGasCylinder,
humidity: mdiWaterPercent,
illuminance: mdiBrightness5,
monetary: mdiCash,
nitrogen_dioxide: mdiMolecule,
nitrogen_monoxide: mdiMolecule,
nitrous_oxide: mdiMolecule,
ozone: mdiMolecule,
pm1: mdiMolecule,
pm10: mdiMolecule,
pm25: mdiMolecule,
power: mdiFlash,
power_factor: mdiAngleAcute,
pressure: mdiGauge,
signal_strength: mdiWifi,
sulphur_dioxide: mdiMolecule,
temperature: mdiThermometer,
timestamp: mdiClock,
volatile_organic_compounds: mdiMolecule,
voltage: mdiSineWave,
};
/** Domains that have a state card. */

View File

@ -1,24 +1,36 @@
/** Return an icon representing a alarm panel state. */
import {
mdiShieldLock,
mdiShieldAirplane,
mdiShieldHome,
mdiShieldMoon,
mdiSecurity,
mdiShieldOutline,
mdiBellRing,
mdiShieldOff,
mdiShield,
} from "@mdi/js";
export const alarmPanelIcon = (state?: string) => {
switch (state) {
case "armed_away":
return "hass:shield-lock";
return mdiShieldLock;
case "armed_vacation":
return "hass:shield-airplane";
return mdiShieldAirplane;
case "armed_home":
return "hass:shield-home";
return mdiShieldHome;
case "armed_night":
return "hass:shield-moon";
return mdiShieldMoon;
case "armed_custom_bypass":
return "hass:security";
return mdiSecurity;
case "pending":
return "hass:shield-outline";
return mdiShieldOutline;
case "triggered":
return "hass:bell-ring";
return mdiBellRing;
case "disarmed":
return "hass:shield-off";
return mdiShieldOff;
default:
return "hass:shield";
return mdiShield;
}
};

View File

@ -1,35 +1,92 @@
/** Return an icon representing a battery state. */
import {
mdiBattery,
mdiBattery10,
mdiBattery20,
mdiBattery30,
mdiBattery40,
mdiBattery50,
mdiBattery60,
mdiBattery70,
mdiBattery80,
mdiBattery90,
mdiBatteryAlert,
mdiBatteryAlertVariantOutline,
mdiBatteryCharging,
mdiBatteryCharging10,
mdiBatteryCharging20,
mdiBatteryCharging30,
mdiBatteryCharging40,
mdiBatteryCharging50,
mdiBatteryCharging60,
mdiBatteryCharging70,
mdiBatteryCharging80,
mdiBatteryCharging90,
mdiBatteryChargingOutline,
mdiBatteryUnknown,
} from "@mdi/js";
import { HassEntity } from "home-assistant-js-websocket";
export const batteryIcon = (
const BATTERY_ICONS = {
10: mdiBattery10,
20: mdiBattery20,
30: mdiBattery30,
40: mdiBattery40,
50: mdiBattery50,
60: mdiBattery60,
70: mdiBattery70,
80: mdiBattery80,
90: mdiBattery90,
100: mdiBattery,
};
const BATTERY_CHARGING_ICONS = {
10: mdiBatteryCharging10,
20: mdiBatteryCharging20,
30: mdiBatteryCharging30,
40: mdiBatteryCharging40,
50: mdiBatteryCharging50,
60: mdiBatteryCharging60,
70: mdiBatteryCharging70,
80: mdiBatteryCharging80,
90: mdiBatteryCharging90,
100: mdiBatteryCharging,
};
export const batteryStateIcon = (
batteryState: HassEntity,
batteryChargingState?: HassEntity
) => {
const battery = Number(batteryState.state);
const battery_charging =
const battery = batteryState.state;
const batteryCharging =
batteryChargingState && batteryChargingState.state === "on";
let icon = "hass:battery";
if (isNaN(battery)) {
if (batteryState.state === "off") {
icon += "-full";
} else if (batteryState.state === "on") {
icon += "-alert";
} else {
icon += "-unknown";
}
return icon;
}
const batteryRound = Math.round(battery / 10) * 10;
if (battery_charging && battery > 10) {
icon += `-charging-${batteryRound}`;
} else if (battery_charging) {
icon += "-outline";
} else if (battery <= 5) {
icon += "-alert";
} else if (battery > 5 && battery < 95) {
icon += `-${batteryRound}`;
}
return icon;
return batteryIcon(battery, batteryCharging);
};
export const batteryIcon = (
batteryState: number | string,
batteryCharging?: boolean
) => {
const batteryValue = Number(batteryState);
if (isNaN(batteryValue)) {
if (batteryState === "off") {
return mdiBattery;
}
if (batteryState === "on") {
return mdiBatteryAlert;
}
return mdiBatteryUnknown;
}
const batteryRound = Math.round(batteryValue / 10) * 10;
if (batteryCharging && batteryValue >= 10) {
return BATTERY_CHARGING_ICONS[batteryRound];
}
if (batteryCharging) {
return mdiBatteryChargingOutline;
}
if (batteryValue <= 5) {
return mdiBatteryAlertVariantOutline;
}
return BATTERY_ICONS[batteryRound];
};

View File

@ -1,3 +1,44 @@
import {
mdiBattery,
mdiBatteryOutline,
mdiBatteryCharging,
mdiThermometer,
mdiSnowflake,
mdiServerNetworkOff,
mdiServerNetwork,
mdiDoorClosed,
mdiDoorOpen,
mdiGarage,
mdiGarageOpen,
mdiPowerPlugOff,
mdiPowerPlug,
mdiCheckCircle,
mdiAlertCircle,
mdiSmoke,
mdiFire,
mdiBrightness5,
mdiBrightness7,
mdiLock,
mdiLockOpen,
mdiWaterOff,
mdiWater,
mdiWalk,
mdiRun,
mdiHomeOutline,
mdiHome,
mdiSquare,
mdiSquareOutline,
mdiMusicNoteOff,
mdiMusicNote,
mdiPackage,
mdiPackageUp,
mdiCropPortrait,
mdiVibrate,
mdiWindowClosed,
mdiWindowOpen,
mdiRadioboxBlank,
mdiCheckboxMarkedCircle,
} from "@mdi/js";
import { HassEntity } from "home-assistant-js-websocket";
/** Return an icon representing a binary sensor state. */
@ -6,53 +47,53 @@ export const binarySensorIcon = (state?: string, stateObj?: HassEntity) => {
const is_off = state === "off";
switch (stateObj?.attributes.device_class) {
case "battery":
return is_off ? "hass:battery" : "hass:battery-outline";
return is_off ? mdiBattery : mdiBatteryOutline;
case "battery_charging":
return is_off ? "hass:battery" : "hass:battery-charging";
return is_off ? mdiBattery : mdiBatteryCharging;
case "cold":
return is_off ? "hass:thermometer" : "hass:snowflake";
return is_off ? mdiThermometer : mdiSnowflake;
case "connectivity":
return is_off ? "hass:server-network-off" : "hass:server-network";
return is_off ? mdiServerNetworkOff : mdiServerNetwork;
case "door":
return is_off ? "hass:door-closed" : "hass:door-open";
return is_off ? mdiDoorClosed : mdiDoorOpen;
case "garage_door":
return is_off ? "hass:garage" : "hass:garage-open";
return is_off ? mdiGarage : mdiGarageOpen;
case "power":
return is_off ? "hass:power-plug-off" : "hass:power-plug";
return is_off ? mdiPowerPlugOff : mdiPowerPlug;
case "gas":
case "problem":
case "safety":
case "tamper":
return is_off ? "hass:check-circle" : "hass:alert-circle";
return is_off ? mdiCheckCircle : mdiAlertCircle;
case "smoke":
return is_off ? "hass:check-circle" : "hass:smoke";
return is_off ? mdiCheckCircle : mdiSmoke;
case "heat":
return is_off ? "hass:thermometer" : "hass:fire";
return is_off ? mdiThermometer : mdiFire;
case "light":
return is_off ? "hass:brightness-5" : "hass:brightness-7";
return is_off ? mdiBrightness5 : mdiBrightness7;
case "lock":
return is_off ? "hass:lock" : "hass:lock-open";
return is_off ? mdiLock : mdiLockOpen;
case "moisture":
return is_off ? "hass:water-off" : "hass:water";
return is_off ? mdiWaterOff : mdiWater;
case "motion":
return is_off ? "hass:walk" : "hass:run";
return is_off ? mdiWalk : mdiRun;
case "occupancy":
return is_off ? "hass:home-outline" : "hass:home";
return is_off ? mdiHomeOutline : mdiHome;
case "opening":
return is_off ? "hass:square" : "hass:square-outline";
return is_off ? mdiSquare : mdiSquareOutline;
case "plug":
return is_off ? "hass:power-plug-off" : "hass:power-plug";
return is_off ? mdiPowerPlugOff : mdiPowerPlug;
case "presence":
return is_off ? "hass:home-outline" : "hass:home";
return is_off ? mdiHomeOutline : mdiHome;
case "sound":
return is_off ? "hass:music-note-off" : "hass:music-note";
return is_off ? mdiMusicNoteOff : mdiMusicNote;
case "update":
return is_off ? "mdi:package" : "mdi:package-up";
return is_off ? mdiPackage : mdiPackageUp;
case "vibration":
return is_off ? "hass:crop-portrait" : "hass:vibrate";
return is_off ? mdiCropPortrait : mdiVibrate;
case "window":
return is_off ? "hass:window-closed" : "hass:window-open";
return is_off ? mdiWindowClosed : mdiWindowOpen;
default:
return is_off ? "hass:radiobox-blank" : "hass:checkbox-marked-circle";
return is_off ? mdiRadioboxBlank : mdiCheckboxMarkedCircle;
}
};

View File

@ -1,4 +1,30 @@
/** Return an icon representing a cover state. */
import {
mdiArrowUpBox,
mdiArrowDownBox,
mdiGarage,
mdiGarageOpen,
mdiGateArrowRight,
mdiGate,
mdiGateOpen,
mdiDoorOpen,
mdiDoorClosed,
mdiCircle,
mdiWindowShutter,
mdiWindowShutterOpen,
mdiBlinds,
mdiBlindsOpen,
mdiWindowClosed,
mdiWindowOpen,
mdiArrowExpandHorizontal,
mdiArrowUp,
mdiArrowCollapseHorizontal,
mdiArrowDown,
mdiCircleSlice8,
mdiArrowSplitVertical,
mdiCurtains,
mdiCurtainsClosed,
} from "@mdi/js";
import { HassEntity } from "home-assistant-js-websocket";
export const coverIcon = (state?: string, stateObj?: HassEntity): string => {
@ -8,74 +34,84 @@ export const coverIcon = (state?: string, stateObj?: HassEntity): string => {
case "garage":
switch (state) {
case "opening":
return "hass:arrow-up-box";
return mdiArrowUpBox;
case "closing":
return "hass:arrow-down-box";
return mdiArrowDownBox;
case "closed":
return "hass:garage";
return mdiGarage;
default:
return "hass:garage-open";
return mdiGarageOpen;
}
case "gate":
switch (state) {
case "opening":
case "closing":
return "hass:gate-arrow-right";
return mdiGateArrowRight;
case "closed":
return "hass:gate";
return mdiGate;
default:
return "hass:gate-open";
return mdiGateOpen;
}
case "door":
return open ? "hass:door-open" : "hass:door-closed";
return open ? mdiDoorOpen : mdiDoorClosed;
case "damper":
return open ? "hass:circle" : "hass:circle-slice-8";
return open ? mdiCircle : mdiCircleSlice8;
case "shutter":
switch (state) {
case "opening":
return "hass:arrow-up-box";
return mdiArrowUpBox;
case "closing":
return "hass:arrow-down-box";
return mdiArrowDownBox;
case "closed":
return "hass:window-shutter";
return mdiWindowShutter;
default:
return "hass:window-shutter-open";
return mdiWindowShutterOpen;
}
case "curtain":
switch (state) {
case "opening":
return mdiArrowSplitVertical;
case "closing":
return mdiArrowCollapseHorizontal;
case "closed":
return mdiCurtainsClosed;
default:
return mdiCurtains;
}
case "blind":
case "curtain":
case "shade":
switch (state) {
case "opening":
return "hass:arrow-up-box";
return mdiArrowUpBox;
case "closing":
return "hass:arrow-down-box";
return mdiArrowDownBox;
case "closed":
return "hass:blinds";
return mdiBlinds;
default:
return "hass:blinds-open";
return mdiBlindsOpen;
}
case "window":
switch (state) {
case "opening":
return "hass:arrow-up-box";
return mdiArrowUpBox;
case "closing":
return "hass:arrow-down-box";
return mdiArrowDownBox;
case "closed":
return "hass:window-closed";
return mdiWindowClosed;
default:
return "hass:window-open";
return mdiWindowOpen;
}
}
switch (state) {
case "opening":
return "hass:arrow-up-box";
return mdiArrowUpBox;
case "closing":
return "hass:arrow-down-box";
return mdiArrowDownBox;
case "closed":
return "hass:window-closed";
return mdiWindowClosed;
default:
return "hass:window-open";
return mdiWindowOpen;
}
};
@ -84,9 +120,9 @@ export const computeOpenIcon = (stateObj: HassEntity): string => {
case "awning":
case "door":
case "gate":
return "hass:arrow-expand-horizontal";
return mdiArrowExpandHorizontal;
default:
return "hass:arrow-up";
return mdiArrowUp;
}
};
@ -95,8 +131,8 @@ export const computeCloseIcon = (stateObj: HassEntity): string => {
case "awning":
case "door":
case "gate":
return "hass:arrow-collapse-horizontal";
return mdiArrowCollapseHorizontal;
default:
return "hass:arrow-down";
return mdiArrowDown;
}
};

View File

@ -1,3 +1,20 @@
import {
mdiAirHumidifierOff,
mdiAirHumidifier,
mdiLockOpen,
mdiLockAlert,
mdiLockClock,
mdiLock,
mdiCastConnected,
mdiCast,
mdiEmoticonDead,
mdiSleep,
mdiTimerSand,
mdiZWave,
mdiClock,
mdiCalendar,
mdiWeatherNight,
} from "@mdi/js";
import { HassEntity } from "home-assistant-js-websocket";
/**
* Return the icon to be used for a domain.
@ -28,36 +45,34 @@ export const domainIcon = (
return coverIcon(compareState, stateObj);
case "humidifier":
return state && state === "off"
? "hass:air-humidifier-off"
: "hass:air-humidifier";
return state && state === "off" ? mdiAirHumidifierOff : mdiAirHumidifier;
case "lock":
switch (compareState) {
case "unlocked":
return "hass:lock-open";
return mdiLockOpen;
case "jammed":
return "hass:lock-alert";
return mdiLockAlert;
case "locking":
case "unlocking":
return "hass:lock-clock";
return mdiLockClock;
default:
return "hass:lock";
return mdiLock;
}
case "media_player":
return compareState === "playing" ? "hass:cast-connected" : "hass:cast";
return compareState === "playing" ? mdiCastConnected : mdiCast;
case "zwave":
switch (compareState) {
case "dead":
return "hass:emoticon-dead";
return mdiEmoticonDead;
case "sleeping":
return "hass:sleep";
return mdiSleep;
case "initializing":
return "hass:timer-sand";
return mdiTimerSand;
default:
return "hass:z-wave";
return mdiZWave;
}
case "sensor": {
@ -71,17 +86,17 @@ export const domainIcon = (
case "input_datetime":
if (!stateObj?.attributes.has_date) {
return "hass:clock";
return mdiClock;
}
if (!stateObj.attributes.has_time) {
return "hass:calendar";
return mdiCalendar;
}
break;
case "sun":
return stateObj?.state === "above_horizon"
? FIXED_DOMAIN_ICONS[domain]
: "hass:weather-night";
: mdiWeatherNight;
}
if (domain in FIXED_DOMAIN_ICONS) {

View File

@ -1,8 +1,9 @@
/** Return an icon representing a sensor state. */
import { mdiBattery, mdiThermometer } from "@mdi/js";
import { HassEntity } from "home-assistant-js-websocket";
import { FIXED_DEVICE_CLASS_ICONS, UNIT_C, UNIT_F } from "../const";
import { batteryIcon } from "./battery_icon";
import { SENSOR_DEVICE_CLASS_BATTERY } from "../../data/sensor";
import { FIXED_DEVICE_CLASS_ICONS, UNIT_C, UNIT_F } from "../const";
import { batteryStateIcon } from "./battery_icon";
export const sensorIcon = (stateObj?: HassEntity): string | undefined => {
const dclass = stateObj?.attributes.device_class;
@ -12,12 +13,12 @@ export const sensorIcon = (stateObj?: HassEntity): string | undefined => {
}
if (dclass === SENSOR_DEVICE_CLASS_BATTERY) {
return stateObj ? batteryIcon(stateObj) : "hass:battery";
return stateObj ? batteryStateIcon(stateObj) : mdiBattery;
}
const unit = stateObj?.attributes.unit_of_measurement;
if (unit === UNIT_C || unit === UNIT_F) {
return "hass:thermometer";
return mdiThermometer;
}
return undefined;

View File

@ -4,13 +4,9 @@ import { DEFAULT_DOMAIN_ICON } from "../const";
import { computeDomain } from "./compute_domain";
import { domainIcon } from "./domain_icon";
export const stateIcon = (state?: HassEntity) => {
export const stateIconPath = (state?: HassEntity) => {
if (!state) {
return DEFAULT_DOMAIN_ICON;
}
if (state.attributes.icon) {
return state.attributes.icon;
}
return domainIcon(computeDomain(state.entity_id), state);
};

View File

@ -1,57 +1,57 @@
import { css } from "lit";
export const iconColorCSS = css`
ha-icon[data-domain="alert"][data-state="on"],
ha-icon[data-domain="automation"][data-state="on"],
ha-icon[data-domain="binary_sensor"][data-state="on"],
ha-icon[data-domain="calendar"][data-state="on"],
ha-icon[data-domain="camera"][data-state="streaming"],
ha-icon[data-domain="cover"][data-state="open"],
ha-icon[data-domain="fan"][data-state="on"],
ha-icon[data-domain="humidifier"][data-state="on"],
ha-icon[data-domain="light"][data-state="on"],
ha-icon[data-domain="input_boolean"][data-state="on"],
ha-icon[data-domain="lock"][data-state="unlocked"],
ha-icon[data-domain="media_player"][data-state="on"],
ha-icon[data-domain="media_player"][data-state="paused"],
ha-icon[data-domain="media_player"][data-state="playing"],
ha-icon[data-domain="script"][data-state="on"],
ha-icon[data-domain="sun"][data-state="above_horizon"],
ha-icon[data-domain="switch"][data-state="on"],
ha-icon[data-domain="timer"][data-state="active"],
ha-icon[data-domain="vacuum"][data-state="cleaning"],
ha-icon[data-domain="group"][data-state="on"],
ha-icon[data-domain="group"][data-state="home"],
ha-icon[data-domain="group"][data-state="open"],
ha-icon[data-domain="group"][data-state="locked"],
ha-icon[data-domain="group"][data-state="problem"] {
ha-state-icon[data-domain="alert"][data-state="on"],
ha-state-icon[data-domain="automation"][data-state="on"],
ha-state-icon[data-domain="binary_sensor"][data-state="on"],
ha-state-icon[data-domain="calendar"][data-state="on"],
ha-state-icon[data-domain="camera"][data-state="streaming"],
ha-state-icon[data-domain="cover"][data-state="open"],
ha-state-icon[data-domain="fan"][data-state="on"],
ha-state-icon[data-domain="humidifier"][data-state="on"],
ha-state-icon[data-domain="light"][data-state="on"],
ha-state-icon[data-domain="input_boolean"][data-state="on"],
ha-state-icon[data-domain="lock"][data-state="unlocked"],
ha-state-icon[data-domain="media_player"][data-state="on"],
ha-state-icon[data-domain="media_player"][data-state="paused"],
ha-state-icon[data-domain="media_player"][data-state="playing"],
ha-state-icon[data-domain="script"][data-state="on"],
ha-state-icon[data-domain="sun"][data-state="above_horizon"],
ha-state-icon[data-domain="switch"][data-state="on"],
ha-state-icon[data-domain="timer"][data-state="active"],
ha-state-icon[data-domain="vacuum"][data-state="cleaning"],
ha-state-icon[data-domain="group"][data-state="on"],
ha-state-icon[data-domain="group"][data-state="home"],
ha-state-icon[data-domain="group"][data-state="open"],
ha-state-icon[data-domain="group"][data-state="locked"],
ha-state-icon[data-domain="group"][data-state="problem"] {
color: var(--paper-item-icon-active-color, #fdd835);
}
ha-icon[data-domain="climate"][data-state="cooling"] {
ha-state-icon[data-domain="climate"][data-state="cooling"] {
color: var(--cool-color, var(--state-climate-cool-color));
}
ha-icon[data-domain="climate"][data-state="heating"] {
ha-state-icon[data-domain="climate"][data-state="heating"] {
color: var(--heat-color, var(--state-climate-heat-color));
}
ha-icon[data-domain="climate"][data-state="drying"] {
ha-state-icon[data-domain="climate"][data-state="drying"] {
color: var(--dry-color, var(--state-climate-dry-color));
}
ha-icon[data-domain="alarm_control_panel"] {
ha-state-icon[data-domain="alarm_control_panel"] {
color: var(--alarm-color-armed, var(--label-badge-red));
}
ha-icon[data-domain="alarm_control_panel"][data-state="disarmed"] {
ha-state-icon[data-domain="alarm_control_panel"][data-state="disarmed"] {
color: var(--alarm-color-disarmed, var(--label-badge-green));
}
ha-icon[data-domain="alarm_control_panel"][data-state="pending"],
ha-icon[data-domain="alarm_control_panel"][data-state="arming"] {
ha-state-icon[data-domain="alarm_control_panel"][data-state="pending"],
ha-state-icon[data-domain="alarm_control_panel"][data-state="arming"] {
color: var(--alarm-color-pending, var(--label-badge-yellow));
animation: pulse 1s infinite;
}
ha-icon[data-domain="alarm_control_panel"][data-state="triggered"] {
ha-state-icon[data-domain="alarm_control_panel"][data-state="triggered"] {
color: var(--alarm-color-triggered, var(--label-badge-red));
animation: pulse 1s infinite;
}
@ -68,13 +68,13 @@ export const iconColorCSS = css`
}
}
ha-icon[data-domain="plant"][data-state="problem"],
ha-icon[data-domain="zwave"][data-state="dead"] {
ha-state-icon[data-domain="plant"][data-state="problem"],
ha-state-icon[data-domain="zwave"][data-state="dead"] {
color: var(--state-icon-error-color);
}
/* Color the icon if unavailable */
ha-icon[data-state="unavailable"] {
ha-state-icon[data-state="unavailable"] {
color: var(--state-unavailable-color);
}
`;

View File

@ -747,10 +747,16 @@ export class HaDataTable extends LitElement {
text-align: right;
}
.mdc-data-table__cell--icon:first-child ha-icon {
.mdc-data-table__cell--icon:first-child ha-icon,
.mdc-data-table__cell--icon:first-child ha-state-icon,
.mdc-data-table__cell--icon:first-child ha-svg-icon {
margin-left: 8px;
}
:host([dir="rtl"]) .mdc-data-table__cell--icon:first-child ha-icon {
:host([dir="rtl"]) .mdc-data-table__cell--icon:first-child ha-icon,
:host([dir="rtl"])
.mdc-data-table__cell--icon:first-child
ha-state-icon,
:host([dir="rtl"]) .mdc-data-table__cell--icon:first-child ha-svg-icon {
margin-left: auto;
margin-right: 8px;
}

View File

@ -1,7 +1,7 @@
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { batteryIcon } from "../../common/entity/battery_icon";
import "../ha-icon";
import { batteryStateIcon } from "../../common/entity/battery_icon";
import "../ha-svg-icon";
@customElement("ha-battery-icon")
export class HaBatteryIcon extends LitElement {
@ -11,9 +11,18 @@ export class HaBatteryIcon extends LitElement {
protected render() {
return html`
<ha-icon
.icon=${batteryIcon(this.batteryStateObj, this.batteryChargingStateObj)}
></ha-icon>
<ha-svg-icon
.path=${batteryStateIcon(
this.batteryStateObj,
this.batteryChargingStateObj
)}
></ha-svg-icon>
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-battery-icon": HaBatteryIcon;
}
}

View File

@ -14,19 +14,18 @@ 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 { stateIcon } from "../../common/entity/state_icon";
import { formatNumber } from "../../common/number/format_number";
import { UNAVAILABLE, UNKNOWN } from "../../data/entity";
import { timerTimeRemaining } from "../../data/timer";
import { HomeAssistant } from "../../types";
import "../ha-label-badge";
import "../ha-icon";
import "../ha-state-icon";
@customElement("ha-state-label-badge")
export class HaStateLabelBadge extends LitElement {
@property({ attribute: false }) public hass?: HomeAssistant;
@property() public state?: HassEntity;
@property({ attribute: false }) public state?: HassEntity;
@property() public name?: string;
@ -76,15 +75,16 @@ export class HaStateLabelBadge extends LitElement {
// 4. Icon determined via entity state
// 5. Value string as fallback
const domain = computeStateDomain(entityState);
const icon = this.icon ? this.icon : this._computeIcon(domain, entityState);
const image = this.icon
const showIcon = this.icon || this._computeShowIcon(domain, entityState);
const image = showIcon
? ""
: this.image
? this.image
: entityState.attributes.entity_picture_local ||
entityState.attributes.entity_picture;
const value =
!image && !icon ? this._computeValue(domain, entityState) : undefined;
!image && !showIcon ? this._computeValue(domain, entityState) : undefined;
return html`
<ha-label-badge
@ -101,8 +101,13 @@ export class HaStateLabelBadge extends LitElement {
)}
.description=${this.name ?? computeStateName(entityState)}
>
${!image && icon ? html`<ha-icon .icon=${icon}></ha-icon>` : ""}
${value && !icon && !image
${!image && showIcon
? html`<ha-state-icon
.icon=${this.icon}
.state=${entityState}
></ha-state-icon>`
: ""}
${value && !image && !showIcon
? html`<span class=${value && value.length > 4 ? "big" : ""}
>${value}</span
>`
@ -150,9 +155,9 @@ export class HaStateLabelBadge extends LitElement {
}
}
private _computeIcon(domain: string, entityState: HassEntity) {
private _computeShowIcon(domain: string, entityState: HassEntity): boolean {
if (entityState.state === UNAVAILABLE) {
return null;
return false;
}
switch (domain) {
case "alarm_control_panel":
@ -162,17 +167,13 @@ export class HaStateLabelBadge extends LitElement {
case "person":
case "scene":
case "sun":
return stateIcon(entityState);
return true;
case "timer":
return entityState.state === "active"
? "hass:timer-outline"
: "hass:timer-off-outline";
return true;
case "sensor":
return entityState.attributes.device_class === "moon__phase"
? stateIcon(entityState)
: null;
return entityState.attributes.device_class === "moon__phase";
default:
return null;
return false;
}
}

View File

@ -1,3 +1,4 @@
import { mdiAlert } from "@mdi/js";
import type { HassEntity } from "home-assistant-js-websocket";
import {
css,
@ -12,10 +13,9 @@ import { ifDefined } from "lit/directives/if-defined";
import { styleMap } from "lit/directives/style-map";
import { computeActiveState } from "../../common/entity/compute_active_state";
import { computeStateDomain } from "../../common/entity/compute_state_domain";
import { stateIcon } from "../../common/entity/state_icon";
import { iconColorCSS } from "../../common/style/icon_color_css";
import type { HomeAssistant } from "../../types";
import "../ha-icon";
import "../ha-state-icon";
export class StateBadge extends LitElement {
public hass?: HomeAssistant;
@ -39,7 +39,7 @@ export class StateBadge extends LitElement {
// We either need a `stateObj` or one override
if (!stateObj && !this.overrideIcon && !this.overrideImage) {
return html`<div class="missing">
<ha-icon icon="hass:alert"></ha-icon>
<ha-svg-icon .path=${mdiAlert}></ha-svg-icon>
</div>`;
}
@ -49,8 +49,7 @@ export class StateBadge extends LitElement {
const domain = stateObj ? computeStateDomain(stateObj) : undefined;
return html`
<ha-icon
return html`<ha-state-icon
style=${styleMap(this._iconStyle)}
data-domain=${ifDefined(
this.stateColor || (domain === "light" && this.stateColor !== false)
@ -58,9 +57,9 @@ export class StateBadge extends LitElement {
: undefined
)}
data-state=${stateObj ? computeActiveState(stateObj) : ""}
.icon=${this.overrideIcon || (stateObj ? stateIcon(stateObj) : "")}
></ha-icon>
`;
.icon=${this.overrideIcon}
.state=${stateObj}
></ha-state-icon>`;
}
public willUpdate(changedProps: PropertyValues) {
@ -154,7 +153,7 @@ export class StateBadge extends LitElement {
:host([icon]:focus) {
background: var(--divider-color);
}
ha-icon {
ha-state-icon {
transition: color 0.3s ease-in-out, filter 0.3s ease-in-out;
}
.missing {

View File

@ -14,7 +14,6 @@ import { computeCloseIcon, computeOpenIcon } from "../common/entity/cover_icon";
import { UNAVAILABLE } from "../data/entity";
import type { HomeAssistant } from "../types";
import CoverEntity from "../util/cover-model";
import "./ha-icon";
import "./ha-icon-button";
@customElement("ha-cover-controls")
@ -49,8 +48,8 @@ class HaCoverControls extends LitElement {
)}
@click=${this._onOpenTap}
.disabled=${this._computeOpenDisabled()}
.path=${computeOpenIcon(this.stateObj)}
>
<ha-icon .icon=${computeOpenIcon(this.stateObj)}></ha-icon>
</ha-icon-button>
<ha-icon-button
class=${classMap({
@ -72,8 +71,8 @@ class HaCoverControls extends LitElement {
)}
@click=${this._onCloseTap}
.disabled=${this._computeClosedDisabled()}
.path=${computeCloseIcon(this.stateObj)}
>
<ha-icon .icon=${computeCloseIcon(this.stateObj)}></ha-icon>
</ha-icon-button>
</div>
`;

View File

@ -1,63 +0,0 @@
import "@polymer/paper-input/paper-input";
import { css, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../common/dom/fire_event";
import "./ha-icon";
@customElement("ha-icon-input")
export class HaIconInput extends LitElement {
@property() public value?: string;
@property() public label?: string;
@property() public placeholder?: string;
@property({ attribute: "error-message" }) public errorMessage?: string;
@property({ type: Boolean }) public disabled = false;
protected render(): TemplateResult {
return html`
<paper-input
.value=${this.value}
.label=${this.label}
.placeholder=${this.placeholder}
@value-changed=${this._valueChanged}
.disabled=${this.disabled}
auto-validate
.errorMessage=${this.errorMessage}
pattern="^\\S+:\\S+$"
>
${this.value || this.placeholder
? html`
<ha-icon .icon=${this.value || this.placeholder} slot="suffix">
</ha-icon>
`
: ""}
</paper-input>
`;
}
private _valueChanged(ev: CustomEvent) {
this.value = ev.detail.value;
fireEvent(
this,
"value-changed",
{ value: ev.detail.value },
{
bubbles: false,
composed: false,
}
);
}
static get styles() {
return css`
ha-icon {
position: absolute;
bottom: 2px;
right: 0;
}
`;
}
}

View File

@ -46,14 +46,14 @@ export class HaIconPicker extends LitElement {
@property() public placeholder?: string;
@property() public fallbackPath?: string;
@property({ attribute: "error-message" }) public errorMessage?: string;
@property({ type: Boolean }) public disabled = false;
@query("vaadin-combo-box-light", true) private comboBox!: HTMLElement;
@property({ type: Boolean }) private _opened = false;
protected render(): TemplateResult {
return html`
<vaadin-combo-box-light
@ -63,7 +63,6 @@ export class HaIconPicker extends LitElement {
.allowCustomValue=${true}
.filteredItems=${[]}
${comboBoxRenderer(rowRenderer)}
@opened-changed=${this._openedChanged}
@value-changed=${this._valueChanged}
@filter-changed=${this._filterChanged}
>
@ -77,21 +76,22 @@ export class HaIconPicker extends LitElement {
autocorrect="off"
spellcheck="false"
>
${!this._opened && (this._value || this.placeholder)
${this._value || this.placeholder
? html`
<ha-icon .icon=${this._value || this.placeholder} slot="suffix">
</ha-icon>
`
: this.fallbackPath
? html`<ha-svg-icon
.path=${this.fallbackPath}
slot="suffix"
></ha-svg-icon>`
: ""}
</paper-input>
</vaadin-combo-box-light>
`;
}
private _openedChanged(ev: PolymerChangedEvent<boolean>) {
this._opened = ev.detail.value;
}
private _valueChanged(ev: PolymerChangedEvent<string>) {
this._setValue(ev.detail.value);
}
@ -132,10 +132,10 @@ export class HaIconPicker extends LitElement {
static get styles() {
return css`
ha-icon {
position: absolute;
ha-icon,
ha-svg-icon {
position: relative;
bottom: 2px;
right: 0;
}
`;
}

View File

@ -1,26 +1,27 @@
import { mdiStar } from "@mdi/js";
import "@polymer/paper-tooltip/paper-tooltip";
import {
css,
CSSResultGroup,
html,
nothing,
LitElement,
nothing,
TemplateResult,
} from "lit";
import { customElement, state, property } from "lit/decorators";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../common/dom/fire_event";
import {
Adapter,
NetworkConfig,
IPv6ConfiguredAddress,
IPv4ConfiguredAddress,
IPv6ConfiguredAddress,
NetworkConfig,
} from "../data/network";
import { fireEvent } from "../common/dom/fire_event";
import { haStyle } from "../resources/styles";
import { HomeAssistant } from "../types";
import "./ha-checkbox";
import type { HaCheckbox } from "./ha-checkbox";
import "./ha-settings-row";
import "./ha-icon";
import "./ha-svg-icon";
const format_addresses = (
addresses: IPv6ConfiguredAddress[] | IPv4ConfiguredAddress[]
@ -92,7 +93,8 @@ export class HaNetwork extends LitElement {
<span slot="heading">
Adapter: ${adapter.name}
${adapter.default
? html`<ha-icon .icon="hass:star"></ha-icon> (Default)`
? html`<ha-svg-icon .path=${mdiStar}></ha-svg-icon>
(Default)`
: ""}
</span>
<span slot="description">

View File

@ -0,0 +1,27 @@
import { HassEntity } from "home-assistant-js-websocket";
import { html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import { stateIconPath } from "../common/entity/state_icon_path";
import "./ha-icon";
import "./ha-svg-icon";
@customElement("ha-state-icon")
export class HaStateIcon extends LitElement {
@property({ attribute: false }) public state?: HassEntity;
@property() public icon?: string;
protected render(): TemplateResult {
if (this.icon || this.state?.attributes.icon) {
return html`<ha-icon
.icon=${this.icon || this.state?.attributes.icon}
></ha-icon>`;
}
return html`<ha-svg-icon .path=${stateIconPath(this.state)}></ha-svg-icon>`;
}
}
declare global {
interface HTMLElementTagNameMap {
"ha-state-icon": HaStateIcon;
}
}

View File

@ -10,6 +10,7 @@ import {
} from "@mdi/js";
import "@polymer/paper-tooltip/paper-tooltip";
import {
HassEntity,
HassServiceTarget,
UnsubscribeFunc,
} from "home-assistant-js-websocket";
@ -20,7 +21,6 @@ import { fireEvent } from "../common/dom/fire_event";
import { ensureArray } from "../common/ensure-array";
import { computeDomain } from "../common/entity/compute_domain";
import { computeStateName } from "../common/entity/compute_state_name";
import { stateIcon } from "../common/entity/state_icon";
import {
AreaRegistryEntry,
subscribeAreaRegistry,
@ -41,15 +41,14 @@ import type { HaDevicePickerDeviceFilterFunc } from "./device/ha-device-picker";
import "./entity/ha-entity-picker";
import type { HaEntityPickerEntityFilterFunc } from "./entity/ha-entity-picker";
import "./ha-area-picker";
import "./ha-icon";
import "./ha-icon-button";
import "./ha-svg-icon";
@customElement("ha-target-picker")
export class HaTargetPicker extends SubscribeMixin(LitElement) {
@property() public hass!: HomeAssistant;
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public value?: HassServiceTarget;
@property({ attribute: false }) public value?: HassServiceTarget;
@property() public label?: string;
@ -147,7 +146,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
"entity_id",
entity_id,
entity ? computeStateName(entity) : entity_id,
entity ? stateIcon(entity) : undefined
entity
);
})
: ""}
@ -230,7 +229,7 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
type: string,
id: string,
name: string,
icon?: string,
entityState?: HassEntity,
iconPath?: string
) {
return html`
@ -245,11 +244,11 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
.path=${iconPath}
></ha-svg-icon>`
: ""}
${icon
? html`<ha-icon
${entityState
? html`<ha-state-icon
class="mdc-chip__icon mdc-chip__icon--leading"
.icon=${icon}
></ha-icon>`
.state=${entityState}
></ha-state-icon>`
: ""}
<span role="gridcell">
<span role="button" tabindex="0" class="mdc-chip__primary-action">

View File

@ -10,8 +10,15 @@ import {
mdiImage,
mdiMovie,
mdiMusic,
mdiPause,
mdiPlay,
mdiPlaylistMusic,
mdiPlayPause,
mdiPodcast,
mdiPower,
mdiSkipNext,
mdiSkipPrevious,
mdiStop,
mdiTelevisionClassic,
mdiVideo,
mdiWeb,
@ -246,7 +253,7 @@ export const computeMediaControls = (
return supportsFeature(stateObj, SUPPORT_TURN_ON)
? [
{
icon: "hass:power",
icon: mdiPower,
action: "turn_on",
},
]
@ -257,7 +264,7 @@ export const computeMediaControls = (
if (supportsFeature(stateObj, SUPPORT_TURN_OFF)) {
buttons.push({
icon: "hass:power",
icon: mdiPower,
action: "turn_off",
});
}
@ -267,7 +274,7 @@ export const computeMediaControls = (
supportsFeature(stateObj, SUPPORT_PREVIOUS_TRACK)
) {
buttons.push({
icon: "hass:skip-previous",
icon: mdiSkipPrevious,
action: "media_previous_track",
});
}
@ -285,12 +292,12 @@ export const computeMediaControls = (
buttons.push({
icon:
state === "on"
? "hass:play-pause"
? mdiPlayPause
: state !== "playing"
? "hass:play"
? mdiPlay
: supportsFeature(stateObj, SUPPORT_PAUSE)
? "hass:pause"
: "hass:stop",
? mdiPause
: mdiStop,
action:
state !== "playing"
? "media_play"
@ -305,7 +312,7 @@ export const computeMediaControls = (
supportsFeature(stateObj, SUPPORT_NEXT_TRACK)
) {
buttons.push({
icon: "hass:skip-next",
icon: mdiSkipNext,
action: "media_next_track",
});
}

View File

@ -1,4 +1,5 @@
import {
mdiAlertCircleOutline,
mdiGauge,
mdiWaterPercent,
mdiWeatherFog,
@ -12,7 +13,6 @@ import {
import { css, html, svg, SVGTemplateResult, TemplateResult } from "lit";
import { styleMap } from "lit/directives/style-map";
import { formatNumber } from "../common/number/format_number";
import "../components/ha-icon";
import "../components/ha-svg-icon";
import type { HomeAssistant } from "../types";
@ -57,7 +57,7 @@ export const weatherSVGs = new Set<string>([
]);
export const weatherIcons = {
exceptional: "hass:alert-circle-outline",
exceptional: mdiAlertCircleOutline,
};
export const weatherAttrIcons = {
@ -433,7 +433,10 @@ export const getWeatherStateIcon = (
if (state in weatherIcons) {
return html`
<ha-icon class="weather-icon" .icon=${weatherIcons[state]}></ha-icon>
<ha-svg-icon
class="weather-icon"
.path=${weatherIcons[state]}
></ha-svg-icon>
`;
}

View File

@ -1,5 +1,7 @@
import "@material/mwc-button/mwc-button";
import {
mdiLoginVariant,
mdiMusicNote,
mdiPlayBoxMultiple,
mdiSend,
mdiVolumeHigh,
@ -15,8 +17,8 @@ import { customElement, property, query } from "lit/decorators";
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
import { supportsFeature } from "../../../common/entity/supports-feature";
import { computeRTLDirection } from "../../../common/util/compute_rtl";
import "../../../components/ha-icon";
import "../../../components/ha-icon-button";
import "../../../components/ha-svg-icon";
import "../../../components/ha-paper-dropdown-menu";
import "../../../components/ha-slider";
import { showMediaBrowserDialog } from "../../../components/media-player/show-media-browser-dialog";
@ -62,8 +64,8 @@ class MoreInfoMediaPlayer extends LitElement {
<ha-icon-button
action=${control.action}
@click=${this._handleClick}
.path=${control.icon}
>
<ha-icon .icon=${control.icon}></ha-icon>
</ha-icon-button>
`
)}
@ -130,7 +132,10 @@ class MoreInfoMediaPlayer extends LitElement {
stateObj.attributes.source_list?.length
? html`
<div class="source-input">
<ha-icon class="source-input" icon="hass:login-variant"></ha-icon>
<ha-svg-icon
class="source-input"
.path=${mdiLoginVariant}
></ha-svg-icon>
<ha-paper-dropdown-menu
.label=${this.hass.localize("ui.card.media_player.source")}
>
@ -155,7 +160,7 @@ class MoreInfoMediaPlayer extends LitElement {
stateObj.attributes.sound_mode_list?.length
? html`
<div class="sound-input">
<ha-icon icon="hass:music-note"></ha-icon>
<ha-svg-icon .path=${mdiMusicNote}></ha-svg-icon>
<ha-paper-dropdown-menu
dynamic-align
label-float
@ -228,8 +233,8 @@ class MoreInfoMediaPlayer extends LitElement {
justify-content: space-between;
}
.source-input ha-icon,
.sound-input ha-icon {
.source-input ha-svg-icon,
.sound-input ha-svg-icon {
padding: 7px;
margin-top: 24px;
}

View File

@ -1,4 +1,5 @@
import {
mdiFan,
mdiHomeMapMarker,
mdiMapMarker,
mdiPause,
@ -195,7 +196,7 @@ class MoreInfoVacuum extends LitElement {
style="justify-content: center; align-self: center; padding-top: 1.3em"
>
<span>
<ha-icon icon="hass:fan"></ha-icon>
<ha-svg-icon .path=${mdiFan}></ha-svg-icon>
${stateObj.attributes.fan_speed}
</span>
</div>

View File

@ -386,10 +386,14 @@ export class QuickBar extends LitElement {
private _generateEntityItems(): EntityItem[] {
return Object.keys(this.hass.states)
.map((entityId) => {
const entityState = this.hass.states[entityId];
const entityItem = {
primaryText: computeStateName(this.hass.states[entityId]),
primaryText: computeStateName(entityState),
altText: entityId,
icon: domainIcon(computeDomain(entityId), this.hass.states[entityId]),
icon: entityState.attributes.icon,
iconPath: entityState.attributes.icon
? undefined
: domainIcon(computeDomain(entityId), entityState),
action: () => fireEvent(this, "hass-more-info", { entityId }),
};

View File

@ -1,6 +1,6 @@
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import "../components/ha-icon";
import "../components/ha-svg-icon";
@customElement("action-badge")
class ActionBadge extends LitElement {
@ -15,9 +15,12 @@ class ActionBadge extends LitElement {
protected render(): TemplateResult {
return html`
<div class="icon">
<ha-icon .icon=${this.icon}></ha-icon>
<ha-svg-icon .path=${this.icon}></ha-svg-icon>
${this.badgeIcon
? html` <ha-icon class="badge" .icon=${this.badgeIcon}></ha-icon> `
? html`<ha-svg-icon
class="badge"
.path=${this.badgeIcon}
></ha-svg-icon>`
: ""}
</div>
<div class="title">${this.title}</div>

View File

@ -1,6 +1,6 @@
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import "../components/ha-icon";
import "../components/ha-svg-icon";
import { brandsUrl } from "../util/brands-url";
@customElement("integration-badge")
@ -27,7 +27,10 @@ class IntegrationBadge extends LitElement {
referrerpolicy="no-referrer"
/>
${this.badgeIcon
? html` <ha-icon class="badge" .icon=${this.badgeIcon}></ha-icon> `
? html`<ha-svg-icon
class="badge"
.path=${this.badgeIcon}
></ha-svg-icon>`
: ""}
</div>
<div class="title">${this.title}</div>

View File

@ -8,6 +8,7 @@ import {
TemplateResult,
} from "lit";
import { customElement, property, state } from "lit/decorators";
import { mdiCheck, mdiDotsHorizontal } from "@mdi/js";
import { fireEvent } from "../common/dom/fire_event";
import { stringCompare } from "../common/string/compare";
import { isComponentLoaded } from "../common/config/is_component_loaded";
@ -79,7 +80,7 @@ class OnboardingIntegrations extends LitElement {
<integration-badge
.domain=${entry.domain}
.title=${title}
badgeIcon="hass:check"
.badgeIcon=${mdiCheck}
.darkOptimizedIcon=${this.hass.selectedTheme?.dark}
></integration-badge>
`,
@ -120,7 +121,7 @@ class OnboardingIntegrations extends LitElement {
title=${this.onboardingLocalize(
"ui.panel.page-onboarding.integration.more_integrations"
)}
icon="hass:dots-horizontal"
.icon=${mdiDotsHorizontal}
></action-badge>
</button>
</div>

View File

@ -3,7 +3,6 @@ import "@polymer/app-layout/app-toolbar/app-toolbar";
import { html } from "@polymer/polymer/lib/utils/html-tag";
/* eslint-plugin-disable lit */
import { PolymerElement } from "@polymer/polymer/polymer-element";
import "../../../components/ha-icon-button";
import "../../../layouts/hass-tabs-subpage";
import LocalizeMixin from "../../../mixins/localize-mixin";
import "../../../styles/polymer-ha-style";

View File

@ -132,10 +132,10 @@ export class HaDeviceEntitiesCard extends LitElement {
private _renderEntry(entry: EntityRegistryStateEntry): TemplateResult {
return html`
<paper-icon-item .entry=${entry} @click=${this._openEditEntry}>
<ha-icon
<ha-svg-icon
slot="item-icon"
.icon=${domainIcon(computeDomain(entry.entity_id))}
></ha-icon>
.path=${domainIcon(computeDomain(entry.entity_id))}
></ha-svg-icon>
<paper-item-body>
<div class="name">${entry.stateName || entry.entity_id}</div>
</paper-item-body>

View File

@ -4,9 +4,9 @@ import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../../../common/dom/fire_event";
import { computeStateName } from "../../../../common/entity/compute_state_name";
import { stateIcon } from "../../../../common/entity/state_icon";
import "../../../../components/ha-card";
import "../../../../components/ha-icon-button";
import "../../../../components/ha-state-icon";
import {
DeviceConsumptionEnergyPreference,
EnergyPreferences,
@ -79,7 +79,7 @@ export class EnergyDeviceSettings extends LitElement {
const entityState = this.hass.states[device.stat_consumption];
return html`
<div class="row">
<ha-icon .icon=${stateIcon(entityState)}></ha-icon>
<ha-state-icon .state=${entityState}></ha-state-icon>
<span class="content"
>${entityState
? computeStateName(entityState)

View File

@ -137,11 +137,10 @@ export class EntityRegistrySettings extends SubscribeMixin(LitElement) {
.value=${this._icon}
@value-changed=${this._iconChanged}
.label=${this.hass.localize("ui.dialogs.entity_registry.editor.icon")}
.placeholder=${this.entry.original_icon ||
domainIcon(
computeDomain(this.entry.entity_id),
this.hass.states[this.entry.entity_id]
)}
.placeholder=${this.entry.original_icon || stateObj?.attributes.icon}
.fallbackPath=${!this._icon && !stateObj?.attributes.icon && stateObj
? domainIcon(computeDomain(stateObj.entity_id), stateObj)
: undefined}
.disabled=${this._submitting}
></ha-icon-picker>
<paper-input

View File

@ -1,17 +1,20 @@
import "@material/mwc-list/mwc-list-item";
import type { RequestSelectedDetail } from "@material/mwc-list/mwc-list-item";
import {
mdiAlertCircle,
mdiCancel,
mdiDelete,
mdiFilterVariant,
mdiPencilOff,
mdiPlus,
mdiRestoreAlert,
mdiUndo,
} from "@mdi/js";
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
import "@polymer/paper-item/paper-icon-item";
import "@polymer/paper-listbox/paper-listbox";
import "@polymer/paper-tooltip/paper-tooltip";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, query, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
@ -20,8 +23,6 @@ import memoize from "memoize-one";
import type { HASSDomEvent } from "../../../common/dom/fire_event";
import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { domainIcon } from "../../../common/entity/domain_icon";
import { stateIcon } from "../../../common/entity/state_icon";
import { navigate } from "../../../common/navigate";
import "../../../common/search/search-input";
import { LocalizeFunc } from "../../../common/translations/localize";
@ -75,7 +76,7 @@ export interface StateEntity extends EntityRegistryEntry {
}
export interface EntityRow extends StateEntity {
icon: string;
entity: HassEntity;
unavailable: boolean;
restored: boolean;
status: string;
@ -168,8 +169,11 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
icon: {
title: "",
type: "icon",
template: (icon) => html`
<ha-icon slot="item-icon" .icon=${icon}></ha-icon>
template: (_, entry: any) => html`
<ha-state-icon
slot="item-icon"
.state=${entry.entity}
></ha-state-icon>
`,
},
name: {
@ -249,18 +253,18 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
tabindex="0"
style="display:inline-block; position: relative;"
>
<ha-icon
<ha-svg-icon
style=${styleMap({
color: entity.unavailable ? "var(--error-color)" : "",
})}
.icon=${entity.restored
? "hass:restore-alert"
.path=${entity.restored
? mdiRestoreAlert
: entity.unavailable
? "hass:alert-circle"
? mdiAlertCircle
: entity.disabled_by
? "hass:cancel"
: "hass:pencil-off"}
></ha-icon>
? mdiCancel
: mdiPencilOff}
></ha-svg-icon>
<paper-tooltip animation-delay="0" position="left">
${entity.restored
? this.hass.localize(
@ -371,9 +375,7 @@ export class HaConfigEntities extends SubscribeMixin(LitElement) {
result.push({
...entry,
icon: entity
? stateIcon(entity)
: domainIcon(computeDomain(entry.entity_id)),
entity,
name:
computeEntityRegistryName(this.hass!, entry) ||
this.hass.localize("state.default.unavailable"),

View File

@ -121,10 +121,10 @@ export class DialogHelperDetail extends LitElement {
.platform=${platform}
dialogInitialFocus
>
<ha-icon
<ha-svg-icon
slot="item-icon"
.icon=${domainIcon(platform)}
></ha-icon>
.path=${domainIcon(platform)}
></ha-svg-icon>
<span class="item-text">
${this.hass.localize(
`ui.panel.config.helpers.types.${platform}`

View File

@ -1,4 +1,4 @@
import { mdiPlus } from "@mdi/js";
import { mdiPencilOff, mdiPlus } from "@mdi/js";
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
import "@polymer/paper-item/paper-icon-item";
import "@polymer/paper-listbox/paper-listbox";
@ -42,9 +42,12 @@ export class HaConfigHelpers extends LitElement {
icon: {
title: "",
type: "icon",
template: (icon, helper: any) => html`
<ha-icon .icon=${icon || domainIcon(helper.type)}></ha-icon>
`,
template: (icon, helper: any) =>
icon
? html` <ha-icon .icon=${icon}></ha-icon> `
: html`<ha-svg-icon
.path=${domainIcon(helper.type)}
></ha-svg-icon>`,
},
name: {
title: this.hass.localize(
@ -93,7 +96,7 @@ export class HaConfigHelpers extends LitElement {
tabindex="0"
style="display:inline-block; position: relative;"
>
<ha-icon icon="hass:pencil-off"></ha-icon>
<ha-svg-icon .path=${mdiPencilOff}></ha-svg-icon>
<paper-tooltip animation-delay="0" position="left">
${this.hass.localize(
"ui.panel.config.entities.picker.status.readonly"

View File

@ -691,9 +691,6 @@ class HaConfigIntegrations extends SubscribeMixin(LitElement) {
margin-left: 4px;
font-size: 14px;
}
.active-filters ha-icon {
color: var(--primary-color);
}
.active-filters mwc-button {
margin-left: 8px;
}

View File

@ -6,7 +6,6 @@ import { classMap } from "lit/directives/class-map";
import { navigate } from "../../../../../common/navigate";
import "../../../../../components/buttons/ha-call-service-button";
import "../../../../../components/ha-card";
import "../../../../../components/ha-icon-next";
import {
fetchOZWNetworkStatistics,
fetchOZWNetworkStatus,

View File

@ -11,7 +11,6 @@ import {
RowClickedEvent,
} from "../../../../../components/data-table/ha-data-table";
import "../../../../../components/ha-card";
import "../../../../../components/ha-icon-next";
import { fetchOZWNodes, OZWDevice } from "../../../../../data/ozw";
import "../../../../../layouts/hass-tabs-subpage";
import "../../../../../layouts/hass-tabs-subpage-data-table";

View File

@ -4,7 +4,6 @@ import { customElement, property, state } from "lit/decorators";
import { navigate } from "../../../../../common/navigate";
import "../../../../../components/buttons/ha-call-service-button";
import "../../../../../components/ha-card";
import "../../../../../components/ha-icon-next";
import {
fetchOZWNodeConfig,
fetchOZWNodeMetadata,

View File

@ -4,7 +4,6 @@ import { customElement, property, state } from "lit/decorators";
import { navigate } from "../../../../../common/navigate";
import "../../../../../components/buttons/ha-call-service-button";
import "../../../../../components/ha-card";
import "../../../../../components/ha-icon-next";
import {
fetchOZWNodeMetadata,
fetchOZWNodeStatus,

View File

@ -10,7 +10,6 @@ import {
} from "lit";
import { customElement, property, state } from "lit/decorators";
import "../../../../../components/ha-circular-progress";
import "../../../../../components/ha-icon-button";
import "../../../../../components/ha-service-description";
import {
DEVICE_MESSAGE_TYPES,

View File

@ -1,4 +1,4 @@
import { mdiHelpCircle } from "@mdi/js";
import { mdiCheckboxMarkedCircle, mdiClose, mdiHelpCircle } from "@mdi/js";
import { UnsubscribeFunc } from "home-assistant-js-websocket";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
@ -6,7 +6,7 @@ import "../../../../../components/buttons/ha-call-api-button";
import "../../../../../components/buttons/ha-call-service-button";
import "../../../../../components/ha-card";
import "../../../../../components/ha-circular-progress";
import "../../../../../components/ha-icon";
import "../../../../../components/ha-svg-icon";
import "../../../../../components/ha-icon-button";
import "../../../../../components/ha-service-description";
import {
@ -81,7 +81,7 @@ export class ZwaveNetwork extends LitElement {
<div class="details">
${this._networkStatus.state === ZWAVE_NETWORK_STATE_STOPPED
? html`
<ha-icon icon="hass:close"></ha-icon>
<ha-svg-icon .path=${mdiClose}></ha-svg-icon>
${this.hass!.localize(
"ui.panel.config.zwave.network_status.network_stopped"
)}
@ -100,7 +100,9 @@ export class ZwaveNetwork extends LitElement {
`
: this._networkStatus.state === ZWAVE_NETWORK_STATE_AWAKED
? html`
<ha-icon icon="hass:checkbox-marked-circle"> </ha-icon>
<ha-svg-icon
.path=${mdiCheckboxMarkedCircle}
></ha-svg-icon>
${this.hass!.localize(
"ui.panel.config.zwave.network_status.network_started"
)}<br />
@ -252,7 +254,7 @@ export class ZwaveNetwork extends LitElement {
padding: 24px;
}
.network-status ha-icon {
.network-status ha-svg-icon {
display: block;
margin: 0px auto 16px;
width: 48px;

View File

@ -1,4 +1,9 @@
import { mdiOpenInNew, mdiPlus } from "@mdi/js";
import {
mdiCheck,
mdiCheckCircleOutline,
mdiOpenInNew,
mdiPlus,
} from "@mdi/js";
import "@polymer/paper-tooltip/paper-tooltip";
import { html, LitElement, PropertyValues, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
@ -65,10 +70,10 @@ export class HaConfigLovelaceDashboards extends LitElement {
${title}
${dashboard.default
? html`
<ha-icon
<ha-svg-icon
style="padding-left: 10px;"
icon="hass:check-circle-outline"
></ha-icon>
.path=${mdiCheckCircleOutline}
></ha-svg-icon>
<paper-tooltip animation-delay="0">
${this.hass.localize(
`ui.panel.config.lovelace.dashboards.default_dashboard`
@ -127,7 +132,7 @@ export class HaConfigLovelaceDashboards extends LitElement {
width: "100px",
template: (requireAdmin: boolean) =>
requireAdmin
? html` <ha-icon icon="hass:check"></ha-icon> `
? html` <ha-svg-icon .path=${mdiCheck}></ha-svg-icon> `
: html` - `,
};
columns.show_in_sidebar = {
@ -137,7 +142,9 @@ export class HaConfigLovelaceDashboards extends LitElement {
type: "icon",
width: "121px",
template: (sidebar) =>
sidebar ? html` <ha-icon icon="hass:check"></ha-icon> ` : html` - `,
sidebar
? html` <ha-svg-icon .path=${mdiCheck}></ha-svg-icon> `
: html` - `,
};
}

View File

@ -11,7 +11,6 @@ import {
RowClickedEvent,
} from "../../../../components/data-table/ha-data-table";
import "../../../../components/ha-fab";
import "../../../../components/ha-icon";
import "../../../../components/ha-svg-icon";
import {
createResource,

View File

@ -13,12 +13,11 @@ import { ifDefined } from "lit/directives/if-defined";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../common/dom/fire_event";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { stateIcon } from "../../../common/entity/state_icon";
import { DataTableColumnContainer } from "../../../components/data-table/ha-data-table";
import "../../../components/ha-button-related-filter-menu";
import "../../../components/ha-fab";
import "../../../components/ha-icon";
import "../../../components/ha-icon-button";
import "../../../components/ha-state-icon";
import "../../../components/ha-svg-icon";
import { forwardHaptic } from "../../../data/haptics";
import { activateScene, SceneEntity } from "../../../data/scene";
@ -60,7 +59,6 @@ class HaSceneDashboard extends LitElement {
).map((scene) => ({
...scene,
name: computeStateName(scene),
icon: stateIcon(scene),
}));
}
);
@ -85,7 +83,8 @@ class HaSceneDashboard extends LitElement {
icon: {
title: "",
type: "icon",
template: (icon) => html` <ha-icon .icon=${icon}></ha-icon> `,
template: (_, scene) =>
html` <ha-state-icon .state=${scene}></ha-state-icon> `,
},
name: {
title: this.hass.localize("ui.panel.config.scene.picker.headers.name"),

View File

@ -13,7 +13,6 @@ import memoizeOne from "memoize-one";
import { formatDateTime } from "../../../common/datetime/format_date_time";
import { fireEvent } from "../../../common/dom/fire_event";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { stateIcon } from "../../../common/entity/state_icon";
import { computeRTL } from "../../../common/util/compute_rtl";
import { DataTableColumnContainer } from "../../../components/data-table/ha-data-table";
import "../../../components/ha-button-related-filter-menu";
@ -61,7 +60,6 @@ class HaScriptPicker extends LitElement {
).map((script) => ({
...script,
name: computeStateName(script),
icon: stateIcon(script),
last_triggered: script.attributes.last_triggered || undefined,
}));
}
@ -87,7 +85,8 @@ class HaScriptPicker extends LitElement {
icon: {
title: "",
type: "icon",
template: (icon) => html` <ha-icon .icon=${icon}></ha-icon> `,
template: (_icon, script) =>
html` <ha-state-icon .state=${script}></ha-state-icon>`,
},
name: {
title: this.hass.localize("ui.panel.config.script.picker.headers.name"),

View File

@ -1,4 +1,4 @@
import { mdiPlus } from "@mdi/js";
import { mdiCheck, mdiPlus } from "@mdi/js";
import { html, LitElement, PropertyValues } from "lit";
import { customElement, property } from "lit/decorators";
import memoizeOne from "memoize-one";
@ -89,7 +89,9 @@ export class HaConfigUsers extends LitElement {
filterable: true,
width: "80px",
template: (is_active) =>
is_active ? html`<ha-icon icon="hass:check"> </ha-icon>` : "",
is_active
? html`<ha-svg-icon .path=${mdiCheck}> </ha-svg-icon>`
: "",
},
system_generated: {
title: this.hass.localize(
@ -100,7 +102,9 @@ export class HaConfigUsers extends LitElement {
filterable: true,
width: "160px",
template: (generated) =>
generated ? html`<ha-icon icon="hass:check"> </ha-icon>` : "",
generated
? html`<ha-svg-icon .path=${mdiCheck}> </ha-svg-icon>`
: "",
},
};

View File

@ -4,7 +4,6 @@ import "@polymer/paper-tabs/paper-tab";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property } from "lit/decorators";
import { navigate } from "../../common/navigate";
import "../../components/ha-icon-button";
import "../../components/ha-menu-button";
import "../../components/ha-tabs";
import "../../layouts/ha-app-layout";

View File

@ -122,9 +122,6 @@ class PanelEnergy extends LitElement {
return [
haStyle,
css`
ha-icon-button {
color: var(--text-primary-color);
}
app-toolbar {
display: flex;
justify-content: space-between;

View File

@ -155,7 +155,7 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
.label=${this._stateIconLabel(stateObj.state)}
@click=${this._handleMoreInfo}
>
<ha-icon .icon=${alarmPanelIcon(stateObj.state)}></ha-icon>
<ha-svg-icon .path=${alarmPanelIcon(stateObj.state)}></ha-svg-icon>
</ha-label-badge>
<div id="armActions" class="actions">
${(stateObj.state === "disarmed"

View File

@ -26,7 +26,6 @@ import { computeDomain } from "../../../common/entity/compute_domain";
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 { stateIcon } from "../../../common/entity/state_icon";
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
import { iconColorCSS } from "../../../common/style/icon_color_css";
import "../../../components/ha-card";
@ -167,7 +166,7 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
>
${this._config.show_icon
? html`
<ha-icon
<ha-state-icon
tabindex="-1"
data-domain=${ifDefined(
this._config.state_color && stateObj
@ -177,8 +176,8 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
data-state=${ifDefined(
stateObj ? computeActiveState(stateObj) : undefined
)}
.icon=${this._config.icon ||
(stateObj ? stateIcon(stateObj) : "")}
.icon=${this._config.icon}
.state=${stateObj}
style=${styleMap({
filter: stateObj ? this._computeBrightness(stateObj) : "",
color: stateObj ? this._computeColor(stateObj) : "",
@ -186,7 +185,7 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
? this._config.icon_height
: "",
})}
></ha-icon>
></ha-state-icon>
`
: ""}
${this._config.show_name
@ -270,18 +269,18 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
outline: none;
}
ha-icon {
ha-state-icon {
width: 40%;
height: auto;
color: var(--paper-item-icon-color, #44739e);
--mdc-icon-size: 100%;
}
ha-icon + span {
ha-state-icon + span {
margin-top: 8px;
}
ha-icon,
ha-state-icon,
span {
outline: none;
}

View File

@ -12,7 +12,6 @@ import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_elemen
import { HASSDomEvent } from "../../../common/dom/fire_event";
import { debounce } from "../../../common/util/debounce";
import "../../../components/ha-card";
import "../../../components/ha-icon";
import { Calendar, fetchCalendarEvents } from "../../../data/calendar";
import type {
CalendarEvent,

View File

@ -14,7 +14,6 @@ import { computeActiveState } from "../../../common/entity/compute_active_state"
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 { stateIcon } from "../../../common/entity/state_icon";
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
import { formatNumber } from "../../../common/number/format_number";
import { iconColorCSS } from "../../../common/style/icon_color_css";
@ -122,8 +121,9 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
<div class="header">
<div class="name" .title=${name}>${name}</div>
<div class="icon">
<ha-icon
.icon=${this._config.icon || stateIcon(stateObj)}
<ha-state-icon
.icon=${this._config.icon}
.state=${stateObj}
data-domain=${ifDefined(
this._config.state_color ||
(domain === "light" && this._config.state_color !== false)
@ -131,7 +131,7 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
: undefined
)}
data-state=${stateObj ? computeActiveState(stateObj) : ""}
></ha-icon>
></ha-state-icon>
</div>
</div>
<div class="info">

View File

@ -15,10 +15,9 @@ import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_elemen
import { fireEvent } from "../../../common/dom/fire_event";
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { stateIcon } from "../../../common/entity/state_icon";
import "../../../components/ha-card";
import "../../../components/ha-icon";
import "../../../components/ha-icon-button";
import "../../../components/ha-state-icon";
import { UNAVAILABLE, UNAVAILABLE_STATES } from "../../../data/entity";
import { LightEntity, lightSupportsDimming } from "../../../data/light";
import { ActionHandlerEvent } from "../../../data/lovelace";
@ -145,9 +144,10 @@ export class HuiLightCard extends LitElement implements LovelaceCard {
})}
tabindex="0"
>
<ha-icon
.icon=${this._config.icon || stateIcon(stateObj)}
></ha-icon>
<ha-state-icon
.icon=${this._config.icon}
.state=${stateObj}
></ha-state-icon>
</ha-icon-button>
</div>
</div>

View File

@ -15,12 +15,11 @@ import { styleMap } from "lit/directives/style-map";
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
import { fireEvent } from "../../../common/dom/fire_event";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { stateIcon } from "../../../common/entity/state_icon";
import { supportsFeature } from "../../../common/entity/supports-feature";
import { extractColors } from "../../../common/image/extract_color";
import { debounce } from "../../../common/util/debounce";
import "../../../components/ha-card";
import "../../../components/ha-icon";
import "../../../components/ha-state-icon";
import "../../../components/ha-icon-button";
import { showMediaBrowserDialog } from "../../../components/media-player/show-media-browser-dialog";
import { UNAVAILABLE_STATES } from "../../../data/entity";
@ -227,7 +226,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
>
<div class="top-info">
<div class="icon-name">
<ha-icon class="icon" .icon=${stateIcon(stateObj)}></ha-icon>
<ha-state-icon class="icon" .state=${stateObj}></ha-state-icon>
<div>
${this._config!.name ||
computeStateName(this.hass!.states[this._config!.entity])}
@ -272,10 +271,10 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
.label=${this.hass.localize(
`ui.card.media_player.${control.action}`
)}
.path=${control.icon}
action=${control.action}
@click=${this._handleClick}
>
<ha-icon .icon=${control.icon}></ha-icon>
</ha-icon-button>
`
)}
@ -706,7 +705,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
align-items: center;
}
.icon-name ha-icon {
.icon-name ha-state-icon {
padding-right: 8px;
}

View File

@ -14,10 +14,9 @@ import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_elemen
import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { stateIcon } from "../../../common/entity/state_icon";
import "../../../components/ha-card";
import "../../../components/ha-icon";
import "../../../components/ha-icon-button";
import "../../../components/ha-state-icon";
import { ActionHandlerEvent } from "../../../data/lovelace";
import { HomeAssistant } from "../../../types";
import { actionHandler } from "../common/directives/action-handler-directive";
@ -253,14 +252,18 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard {
class=${classMap({
"state-on": !STATES_OFF.has(stateObj.state),
})}
.label=${`${computeStateName(stateObj)} : ${computeStateDisplay(
title=${`${computeStateName(stateObj)} : ${computeStateDisplay(
this.hass!.localize,
stateObj,
this.hass!.locale
)}`}
>
<ha-icon .icon=${entityConf.icon || stateIcon(stateObj)}></ha-icon>
<ha-state-icon
.icon=${entityConf.icon}
.state=${stateObj}
></ha-state-icon>
</ha-icon-button>
${this._config!.show_state !== true && entityConf.show_state !== true
? html`<div class="state"></div>`
: html`

View File

@ -1,3 +1,9 @@
import {
mdiEmoticonPoop,
mdiThermometer,
mdiWater,
mdiWhiteBalanceSunny,
} from "@mdi/js";
import { HassEntity } from "home-assistant-js-websocket";
import {
css,
@ -10,9 +16,10 @@ import {
import { customElement, property, state } from "lit/decorators";
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
import { fireEvent } from "../../../common/dom/fire_event";
import { batteryIcon } from "../../../common/entity/battery_icon";
import { computeStateName } from "../../../common/entity/compute_state_name";
import "../../../components/ha-card";
import "../../../components/ha-icon";
import "../../../components/ha-svg-icon";
import { HomeAssistant } from "../../../types";
import { actionHandler } from "../common/directives/action-handler-directive";
import { findEntities } from "../common/find-entities";
@ -21,12 +28,12 @@ import { createEntityNotFoundWarning } from "../components/hui-warning";
import { LovelaceCard, LovelaceCardEditor } from "../types";
import { PlantAttributeTarget, PlantStatusCardConfig } from "./types";
const SENSORS = {
moisture: "hass:water",
temperature: "hass:thermometer",
brightness: "hass:white-balance-sunny",
conductivity: "hass:emoticon-poop",
battery: "hass:battery",
const SENSOR_ICONS = {
moisture: mdiWater,
temperature: mdiThermometer,
brightness: mdiWhiteBalanceSunny,
conductivity: mdiEmoticonPoop,
battery: undefined,
};
@customElement("hui-plant-status-card")
@ -132,9 +139,9 @@ class HuiPlantStatusCard extends LitElement implements LovelaceCard {
.value=${item}
>
<div>
<ha-icon
icon=${this.computeIcon(item, stateObj.attributes.battery)}
></ha-icon>
<ha-svg-icon
.path=${this.computeIcon(item, stateObj.attributes.battery)}
></ha-svg-icon>
</div>
<div
class=${stateObj.attributes.problem.indexOf(item) === -1
@ -207,7 +214,7 @@ class HuiPlantStatusCard extends LitElement implements LovelaceCard {
padding-bottom: 16px;
}
ha-icon {
ha-svg-icon {
color: var(--paper-item-icon-color);
margin-bottom: 8px;
}
@ -238,20 +245,16 @@ class HuiPlantStatusCard extends LitElement implements LovelaceCard {
}
private computeAttributes(stateObj: HassEntity): string[] {
return Object.keys(SENSORS).filter((key) => key in stateObj.attributes);
return Object.keys(SENSOR_ICONS).filter(
(key) => key in stateObj.attributes
);
}
private computeIcon(attr: string, batLvl: number): string {
const icon = SENSORS[attr];
if (attr === "battery") {
if (batLvl <= 5) {
return `${icon}-alert`;
return batteryIcon(batLvl);
}
if (batLvl < 95) {
return `${icon}-${Math.round(batLvl / 10 - 0.01) * 10}`;
}
}
return icon;
return SENSOR_ICONS[attr];
}
private _handleMoreInfo(ev: Event): void {

View File

@ -15,7 +15,7 @@ import { guard } from "lit/directives/guard";
import { repeat } from "lit/directives/repeat";
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
import "../../../components/ha-card";
import "../../../components/ha-icon";
import "../../../components/ha-svg-icon";
import "../../../components/ha-checkbox";
import {
addItem,
@ -366,11 +366,6 @@ class HuiShoppingListCard
align-items: center;
}
.addRow ha-icon {
color: var(--secondary-text-color);
--mdc-icon-size: 26px;
}
.addButton {
padding-right: 16px;
cursor: pointer;

View File

@ -1,4 +1,13 @@
import { mdiDotsVertical } from "@mdi/js";
import {
mdiAutorenew,
mdiCalendarSync,
mdiDotsVertical,
mdiFan,
mdiFire,
mdiPower,
mdiSnowflake,
mdiWaterPercent,
} from "@mdi/js";
import "@thomasloven/round-slider";
import { HassEntity } from "home-assistant-js-websocket";
import {
@ -19,7 +28,6 @@ import { computeStateName } from "../../../common/entity/compute_state_name";
import { formatNumber } from "../../../common/number/format_number";
import "../../../components/ha-card";
import type { HaCard } from "../../../components/ha-card";
import "../../../components/ha-icon";
import "../../../components/ha-icon-button";
import {
ClimateEntity,
@ -36,13 +44,13 @@ import { LovelaceCard, LovelaceCardEditor } from "../types";
import { ThermostatCardConfig } from "./types";
const modeIcons: { [mode in HvacMode]: string } = {
auto: "hass:calendar-sync",
heat_cool: "hass:autorenew",
heat: "hass:fire",
cool: "hass:snowflake",
off: "hass:power",
fan_only: "hass:fan",
dry: "hass:water-percent",
auto: mdiCalendarSync,
heat_cool: mdiAutorenew,
heat: mdiFire,
cool: mdiSnowflake,
off: mdiPower,
fan_only: mdiFan,
dry: mdiWaterPercent,
};
@customElement("hui-thermostat-card")
@ -418,8 +426,8 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
.mode=${mode}
@click=${this._handleAction}
tabindex="0"
.path=${modeIcons[mode]}
>
<ha-icon .icon=${modeIcons[mode]}></ha-icon>
</ha-icon-button>
`;
}

View File

@ -12,12 +12,11 @@ import { formatTime } from "../../../common/datetime/format_time";
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { stateIcon } from "../../../common/entity/state_icon";
import { isValidEntityId } from "../../../common/entity/valid_entity_id";
import { formatNumber } from "../../../common/number/format_number";
import { debounce } from "../../../common/util/debounce";
import "../../../components/ha-card";
import "../../../components/ha-icon";
import "../../../components/ha-svg-icon";
import { UNAVAILABLE } from "../../../data/entity";
import { ActionHandlerEvent } from "../../../data/lovelace";
import {
@ -207,10 +206,10 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
<div class="icon-image">
${weatherStateIcon ||
html`
<ha-icon
<ha-state-icon
class="weather-icon"
.icon=${stateIcon(stateObj)}
></ha-icon>
.state=${stateObj}
></ha-state-icon>
`}
</div>
<div class="info">

View File

@ -15,7 +15,6 @@ import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { computeRTL } from "../../../common/util/compute_rtl";
import "../../../components/entity/state-badge";
import "../../../components/ha-icon";
import "../../../components/ha-relative-time";
import { ActionHandlerEvent } from "../../../data/lovelace";
import { HomeAssistant } from "../../../types";

View File

@ -1,3 +1,4 @@
import { mdiClose } from "@mdi/js";
import "@polymer/paper-dropdown-menu/paper-dropdown-menu";
import "@polymer/paper-item/paper-item";
import "@polymer/paper-listbox/paper-listbox";
@ -6,7 +7,7 @@ import { customElement, property, state } from "lit/decorators";
import { array, assert, assign, object, optional, string } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/entity/ha-entity-picker";
import "../../../../components/ha-icon";
import "../../../../components/ha-svg-icon";
import { HomeAssistant } from "../../../../types";
import { AlarmPanelCardConfig } from "../../cards/types";
import "../../components/hui-theme-select-editor";
@ -73,12 +74,11 @@ export class HuiAlarmPanelCardEditor
return html`
<div class="card-config">
<ha-entity-picker
.label=${this.hass.localize(
.label=${`${this.hass.localize(
"ui.panel.lovelace.editor.card.generic.entity"
)}
(${this.hass.localize(
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.required"
)})
)})`}
.hass=${this.hass}
.value=${this._entity}
.configValue=${"entity"}
@ -87,12 +87,11 @@ export class HuiAlarmPanelCardEditor
allow-custom-entity
></ha-entity-picker>
<paper-input
.label=${this.hass.localize(
.label=${`${this.hass.localize(
"ui.panel.lovelace.editor.card.generic.name"
)}
(${this.hass.localize(
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})
)})`}
.value=${this._name}
.configValue=${"name"}
@value-changed=${this._valueChanged}
@ -101,12 +100,12 @@ export class HuiAlarmPanelCardEditor
(entityState, index) => html`
<div class="states">
<paper-item>${entityState}</paper-item>
<ha-icon
<ha-svg-icon
class="deleteState"
.value=${index}
icon="hass:close"
.path=${mdiClose}
@click=${this._stateRemoved}
></ha-icon>
></ha-svg-icon>
</div>
`
)}
@ -146,7 +145,7 @@ export class HuiAlarmPanelCardEditor
.states:hover > .deleteState {
visibility: visible;
}
ha-icon {
ha-svg-icon {
padding-top: 12px;
}
`,

View File

@ -3,7 +3,6 @@ import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { assert, boolean, object, optional, string, assign } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event";
import { stateIcon } from "../../../../common/entity/state_icon";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import "../../../../components/ha-formfield";
import "../../../../components/ha-icon-picker";
@ -19,6 +18,8 @@ import { actionConfigStruct } from "../structs/action-struct";
import { EditorTarget } from "../types";
import { configElementStyle } from "./config-elements-style";
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
import { computeDomain } from "../../../../common/entity/compute_domain";
import { domainIcon } from "../../../../common/entity/domain_icon";
const cardConfigStruct = assign(
baseLovelaceCardConfig,
@ -107,6 +108,7 @@ export class HuiButtonCardEditor
}
const dir = computeRTLDirection(this.hass!);
const entityState = this.hass.states[this._entity];
return html`
<div class="card-config">
@ -140,8 +142,12 @@ export class HuiButtonCardEditor
"ui.panel.lovelace.editor.card.config.optional"
)})"
.value=${this._icon}
.placeholder=${this._icon ||
stateIcon(this.hass.states[this._entity])}
.placeholder=${this._icon || entityState?.attributes.icon}
.fallbackPath=${!this._icon &&
!entityState?.attributes.icon &&
entityState
? domainIcon(computeDomain(entityState.entity_id), entityState)
: undefined}
.configValue=${"icon"}
@value-changed=${this._valueChanged}
></ha-icon-picker>

View File

@ -3,7 +3,8 @@ import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { assert, assign, boolean, object, optional, string } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event";
import { stateIcon } from "../../../../common/entity/state_icon";
import { computeDomain } from "../../../../common/entity/compute_domain";
import { domainIcon } from "../../../../common/entity/domain_icon";
import "../../../../components/entity/ha-entity-attribute-picker";
import "../../../../components/ha-icon-picker";
import { HomeAssistant } from "../../../../types";
@ -77,6 +78,7 @@ export class HuiEntityCardEditor
if (!this.hass || !this._config) {
return html``;
}
const entityState = this.hass.states[this._entity];
return html`
<div class="card-config">
@ -110,8 +112,12 @@ export class HuiEntityCardEditor
"ui.panel.lovelace.editor.card.config.optional"
)})"
.value=${this._icon}
.placeholder=${this._icon ||
stateIcon(this.hass.states[this._entity])}
.placeholder=${this._icon || entityState?.attributes.icon}
.fallbackPath=${!this._icon &&
!entityState?.attributes.icon &&
entityState
? domainIcon(computeDomain(entityState.entity_id), entityState)
: undefined}
.configValue=${"icon"}
@value-changed=${this._valueChanged}
></ha-icon-picker>

View File

@ -4,7 +4,7 @@ import { customElement, property, state } from "lit/decorators";
import { assert } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event";
import { computeDomain } from "../../../../common/entity/compute_domain";
import { stateIcon } from "../../../../common/entity/state_icon";
import { domainIcon } from "../../../../common/entity/domain_icon";
import "../../../../components/ha-formfield";
import "../../../../components/ha-icon-picker";
import "../../../../components/ha-switch";
@ -64,6 +64,7 @@ export class HuiGenericEntityRowEditor
}
const domain = computeDomain(this._entity);
const entityState = this.hass.states[this._entity];
return html`
<div class="card-config">
@ -88,8 +89,13 @@ export class HuiGenericEntityRowEditor
"ui.panel.lovelace.editor.card.generic.icon"
)}
.value=${this._config.icon}
.placeholder=${stateIcon(this.hass!.states[this._config.entity])}
.configValue=${"icon"}
.placeholder=${entityState?.attributes.icon}
.fallbackPath=${!this._icon &&
!entityState?.attributes.icon &&
entityState
? domainIcon(computeDomain(entityState.entity_id), entityState)
: undefined}
@value-changed=${this._valueChanged}
></ha-icon-picker>
</div>

View File

@ -3,7 +3,6 @@ import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { assert, object, optional, string, assign } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event";
import { stateIcon } from "../../../../common/entity/state_icon";
import "../../../../components/ha-icon-picker";
import { ActionConfig } from "../../../../data/lovelace";
import { HomeAssistant } from "../../../../types";
@ -16,6 +15,8 @@ import { actionConfigStruct } from "../structs/action-struct";
import { EditorTarget } from "../types";
import { configElementStyle } from "./config-elements-style";
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
import { domainIcon } from "../../../../common/entity/domain_icon";
import { computeDomain } from "../../../../common/entity/compute_domain";
const cardConfigStruct = assign(
baseLovelaceCardConfig,
@ -83,6 +84,8 @@ export class HuiLightCardEditor
"none",
];
const entityState = this.hass.states[this._entity];
return html`
<div class="card-config">
<ha-entity-picker
@ -116,8 +119,12 @@ export class HuiLightCardEditor
"ui.panel.lovelace.editor.card.config.optional"
)})"
.value=${this._icon}
.placeholder=${this._icon ||
stateIcon(this.hass.states[this._entity])}
.placeholder=${this._icon || entityState?.attributes.icon}
.fallbackPath=${!this._icon &&
!entityState?.attributes.icon &&
entityState
? domainIcon(computeDomain(entityState.entity_id), entityState)
: undefined}
.configValue=${"icon"}
@value-changed=${this._valueChanged}
></ha-icon-picker>

View File

@ -4,7 +4,6 @@ import { customElement, property, state } from "lit/decorators";
import { assert, assign, object, optional, string } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event";
import "../../../../components/entity/ha-entity-picker";
import "../../../../components/ha-icon";
import { HomeAssistant } from "../../../../types";
import { PlantStatusCardConfig } from "../../cards/types";
import "../../components/hui-theme-select-editor";

View File

@ -6,7 +6,8 @@ import { CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { assert, assign, number, object, optional, string } from "superstruct";
import { fireEvent } from "../../../../common/dom/fire_event";
import { stateIcon } from "../../../../common/entity/state_icon";
import { computeDomain } from "../../../../common/entity/compute_domain";
import { domainIcon } from "../../../../common/entity/domain_icon";
import "../../../../components/entity/ha-entity-picker";
import "../../../../components/ha-formfield";
import "../../../../components/ha-icon-picker";
@ -88,6 +89,8 @@ export class HuiSensorCardEditor
const graphs = ["line", "none"];
const entityState = this.hass.states[this._entity];
return html`
<div class="card-config">
<ha-entity-picker
@ -121,8 +124,12 @@ export class HuiSensorCardEditor
"ui.panel.lovelace.editor.card.config.optional"
)})"
.value=${this._icon}
.placeholder=${this._icon ||
stateIcon(this.hass.states[this._entity])}
.placeholder=${this._icon || entityState?.attributes.icon}
.fallbackPath=${!this._icon &&
!entityState?.attributes.icon &&
entityState
? domainIcon(computeDomain(entityState.entity_id), entityState)
: undefined}
.configValue=${"icon"}
@value-changed=${this._valueChanged}
></ha-icon-picker>

View File

@ -8,7 +8,6 @@ import { navigate } from "../../../../common/navigate";
import "../../../../components/ha-circular-progress";
import "../../../../components/ha-dialog";
import "../../../../components/ha-alert";
import "../../../../components/ha-icon-button";
import type {
LovelaceBadgeConfig,
LovelaceCardConfig,

View File

@ -13,7 +13,6 @@ import { DOMAINS_HIDE_MORE_INFO } from "../../../common/const";
import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { stateIcon } from "../../../common/entity/state_icon";
import { formatNumber } from "../../../common/number/format_number";
import "../../../components/entity/state-badge";
import { UNAVAILABLE_STATES } from "../../../data/entity";
@ -89,7 +88,10 @@ class HuiWeatherEntityRow extends LitElement implements LovelaceRow {
>
${weatherStateIcon ||
html`
<ha-icon class="weather-icon" .icon=${stateIcon(stateObj)}></ha-icon>
<ha-state-icon
class="weather-icon"
.state=${stateObj}
></ha-state-icon>
`}
</div>
<div

View File

@ -20,7 +20,6 @@ import { deepEqual } from "../../common/util/deep-equal";
import "../../components/ha-circular-progress";
import "../../components/ha-code-editor";
import type { HaCodeEditor } from "../../components/ha-code-editor";
import "../../components/ha-icon";
import "../../components/ha-icon-button";
import type { LovelaceConfig } from "../../data/lovelace";
import {

View File

@ -4,14 +4,13 @@ import { customElement, state } from "lit/decorators";
import { DOMAINS_TOGGLE } from "../../../common/const";
import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateName } from "../../../common/entity/compute_state_name";
import { stateIcon } from "../../../common/entity/state_icon";
import "../../../components/ha-icon";
import { ActionHandlerEvent } from "../../../data/lovelace";
import { HomeAssistant } from "../../../types";
import { actionHandler } from "../common/directives/action-handler-directive";
import { handleAction } from "../common/handle-action";
import { hasAction } from "../common/has-action";
import { ButtonRowConfig, LovelaceRow } from "../entity-rows/types";
import "../../../components/ha-state-icon";
@customElement("hui-button-row")
export class HuiButtonRow extends LitElement implements LovelaceRow {
@ -54,11 +53,8 @@ export class HuiButtonRow extends LitElement implements LovelaceRow {
this._config.name ?? (stateObj ? computeStateName(stateObj) : "");
return html`
<ha-icon
.icon=${this._config.icon ||
(stateObj ? stateIcon(stateObj) : "hass:remote")}
>
</ha-icon>
<ha-state-icon .icon=${this._config.icon} .state=${stateObj}>
</ha-state-icon>
<div class="flex">
<div .title=${name}>${name}</div>
<mwc-button
@ -81,7 +77,7 @@ export class HuiButtonRow extends LitElement implements LovelaceRow {
display: flex;
align-items: center;
}
ha-icon {
ha-state-icon {
padding: 8px;
color: var(--paper-item-icon-color);
}

View File

@ -1,6 +1,5 @@
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, state } from "lit/decorators";
import "../../../components/ha-icon";
import { HomeAssistant } from "../../../types";
import { LovelaceRow, SectionConfig } from "../entity-rows/types";