Add switch toggle feature to tile card (#24325)

* Add tile switch toggle feature

* Remove _currentState
This commit is contained in:
Jan-Philipp Benecke 2025-02-20 09:16:14 +01:00 committed by GitHub
parent a68bdbfe08
commit 91bd5cba08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 122 additions and 0 deletions

View File

@ -0,0 +1,109 @@
import { mdiPowerOff, mdiPower } from "@mdi/js";
import type { HassEntity } from "home-assistant-js-websocket";
import type { TemplateResult } from "lit";
import { LitElement, html } from "lit";
import { customElement, property, state } from "lit/decorators";
import { styleMap } from "lit/directives/style-map";
import { computeDomain } from "../../../common/entity/compute_domain";
import { stateColorCss } from "../../../common/entity/state_color";
import "../../../components/ha-control-select";
import type { ControlSelectOption } from "../../../components/ha-control-select";
import { UNAVAILABLE } from "../../../data/entity";
import type { HomeAssistant } from "../../../types";
import type { LovelaceCardFeature } from "../types";
import { cardFeatureStyles } from "./common/card-feature-styles";
import type { SwitchToggleCardFeatureConfig } from "./types";
import { showToast } from "../../../util/toast";
export const supportsSwitchToggleCardFeature = (stateObj: HassEntity) => {
const domain = computeDomain(stateObj.entity_id);
return domain === "switch";
};
@customElement("hui-switch-toggle-card-feature")
class HuiSwitchToggleCardFeature
extends LitElement
implements LovelaceCardFeature
{
@property({ attribute: false }) public hass?: HomeAssistant;
@property({ attribute: false }) public stateObj?: HassEntity;
@state() private _config?: SwitchToggleCardFeatureConfig;
static getStubConfig(): SwitchToggleCardFeatureConfig {
return {
type: "switch-toggle",
};
}
public setConfig(config: SwitchToggleCardFeatureConfig): void {
if (!config) {
throw new Error("Invalid configuration");
}
this._config = config;
}
protected render(): TemplateResult | null {
if (
!this._config ||
!this.hass ||
!this.stateObj ||
!supportsSwitchToggleCardFeature(this.stateObj)
) {
return null;
}
const color = stateColorCss(this.stateObj);
const options = ["on", "off"].map<ControlSelectOption>((entityState) => ({
value: entityState,
label: this.hass!.formatEntityState(this.stateObj!, entityState),
path: entityState === "on" ? mdiPower : mdiPowerOff,
}));
return html`
<ha-control-select
.options=${options}
.value=${this.stateObj.state}
@value-changed=${this._valueChanged}
hide-label
.ariaLabel=${this.hass.localize("ui.card.humidifier.state")}
style=${styleMap({
"--control-select-color": color,
})}
.disabled=${this.stateObj!.state === UNAVAILABLE}
>
</ha-control-select>
`;
}
private async _valueChanged(ev: CustomEvent) {
const newState = (ev.detail as any).value;
if (newState === this.stateObj!.state) return;
const service = newState === "on" ? "turn_on" : "turn_off";
try {
await this.hass!.callService("switch", service, {
entity_id: this.stateObj!.entity_id,
});
} catch (_err) {
showToast(this, {
message: this.hass!.localize("ui.notification_toast.action_failed", {
service: "switch." + service,
}),
duration: 5000,
dismissable: true,
});
}
}
static styles = cardFeatureStyles;
}
declare global {
interface HTMLElementTagNameMap {
"hui-switch-toggle-card-feature": HuiSwitchToggleCardFeature;
}
}

View File

@ -88,6 +88,10 @@ export interface SelectOptionsCardFeatureConfig {
options?: string[];
}
export interface SwitchToggleCardFeatureConfig {
type: "switch-toggle";
}
export interface NumericInputCardFeatureConfig {
type: "numeric-input";
style?: "buttons" | "slider";
@ -168,6 +172,7 @@ export type LovelaceCardFeatureConfig =
| MediaPlayerVolumeSliderCardFeatureConfig
| NumericInputCardFeatureConfig
| SelectOptionsCardFeatureConfig
| SwitchToggleCardFeatureConfig
| TargetHumidityCardFeatureConfig
| TargetTemperatureCardFeatureConfig
| UpdateActionsCardFeatureConfig

View File

@ -20,6 +20,7 @@ import "../card-features/hui-lock-open-door-card-feature";
import "../card-features/hui-media-player-volume-slider-card-feature";
import "../card-features/hui-numeric-input-card-feature";
import "../card-features/hui-select-options-card-feature";
import "../card-features/hui-switch-toggle-card-feature";
import "../card-features/hui-target-temperature-card-feature";
import "../card-features/hui-target-humidity-card-feature";
import "../card-features/hui-update-actions-card-feature";
@ -55,6 +56,7 @@ const TYPES = new Set<LovelaceCardFeatureConfig["type"]>([
"media-player-volume-slider",
"numeric-input",
"select-options",
"switch-toggle",
"target-humidity",
"target-temperature",
"update-actions",

View File

@ -40,6 +40,7 @@ import { supportsLockOpenDoorCardFeature } from "../../card-features/hui-lock-op
import { supportsMediaPlayerVolumeSliderCardFeature } from "../../card-features/hui-media-player-volume-slider-card-feature";
import { supportsNumericInputCardFeature } from "../../card-features/hui-numeric-input-card-feature";
import { supportsSelectOptionsCardFeature } from "../../card-features/hui-select-options-card-feature";
import { supportsSwitchToggleCardFeature } from "../../card-features/hui-switch-toggle-card-feature";
import { supportsTargetHumidityCardFeature } from "../../card-features/hui-target-humidity-card-feature";
import { supportsTargetTemperatureCardFeature } from "../../card-features/hui-target-temperature-card-feature";
import { supportsUpdateActionsCardFeature } from "../../card-features/hui-update-actions-card-feature";
@ -74,6 +75,7 @@ const UI_FEATURE_TYPES = [
"media-player-volume-slider",
"numeric-input",
"select-options",
"switch-toggle",
"target-humidity",
"target-temperature",
"update-actions",
@ -132,6 +134,7 @@ const SUPPORTS_FEATURE_TYPES: Record<
"update-actions": supportsUpdateActionsCardFeature,
"vacuum-commands": supportsVacuumCommandsCardFeature,
"water-heater-operation-modes": supportsWaterHeaterOperationModesCardFeature,
"switch-toggle": supportsSwitchToggleCardFeature,
};
const customCardFeatures = getCustomCardFeatures();

View File

@ -7343,6 +7343,9 @@
"options": "Options",
"customize_options": "Customize options"
},
"switch-toggle": {
"label": "Switch toggle"
},
"numeric-input": {
"label": "Numeric input",
"style": "Style",