mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-25 13:57:21 +00:00
Group entities in area card by domain (#10767)
* Group entities in area card by domain * Update hui-area-card.ts * Update * Add background color when no image * Add camera support * exclude unavailable states * Update hui-area-card.ts
This commit is contained in:
parent
60ce805b3b
commit
48d12ceafe
@ -1,4 +1,12 @@
|
|||||||
import "@material/mwc-ripple";
|
import "@material/mwc-ripple";
|
||||||
|
import {
|
||||||
|
mdiLightbulbMultiple,
|
||||||
|
mdiLightbulbMultipleOff,
|
||||||
|
mdiRun,
|
||||||
|
mdiToggleSwitch,
|
||||||
|
mdiToggleSwitchOff,
|
||||||
|
mdiWaterPercent,
|
||||||
|
} from "@mdi/js";
|
||||||
import type { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
import type { HassEntity, UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
@ -10,13 +18,13 @@ import {
|
|||||||
} from "lit";
|
} from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { styleMap } from "lit/directives/style-map";
|
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
|
import { STATES_OFF } from "../../../common/const";
|
||||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
|
||||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
import { computeStateDisplay } from "../../../common/entity/compute_state_display";
|
import { domainIcon } from "../../../common/entity/domain_icon";
|
||||||
import { navigate } from "../../../common/navigate";
|
import { navigate } from "../../../common/navigate";
|
||||||
|
import { formatNumber } from "../../../common/number/format_number";
|
||||||
import "../../../components/entity/state-badge";
|
import "../../../components/entity/state-badge";
|
||||||
import "../../../components/ha-card";
|
import "../../../components/ha-card";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
@ -30,31 +38,40 @@ import {
|
|||||||
DeviceRegistryEntry,
|
DeviceRegistryEntry,
|
||||||
subscribeDeviceRegistry,
|
subscribeDeviceRegistry,
|
||||||
} from "../../../data/device_registry";
|
} from "../../../data/device_registry";
|
||||||
|
import { UNAVAILABLE_STATES } from "../../../data/entity";
|
||||||
import {
|
import {
|
||||||
EntityRegistryEntry,
|
EntityRegistryEntry,
|
||||||
subscribeEntityRegistry,
|
subscribeEntityRegistry,
|
||||||
} from "../../../data/entity_registry";
|
} from "../../../data/entity_registry";
|
||||||
import { forwardHaptic } from "../../../data/haptics";
|
import { forwardHaptic } from "../../../data/haptics";
|
||||||
import { ActionHandlerEvent } from "../../../data/lovelace";
|
|
||||||
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
|
||||||
import { toggleEntity } from "../common/entity/toggle-entity";
|
|
||||||
import "../components/hui-warning";
|
import "../components/hui-warning";
|
||||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
||||||
import { AreaCardConfig } from "./types";
|
import { AreaCardConfig } from "./types";
|
||||||
|
|
||||||
const SENSOR_DOMAINS = new Set(["sensor", "binary_sensor"]);
|
const SENSOR_DOMAINS = ["sensor"];
|
||||||
|
|
||||||
const SENSOR_DEVICE_CLASSES = new Set([
|
const ALERT_DOMAINS = ["binary_sensor"];
|
||||||
"temperature",
|
|
||||||
"humidity",
|
|
||||||
"motion",
|
|
||||||
"door",
|
|
||||||
"aqi",
|
|
||||||
]);
|
|
||||||
|
|
||||||
const TOGGLE_DOMAINS = new Set(["light", "fan", "switch"]);
|
const TOGGLE_DOMAINS = ["light", "switch", "fan"];
|
||||||
|
|
||||||
|
const OTHER_DOMAINS = ["camera"];
|
||||||
|
|
||||||
|
const DEVICE_CLASSES = {
|
||||||
|
sensor: ["temperature"],
|
||||||
|
binary_sensor: ["motion"],
|
||||||
|
};
|
||||||
|
|
||||||
|
const DOMAIN_ICONS = {
|
||||||
|
light: { on: mdiLightbulbMultiple, off: mdiLightbulbMultipleOff },
|
||||||
|
switch: { on: mdiToggleSwitch, off: mdiToggleSwitchOff },
|
||||||
|
fan: { on: domainIcon("fan"), off: domainIcon("fan") },
|
||||||
|
sensor: { humidity: mdiWaterPercent },
|
||||||
|
binary_sensor: {
|
||||||
|
motion: mdiRun,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
@customElement("hui-area-card")
|
@customElement("hui-area-card")
|
||||||
export class HuiAreaCard
|
export class HuiAreaCard
|
||||||
@ -80,7 +97,7 @@ export class HuiAreaCard
|
|||||||
|
|
||||||
@state() private _areas?: AreaRegistryEntry[];
|
@state() private _areas?: AreaRegistryEntry[];
|
||||||
|
|
||||||
private _memberships = memoizeOne(
|
private _entitiesByDomain = memoizeOne(
|
||||||
(
|
(
|
||||||
areaId: string,
|
areaId: string,
|
||||||
devicesInArea: Set<string>,
|
devicesInArea: Set<string>,
|
||||||
@ -97,44 +114,98 @@ export class HuiAreaCard
|
|||||||
)
|
)
|
||||||
.map((entry) => entry.entity_id);
|
.map((entry) => entry.entity_id);
|
||||||
|
|
||||||
const sensorEntities: HassEntity[] = [];
|
const entitiesByDomain: { [domain: string]: HassEntity[] } = {};
|
||||||
const entitiesToggle: HassEntity[] = [];
|
|
||||||
|
|
||||||
for (const entity of entitiesInArea) {
|
for (const entity of entitiesInArea) {
|
||||||
const domain = computeDomain(entity);
|
const domain = computeDomain(entity);
|
||||||
if (!TOGGLE_DOMAINS.has(domain) && !SENSOR_DOMAINS.has(domain)) {
|
if (
|
||||||
|
!TOGGLE_DOMAINS.includes(domain) &&
|
||||||
|
!SENSOR_DOMAINS.includes(domain) &&
|
||||||
|
!ALERT_DOMAINS.includes(domain) &&
|
||||||
|
!OTHER_DOMAINS.includes(domain)
|
||||||
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const stateObj: HassEntity | undefined = states[entity];
|
const stateObj: HassEntity | undefined = states[entity];
|
||||||
|
|
||||||
if (!stateObj) {
|
if (!stateObj) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entitiesToggle.length < 3 && TOGGLE_DOMAINS.has(domain)) {
|
if (
|
||||||
entitiesToggle.push(stateObj);
|
(SENSOR_DOMAINS.includes(domain) || ALERT_DOMAINS.includes(domain)) &&
|
||||||
|
!DEVICE_CLASSES[domain].includes(
|
||||||
|
stateObj.attributes.device_class || ""
|
||||||
|
)
|
||||||
|
) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (!(domain in entitiesByDomain)) {
|
||||||
sensorEntities.length < 3 &&
|
entitiesByDomain[domain] = [];
|
||||||
SENSOR_DOMAINS.has(domain) &&
|
}
|
||||||
stateObj.attributes.device_class &&
|
entitiesByDomain[domain].push(stateObj);
|
||||||
SENSOR_DEVICE_CLASSES.has(stateObj.attributes.device_class)
|
|
||||||
) {
|
|
||||||
sensorEntities.push(stateObj);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sensorEntities.length === 3 && entitiesToggle.length === 3) {
|
return entitiesByDomain;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return { sensorEntities, entitiesToggle };
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private _isOn(domain: string, deviceClass?: string): boolean | undefined {
|
||||||
|
const entities = this._entitiesByDomain(
|
||||||
|
this._config!.area,
|
||||||
|
this._devicesInArea(this._config!.area, this._devices!),
|
||||||
|
this._entities!,
|
||||||
|
this.hass.states
|
||||||
|
)[domain];
|
||||||
|
if (!entities) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
deviceClass
|
||||||
|
? entities.filter(
|
||||||
|
(entity) => entity.attributes.device_class === deviceClass
|
||||||
|
)
|
||||||
|
: entities
|
||||||
|
).some(
|
||||||
|
(entity) =>
|
||||||
|
!UNAVAILABLE_STATES.includes(entity.state) &&
|
||||||
|
!STATES_OFF.includes(entity.state)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _average(domain: string, deviceClass?: string): string | undefined {
|
||||||
|
const entities = this._entitiesByDomain(
|
||||||
|
this._config!.area,
|
||||||
|
this._devicesInArea(this._config!.area, this._devices!),
|
||||||
|
this._entities!,
|
||||||
|
this.hass.states
|
||||||
|
)[domain].filter((entity) =>
|
||||||
|
deviceClass ? entity.attributes.device_class === deviceClass : true
|
||||||
|
);
|
||||||
|
if (!entities) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
let uom;
|
||||||
|
const values = entities.filter((entity) => {
|
||||||
|
if (!entity.attributes.unit_of_measurement) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!uom) {
|
||||||
|
uom = entity.attributes.unit_of_measurement;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return entity.attributes.unit_of_measurement === uom;
|
||||||
|
});
|
||||||
|
if (!values.length) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const sum = values.reduce((a, b) => a + Number(b.state), 0);
|
||||||
|
return `${formatNumber(sum / values.length, this.hass!.locale, {
|
||||||
|
maximumFractionDigits: 1,
|
||||||
|
})} ${uom}`;
|
||||||
|
}
|
||||||
|
|
||||||
private _area = memoizeOne(
|
private _area = memoizeOne(
|
||||||
(areaId: string | undefined, areas: AreaRegistryEntry[]) =>
|
(areaId: string | undefined, areas: AreaRegistryEntry[]) =>
|
||||||
areas.find((area) => area.area_id === areaId) || null
|
areas.find((area) => area.area_id === areaId) || null
|
||||||
@ -212,23 +283,19 @@ export class HuiAreaCard
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { sensorEntities, entitiesToggle } = this._memberships(
|
const entities = this._entitiesByDomain(
|
||||||
this._config.area,
|
this._config.area,
|
||||||
this._devicesInArea(this._config.area, this._devices),
|
this._devicesInArea(this._config.area, this._devices),
|
||||||
this._entities,
|
this._entities,
|
||||||
this.hass.states
|
this.hass.states
|
||||||
);
|
);
|
||||||
|
|
||||||
for (const stateObj of sensorEntities) {
|
for (const domainEntities of Object.values(entities)) {
|
||||||
|
for (const stateObj of domainEntities) {
|
||||||
if (oldHass!.states[stateObj.entity_id] !== stateObj) {
|
if (oldHass!.states[stateObj.entity_id] !== stateObj) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const stateObj of entitiesToggle) {
|
|
||||||
if (oldHass!.states[stateObj.entity_id] !== stateObj) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -245,13 +312,12 @@ export class HuiAreaCard
|
|||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { sensorEntities, entitiesToggle } = this._memberships(
|
const entitiesByDomain = this._entitiesByDomain(
|
||||||
this._config.area,
|
this._config.area,
|
||||||
this._devicesInArea(this._config.area, this._devices),
|
this._devicesInArea(this._config.area, this._devices),
|
||||||
this._entities,
|
this._entities,
|
||||||
this.hass.states
|
this.hass.states
|
||||||
);
|
);
|
||||||
|
|
||||||
const area = this._area(this._config.area, this._areas);
|
const area = this._area(this._config.area, this._areas);
|
||||||
|
|
||||||
if (area === null) {
|
if (area === null) {
|
||||||
@ -262,62 +328,98 @@ export class HuiAreaCard
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const sensors: TemplateResult[] = [];
|
||||||
|
SENSOR_DOMAINS.forEach((domain) => {
|
||||||
|
if (!(domain in entitiesByDomain)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
DEVICE_CLASSES[domain].forEach((deviceClass) => {
|
||||||
|
if (
|
||||||
|
entitiesByDomain[domain].some(
|
||||||
|
(entity) => entity.attributes.device_class === deviceClass
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
sensors.push(html`
|
||||||
|
${DOMAIN_ICONS[domain][deviceClass]
|
||||||
|
? html`<ha-svg-icon
|
||||||
|
.path=${DOMAIN_ICONS[domain][deviceClass]}
|
||||||
|
></ha-svg-icon>`
|
||||||
|
: ""}
|
||||||
|
${this._average(domain, deviceClass)}
|
||||||
|
`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let cameraEntityId: string | undefined;
|
||||||
|
if ("camera" in entitiesByDomain) {
|
||||||
|
cameraEntityId = entitiesByDomain.camera[0].entity_id;
|
||||||
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card
|
<ha-card class=${area.picture ? "image" : ""}>
|
||||||
style=${styleMap({
|
${area.picture || cameraEntityId
|
||||||
"background-image": `url(${this.hass.hassUrl(area.picture)})`,
|
? html`<hui-image
|
||||||
})}
|
.config=${this._config}
|
||||||
>
|
.hass=${this.hass}
|
||||||
<div class="container">
|
.image=${area.picture
|
||||||
<div class="sensors">
|
? this.hass.hassUrl(area.picture)
|
||||||
${sensorEntities.map(
|
: undefined}
|
||||||
(stateObj) => html`
|
.cameraImage=${cameraEntityId}
|
||||||
<span
|
aspectRatio="16:9"
|
||||||
.entity=${stateObj.entity_id}
|
></hui-image>`
|
||||||
@click=${this._handleMoreInfo}
|
: ""}
|
||||||
>
|
|
||||||
<ha-state-icon .state=${stateObj}></ha-state-icon>
|
|
||||||
${computeDomain(stateObj.entity_id) === "binary_sensor"
|
|
||||||
? ""
|
|
||||||
: html`
|
|
||||||
${computeStateDisplay(
|
|
||||||
this.hass!.localize,
|
|
||||||
stateObj,
|
|
||||||
this.hass!.locale
|
|
||||||
)}
|
|
||||||
`}
|
|
||||||
</span>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div class="bottom">
|
|
||||||
<div
|
<div
|
||||||
class="name ${this._config.navigation_path ? "navigate" : ""}"
|
class="container ${classMap({
|
||||||
|
navigate: this._config.navigation_path !== undefined,
|
||||||
|
})}"
|
||||||
@click=${this._handleNavigation}
|
@click=${this._handleNavigation}
|
||||||
>
|
>
|
||||||
${area.name}
|
<div class="alerts">
|
||||||
|
${ALERT_DOMAINS.map((domain) => {
|
||||||
|
if (!(domain in entitiesByDomain)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return DEVICE_CLASSES[domain].map((deviceClass) =>
|
||||||
|
this._isOn(domain, deviceClass)
|
||||||
|
? html`
|
||||||
|
${DOMAIN_ICONS[domain][deviceClass]
|
||||||
|
? html`<ha-svg-icon
|
||||||
|
.path=${DOMAIN_ICONS[domain][deviceClass]}
|
||||||
|
></ha-svg-icon>`
|
||||||
|
: ""}
|
||||||
|
`
|
||||||
|
: ""
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<div class="bottom">
|
||||||
|
<div>
|
||||||
|
<div class="name">${area.name}</div>
|
||||||
|
${sensors.length
|
||||||
|
? html`<div class="sensors">${sensors}</div>`
|
||||||
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
${entitiesToggle.map(
|
${TOGGLE_DOMAINS.map((domain) => {
|
||||||
(stateObj) => html`
|
if (!(domain in entitiesByDomain)) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const on = this._isOn(domain)!;
|
||||||
|
return TOGGLE_DOMAINS.includes(domain)
|
||||||
|
? html`
|
||||||
<ha-icon-button
|
<ha-icon-button
|
||||||
class=${classMap({
|
class=${on ? "on" : "off"}
|
||||||
off: stateObj.state === "off",
|
.path=${DOMAIN_ICONS[domain][on ? "on" : "off"]}
|
||||||
})}
|
.domain=${domain}
|
||||||
.entity=${stateObj.entity_id}
|
@click=${this._toggle}
|
||||||
.actionHandler=${actionHandler({
|
|
||||||
hasHold: true,
|
|
||||||
})}
|
|
||||||
@action=${this._handleAction}
|
|
||||||
>
|
>
|
||||||
<state-badge
|
|
||||||
.hass=${this.hass}
|
|
||||||
.stateObj=${stateObj}
|
|
||||||
stateColor
|
|
||||||
></state-badge>
|
|
||||||
</ha-icon-button>
|
</ha-icon-button>
|
||||||
`
|
`
|
||||||
)}
|
: "";
|
||||||
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -343,25 +445,26 @@ export class HuiAreaCard
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleMoreInfo(ev) {
|
|
||||||
const entity = (ev.currentTarget as any).entity;
|
|
||||||
fireEvent(this, "hass-more-info", { entityId: entity });
|
|
||||||
}
|
|
||||||
|
|
||||||
private _handleNavigation() {
|
private _handleNavigation() {
|
||||||
if (this._config!.navigation_path) {
|
if (this._config!.navigation_path) {
|
||||||
navigate(this._config!.navigation_path);
|
navigate(this._config!.navigation_path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleAction(ev: ActionHandlerEvent) {
|
private _toggle(ev: Event) {
|
||||||
const entity = (ev.currentTarget as any).entity as string;
|
ev.stopPropagation();
|
||||||
if (ev.detail.action === "hold") {
|
const domain = (ev.currentTarget as any).domain as string;
|
||||||
fireEvent(this, "hass-more-info", { entityId: entity });
|
if (TOGGLE_DOMAINS.includes(domain)) {
|
||||||
} else if (ev.detail.action === "tap") {
|
this.hass.callService(
|
||||||
toggleEntity(this.hass, entity);
|
domain,
|
||||||
forwardHaptic("light");
|
this._isOn(domain) ? "turn_off" : "turn_on",
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
area_id: this._config!.area,
|
||||||
}
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
forwardHaptic("light");
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResultGroup {
|
static get styles(): CSSResultGroup {
|
||||||
@ -373,24 +476,52 @@ export class HuiAreaCard
|
|||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ha-card.image {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
background-color: rgba(0, 0, 0, 0.4);
|
background: linear-gradient(
|
||||||
|
0,
|
||||||
|
rgba(33, 33, 33, 0.9) 0%,
|
||||||
|
rgba(33, 33, 33, 0) 45%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ha-card:not(.image) .container::before {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: var(--sidebar-selected-icon-color);
|
||||||
|
opacity: 0.12;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sensors {
|
.sensors {
|
||||||
color: white;
|
color: #e3e3e3;
|
||||||
font-size: 18px;
|
font-size: 16px;
|
||||||
flex: 1;
|
--mdc-icon-size: 24px;
|
||||||
|
opacity: 0.6;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.alerts {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
--mdc-icon-size: 28px;
|
}
|
||||||
cursor: pointer;
|
|
||||||
|
.alerts ha-svg-icon {
|
||||||
|
background: var(--accent-color);
|
||||||
|
color: var(--text-accent-color, var(--text-primary-color));
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
@ -402,24 +533,23 @@ export class HuiAreaCard
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 8px 8px 8px 16px;
|
padding: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name.navigate {
|
.navigate {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
state-badge {
|
|
||||||
--ha-icon-display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
ha-icon-button {
|
ha-icon-button {
|
||||||
color: white;
|
color: white;
|
||||||
background-color: var(--area-button-color, rgb(175, 175, 175, 0.5));
|
background-color: var(--area-button-color, #727272b2);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
--mdc-icon-button-size: 44px;
|
--mdc-icon-button-size: 44px;
|
||||||
}
|
}
|
||||||
|
.on {
|
||||||
|
color: var(--paper-item-icon-active-color, #fdd835);
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user