mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Add double tap action (#3879)
* add dbltap_action * apply to picture-glance * types and boolean * fix typo * simplify double tap logic * extract hasDoubleClick functionality * address comments * address comments * double_tap_action
This commit is contained in:
parent
fb589337f8
commit
df29a5becb
@ -12,7 +12,7 @@ export class DemoUtilLongPress extends LitElement {
|
|||||||
() => html`
|
() => html`
|
||||||
<ha-card>
|
<ha-card>
|
||||||
<mwc-button
|
<mwc-button
|
||||||
@ha-click="${this._handleTap}"
|
@ha-click="${this._handleClick}"
|
||||||
@ha-hold="${this._handleHold}"
|
@ha-hold="${this._handleHold}"
|
||||||
.longPress="${longPress()}"
|
.longPress="${longPress()}"
|
||||||
>
|
>
|
||||||
@ -28,7 +28,7 @@ export class DemoUtilLongPress extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleTap(ev: Event) {
|
private _handleClick(ev: Event) {
|
||||||
this._addValue(ev, "tap");
|
this._addValue(ev, "tap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,3 +108,7 @@ export const getLovelaceCollection = (conn: Connection) =>
|
|||||||
export interface WindowWithLovelaceProm extends Window {
|
export interface WindowWithLovelaceProm extends Window {
|
||||||
llConfProm?: Promise<LovelaceConfig>;
|
llConfProm?: Promise<LovelaceConfig>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LongPressOptions {
|
||||||
|
hasDoubleClick?: boolean;
|
||||||
|
}
|
||||||
|
@ -28,6 +28,7 @@ import { longPress } from "../common/directives/long-press-directive";
|
|||||||
import { handleClick } from "../common/handle-click";
|
import { handleClick } from "../common/handle-click";
|
||||||
import { DOMAINS_TOGGLE } from "../../../common/const";
|
import { DOMAINS_TOGGLE } from "../../../common/const";
|
||||||
import { EntityButtonCardConfig } from "./types";
|
import { EntityButtonCardConfig } from "./types";
|
||||||
|
import { hasDoubleClick } from "../common/has-double-click";
|
||||||
|
|
||||||
@customElement("hui-entity-button-card")
|
@customElement("hui-entity-button-card")
|
||||||
class HuiEntityButtonCard extends LitElement implements LovelaceCard {
|
class HuiEntityButtonCard extends LitElement implements LovelaceCard {
|
||||||
@ -61,6 +62,7 @@ class HuiEntityButtonCard extends LitElement implements LovelaceCard {
|
|||||||
this._config = {
|
this._config = {
|
||||||
theme: "default",
|
theme: "default",
|
||||||
hold_action: { action: "more-info" },
|
hold_action: { action: "more-info" },
|
||||||
|
double_tap_action: { action: "none" },
|
||||||
show_icon: true,
|
show_icon: true,
|
||||||
show_name: true,
|
show_name: true,
|
||||||
...config,
|
...config,
|
||||||
@ -118,9 +120,12 @@ class HuiEntityButtonCard extends LitElement implements LovelaceCard {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card
|
<ha-card
|
||||||
@ha-click="${this._handleTap}"
|
@ha-click=${this._handleClick}
|
||||||
@ha-hold="${this._handleHold}"
|
@ha-hold=${this._handleHold}
|
||||||
.longPress="${longPress()}"
|
@ha-dblclick=${this._handleDblClick}
|
||||||
|
.longPress=${longPress({
|
||||||
|
hasDoubleClick: hasDoubleClick(this._config!.double_tap_action),
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
${this._config.show_icon
|
${this._config.show_icon
|
||||||
? html`
|
? html`
|
||||||
@ -212,12 +217,16 @@ class HuiEntityButtonCard extends LitElement implements LovelaceCard {
|
|||||||
return `hsl(${hue}, 100%, ${100 - sat / 2}%)`;
|
return `hsl(${hue}, 100%, ${100 - sat / 2}%)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleTap() {
|
private _handleClick() {
|
||||||
handleClick(this, this.hass!, this._config!, false);
|
handleClick(this, this.hass!, this._config!, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleHold() {
|
private _handleHold() {
|
||||||
handleClick(this, this.hass!, this._config!, true);
|
handleClick(this, this.hass!, this._config!, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleDblClick() {
|
||||||
|
handleClick(this, this.hass!, this._config!, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ import { longPress } from "../common/directives/long-press-directive";
|
|||||||
import { processConfigEntities } from "../common/process-config-entities";
|
import { processConfigEntities } from "../common/process-config-entities";
|
||||||
import { handleClick } from "../common/handle-click";
|
import { handleClick } from "../common/handle-click";
|
||||||
import { GlanceCardConfig, GlanceConfigEntity } from "./types";
|
import { GlanceCardConfig, GlanceConfigEntity } from "./types";
|
||||||
|
import { hasDoubleClick } from "../common/has-double-click";
|
||||||
|
|
||||||
@customElement("hui-glance-card")
|
@customElement("hui-glance-card")
|
||||||
export class HuiGlanceCard extends LitElement implements LovelaceCard {
|
export class HuiGlanceCard extends LitElement implements LovelaceCard {
|
||||||
@ -183,9 +184,12 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard {
|
|||||||
<div
|
<div
|
||||||
class="entity"
|
class="entity"
|
||||||
.entityConf="${entityConf}"
|
.entityConf="${entityConf}"
|
||||||
@ha-click="${this._handleTap}"
|
@ha-click=${this._handleClick}
|
||||||
@ha-hold="${this._handleHold}"
|
@ha-hold=${this._handleHold}
|
||||||
.longPress="${longPress()}"
|
@ha-dblclick=${this._handleDblClick}
|
||||||
|
.longPress=${longPress({
|
||||||
|
hasDoubleClick: hasDoubleClick(entityConf.double_tap_action),
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
${this._config!.show_name !== false
|
${this._config!.show_name !== false
|
||||||
? html`
|
? html`
|
||||||
@ -226,14 +230,19 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleTap(ev: MouseEvent): void {
|
private _handleClick(ev: MouseEvent): void {
|
||||||
const config = (ev.currentTarget as any).entityConf as GlanceConfigEntity;
|
const config = (ev.currentTarget as any).entityConf as GlanceConfigEntity;
|
||||||
handleClick(this, this.hass!, config, false);
|
handleClick(this, this.hass!, config, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleHold(ev: MouseEvent): void {
|
private _handleHold(ev: MouseEvent): void {
|
||||||
const config = (ev.currentTarget as any).entityConf as GlanceConfigEntity;
|
const config = (ev.currentTarget as any).entityConf as GlanceConfigEntity;
|
||||||
handleClick(this, this.hass!, config, true);
|
handleClick(this, this.hass!, config, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleDblClick(ev: MouseEvent): void {
|
||||||
|
const config = (ev.currentTarget as any).entityConf as GlanceConfigEntity;
|
||||||
|
handleClick(this, this.hass!, config, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,12 +112,12 @@ export class HuiLightCard extends LitElement implements LovelaceCard {
|
|||||||
filter: this._computeBrightness(stateObj),
|
filter: this._computeBrightness(stateObj),
|
||||||
color: this._computeColor(stateObj),
|
color: this._computeColor(stateObj),
|
||||||
})}"
|
})}"
|
||||||
@click="${this._handleTap}"
|
@click="${this._handleClick}"
|
||||||
></ha-icon>
|
></ha-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="tooltip">
|
<div id="tooltip">
|
||||||
<div class="brightness" @ha-click="${this._handleTap}">
|
<div class="brightness" @ha-click="${this._handleClick}">
|
||||||
${brightness} %
|
${brightness} %
|
||||||
</div>
|
</div>
|
||||||
<div class="name">
|
<div class="name">
|
||||||
@ -297,7 +297,7 @@ export class HuiLightCard extends LitElement implements LovelaceCard {
|
|||||||
return `hsl(${hue}, 100%, ${100 - sat / 2}%)`;
|
return `hsl(${hue}, 100%, ${100 - sat / 2}%)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleTap() {
|
private _handleClick() {
|
||||||
toggleEntity(this.hass!, this._config!.entity!);
|
toggleEntity(this.hass!, this._config!.entity!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import { classMap } from "lit-html/directives/class-map";
|
|||||||
import { handleClick } from "../common/handle-click";
|
import { handleClick } from "../common/handle-click";
|
||||||
import { longPress } from "../common/directives/long-press-directive";
|
import { longPress } from "../common/directives/long-press-directive";
|
||||||
import { PictureCardConfig } from "./types";
|
import { PictureCardConfig } from "./types";
|
||||||
|
import { hasDoubleClick } from "../common/has-double-click";
|
||||||
|
|
||||||
@customElement("hui-picture-card")
|
@customElement("hui-picture-card")
|
||||||
export class HuiPictureCard extends LitElement implements LovelaceCard {
|
export class HuiPictureCard extends LitElement implements LovelaceCard {
|
||||||
@ -55,9 +56,12 @@ export class HuiPictureCard extends LitElement implements LovelaceCard {
|
|||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-card
|
<ha-card
|
||||||
@ha-click="${this._handleTap}"
|
@ha-click=${this._handleClick}
|
||||||
@ha-hold="${this._handleHold}"
|
@ha-hold=${this._handleHold}
|
||||||
.longPress="${longPress()}"
|
@ha-dblclick=${this._handleDblClick}
|
||||||
|
.longPress=${longPress({
|
||||||
|
hasDoubleClick: hasDoubleClick(this._config!.double_tap_action),
|
||||||
|
})}
|
||||||
class="${classMap({
|
class="${classMap({
|
||||||
clickable: Boolean(
|
clickable: Boolean(
|
||||||
this._config.tap_action || this._config.hold_action
|
this._config.tap_action || this._config.hold_action
|
||||||
@ -86,12 +90,16 @@ export class HuiPictureCard extends LitElement implements LovelaceCard {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleTap() {
|
private _handleClick() {
|
||||||
handleClick(this, this.hass!, this._config!, false);
|
handleClick(this, this.hass!, this._config!, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleHold() {
|
private _handleHold() {
|
||||||
handleClick(this, this.hass!, this._config!, true);
|
handleClick(this, this.hass!, this._config!, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleDblClick() {
|
||||||
|
handleClick(this, this.hass!, this._config!, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import { handleClick } from "../common/handle-click";
|
|||||||
import { UNAVAILABLE } from "../../../data/entity";
|
import { UNAVAILABLE } from "../../../data/entity";
|
||||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||||
import { PictureEntityCardConfig } from "./types";
|
import { PictureEntityCardConfig } from "./types";
|
||||||
|
import { hasDoubleClick } from "../common/has-double-click";
|
||||||
|
|
||||||
@customElement("hui-picture-entity-card")
|
@customElement("hui-picture-entity-card")
|
||||||
class HuiPictureEntityCard extends LitElement implements LovelaceCard {
|
class HuiPictureEntityCard extends LitElement implements LovelaceCard {
|
||||||
@ -124,9 +125,12 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard {
|
|||||||
.cameraView=${this._config.camera_view}
|
.cameraView=${this._config.camera_view}
|
||||||
.entity=${this._config.entity}
|
.entity=${this._config.entity}
|
||||||
.aspectRatio=${this._config.aspect_ratio}
|
.aspectRatio=${this._config.aspect_ratio}
|
||||||
@ha-click=${this._handleTap}
|
@ha-click=${this._handleClick}
|
||||||
@ha-hold=${this._handleHold}
|
@ha-hold=${this._handleHold}
|
||||||
.longPress=${longPress()}
|
@ha-dblclick=${this._handleDblClick}
|
||||||
|
.longPress=${longPress({
|
||||||
|
hasDoubleClick: hasDoubleClick(this._config!.double_tap_action),
|
||||||
|
})}
|
||||||
class=${classMap({
|
class=${classMap({
|
||||||
clickable: stateObj.state !== UNAVAILABLE,
|
clickable: stateObj.state !== UNAVAILABLE,
|
||||||
})}
|
})}
|
||||||
@ -177,12 +181,16 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleTap() {
|
private _handleClick() {
|
||||||
handleClick(this, this.hass!, this._config!, false);
|
handleClick(this, this.hass!, this._config!, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleHold() {
|
private _handleHold() {
|
||||||
handleClick(this, this.hass!, this._config!, true);
|
handleClick(this, this.hass!, this._config!, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleDblClick() {
|
||||||
|
handleClick(this, this.hass!, this._config!, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import { HomeAssistant } from "../../../types";
|
|||||||
import { longPress } from "../common/directives/long-press-directive";
|
import { longPress } from "../common/directives/long-press-directive";
|
||||||
import { processConfigEntities } from "../common/process-config-entities";
|
import { processConfigEntities } from "../common/process-config-entities";
|
||||||
import { handleClick } from "../common/handle-click";
|
import { handleClick } from "../common/handle-click";
|
||||||
|
import { hasDoubleClick } from "../common/has-double-click";
|
||||||
import { PictureGlanceCardConfig, PictureGlanceEntityConfig } from "./types";
|
import { PictureGlanceCardConfig, PictureGlanceEntityConfig } from "./types";
|
||||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||||
|
|
||||||
@ -130,9 +131,12 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard {
|
|||||||
this._config.camera_image
|
this._config.camera_image
|
||||||
),
|
),
|
||||||
})}
|
})}
|
||||||
@ha-click=${this._handleTap}
|
@ha-click=${this._handleClick}
|
||||||
@ha-hold=${this._handleHold}
|
@ha-hold=${this._handleHold}
|
||||||
.longPress=${longPress()}
|
@ha-dblclick=${this._handleDblClick}
|
||||||
|
.longPress=${longPress({
|
||||||
|
hasDoubleClick: hasDoubleClick(this._config!.double_tap_action),
|
||||||
|
})}
|
||||||
.config=${this._config}
|
.config=${this._config}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.image=${this._config.image}
|
.image=${this._config.image}
|
||||||
@ -190,9 +194,12 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard {
|
|||||||
return html`
|
return html`
|
||||||
<div class="wrapper">
|
<div class="wrapper">
|
||||||
<ha-icon
|
<ha-icon
|
||||||
@ha-click=${this._handleTap}
|
@ha-click=${this._handleClick}
|
||||||
@ha-hold=${this._handleHold}
|
@ha-hold=${this._handleHold}
|
||||||
.longPress=${longPress()}
|
@ha-dblclick=${this._handleDblClick}
|
||||||
|
.longPress=${longPress({
|
||||||
|
hasDoubleClick: hasDoubleClick(entityConf.double_tap_action),
|
||||||
|
})}
|
||||||
.config=${entityConf}
|
.config=${entityConf}
|
||||||
class="${classMap({
|
class="${classMap({
|
||||||
"state-on": !STATES_OFF.has(stateObj.state),
|
"state-on": !STATES_OFF.has(stateObj.state),
|
||||||
@ -223,14 +230,19 @@ class HuiPictureGlanceCard extends LitElement implements LovelaceCard {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleTap(ev: MouseEvent): void {
|
private _handleClick(ev: MouseEvent): void {
|
||||||
const config = (ev.currentTarget as any).config as any;
|
const config = (ev.currentTarget as any).config as any;
|
||||||
handleClick(this, this.hass!, config, false);
|
handleClick(this, this.hass!, config, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleHold(ev: MouseEvent): void {
|
private _handleHold(ev: MouseEvent): void {
|
||||||
const config = (ev.currentTarget as any).config as any;
|
const config = (ev.currentTarget as any).config as any;
|
||||||
handleClick(this, this.hass!, config, true);
|
handleClick(this, this.hass!, config, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleDblClick(ev: MouseEvent): void {
|
||||||
|
const config = (ev.currentTarget as any).entityConf as any;
|
||||||
|
handleClick(this, this.hass!, config, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
|
@ -46,6 +46,7 @@ export interface EntityButtonCardConfig extends LovelaceCardConfig {
|
|||||||
theme?: string;
|
theme?: string;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
|
double_tap_action?: ActionConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface EntityFilterCardConfig extends LovelaceCardConfig {
|
export interface EntityFilterCardConfig extends LovelaceCardConfig {
|
||||||
@ -80,6 +81,7 @@ export interface GaugeCardConfig extends LovelaceCardConfig {
|
|||||||
export interface ConfigEntity extends EntityConfig {
|
export interface ConfigEntity extends EntityConfig {
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
|
double_tap_action?: ActionConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PictureGlanceEntityConfig extends ConfigEntity {
|
export interface PictureGlanceEntityConfig extends ConfigEntity {
|
||||||
@ -141,6 +143,7 @@ export interface PictureCardConfig extends LovelaceCardConfig {
|
|||||||
image?: string;
|
image?: string;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
|
double_tap_action?: ActionConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PictureElementsCardConfig extends LovelaceCardConfig {
|
export interface PictureElementsCardConfig extends LovelaceCardConfig {
|
||||||
@ -166,6 +169,7 @@ export interface PictureEntityCardConfig extends LovelaceCardConfig {
|
|||||||
aspect_ratio?: string;
|
aspect_ratio?: string;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
|
double_tap_action?: ActionConfig;
|
||||||
show_name?: boolean;
|
show_name?: boolean;
|
||||||
show_state?: boolean;
|
show_state?: boolean;
|
||||||
}
|
}
|
||||||
@ -182,6 +186,7 @@ export interface PictureGlanceCardConfig extends LovelaceCardConfig {
|
|||||||
entity?: string;
|
entity?: string;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
|
double_tap_action?: ActionConfig;
|
||||||
show_state?: boolean;
|
show_state?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ interface Config extends LovelaceElementConfig {
|
|||||||
title?: string;
|
title?: string;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
|
double_tap_action?: ActionConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const computeTooltip = (hass: HomeAssistant, config: Config): string => {
|
export const computeTooltip = (hass: HomeAssistant, config: Config): string => {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { directive, PropertyPart } from "lit-html";
|
import { directive, PropertyPart } from "lit-html";
|
||||||
import "@material/mwc-ripple";
|
import "@material/mwc-ripple";
|
||||||
|
import { LongPressOptions } from "../../../../data/lovelace";
|
||||||
|
|
||||||
const isTouch =
|
const isTouch =
|
||||||
"ontouchstart" in window ||
|
"ontouchstart" in window ||
|
||||||
@ -8,7 +9,7 @@ const isTouch =
|
|||||||
|
|
||||||
interface LongPress extends HTMLElement {
|
interface LongPress extends HTMLElement {
|
||||||
holdTime: number;
|
holdTime: number;
|
||||||
bind(element: Element): void;
|
bind(element: Element, options): void;
|
||||||
}
|
}
|
||||||
interface LongPressElement extends Element {
|
interface LongPressElement extends Element {
|
||||||
longPress?: boolean;
|
longPress?: boolean;
|
||||||
@ -21,6 +22,7 @@ class LongPress extends HTMLElement implements LongPress {
|
|||||||
protected held: boolean;
|
protected held: boolean;
|
||||||
protected cooldownStart: boolean;
|
protected cooldownStart: boolean;
|
||||||
protected cooldownEnd: boolean;
|
protected cooldownEnd: boolean;
|
||||||
|
private dblClickTimeout: number | undefined;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -65,7 +67,7 @@ class LongPress extends HTMLElement implements LongPress {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public bind(element: LongPressElement) {
|
public bind(element: LongPressElement, options) {
|
||||||
if (element.longPress) {
|
if (element.longPress) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -120,6 +122,15 @@ class LongPress extends HTMLElement implements LongPress {
|
|||||||
this.timer = undefined;
|
this.timer = undefined;
|
||||||
if (this.held) {
|
if (this.held) {
|
||||||
element.dispatchEvent(new Event("ha-hold"));
|
element.dispatchEvent(new Event("ha-hold"));
|
||||||
|
} else if (options.hasDoubleClick) {
|
||||||
|
if ((ev as MouseEvent).detail === 1) {
|
||||||
|
this.dblClickTimeout = window.setTimeout(() => {
|
||||||
|
element.dispatchEvent(new Event("ha-click"));
|
||||||
|
}, 250);
|
||||||
|
} else {
|
||||||
|
clearTimeout(this.dblClickTimeout);
|
||||||
|
element.dispatchEvent(new Event("ha-dblclick"));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
element.dispatchEvent(new Event("ha-click"));
|
element.dispatchEvent(new Event("ha-click"));
|
||||||
}
|
}
|
||||||
@ -174,14 +185,19 @@ const getLongPress = (): LongPress => {
|
|||||||
return longpress as LongPress;
|
return longpress as LongPress;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const longPressBind = (element: LongPressElement) => {
|
export const longPressBind = (
|
||||||
|
element: LongPressElement,
|
||||||
|
options: LongPressOptions
|
||||||
|
) => {
|
||||||
const longpress: LongPress = getLongPress();
|
const longpress: LongPress = getLongPress();
|
||||||
if (!longpress) {
|
if (!longpress) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
longpress.bind(element);
|
longpress.bind(element, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const longPress = directive(() => (part: PropertyPart) => {
|
export const longPress = directive(
|
||||||
longPressBind(part.committer.element);
|
(options: LongPressOptions = {}) => (part: PropertyPart) => {
|
||||||
});
|
longPressBind(part.committer.element, options);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
@ -13,12 +13,16 @@ export const handleClick = (
|
|||||||
camera_image?: string;
|
camera_image?: string;
|
||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
|
double_tap_action?: ActionConfig;
|
||||||
},
|
},
|
||||||
hold: boolean
|
hold: boolean,
|
||||||
|
dblClick: boolean
|
||||||
): void => {
|
): void => {
|
||||||
let actionConfig: ActionConfig | undefined;
|
let actionConfig: ActionConfig | undefined;
|
||||||
|
|
||||||
if (hold && config.hold_action) {
|
if (dblClick && config.double_tap_action) {
|
||||||
|
actionConfig = config.double_tap_action;
|
||||||
|
} else if (hold && config.hold_action) {
|
||||||
actionConfig = config.hold_action;
|
actionConfig = config.hold_action;
|
||||||
} else if (!hold && config.tap_action) {
|
} else if (!hold && config.tap_action) {
|
||||||
actionConfig = config.tap_action;
|
actionConfig = config.tap_action;
|
||||||
|
6
src/panels/lovelace/common/has-double-click.ts
Normal file
6
src/panels/lovelace/common/has-double-click.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { ActionConfig } from "../../../data/lovelace";
|
||||||
|
|
||||||
|
// Check if config or Entity changed
|
||||||
|
export function hasDoubleClick(config?: ActionConfig): boolean {
|
||||||
|
return config !== undefined && config.action !== "none";
|
||||||
|
}
|
@ -15,6 +15,7 @@ import { handleClick } from "../common/handle-click";
|
|||||||
import { longPress } from "../common/directives/long-press-directive";
|
import { longPress } from "../common/directives/long-press-directive";
|
||||||
import { LovelaceElement, IconElementConfig } from "./types";
|
import { LovelaceElement, IconElementConfig } from "./types";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
|
import { hasDoubleClick } from "../common/has-double-click";
|
||||||
|
|
||||||
@customElement("hui-icon-element")
|
@customElement("hui-icon-element")
|
||||||
export class HuiIconElement extends LitElement implements LovelaceElement {
|
export class HuiIconElement extends LitElement implements LovelaceElement {
|
||||||
@ -38,19 +39,26 @@ export class HuiIconElement extends LitElement implements LovelaceElement {
|
|||||||
<ha-icon
|
<ha-icon
|
||||||
.icon="${this._config.icon}"
|
.icon="${this._config.icon}"
|
||||||
.title="${computeTooltip(this.hass, this._config)}"
|
.title="${computeTooltip(this.hass, this._config)}"
|
||||||
@ha-click="${this._handleTap}"
|
@ha-click=${this._handleClick}
|
||||||
@ha-hold="${this._handleHold}"
|
@ha-hold=${this._handleHold}
|
||||||
.longPress="${longPress()}"
|
@ha-dblclick=${this._handleDblClick}
|
||||||
|
.longPress=${longPress({
|
||||||
|
hasDoubleClick: hasDoubleClick(this._config!.double_tap_action),
|
||||||
|
})}
|
||||||
></ha-icon>
|
></ha-icon>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleTap(): void {
|
private _handleClick(): void {
|
||||||
handleClick(this, this.hass!, this._config!, false);
|
handleClick(this, this.hass!, this._config!, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleHold(): void {
|
private _handleHold(): void {
|
||||||
handleClick(this, this.hass!, this._config!, true);
|
handleClick(this, this.hass!, this._config!, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleDblClick() {
|
||||||
|
handleClick(this, this.hass!, this._config!, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
|
@ -15,6 +15,7 @@ import { handleClick } from "../common/handle-click";
|
|||||||
import { longPress } from "../common/directives/long-press-directive";
|
import { longPress } from "../common/directives/long-press-directive";
|
||||||
import { LovelaceElement, ImageElementConfig } from "./types";
|
import { LovelaceElement, ImageElementConfig } from "./types";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
|
import { hasDoubleClick } from "../common/has-double-click";
|
||||||
|
|
||||||
@customElement("hui-image-element")
|
@customElement("hui-image-element")
|
||||||
export class HuiImageElement extends LitElement implements LovelaceElement {
|
export class HuiImageElement extends LitElement implements LovelaceElement {
|
||||||
@ -49,9 +50,12 @@ export class HuiImageElement extends LitElement implements LovelaceElement {
|
|||||||
.stateFilter="${this._config.state_filter}"
|
.stateFilter="${this._config.state_filter}"
|
||||||
.title="${computeTooltip(this.hass, this._config)}"
|
.title="${computeTooltip(this.hass, this._config)}"
|
||||||
.aspectRatio="${this._config.aspect_ratio}"
|
.aspectRatio="${this._config.aspect_ratio}"
|
||||||
@ha-click="${this._handleTap}"
|
@ha-click=${this._handleClick}
|
||||||
@ha-hold="${this._handleHold}"
|
@ha-hold=${this._handleHold}
|
||||||
.longPress="${longPress()}"
|
@ha-dblclick=${this._handleDblClick}
|
||||||
|
.longPress=${longPress({
|
||||||
|
hasDoubleClick: hasDoubleClick(this._config!.double_tap_action),
|
||||||
|
})}
|
||||||
></hui-image>
|
></hui-image>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -69,12 +73,16 @@ export class HuiImageElement extends LitElement implements LovelaceElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleTap(): void {
|
private _handleClick(): void {
|
||||||
handleClick(this, this.hass!, this._config!, false);
|
handleClick(this, this.hass!, this._config!, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleHold(): void {
|
private _handleHold(): void {
|
||||||
handleClick(this, this.hass!, this._config!, true);
|
handleClick(this, this.hass!, this._config!, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleDblClick() {
|
||||||
|
handleClick(this, this.hass!, this._config!, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ import { longPress } from "../common/directives/long-press-directive";
|
|||||||
import { LovelaceElement, StateIconElementConfig } from "./types";
|
import { LovelaceElement, StateIconElementConfig } from "./types";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||||
|
import { hasDoubleClick } from "../common/has-double-click";
|
||||||
|
|
||||||
@customElement("hui-state-icon-element")
|
@customElement("hui-state-icon-element")
|
||||||
export class HuiStateIconElement extends LitElement implements LovelaceElement {
|
export class HuiStateIconElement extends LitElement implements LovelaceElement {
|
||||||
@ -59,9 +60,12 @@ export class HuiStateIconElement extends LitElement implements LovelaceElement {
|
|||||||
<state-badge
|
<state-badge
|
||||||
.stateObj="${stateObj}"
|
.stateObj="${stateObj}"
|
||||||
.title="${computeTooltip(this.hass, this._config)}"
|
.title="${computeTooltip(this.hass, this._config)}"
|
||||||
@ha-click="${this._handleClick}"
|
@ha-click=${this._handleClick}
|
||||||
@ha-hold="${this._handleHold}"
|
@ha-hold=${this._handleHold}
|
||||||
.longPress="${longPress()}"
|
@ha-dblclick=${this._handleDblClick}
|
||||||
|
.longPress=${longPress({
|
||||||
|
hasDoubleClick: hasDoubleClick(this._config!.double_tap_action),
|
||||||
|
})}
|
||||||
.overrideIcon=${this._config.icon}
|
.overrideIcon=${this._config.icon}
|
||||||
></state-badge>
|
></state-badge>
|
||||||
`;
|
`;
|
||||||
@ -76,11 +80,15 @@ export class HuiStateIconElement extends LitElement implements LovelaceElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _handleClick(): void {
|
private _handleClick(): void {
|
||||||
handleClick(this, this.hass!, this._config!, false);
|
handleClick(this, this.hass!, this._config!, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleHold(): void {
|
private _handleHold(): void {
|
||||||
handleClick(this, this.hass!, this._config!, true);
|
handleClick(this, this.hass!, this._config!, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleDblClick() {
|
||||||
|
handleClick(this, this.hass!, this._config!, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@ import { longPress } from "../common/directives/long-press-directive";
|
|||||||
import { LovelaceElement, StateLabelElementConfig } from "./types";
|
import { LovelaceElement, StateLabelElementConfig } from "./types";
|
||||||
import { HomeAssistant } from "../../../types";
|
import { HomeAssistant } from "../../../types";
|
||||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||||
|
import { hasDoubleClick } from "../common/has-double-click";
|
||||||
|
|
||||||
@customElement("hui-state-label-element")
|
@customElement("hui-state-label-element")
|
||||||
class HuiStateLabelElement extends LitElement implements LovelaceElement {
|
class HuiStateLabelElement extends LitElement implements LovelaceElement {
|
||||||
@ -59,9 +60,12 @@ class HuiStateLabelElement extends LitElement implements LovelaceElement {
|
|||||||
return html`
|
return html`
|
||||||
<div
|
<div
|
||||||
.title="${computeTooltip(this.hass, this._config)}"
|
.title="${computeTooltip(this.hass, this._config)}"
|
||||||
@ha-click="${this._handleTap}"
|
@ha-click=${this._handleClick}
|
||||||
@ha-hold="${this._handleHold}"
|
@ha-hold=${this._handleHold}
|
||||||
.longPress="${longPress()}"
|
@ha-dblclick=${this._handleDblClick}
|
||||||
|
.longPress=${longPress({
|
||||||
|
hasDoubleClick: hasDoubleClick(this._config!.double_tap_action),
|
||||||
|
})}
|
||||||
>
|
>
|
||||||
${this._config.prefix}${stateObj
|
${this._config.prefix}${stateObj
|
||||||
? computeStateDisplay(
|
? computeStateDisplay(
|
||||||
@ -74,12 +78,16 @@ class HuiStateLabelElement extends LitElement implements LovelaceElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleTap(): void {
|
private _handleClick(): void {
|
||||||
handleClick(this, this.hass!, this._config!, false);
|
handleClick(this, this.hass!, this._config!, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private _handleHold(): void {
|
private _handleHold(): void {
|
||||||
handleClick(this, this.hass!, this._config!, true);
|
handleClick(this, this.hass!, this._config!, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleDblClick() {
|
||||||
|
handleClick(this, this.hass!, this._config!, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
|
@ -22,6 +22,7 @@ export interface IconElementConfig extends LovelaceElementConfig {
|
|||||||
name?: string;
|
name?: string;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
|
double_tap_action?: ActionConfig;
|
||||||
icon: string;
|
icon: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,6 +30,7 @@ export interface ImageElementConfig extends LovelaceElementConfig {
|
|||||||
entity?: string;
|
entity?: string;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
|
double_tap_action?: ActionConfig;
|
||||||
image?: string;
|
image?: string;
|
||||||
state_image?: string;
|
state_image?: string;
|
||||||
camera_image?: string;
|
camera_image?: string;
|
||||||
@ -52,6 +54,7 @@ export interface StateIconElementConfig extends LovelaceElementConfig {
|
|||||||
entity: string;
|
entity: string;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
|
double_tap_action?: ActionConfig;
|
||||||
icon?: string;
|
icon?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,4 +64,5 @@ export interface StateLabelElementConfig extends LovelaceElementConfig {
|
|||||||
suffix?: string;
|
suffix?: string;
|
||||||
tap_action?: ActionConfig;
|
tap_action?: ActionConfig;
|
||||||
hold_action?: ActionConfig;
|
hold_action?: ActionConfig;
|
||||||
|
double_tap_action?: ActionConfig;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user