fix build

This commit is contained in:
Ian Richardson
2019-11-05 13:49:11 -06:00
parent d74ecba6ab
commit aba2cb88a3
11 changed files with 180 additions and 157 deletions
+39 -58
View File
@@ -1,10 +1,7 @@
import { directive, PropertyPart } from "lit-html";
import { fireEvent, ActionHandlerOptions } from "custom-card-helpers";
import { directive, PropertyPart } from 'lit-html';
import { fireEvent, ActionHandlerOptions } from 'custom-card-helpers';
const isTouch =
"ontouchstart" in window ||
navigator.maxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0;
const isTouch = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
interface ActionHandler extends HTMLElement {
holdTime: number;
@@ -16,6 +13,7 @@ interface ActionHandlerElement extends Element {
class ActionHandler extends HTMLElement implements ActionHandler {
public holdTime: number;
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
public ripple: any;
protected timer: number | undefined;
protected held: boolean;
@@ -26,34 +24,26 @@ class ActionHandler extends HTMLElement implements ActionHandler {
constructor() {
super();
this.holdTime = 500;
this.ripple = document.createElement("mwc-ripple");
this.ripple = document.createElement('mwc-ripple');
this.timer = undefined;
this.held = false;
this.cooldownStart = false;
this.cooldownEnd = false;
}
public connectedCallback() {
public connectedCallback(): void {
Object.assign(this.style, {
position: "absolute",
width: isTouch ? "100px" : "50px",
height: isTouch ? "100px" : "50px",
transform: "translate(-50%, -50%)",
pointerEvents: "none",
position: 'absolute',
width: isTouch ? '100px' : '50px',
height: isTouch ? '100px' : '50px',
transform: 'translate(-50%, -50%)',
pointerEvents: 'none',
});
this.appendChild(this.ripple);
this.ripple.primary = true;
[
"touchcancel",
"mouseout",
"mouseup",
"touchmove",
"mousewheel",
"wheel",
"scroll",
].forEach((ev) => {
['touchcancel', 'mouseout', 'mouseup', 'touchmove', 'mousewheel', 'wheel', 'scroll'].forEach(ev => {
document.addEventListener(
ev,
() => {
@@ -61,18 +51,18 @@ class ActionHandler extends HTMLElement implements ActionHandler {
this.stopAnimation();
this.timer = undefined;
},
{ passive: true }
{ passive: true },
);
});
}
public bind(element: ActionHandlerElement, options) {
public bind(element: ActionHandlerElement, options): void {
if (element.actionHandler) {
return;
}
element.actionHandler = true;
element.addEventListener("contextmenu", (ev: Event) => {
element.addEventListener('contextmenu', (ev: Event) => {
const e = ev || window.event;
if (e.preventDefault) {
e.preventDefault();
@@ -82,10 +72,10 @@ class ActionHandler extends HTMLElement implements ActionHandler {
}
e.cancelBubble = true;
e.returnValue = false;
return false;
return;
});
const clickStart = (ev: Event) => {
const clickStart = (ev: Event): void => {
if (this.cooldownStart) {
return;
}
@@ -111,38 +101,34 @@ class ActionHandler extends HTMLElement implements ActionHandler {
window.setTimeout(() => (this.cooldownStart = false), 100);
};
const clickEnd = (ev: Event) => {
if (
this.cooldownEnd ||
(["touchend", "touchcancel"].includes(ev.type) &&
this.timer === undefined)
) {
const clickEnd = (ev: Event): void => {
if (this.cooldownEnd || (['touchend', 'touchcancel'].includes(ev.type) && this.timer === undefined)) {
return;
}
clearTimeout(this.timer);
this.stopAnimation();
this.timer = undefined;
if (this.held) {
fireEvent(element as HTMLElement, "action", { action: "hold" });
fireEvent(element as HTMLElement, 'action', { action: 'hold' });
} else if (options.hasDoubleTap) {
if ((ev as MouseEvent).detail === 1) {
this.dblClickTimeout = window.setTimeout(() => {
fireEvent(element as HTMLElement, "action", { action: "tap" });
fireEvent(element as HTMLElement, 'action', { action: 'tap' });
}, 250);
} else {
clearTimeout(this.dblClickTimeout);
fireEvent(element as HTMLElement, "action", { action: "double_tap" });
fireEvent(element as HTMLElement, 'action', { action: 'double_tap' });
}
} else {
fireEvent(element as HTMLElement, "action", { action: "tap" });
fireEvent(element as HTMLElement, 'action', { action: 'tap' });
}
this.cooldownEnd = true;
window.setTimeout(() => (this.cooldownEnd = false), 100);
};
element.addEventListener("touchstart", clickStart, { passive: true });
element.addEventListener("touchend", clickEnd);
element.addEventListener("touchcancel", clickEnd);
element.addEventListener('touchstart', clickStart, { passive: true });
element.addEventListener('touchend', clickEnd);
element.addEventListener('touchcancel', clickEnd);
// iOS 13 sends a complete normal touchstart-touchend series of events followed by a mousedown-click series.
// That might be a bug, but until it's fixed, this should make action-handler work.
@@ -150,12 +136,12 @@ class ActionHandler extends HTMLElement implements ActionHandler {
// Note that all events (both touch and mouse) must be listened for in order to work on computers with both mouse and touchscreen.
const isIOS13 = window.navigator.userAgent.match(/iPhone OS 13_/);
if (!isIOS13) {
element.addEventListener("mousedown", clickStart, { passive: true });
element.addEventListener("click", clickEnd);
element.addEventListener('mousedown', clickStart, { passive: true });
element.addEventListener('click', clickEnd);
}
}
private startAnimation(x: number, y: number) {
private startAnimation(x: number, y: number): void {
Object.assign(this.style, {
left: `${x}px`,
top: `${y}px`,
@@ -166,32 +152,29 @@ class ActionHandler extends HTMLElement implements ActionHandler {
this.ripple.unbounded = true;
}
private stopAnimation() {
private stopAnimation(): void {
this.ripple.active = false;
this.ripple.disabled = true;
this.style.display = "none";
this.style.display = 'none';
}
}
// TODO You need to replace all instances of "action-handler-boilerplate" with "action-handler-<your card name>"
customElements.define("action-handler-boilerplate", ActionHandler);
customElements.define('action-handler-boilerplate', ActionHandler);
const geActionHandler = (): ActionHandler => {
const body = document.body;
if (body.querySelector("action-handler-boilerplate")) {
return body.querySelector("action-handler-boilerplate") as ActionHandler;
if (body.querySelector('action-handler-boilerplate')) {
return body.querySelector('action-handler-boilerplate') as ActionHandler;
}
const actionhandler = document.createElement("action-handler-boilerplate");
const actionhandler = document.createElement('action-handler-boilerplate');
body.appendChild(actionhandler);
return actionhandler as ActionHandler;
};
export const actionHandlerBind = (
element: ActionHandlerElement,
options: ActionHandlerOptions
) => {
export const actionHandlerBind = (element: ActionHandlerElement, options: ActionHandlerOptions): void => {
const actionhandler: ActionHandler = geActionHandler();
if (!actionhandler) {
return;
@@ -199,8 +182,6 @@ export const actionHandlerBind = (
actionhandler.bind(element, options);
};
export const actionHandler = directive(
(options: ActionHandlerOptions = {}) => (part: PropertyPart) => {
actionHandlerBind(part.committer.element, options);
}
);
export const actionHandler = directive((options: ActionHandlerOptions = {}) => (part: PropertyPart): void => {
actionHandlerBind(part.committer.element, options);
});
+25 -23
View File
@@ -1,27 +1,26 @@
import {
LitElement,
html,
customElement,
property,
CSSResult,
TemplateResult,
css,
PropertyValues
} from "lit-element";
import { LitElement, html, customElement, property, CSSResult, TemplateResult, css, PropertyValues } from 'lit-element';
import {
HomeAssistant,
hasConfigOrEntityChanged,
hasAction,
ActionHandlerEvent,
handleAction
} from "custom-card-helpers";
handleAction,
} from 'custom-card-helpers';
import { BoilerplateConfig } from "./types";
import { actionHandler } from "./action-handler-directive";
import { BoilerplateConfig } from './types';
import { actionHandler } from './action-handler-directive';
import { CARD_VERSION } from './const';
/* eslint no-console: 0 */
console.info(
`%c BOILERPLATE-CARD \n%c Version ${CARD_VERSION} `,
'color: orange; font-weight: bold; background: black',
'color: white; font-weight: bold; background: dimgray',
);
// TODO Name your custom element
@customElement("boilerplate-card")
class BoilerplateCard extends LitElement {
@customElement('boilerplate-card')
export class BoilerplateCard extends LitElement {
// TODO Add any properities that should cause your element to re-render here
@property() public hass?: HomeAssistant;
@property() private _config?: BoilerplateConfig;
@@ -29,12 +28,12 @@ class BoilerplateCard extends LitElement {
public setConfig(config: BoilerplateConfig): void {
// TODO Check for required fields and that they are of the proper format
if (!config || config.show_error) {
throw new Error("Invalid configuration");
throw new Error('Invalid configuration');
}
this._config = {
name: "Boilerplate",
...config
name: 'Boilerplate',
...config,
};
}
@@ -61,15 +60,18 @@ class BoilerplateCard extends LitElement {
.header=${this._config.name}
@action=${this._handleAction}
.actionHandler=${actionHandler({
hasHold: hasAction(this._config!.hold_action),
hasDoubleTap: hasAction(this._config!.double_tap_action)
hasHold: hasAction(this._config.hold_action),
hasDoubleTap: hasAction(this._config.double_tap_action),
repeat: this._config.hold_action ? this._config.hold_action.repeat : undefined,
})}
></ha-card>
`;
}
private _handleAction(ev: ActionHandlerEvent) {
handleAction(this, this.hass!, this._config!, ev.detail.action!);
private _handleAction(ev: ActionHandlerEvent): void {
if (this.hass && this._config && ev.detail.action) {
handleAction(this, this.hass, this._config, ev.detail.action);
}
}
static get styles(): CSSResult {
+1
View File
@@ -0,0 +1 @@
export const CARD_VERSION = '1.1.2';
+1 -1
View File
@@ -1,4 +1,4 @@
import { ActionConfig, HASSDomEvent } from "custom-card-helpers";
import { ActionConfig } from 'custom-card-helpers';
// TODO Add your configuration elements here for type-checking
export interface BoilerplateConfig {