mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-20 15:56:35 +00:00
Some fixes in focus and click handling (#5847)
This commit is contained in:
parent
7f1fb6f75f
commit
cc46797576
@ -1,4 +1,5 @@
|
|||||||
import type { HassEntity } from "home-assistant-js-websocket";
|
import type { HassEntity } from "home-assistant-js-websocket";
|
||||||
|
import { styleMap } from "lit-html/directives/style-map";
|
||||||
import {
|
import {
|
||||||
css,
|
css,
|
||||||
CSSResult,
|
CSSResult,
|
||||||
@ -6,7 +7,6 @@ import {
|
|||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
query,
|
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { ifDefined } from "lit-html/directives/if-defined";
|
import { ifDefined } from "lit-html/directives/if-defined";
|
||||||
@ -16,7 +16,6 @@ import { stateIcon } from "../../common/entity/state_icon";
|
|||||||
import { iconColorCSS } from "../../common/style/icon_color_css";
|
import { iconColorCSS } from "../../common/style/icon_color_css";
|
||||||
import type { HomeAssistant } from "../../types";
|
import type { HomeAssistant } from "../../types";
|
||||||
import "../ha-icon";
|
import "../ha-icon";
|
||||||
import type { HaIcon } from "../ha-icon";
|
|
||||||
|
|
||||||
export class StateBadge extends LitElement {
|
export class StateBadge extends LitElement {
|
||||||
public hass?: HomeAssistant;
|
public hass?: HomeAssistant;
|
||||||
@ -29,12 +28,15 @@ export class StateBadge extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public stateColor?: boolean;
|
@property({ type: Boolean }) public stateColor?: boolean;
|
||||||
|
|
||||||
@query("ha-icon") private _icon!: HaIcon;
|
@property({ type: Boolean, reflect: true, attribute: "icon" })
|
||||||
|
private _showIcon = true;
|
||||||
|
|
||||||
|
@property() private _iconStyle: { [name: string]: string } = {};
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const stateObj = this.stateObj;
|
const stateObj = this.stateObj;
|
||||||
|
|
||||||
if (!stateObj) {
|
if (!stateObj || !this._showIcon) {
|
||||||
return html``;
|
return html``;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +44,7 @@ export class StateBadge extends LitElement {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-icon
|
<ha-icon
|
||||||
id="icon"
|
style=${styleMap(this._iconStyle)}
|
||||||
data-domain=${ifDefined(
|
data-domain=${ifDefined(
|
||||||
this.stateColor || (domain === "light" && this.stateColor !== false)
|
this.stateColor || (domain === "light" && this.stateColor !== false)
|
||||||
? domain
|
? domain
|
||||||
@ -60,14 +62,13 @@ export class StateBadge extends LitElement {
|
|||||||
}
|
}
|
||||||
const stateObj = this.stateObj;
|
const stateObj = this.stateObj;
|
||||||
|
|
||||||
const iconStyle: Partial<CSSStyleDeclaration> = {
|
const iconStyle: { [name: string]: string } = {};
|
||||||
color: "",
|
|
||||||
filter: "",
|
|
||||||
display: "",
|
|
||||||
};
|
|
||||||
const hostStyle: Partial<CSSStyleDeclaration> = {
|
const hostStyle: Partial<CSSStyleDeclaration> = {
|
||||||
backgroundImage: "",
|
backgroundImage: "",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this._showIcon = true;
|
||||||
|
|
||||||
if (stateObj) {
|
if (stateObj) {
|
||||||
// hide icon if we have entity picture
|
// hide icon if we have entity picture
|
||||||
if (
|
if (
|
||||||
@ -79,7 +80,7 @@ export class StateBadge extends LitElement {
|
|||||||
imageUrl = this.hass.hassUrl(imageUrl);
|
imageUrl = this.hass.hassUrl(imageUrl);
|
||||||
}
|
}
|
||||||
hostStyle.backgroundImage = `url(${imageUrl})`;
|
hostStyle.backgroundImage = `url(${imageUrl})`;
|
||||||
iconStyle.display = "none";
|
this._showIcon = false;
|
||||||
} else if (stateObj.state === "on") {
|
} else if (stateObj.state === "on") {
|
||||||
if (stateObj.attributes.hs_color && this.stateColor !== false) {
|
if (stateObj.attributes.hs_color && this.stateColor !== false) {
|
||||||
const hue = stateObj.attributes.hs_color[0];
|
const hue = stateObj.attributes.hs_color[0];
|
||||||
@ -102,7 +103,7 @@ export class StateBadge extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Object.assign(this._icon.style, iconStyle);
|
this._iconStyle = iconStyle;
|
||||||
Object.assign(this.style, hostStyle);
|
Object.assign(this.style, hostStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,8 +120,17 @@ export class StateBadge extends LitElement {
|
|||||||
background-size: cover;
|
background-size: cover;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
:host(:focus) {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
:host(:not([icon]):focus) {
|
||||||
|
border: 2px solid var(--divider-color);
|
||||||
|
}
|
||||||
|
:host([icon]:focus) {
|
||||||
|
background: var(--divider-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
ha-icon {
|
ha-icon {
|
||||||
transition: color 0.3s ease-in-out, filter 0.3s ease-in-out;
|
transition: color 0.3s ease-in-out, filter 0.3s ease-in-out;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ import "../../../components/ha-card";
|
|||||||
import "../../../components/ha-icon";
|
import "../../../components/ha-icon";
|
||||||
import { UNAVAILABLE_STATES } from "../../../data/entity";
|
import { UNAVAILABLE_STATES } from "../../../data/entity";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
|
||||||
import { findEntities } from "../common/find-entites";
|
import { findEntities } from "../common/find-entites";
|
||||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||||
import "../components/hui-warning";
|
import "../components/hui-warning";
|
||||||
@ -108,46 +107,40 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
|
|||||||
: !UNAVAILABLE_STATES.includes(stateObj.state);
|
: !UNAVAILABLE_STATES.includes(stateObj.state);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card>
|
<ha-card @click=${this._handleClick} tabindex="0">
|
||||||
<div
|
<div class="header">
|
||||||
@action=${this._handleClick}
|
<div class="name">
|
||||||
.actionHandler=${actionHandler()}
|
${this._config.name || computeStateName(stateObj)}
|
||||||
tabindex="0"
|
|
||||||
>
|
|
||||||
<div class="header">
|
|
||||||
<div class="name">
|
|
||||||
${this._config.name || computeStateName(stateObj)}
|
|
||||||
</div>
|
|
||||||
<div class="icon">
|
|
||||||
<ha-icon
|
|
||||||
.icon=${this._config.icon || stateIcon(stateObj)}
|
|
||||||
></ha-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="icon">
|
||||||
<span class="value"
|
<ha-icon
|
||||||
>${"attribute" in this._config
|
.icon=${this._config.icon || stateIcon(stateObj)}
|
||||||
? stateObj.attributes[this._config.attribute!] ||
|
></ha-icon>
|
||||||
this.hass.localize("state.default.unknown")
|
|
||||||
: stateObj.attributes.unit_of_measurement
|
|
||||||
? stateObj.state
|
|
||||||
: computeStateDisplay(
|
|
||||||
this.hass.localize,
|
|
||||||
stateObj,
|
|
||||||
this.hass.language
|
|
||||||
)}</span
|
|
||||||
>${showUnit
|
|
||||||
? html`
|
|
||||||
<span class="measurement"
|
|
||||||
>${this._config.unit ||
|
|
||||||
(this._config.attribute
|
|
||||||
? ""
|
|
||||||
: stateObj.attributes.unit_of_measurement)}</span
|
|
||||||
>
|
|
||||||
`
|
|
||||||
: ""}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="info">
|
||||||
|
<span class="value"
|
||||||
|
>${"attribute" in this._config
|
||||||
|
? stateObj.attributes[this._config.attribute!] ||
|
||||||
|
this.hass.localize("state.default.unknown")
|
||||||
|
: stateObj.attributes.unit_of_measurement
|
||||||
|
? stateObj.state
|
||||||
|
: computeStateDisplay(
|
||||||
|
this.hass.localize,
|
||||||
|
stateObj,
|
||||||
|
this.hass.language
|
||||||
|
)}</span
|
||||||
|
>${showUnit
|
||||||
|
? html`
|
||||||
|
<span class="measurement"
|
||||||
|
>${this._config.unit ||
|
||||||
|
(this._config.attribute
|
||||||
|
? ""
|
||||||
|
: stateObj.attributes.unit_of_measurement)}</span
|
||||||
|
>
|
||||||
|
`
|
||||||
|
: ""}
|
||||||
|
</div>
|
||||||
${this._footerElement}
|
${this._footerElement}
|
||||||
</ha-card>
|
</ha-card>
|
||||||
`;
|
`;
|
||||||
@ -194,9 +187,8 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
|
||||||
ha-card > div {
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
|
@ -327,6 +327,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
|
|||||||
ha-card {
|
ha-card {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
|
@ -184,11 +184,6 @@ class HuiGenericEntityRow extends LitElement {
|
|||||||
state-badge {
|
state-badge {
|
||||||
flex: 0 0 40px;
|
flex: 0 0 40px;
|
||||||
}
|
}
|
||||||
state-badge:focus {
|
|
||||||
outline: none;
|
|
||||||
background: var(--divider-color);
|
|
||||||
border-radius: 100%;
|
|
||||||
}
|
|
||||||
:host([rtl]) .flex {
|
:host([rtl]) .flex {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
|
@ -13,15 +13,23 @@ import { HomeAssistant } from "../../../types";
|
|||||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||||
import "../components/hui-generic-entity-row";
|
import "../components/hui-generic-entity-row";
|
||||||
import "../components/hui-warning";
|
import "../components/hui-warning";
|
||||||
import { EntityConfig, LovelaceRow } from "./types";
|
import { LovelaceRow } from "./types";
|
||||||
|
import { DOMAINS_HIDE_MORE_INFO } from "../../../common/const";
|
||||||
|
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||||
|
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||||
|
import { hasAction } from "../common/has-action";
|
||||||
|
import { ActionHandlerEvent } from "../../../data/lovelace";
|
||||||
|
import { handleAction } from "../common/handle-action";
|
||||||
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
|
import { EntitiesCardEntityConfig } from "../cards/types";
|
||||||
|
|
||||||
@customElement("hui-text-entity-row")
|
@customElement("hui-text-entity-row")
|
||||||
class HuiTextEntityRow extends LitElement implements LovelaceRow {
|
class HuiTextEntityRow extends LitElement implements LovelaceRow {
|
||||||
@property() public hass?: HomeAssistant;
|
@property() public hass?: HomeAssistant;
|
||||||
|
|
||||||
@property() private _config?: EntityConfig;
|
@property() private _config?: EntitiesCardEntityConfig;
|
||||||
|
|
||||||
public setConfig(config: EntityConfig): void {
|
public setConfig(config: EntitiesCardEntityConfig): void {
|
||||||
if (!config) {
|
if (!config) {
|
||||||
throw new Error("Configuration error");
|
throw new Error("Configuration error");
|
||||||
}
|
}
|
||||||
@ -51,9 +59,23 @@ class HuiTextEntityRow extends LitElement implements LovelaceRow {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const pointer =
|
||||||
|
(this._config.tap_action && this._config.tap_action.action !== "none") ||
|
||||||
|
(this._config.entity &&
|
||||||
|
!DOMAINS_HIDE_MORE_INFO.includes(computeDomain(this._config.entity)));
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
|
<hui-generic-entity-row .hass=${this.hass} .config=${this._config}>
|
||||||
<div class="text-content">
|
<div
|
||||||
|
class="text-content ${classMap({
|
||||||
|
pointer,
|
||||||
|
})}"
|
||||||
|
@action=${this._handleAction}
|
||||||
|
.actionHandler=${actionHandler({
|
||||||
|
hasHold: hasAction(this._config.hold_action),
|
||||||
|
hasDoubleClick: hasAction(this._config.double_tap_action),
|
||||||
|
})}
|
||||||
|
>
|
||||||
${computeStateDisplay(
|
${computeStateDisplay(
|
||||||
this.hass!.localize,
|
this.hass!.localize,
|
||||||
stateObj,
|
stateObj,
|
||||||
@ -64,11 +86,18 @@ class HuiTextEntityRow extends LitElement implements LovelaceRow {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleAction(ev: ActionHandlerEvent) {
|
||||||
|
handleAction(this, this.hass!, this._config!, ev.detail.action);
|
||||||
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
return css`
|
return css`
|
||||||
div {
|
div {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
.pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ class HuiWeatherEntityRow extends LitElement implements LovelaceRow {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
class="icon-image${classMap({
|
class="icon-image ${classMap({
|
||||||
pointer,
|
pointer,
|
||||||
})}"
|
})}"
|
||||||
@action=${this._handleAction}
|
@action=${this._handleAction}
|
||||||
@ -165,6 +165,12 @@ class HuiWeatherEntityRow extends LitElement implements LovelaceRow {
|
|||||||
height: 40px;
|
height: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-image:focus {
|
||||||
|
outline: none;
|
||||||
|
background-color: var(--divider-color);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
.weather-icon {
|
.weather-icon {
|
||||||
--iron-icon-width: 40px;
|
--iron-icon-width: 40px;
|
||||||
--iron-icon-height: 40px;
|
--iron-icon-height: 40px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user