Lovelace: Allow press-and-hold on picture-elements elements. (#1745)

* Allow press-and-hold on picture-elements elements.
This commit is contained in:
Thomas Lovén 2018-10-17 22:16:17 +02:00 committed by GitHub
parent 1f642f436a
commit f146a1d80f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 139 additions and 25 deletions

View File

@ -17,6 +17,7 @@
"author": "Paulus Schoutsen <Paulus@PaulusSchoutsen.nl> (http://paulusschoutsen.nl)",
"license": "Apache-2.0",
"dependencies": {
"@material/mwc-ripple": "^0.3.1",
"@mdi/svg": "^2.7.94",
"@polymer/app-layout": "^3.0.1",
"@polymer/app-localize-behavior": "^3.0.1",

View File

@ -22,9 +22,6 @@ class HuiPictureElementsCard extends PolymerElement {
position: absolute;
transform: translate(-50%, -50%);
}
hui-image-element {
overflow-y: hidden;
}
</style>
<ha-card header="[[_config.title]]">

View File

@ -13,13 +13,13 @@ class HuiIconElement extends ElementClickMixin(PolymerElement) {
return html`
<style>
:host {
cursor: pointer;
}
cursor: pointer;
}
</style>
<ha-icon
<ha-icon
icon="[[_config.icon]]"
title$="[[computeTooltip(hass, _config)]]"
></ha-icon>
></ha-icon>
`;
}
@ -32,9 +32,7 @@ class HuiIconElement extends ElementClickMixin(PolymerElement) {
ready() {
super.ready();
this.addEventListener("click", () =>
this.handleClick(this.hass, this._config)
);
this.registerMouse(this._config);
}
setConfig(config) {

View File

@ -14,9 +14,11 @@ class HuiImageElement extends ElementClickMixin(PolymerElement) {
<style>
:host(.clickable) {
cursor: pointer;
-webkit-touch-callout: none !important;
}
hui-image {
overflow-y: hidden;
-webkit-user-select: none !important;
}
</style>
<hui-image
@ -42,9 +44,7 @@ class HuiImageElement extends ElementClickMixin(PolymerElement) {
ready() {
super.ready();
this.addEventListener("click", () =>
this.handleClick(this.hass, this._config)
);
this.registerMouse(this._config);
}
setConfig(config) {

View File

@ -13,13 +13,13 @@ class HuiStateIconElement extends ElementClickMixin(PolymerElement) {
return html`
<style>
:host {
cursor: pointer;
}
cursor: pointer;
}
</style>
<state-badge
<state-badge
state-obj="[[_stateObj]]"
title$="[[computeTooltip(hass, _config)]]"
></state-badge>
></state-badge>
`;
}
@ -36,9 +36,7 @@ class HuiStateIconElement extends ElementClickMixin(PolymerElement) {
ready() {
super.ready();
this.addEventListener("click", () =>
this.handleClick(this.hass, this._config)
);
this.registerMouse(this._config);
}
setConfig(config) {

View File

@ -45,9 +45,7 @@ class HuiStateLabelElement extends LocalizeMixin(
ready() {
super.ready();
this.addEventListener("click", () =>
this.handleClick(this.hass, this._config)
);
this.registerMouse(this._config);
}
setConfig(config) {

View File

@ -3,6 +3,7 @@ import toggleEntity from "../common/entity/toggle-entity.js";
import NavigateMixin from "../../../mixins/navigate-mixin";
import EventsMixin from "../../../mixins/events-mixin.js";
import computeStateName from "../../../common/entity/compute_state_name";
import "@material/mwc-ripple";
/*
* @polymerMixin
@ -12,8 +13,87 @@ import computeStateName from "../../../common/entity/compute_state_name";
export default dedupingMixin(
(superClass) =>
class extends NavigateMixin(EventsMixin(superClass)) {
handleClick(hass, config) {
const tapAction = config.tap_action || "more-info";
registerMouse(config) {
var isTouch =
"ontouchstart" in window ||
navigator.MaxTouchPoints > 0 ||
navigator.msMaxTouchPoints > 0;
let ripple = null;
const rippleWrapper = document.createElement("div");
this.shadowRoot.appendChild(rippleWrapper);
Object.assign(rippleWrapper.style, {
position: "absolute",
width: isTouch ? "100px" : "50px",
height: isTouch ? "100px" : "50px",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
pointerEvents: "none",
});
const loadRipple = () => {
if (ripple) return;
ripple = document.createElement("mwc-ripple");
rippleWrapper.appendChild(ripple);
ripple.unbounded = true;
ripple.primary = true;
};
const startAnimation = () => {
ripple.style.visibility = "visible";
ripple.disabled = false;
ripple.active = true;
};
const stopAnimation = () => {
if (ripple) {
ripple.active = false;
ripple.disabled = true;
ripple.style.visibility = "hidden";
}
};
var mouseDown = isTouch ? "touchstart" : "mousedown";
var mouseOut = isTouch ? "touchcancel" : "mouseout";
var click = isTouch ? "touchend" : "click";
var timer = null;
var held = false;
var holdTime = config.hold_time || 500;
this.addEventListener(mouseDown, () => {
held = false;
loadRipple();
timer = setTimeout(() => {
startAnimation();
held = true;
}, holdTime);
});
this.addEventListener(click, () => {
stopAnimation();
this.handleClick(this.hass, config, held);
});
[
mouseOut,
"mouseup",
"touchmove",
"mousewheel",
"wheel",
"scroll",
].forEach((ev) => {
document.addEventListener(ev, () => {
clearTimeout(timer);
stopAnimation();
});
});
}
handleClick(hass, config, held = false) {
let tapAction = config.tap_action || "more-info";
if (held) {
tapAction = config.hold_action || "none";
}
if (tapAction === "none") return;
switch (tapAction) {

View File

@ -1266,6 +1266,48 @@
dependencies:
base64-js "^1.3.0"
"@material/animation@^0.40.1":
version "0.40.1"
resolved "https://registry.yarnpkg.com/@material/animation/-/animation-0.40.1.tgz#c5ff31e7d7e17324a0045e889d3530b150b9fcec"
integrity sha512-HtxFUw04EHg4S6pXfTA3Z0wKxnNDNcDhe1Np2Y2geo+lAk2Hb7m8yCL/GaL9o2I/eRYsgUXC0U7+Mk74GCz3zw==
"@material/base@^0.40.1":
version "0.40.1"
resolved "https://registry.yarnpkg.com/@material/base/-/base-0.40.1.tgz#a0d8e19cee98dae0f96dbf0887a14b3f7acd2aac"
integrity sha512-vrbOK8hONVCYgURQ9h7nkXvMdYnZVVNmAfFFijF8fbWQdwnoPcNTdqV6RoQlhBEqHYHQqLNfdUDlznAPKLclGQ==
"@material/mwc-base@^0.3.1":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@material/mwc-base/-/mwc-base-0.3.1.tgz#5e1440aa09e0a83633be36eb8102ff88d3fddae8"
integrity sha512-7AdcBu6rxARcUteEBNSJKCen3hP47T/NRsfw+RMn6IedHlEGp2GKwF6YqYDCVSsQbm0IjsJ4ft4+nVXlFVYO2g==
dependencies:
"@polymer/lit-element" "^0.6.2"
lit-html "^0.12.0"
"@material/mwc-ripple@^0.3.1":
version "0.3.1"
resolved "https://registry.yarnpkg.com/@material/mwc-ripple/-/mwc-ripple-0.3.1.tgz#da812516d0bd0b15b0c4793b783fbdb9e04cd7a0"
integrity sha512-pOdBkP6NJyGz9UftvKjrx8sXvz+yIXMC8q6Qx/LgGw67tgU4qM/1Hy22iePiw1UFNhlqD8ZwtdPLXKVaisGauQ==
dependencies:
"@material/mwc-base" "^0.3.1"
"@material/ripple" "^0.40.0"
"@polymer/lit-element" "^0.6.2"
lit-html "^0.12.0"
"@material/ripple@^0.40.0":
version "0.40.1"
resolved "https://registry.yarnpkg.com/@material/ripple/-/ripple-0.40.1.tgz#57cbc689303b48282229cb9b62556af7442e852a"
integrity sha512-sndeTS4VHa0v1UGj7MNcxMCuO9LJ1DjoL1EjE6BH3Lm3M1MnXJHdsBo2CgPbU/FI84tt6+eyHGOYPdPrEDJhCA==
dependencies:
"@material/animation" "^0.40.1"
"@material/base" "^0.40.1"
"@material/theme" "^0.40.1"
"@material/theme@^0.40.1":
version "0.40.1"
resolved "https://registry.yarnpkg.com/@material/theme/-/theme-0.40.1.tgz#3cc3f1bf87ee9581df03e347a1979e53ae617221"
integrity sha512-cH1CsGIDisEQ2oroZhLTypV0Ir00x3WIwFXnPo7qv3832tuIDkZY623U3rUax6KNPz4Hh1j0tNpTwgrNZwvwWA==
"@mdi/svg@^2.7.94":
version "2.8.94"
resolved "https://registry.yarnpkg.com/@mdi/svg/-/svg-2.8.94.tgz#574da5953fb8ccd58b660d95061d43add53f5704"