Skip to content

Commit

Permalink
fix build
Browse files Browse the repository at this point in the history
  • Loading branch information
iantrich committed Nov 5, 2019
1 parent d74ecba commit aba2cb8
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 157 deletions.
13 changes: 13 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module.exports = {
parser: '@typescript-eslint/parser', // Specifies the ESLint parser
extends: [
'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin
'prettier/@typescript-eslint', // Uses eslint-config-prettier to disable ESLint rules from @typescript-eslint/eslint-plugin that would conflict with prettier
'plugin:prettier/recommended', // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array.
],
parserOptions: {
ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
sourceType: 'module', // Allows for the use of imports
experimentalDecorators: true,
},
};
22 changes: 0 additions & 22 deletions .eslintrc.yaml

This file was deleted.

7 changes: 7 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 120,
tabWidth: 2,
};
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ A community driven boilerplate of best practices for Home Assistant Lovelace cus
[![Discord][discord-shield]][discord]
[![Community Forum][forum-shield]][forum]

## Support

Hey dude! Help me out for a couple of :beers: or a :coffee:!

[![coffee](https://www.buymeacoffee.com/assets/img/custom_images/black_img.png)](https://www.buymeacoffee.com/zJtVxUAgH)

## Options

| Name | Type | Requirement | Description | Default |
Expand All @@ -35,6 +41,7 @@ A community driven boilerplate of best practices for Home Assistant Lovelace cus
| service | string | **Optional** | Service to call (e.g. media_player.media_play_pause) when action defined as call-service | `none` |
| service_data | object | **Optional** | Service data to include (e.g. entity_id: media_player.bedroom) when action defined as call-service | `none` |
| haptic | string | **Optional** | Haptic feedback for the [Beta IOS App](http://home-assistant.io/ios/beta) _success, warning, failure, light, medium, heavy, selection_ | `none` |
| repeat | number | **Optional** | How often to repeat the `hold_action` in milliseconds. | `non` |

## Starting a new card from boilerplate-card

Expand Down
8 changes: 4 additions & 4 deletions dist/boilerplate-card.js

Large diffs are not rendered by default.

91 changes: 47 additions & 44 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,46 +1,49 @@
{
"name": "boilerplate-card",
"version": "1.1.1",
"description": "Lovelace boilerplate-card",
"keywords": [
"home-assistant",
"homeassistant",
"hass",
"automation",
"lovelace",
"custom-cards"
],
"module": "boilerplate-card.js",
"repository": "[email protected]:custom_cards/boilerplate-card.git",
"author": "Ian Richardson <[email protected]>",
"license": "MIT",
"dependencies": {
"custom-card-helpers": "^1.3.5",
"home-assistant-js-websocket": "^4.4.0",
"lit-element": "^2.2.1"
},
"devDependencies": {
"@babel/core": "^7.6.4",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-proposal-decorators": "^7.4.0",
"@typescript-eslint/eslint-plugin": "^2.6.0",
"@typescript-eslint/parser": "^2.6.0",
"eslint": "^6.6.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-plugin-import": "^2.18.2",
"prettier": "^1.18.2",
"rollup": "^1.26.0",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-terser": "^5.1.2",
"rollup-plugin-typescript2": "^0.24.3",
"rollup-plugin-uglify": "^6.0.3",
"typescript": "^3.6.4"
},
"scripts": {
"start": "rollup -c --watch",
"build": "npm run lint && npm run rollup",
"lint": "eslint src/*.ts",
"rollup": "rollup -c"
}
"name": "boilerplate-card",
"version": "1.1.1",
"description": "Lovelace boilerplate-card",
"keywords": [
"home-assistant",
"homeassistant",
"hass",
"automation",
"lovelace",
"custom-cards"
],
"module": "boilerplate-card.js",
"repository": "[email protected]:custom_cards/boilerplate-card.git",
"author": "Ian Richardson <[email protected]>",
"license": "MIT",
"dependencies": {
"custom-card-helpers": "^1.3.9",
"home-assistant-js-websocket": "^4.4.0",
"lit-element": "^2.2.1",
"lit-html": "^1.1.2"
},
"devDependencies": {
"@babel/core": "^7.6.4",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/plugin-proposal-decorators": "^7.4.0",
"@typescript-eslint/eslint-plugin": "^2.6.0",
"@typescript-eslint/parser": "^2.6.0",
"eslint": "^6.6.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-config-prettier": "^6.5.0",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-prettier": "^3.1.1",
"prettier": "^1.18.2",
"rollup": "^1.26.0",
"rollup-plugin-babel": "^4.3.3",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-terser": "^5.1.2",
"rollup-plugin-typescript2": "^0.24.3",
"rollup-plugin-uglify": "^6.0.3",
"typescript": "^3.6.4"
},
"scripts": {
"start": "rollup -c --watch",
"build": "npm run lint && npm run rollup",
"lint": "eslint src/*.ts",
"rollup": "rollup -c"
}
}
97 changes: 39 additions & 58 deletions src/action-handler-directive.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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;
Expand All @@ -26,53 +24,45 @@ 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,
() => {
clearTimeout(this.timer);
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();
Expand All @@ -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;
}
Expand All @@ -111,51 +101,47 @@ 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.
// If it's not a bug that is fixed, this might need updating with the next iOS version.
// 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`,
Expand All @@ -166,41 +152,36 @@ 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;
}
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);
});
Loading

0 comments on commit aba2cb8

Please sign in to comment.