+
+ ${picture
+ ? html`
![](${picture})
`
+ : weatherSvg
+ ? weatherSvg
+ : icon
+ ? html`
+
+ `
+ : nothing}
+ ${content
+ ? html`
+
+ ${label ? html`${label}` : nothing}
+ ${content}
+
+ `
+ : nothing}
+
+ `;
+ }
+
+ private _handleAction(ev: ActionHandlerEvent) {
+ handleAction(this, this.hass!, this._config!, ev.detail.action!);
+ }
+
+ public isTemplate(key: TemplateKey) {
+ const value = this._config?.[key];
+ return value?.includes("{");
+ }
+
+ private getValue(key: TemplateKey) {
+ return this.isTemplate(key)
+ ? this._templateResults[key]?.result?.toString()
+ : this._config?.[key];
+ }
+
+ static get styles(): CSSResultGroup {
+ return css`
+ :host {
+ -webkit-tap-highlight-color: transparent;
+ }
+ .badge {
+ position: relative;
+ --ha-ripple-color: var(--badge-color);
+ --ha-ripple-hover-opacity: 0.04;
+ --ha-ripple-pressed-opacity: 0.12;
+ transition:
+ box-shadow 180ms ease-in-out,
+ border-color 180ms ease-in-out;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+ gap: 8px;
+ height: 36px;
+ min-width: 36px;
+ padding: 0px 8px;
+ box-sizing: border-box;
+ width: auto;
+ border-radius: 18px;
+ background-color: var(--card-background-color, white);
+ border-width: var(--ha-card-border-width, 1px);
+ border-style: solid;
+ border-color: var(
+ --ha-card-border-color,
+ var(--divider-color, #e0e0e0)
+ );
+ --mdc-icon-size: 18px;
+ text-align: center;
+ font-family: Roboto;
+ }
+ .badge:focus-visible {
+ --shadow-default: var(--ha-card-box-shadow, 0 0 0 0 transparent);
+ --shadow-focus: 0 0 0 1px var(--badge-color);
+ border-color: var(--badge-color);
+ box-shadow: var(--shadow-default), var(--shadow-focus);
+ }
+ button,
+ [role="button"] {
+ cursor: pointer;
+ }
+ button:focus,
+ [role="button"]:focus {
+ outline: none;
+ }
+ .content {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+ padding-right: 4px;
+ padding-inline-end: 4px;
+ padding-inline-start: initial;
+ }
+ .name {
+ font-size: 10px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: 10px;
+ letter-spacing: 0.1px;
+ color: var(--secondary-text-color);
+ }
+ .state {
+ font-size: 12px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: 16px;
+ letter-spacing: 0.1px;
+ color: var(--primary-text-color);
+ }
+ svg {
+ width: var(--mdc-icon-size);
+ height: var(--mdc-icon-size);
+ display: flex;
+ }
+ ha-state-icon {
+ color: var(--badge-color);
+ line-height: 0;
+ }
+ img {
+ width: 30px;
+ height: 30px;
+ border-radius: 50%;
+ object-fit: cover;
+ overflow: hidden;
+ }
+ .badge.icon-only {
+ padding: 0;
+ }
+ .badge:not(.icon-only) img {
+ margin-left: -6px;
+ margin-inline-start: -6px;
+ margin-inline-end: initial;
+ }
+ .badge.content-only .content {
+ padding-right: 4px;
+ padding-left: 4px;
+ padding-inline-end: 4px;
+ padding-inline-start: 4px;
+ }
+ ${weatherSVGStyles}
+ `;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "hui-entity-badge": HuiEntityBadge;
+ }
+}
diff --git a/src/cards/template-card/template-card.ts b/src/cards/template-card/template-card.ts
index 721058297..d67841ac7 100644
--- a/src/cards/template-card/template-card.ts
+++ b/src/cards/template-card/template-card.ts
@@ -38,8 +38,8 @@ import { TemplateCardConfig } from "./template-card-config";
registerCustomCard({
type: TEMPLATE_CARD_NAME,
- name: "Mushroom Template Card",
- description: "Card for custom rendering with templates",
+ name: "Mushroom Template",
+ description: "Build your own mushroom card using templates",
});
const TEMPLATE_KEYS = [
diff --git a/src/ha/common/color/compute-color.ts b/src/ha/common/color/compute-color.ts
new file mode 100644
index 000000000..bd28631c1
--- /dev/null
+++ b/src/ha/common/color/compute-color.ts
@@ -0,0 +1,35 @@
+export const THEME_COLORS = new Set([
+ "primary",
+ "accent",
+ "disabled",
+ "red",
+ "pink",
+ "purple",
+ "deep-purple",
+ "indigo",
+ "blue",
+ "light-blue",
+ "cyan",
+ "teal",
+ "green",
+ "light-green",
+ "lime",
+ "yellow",
+ "amber",
+ "orange",
+ "deep-orange",
+ "brown",
+ "light-grey",
+ "grey",
+ "dark-grey",
+ "blue-grey",
+ "black",
+ "white",
+]);
+
+export function computeCssColor(color: string): string {
+ if (THEME_COLORS.has(color)) {
+ return `var(--${color}-color)`;
+ }
+ return color;
+}
diff --git a/src/ha/panels/lovelace/types.ts b/src/ha/panels/lovelace/types.ts
index 9a1e2eda3..2f7d32c77 100644
--- a/src/ha/panels/lovelace/types.ts
+++ b/src/ha/panels/lovelace/types.ts
@@ -1,4 +1,8 @@
-import { LovelaceCardConfig, LovelaceConfig } from "../../data/lovelace";
+import {
+ LovelaceBadgeConfig,
+ LovelaceCardConfig,
+ LovelaceConfig,
+} from "../../data/lovelace";
import { FrontendLocaleData } from "../../data/translation";
import { Constructor, HomeAssistant } from "../../types";
@@ -24,6 +28,11 @@ export interface Lovelace {
deleteConfig: () => Promise