mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-22 00:36:34 +00:00
Add buttons header-footer (#4601)
* Add buttons header-footer * Simplify * Update src/panels/lovelace/header-footer/hui-buttons-header-footer.ts Co-Authored-By: Ian Richardson <iantrich@gmail.com> * Address comments Co-authored-by: Ian Richardson <iantrich@gmail.com>
This commit is contained in:
parent
95ba1fd0cb
commit
82fb622904
@ -20,7 +20,7 @@ import { computeActiveState } from "../../common/entity/compute_active_state";
|
|||||||
import { ifDefined } from "lit-html/directives/if-defined";
|
import { ifDefined } from "lit-html/directives/if-defined";
|
||||||
import { iconColorCSS } from "../../common/style/icon_color_css";
|
import { iconColorCSS } from "../../common/style/icon_color_css";
|
||||||
|
|
||||||
class StateBadge extends LitElement {
|
export class StateBadge extends LitElement {
|
||||||
public hass?: HomeAssistant;
|
public hass?: HomeAssistant;
|
||||||
@property() public stateObj?: HassEntity;
|
@property() public stateObj?: HassEntity;
|
||||||
@property() public overrideIcon?: string;
|
@property() public overrideIcon?: string;
|
||||||
|
@ -14,7 +14,11 @@ import "../components/hui-entities-toggle";
|
|||||||
|
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { LovelaceRow } from "../entity-rows/types";
|
import { LovelaceRow } from "../entity-rows/types";
|
||||||
import { LovelaceCard, LovelaceCardEditor } from "../types";
|
import {
|
||||||
|
LovelaceCard,
|
||||||
|
LovelaceCardEditor,
|
||||||
|
LovelaceHeaderFooter,
|
||||||
|
} from "../types";
|
||||||
import { processConfigEntities } from "../common/process-config-entities";
|
import { processConfigEntities } from "../common/process-config-entities";
|
||||||
import { createRowElement } from "../create-element/create-row-element";
|
import { createRowElement } from "../create-element/create-row-element";
|
||||||
import { EntitiesCardConfig, EntitiesCardEntityConfig } from "./types";
|
import { EntitiesCardConfig, EntitiesCardEntityConfig } from "./types";
|
||||||
@ -48,6 +52,11 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
|
|||||||
(element as LovelaceRow).hass = hass;
|
(element as LovelaceRow).hass = hass;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
this.shadowRoot!.querySelectorAll(".header-footer > *").forEach(
|
||||||
|
(element: unknown) => {
|
||||||
|
(element as LovelaceHeaderFooter).hass = hass;
|
||||||
|
}
|
||||||
|
);
|
||||||
const entitiesToggle = this.shadowRoot!.querySelector(
|
const entitiesToggle = this.shadowRoot!.querySelector(
|
||||||
"hui-entities-toggle"
|
"hui-entities-toggle"
|
||||||
);
|
);
|
||||||
@ -135,6 +144,7 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
|
|||||||
this.renderEntity(entityConf)
|
this.renderEntity(entityConf)
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
${this._config.footer
|
${this._config.footer
|
||||||
? this.renderHeaderFooter(this._config.footer, "footer")
|
? this.renderHeaderFooter(this._config.footer, "footer")
|
||||||
: ""}
|
: ""}
|
||||||
@ -192,7 +202,7 @@ class HuiEntitiesCard extends LitElement implements LovelaceCard {
|
|||||||
element.hass = this._hass;
|
element.hass = this._hass;
|
||||||
}
|
}
|
||||||
return html`
|
return html`
|
||||||
<div class=${className}>${element}</div>
|
<div class=${"header-footer " + className}>${element}</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { LovelaceElementConfig } from "../elements/types";
|
|
||||||
import { ActionConfig } from "../../../data/lovelace";
|
import { ActionConfig } from "../../../data/lovelace";
|
||||||
|
|
||||||
interface Config extends LovelaceElementConfig {
|
interface Config {
|
||||||
entity?: string;
|
entity?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
@ -30,6 +29,10 @@ export const computeTooltip = (hass: HomeAssistant, config: Config): string => {
|
|||||||
: config.entity;
|
: config.entity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!config.tap_action && !config.hold_action) {
|
||||||
|
return stateName;
|
||||||
|
}
|
||||||
|
|
||||||
const tapTooltip = config.tap_action
|
const tapTooltip = config.tap_action
|
||||||
? computeActionTooltip(hass, stateName, config.tap_action, false)
|
? computeActionTooltip(hass, stateName, config.tap_action, false)
|
||||||
: "";
|
: "";
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import "../header-footer/hui-picture-header-footer";
|
import "../header-footer/hui-picture-header-footer";
|
||||||
|
import "../header-footer/hui-buttons-header-footer";
|
||||||
import { LovelaceHeaderFooterConfig } from "../header-footer/types";
|
import { LovelaceHeaderFooterConfig } from "../header-footer/types";
|
||||||
import { createLovelaceElement } from "./create-element-base";
|
import { createLovelaceElement } from "./create-element-base";
|
||||||
|
|
||||||
const SPECIAL_TYPES = new Set(["picture"]);
|
const SPECIAL_TYPES = new Set(["picture", "buttons"]);
|
||||||
|
|
||||||
export const createHeaderFooterElement = (config: LovelaceHeaderFooterConfig) =>
|
export const createHeaderFooterElement = (config: LovelaceHeaderFooterConfig) =>
|
||||||
createLovelaceElement("header-footer", config, SPECIAL_TYPES);
|
createLovelaceElement("header-footer", config, SPECIAL_TYPES);
|
||||||
|
@ -31,7 +31,7 @@ import {
|
|||||||
EntitiesCardConfig,
|
EntitiesCardConfig,
|
||||||
EntitiesCardEntityConfig,
|
EntitiesCardEntityConfig,
|
||||||
} from "../../cards/types";
|
} from "../../cards/types";
|
||||||
import { pictureHeaderFooterConfigStruct } from "../../header-footer/types";
|
import { headerFooterConfigStructs } from "../../header-footer/types";
|
||||||
|
|
||||||
const cardConfigStruct = struct({
|
const cardConfigStruct = struct({
|
||||||
type: "string",
|
type: "string",
|
||||||
@ -39,8 +39,8 @@ const cardConfigStruct = struct({
|
|||||||
theme: "string?",
|
theme: "string?",
|
||||||
show_header_toggle: "boolean?",
|
show_header_toggle: "boolean?",
|
||||||
entities: [entitiesConfigStruct],
|
entities: [entitiesConfigStruct],
|
||||||
header: struct.optional(pictureHeaderFooterConfigStruct),
|
header: struct.optional(headerFooterConfigStructs),
|
||||||
footer: struct.optional(pictureHeaderFooterConfigStruct),
|
footer: struct.optional(headerFooterConfigStructs),
|
||||||
});
|
});
|
||||||
|
|
||||||
@customElement("hui-entities-card-editor")
|
@customElement("hui-entities-card-editor")
|
||||||
|
102
src/panels/lovelace/header-footer/hui-buttons-header-footer.ts
Normal file
102
src/panels/lovelace/header-footer/hui-buttons-header-footer.ts
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import {
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
TemplateResult,
|
||||||
|
customElement,
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
queryAll,
|
||||||
|
} from "lit-element";
|
||||||
|
import "@material/mwc-ripple";
|
||||||
|
|
||||||
|
import "../../../components/entity/state-badge";
|
||||||
|
import "../../../components/ha-card";
|
||||||
|
import "../../../components/ha-icon";
|
||||||
|
import "../components/hui-warning-element";
|
||||||
|
|
||||||
|
import { HomeAssistant } from "../../../types";
|
||||||
|
import { LovelaceHeaderFooter } from "../types";
|
||||||
|
import { ButtonsHeaderFooterConfig } from "./types";
|
||||||
|
import { EntityConfig } from "../entity-rows/types";
|
||||||
|
import { processConfigEntities } from "../common/process-config-entities";
|
||||||
|
import { toggleEntity } from "../common/entity/toggle-entity";
|
||||||
|
import { computeTooltip } from "../common/compute-tooltip";
|
||||||
|
// tslint:disable-next-line: no-duplicate-imports
|
||||||
|
import { StateBadge } from "../../../components/entity/state-badge";
|
||||||
|
|
||||||
|
@customElement("hui-buttons-header-footer")
|
||||||
|
export class HuiButtonsHeaderFooter extends LitElement
|
||||||
|
implements LovelaceHeaderFooter {
|
||||||
|
public static getStubConfig(): object {
|
||||||
|
return { entities: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
private _configEntities?: EntityConfig[];
|
||||||
|
private _hass?: HomeAssistant;
|
||||||
|
@queryAll("state-badge") private _badges!: StateBadge[];
|
||||||
|
|
||||||
|
public setConfig(config: ButtonsHeaderFooterConfig): void {
|
||||||
|
this._configEntities = processConfigEntities(config.entities);
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
set hass(hass: HomeAssistant) {
|
||||||
|
this._hass = hass;
|
||||||
|
this._badges.forEach((badge, index: number) => {
|
||||||
|
badge.hass = hass;
|
||||||
|
badge.stateObj = hass.states[this._configEntities![index].entity];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render(): TemplateResult | void {
|
||||||
|
return html`
|
||||||
|
${(this._configEntities || []).map((entityConf) => {
|
||||||
|
const stateObj = this._hass!.states[entityConf.entity];
|
||||||
|
if (!stateObj) {
|
||||||
|
return html`<div class='missing'><iron-icon icon="hass:alert"></div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div>
|
||||||
|
<state-badge
|
||||||
|
title=${computeTooltip(this._hass!, entityConf)}
|
||||||
|
@click=${this._toggle}
|
||||||
|
.hass=${this._hass}
|
||||||
|
.stateObj=${stateObj}
|
||||||
|
.overrideIcon=${entityConf.icon}
|
||||||
|
.overrideImage=${entityConf.image}
|
||||||
|
stateColor
|
||||||
|
tabindex="0"
|
||||||
|
></state-badge>
|
||||||
|
<mwc-ripple unbounded></mwc-ripple>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
})}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _toggle(ev) {
|
||||||
|
await toggleEntity(this._hass!, ev.target.stateObj.entity_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult {
|
||||||
|
return css`
|
||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
}
|
||||||
|
.missing {
|
||||||
|
color: #fce588;
|
||||||
|
}
|
||||||
|
state-badge {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hui-buttons-header-footer": HuiButtonsHeaderFooter;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,15 @@
|
|||||||
import { ActionConfig } from "../../../data/lovelace";
|
import { ActionConfig } from "../../../data/lovelace";
|
||||||
import { struct } from "../common/structs/struct";
|
import { struct } from "../common/structs/struct";
|
||||||
import { actionConfigStruct } from "../editor/types";
|
import { actionConfigStruct, entitiesConfigStruct } from "../editor/types";
|
||||||
|
|
||||||
export interface LovelaceHeaderFooterConfig {
|
export interface LovelaceHeaderFooterConfig {
|
||||||
type: string;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ButtonsHeaderFooterConfig extends LovelaceHeaderFooterConfig {
|
||||||
|
entities: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface PictureHeaderFooterConfig extends LovelaceHeaderFooterConfig {
|
export interface PictureHeaderFooterConfig extends LovelaceHeaderFooterConfig {
|
||||||
image: string;
|
image: string;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
@ -20,3 +24,13 @@ export const pictureHeaderFooterConfigStruct = struct({
|
|||||||
hold_action: struct.optional(actionConfigStruct),
|
hold_action: struct.optional(actionConfigStruct),
|
||||||
double_tap_action: struct.optional(actionConfigStruct),
|
double_tap_action: struct.optional(actionConfigStruct),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const buttonsHeaderFooterConfigStruct = struct({
|
||||||
|
type: "string",
|
||||||
|
entities: [entitiesConfigStruct],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const headerFooterConfigStructs = struct.union([
|
||||||
|
pictureHeaderFooterConfigStruct,
|
||||||
|
buttonsHeaderFooterConfigStruct,
|
||||||
|
]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user