mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-31 13:07:49 +00:00
Add new card feature: button (#26165)
Co-authored-by: Simon Lamon <32477463+silamon@users.noreply.github.com> Co-authored-by: Wendelin <12148533+wendevlin@users.noreply.github.com>
This commit is contained in:
parent
b355556c07
commit
6dbfc2f4ed
98
src/panels/lovelace/card-features/hui-button-card-feature.ts
Normal file
98
src/panels/lovelace/card-features/hui-button-card-feature.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import { html, LitElement, nothing } from "lit";
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import "../../../components/ha-control-button";
|
||||
import "../../../components/ha-control-button-group";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { LovelaceCardFeature } from "../types";
|
||||
import { cardFeatureStyles } from "./common/card-feature-styles";
|
||||
import type {
|
||||
LovelaceCardFeatureContext,
|
||||
ButtonCardFeatureConfig,
|
||||
} from "./types";
|
||||
|
||||
export const supportsButtonCardFeature = (
|
||||
hass: HomeAssistant,
|
||||
context: LovelaceCardFeatureContext
|
||||
) => {
|
||||
const stateObj = context.entity_id
|
||||
? hass.states[context.entity_id]
|
||||
: undefined;
|
||||
if (!stateObj) return false;
|
||||
const domain = computeDomain(stateObj.entity_id);
|
||||
return ["button", "script"].includes(domain);
|
||||
};
|
||||
|
||||
@customElement("hui-button-card-feature")
|
||||
class HuiButtonCardFeature extends LitElement implements LovelaceCardFeature {
|
||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
||||
|
||||
@property({ attribute: false }) public context?: LovelaceCardFeatureContext;
|
||||
|
||||
@state() private _config?: ButtonCardFeatureConfig;
|
||||
|
||||
private get _stateObj() {
|
||||
if (!this.hass || !this.context || !this.context.entity_id) {
|
||||
return undefined;
|
||||
}
|
||||
return this.hass.states[this.context.entity_id!] as HassEntity | undefined;
|
||||
}
|
||||
|
||||
private _pressButton() {
|
||||
if (!this.hass || !this._stateObj) return;
|
||||
|
||||
const domain = computeDomain(this._stateObj.entity_id);
|
||||
const service = domain === "button" ? "press" : "turn_on";
|
||||
|
||||
this.hass.callService(domain, service, {
|
||||
entity_id: this._stateObj.entity_id,
|
||||
});
|
||||
}
|
||||
|
||||
static getStubConfig(): ButtonCardFeatureConfig {
|
||||
return {
|
||||
type: "button",
|
||||
};
|
||||
}
|
||||
|
||||
public setConfig(config: ButtonCardFeatureConfig): void {
|
||||
if (!config) {
|
||||
throw new Error("Invalid configuration");
|
||||
}
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
protected render() {
|
||||
if (
|
||||
!this._config ||
|
||||
!this.hass ||
|
||||
!this.context ||
|
||||
!this._stateObj ||
|
||||
!supportsButtonCardFeature(this.hass, this.context)
|
||||
) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-control-button-group>
|
||||
<ha-control-button
|
||||
.disabled=${["unavailable", "unknown"].includes(this._stateObj.state)}
|
||||
class="press-button"
|
||||
@click=${this._pressButton}
|
||||
>
|
||||
${this._config.action_name ??
|
||||
this.hass.localize("ui.card.button.press")}
|
||||
</ha-control-button>
|
||||
</ha-control-button-group>
|
||||
`;
|
||||
}
|
||||
|
||||
static styles = cardFeatureStyles;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-button-card-feature": HuiButtonCardFeature;
|
||||
}
|
||||
}
|
@ -2,6 +2,11 @@ import type { AlarmMode } from "../../../data/alarm_control_panel";
|
||||
import type { HvacMode } from "../../../data/climate";
|
||||
import type { OperationMode } from "../../../data/water_heater";
|
||||
|
||||
export interface ButtonCardFeatureConfig {
|
||||
type: "button";
|
||||
action_name?: string;
|
||||
}
|
||||
|
||||
export interface CoverOpenCloseCardFeatureConfig {
|
||||
type: "cover-open-close";
|
||||
}
|
||||
@ -185,6 +190,7 @@ export type LovelaceCardFeaturePosition = "bottom" | "inline";
|
||||
|
||||
export type LovelaceCardFeatureConfig =
|
||||
| AlarmModesCardFeatureConfig
|
||||
| ButtonCardFeatureConfig
|
||||
| ClimateFanModesCardFeatureConfig
|
||||
| ClimateSwingModesCardFeatureConfig
|
||||
| ClimateSwingHorizontalModesCardFeatureConfig
|
||||
|
@ -1,4 +1,5 @@
|
||||
import "../card-features/hui-alarm-modes-card-feature";
|
||||
import "../card-features/hui-button-card-feature";
|
||||
import "../card-features/hui-climate-fan-modes-card-feature";
|
||||
import "../card-features/hui-climate-hvac-modes-card-feature";
|
||||
import "../card-features/hui-climate-preset-modes-card-feature";
|
||||
@ -37,6 +38,7 @@ import {
|
||||
|
||||
const TYPES = new Set<LovelaceCardFeatureConfig["type"]>([
|
||||
"alarm-modes",
|
||||
"button",
|
||||
"area-controls",
|
||||
"climate-fan-modes",
|
||||
"climate-swing-modes",
|
||||
|
@ -0,0 +1,60 @@
|
||||
import { html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { ButtonCardFeatureConfig } from "../../card-features/types";
|
||||
import type { LovelaceCardFeatureEditor } from "../../types";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import type { HaFormSchema } from "../../../../components/ha-form/types";
|
||||
|
||||
@customElement("hui-button-card-feature-editor")
|
||||
export class HuiButtonCardFeatureEditor
|
||||
extends LitElement
|
||||
implements LovelaceCardFeatureEditor
|
||||
{
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@state() private _config?: ButtonCardFeatureConfig;
|
||||
|
||||
public setConfig(config: ButtonCardFeatureConfig): void {
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
private _schema: HaFormSchema[] = [
|
||||
{
|
||||
name: "action_name",
|
||||
selector: {
|
||||
text: {},
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
protected render() {
|
||||
if (!this.hass || !this._config) {
|
||||
return nothing;
|
||||
}
|
||||
|
||||
return html`
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._config}
|
||||
.schema=${this._schema}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>
|
||||
`;
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent) {
|
||||
ev.stopPropagation();
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("config-changed", {
|
||||
detail: { config: ev.detail.value },
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-button-card-feature-editor": HuiButtonCardFeatureEditor;
|
||||
}
|
||||
}
|
@ -19,6 +19,7 @@ import {
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import { supportsAlarmModesCardFeature } from "../../card-features/hui-alarm-modes-card-feature";
|
||||
import { supportsAreaControlsCardFeature } from "../../card-features/hui-area-controls-card-feature";
|
||||
import { supportsButtonCardFeature } from "../../card-features/hui-button-card-feature";
|
||||
import { supportsClimateFanModesCardFeature } from "../../card-features/hui-climate-fan-modes-card-feature";
|
||||
import { supportsClimateHvacModesCardFeature } from "../../card-features/hui-climate-hvac-modes-card-feature";
|
||||
import { supportsClimatePresetModesCardFeature } from "../../card-features/hui-climate-preset-modes-card-feature";
|
||||
@ -63,6 +64,7 @@ type SupportsFeature = (
|
||||
const UI_FEATURE_TYPES = [
|
||||
"alarm-modes",
|
||||
"area-controls",
|
||||
"button",
|
||||
"climate-fan-modes",
|
||||
"climate-hvac-modes",
|
||||
"climate-preset-modes",
|
||||
@ -98,6 +100,7 @@ type UiFeatureTypes = (typeof UI_FEATURE_TYPES)[number];
|
||||
const EDITABLES_FEATURE_TYPES = new Set<UiFeatureTypes>([
|
||||
"alarm-modes",
|
||||
"area-controls",
|
||||
"button",
|
||||
"climate-fan-modes",
|
||||
"climate-hvac-modes",
|
||||
"climate-preset-modes",
|
||||
@ -120,6 +123,7 @@ const SUPPORTS_FEATURE_TYPES: Record<
|
||||
> = {
|
||||
"alarm-modes": supportsAlarmModesCardFeature,
|
||||
"area-controls": supportsAreaControlsCardFeature,
|
||||
button: supportsButtonCardFeature,
|
||||
"climate-fan-modes": supportsClimateFanModesCardFeature,
|
||||
"climate-swing-modes": supportsClimateSwingModesCardFeature,
|
||||
"climate-swing-horizontal-modes":
|
||||
|
Loading…
x
Reference in New Issue
Block a user