diff --git a/src/common/entity/cover_icon.ts b/src/common/entity/cover_icon.ts
index 7c9bc5ed53..011f8e7294 100644
--- a/src/common/entity/cover_icon.ts
+++ b/src/common/entity/cover_icon.ts
@@ -78,3 +78,25 @@ export const coverIcon = (state?: string, stateObj?: HassEntity): string => {
return "hass:window-open";
}
};
+
+export const computeOpenIcon = (stateObj: HassEntity): string => {
+ switch (stateObj.attributes.device_class) {
+ case "awning":
+ case "door":
+ case "gate":
+ return "hass:arrow-expand-horizontal";
+ default:
+ return "hass:arrow-up";
+ }
+};
+
+export const computeCloseIcon = (stateObj: HassEntity): string => {
+ switch (stateObj.attributes.device_class) {
+ case "awning":
+ case "door":
+ case "gate":
+ return "hass:arrow-collapse-horizontal";
+ default:
+ return "hass:arrow-down";
+ }
+};
diff --git a/src/components/ha-cover-controls.js b/src/components/ha-cover-controls.js
deleted file mode 100644
index 3c9288399d..0000000000
--- a/src/components/ha-cover-controls.js
+++ /dev/null
@@ -1,126 +0,0 @@
-import "./ha-icon-button";
-import { html } from "@polymer/polymer/lib/utils/html-tag";
-/* eslint-plugin-disable lit */
-import { PolymerElement } from "@polymer/polymer/polymer-element";
-import { UNAVAILABLE } from "../data/entity";
-import CoverEntity from "../util/cover-model";
-
-class HaCoverControls extends PolymerElement {
- static get template() {
- return html`
-
-
-
-
-
-
-
- `;
- }
-
- static get properties() {
- return {
- hass: {
- type: Object,
- },
- stateObj: {
- type: Object,
- },
- entityObj: {
- type: Object,
- computed: "computeEntityObj(hass, stateObj)",
- },
- };
- }
-
- computeEntityObj(hass, stateObj) {
- return new CoverEntity(hass, stateObj);
- }
-
- computeOpenIcon(stateObj) {
- switch (stateObj.attributes.device_class) {
- case "awning":
- case "door":
- case "gate":
- return "hass:arrow-expand-horizontal";
- default:
- return "hass:arrow-up";
- }
- }
-
- computeCloseIcon(stateObj) {
- switch (stateObj.attributes.device_class) {
- case "awning":
- case "door":
- case "gate":
- return "hass:arrow-collapse-horizontal";
- default:
- return "hass:arrow-down";
- }
- }
-
- computeStopDisabled(stateObj) {
- if (stateObj.state === UNAVAILABLE) {
- return true;
- }
- return false;
- }
-
- computeOpenDisabled(stateObj, entityObj) {
- if (stateObj.state === UNAVAILABLE) {
- return true;
- }
- const assumedState = stateObj.attributes.assumed_state === true;
- return (entityObj.isFullyOpen || entityObj.isOpening) && !assumedState;
- }
-
- computeClosedDisabled(stateObj, entityObj) {
- if (stateObj.state === UNAVAILABLE) {
- return true;
- }
- const assumedState = stateObj.attributes.assumed_state === true;
- return (entityObj.isFullyClosed || entityObj.isClosing) && !assumedState;
- }
-
- onOpenTap(ev) {
- ev.stopPropagation();
- this.entityObj.openCover();
- }
-
- onCloseTap(ev) {
- ev.stopPropagation();
- this.entityObj.closeCover();
- }
-
- onStopTap(ev) {
- ev.stopPropagation();
- this.entityObj.stopCover();
- }
-}
-
-customElements.define("ha-cover-controls", HaCoverControls);
diff --git a/src/components/ha-cover-controls.ts b/src/components/ha-cover-controls.ts
new file mode 100644
index 0000000000..06def92e23
--- /dev/null
+++ b/src/components/ha-cover-controls.ts
@@ -0,0 +1,135 @@
+import {
+ css,
+ CSSResult,
+ customElement,
+ html,
+ internalProperty,
+ LitElement,
+ property,
+ PropertyValues,
+ TemplateResult,
+} from "lit-element";
+import { classMap } from "lit-html/directives/class-map";
+import type { HassEntity } from "home-assistant-js-websocket";
+
+import type { HomeAssistant } from "../types";
+import { UNAVAILABLE } from "../data/entity";
+import CoverEntity from "../util/cover-model";
+
+import "./ha-icon-button";
+import { computeCloseIcon, computeOpenIcon } from "../common/entity/cover_icon";
+
+@customElement("ha-cover-controls")
+class HaCoverControls extends LitElement {
+ @property({ attribute: false }) public hass!: HomeAssistant;
+
+ @property({ attribute: false }) public stateObj!: HassEntity;
+
+ @internalProperty() private _entityObj?: CoverEntity;
+
+ protected updated(changedProperties: PropertyValues): void {
+ super.updated(changedProperties);
+
+ if (changedProperties.has("stateObj")) {
+ this._entityObj = new CoverEntity(this.hass, this.stateObj);
+ }
+ }
+
+ protected render(): TemplateResult {
+ if (!this._entityObj) {
+ return html``;
+ }
+
+ return html`
+
+
+
+
+
+ `;
+ }
+
+ private _computeOpenDisabled(): boolean {
+ if (this.stateObj.state === UNAVAILABLE) {
+ return true;
+ }
+ const assumedState = this.stateObj.attributes.assumed_state === true;
+ return (
+ (this._entityObj.isFullyOpen || this._entityObj.isOpening) &&
+ !assumedState
+ );
+ }
+
+ private _computeClosedDisabled(): boolean {
+ if (this.stateObj.state === UNAVAILABLE) {
+ return true;
+ }
+ const assumedState = this.stateObj.attributes.assumed_state === true;
+ return (
+ (this._entityObj.isFullyClosed || this._entityObj.isClosing) &&
+ !assumedState
+ );
+ }
+
+ private _onOpenTap(ev): void {
+ ev.stopPropagation();
+ this._entityObj.openCover();
+ }
+
+ private _onCloseTap(ev): void {
+ ev.stopPropagation();
+ this._entityObj.closeCover();
+ }
+
+ private _onStopTap(ev): void {
+ ev.stopPropagation();
+ this._entityObj.stopCover();
+ }
+
+ static get styles(): CSSResult {
+ return css`
+ .state {
+ white-space: nowrap;
+ }
+ .hidden {
+ visibility: hidden !important;
+ }
+ `;
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ "ha-cover-controls": HaCoverControls;
+ }
+}
diff --git a/src/translations/en.json b/src/translations/en.json
index 10ad5be097..c31db303c6 100755
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -585,6 +585,9 @@
"create_zone": "Create zone from current location"
},
"cover": {
+ "open_cover": "Open cover",
+ "stop_cover": "Stop the cover from moving",
+ "close_cover": "Close cover",
"open_tilt_cover": "Open cover tilt",
"close_tile_cover": "Close cover tilt",
"stop_cover": "Stop cover from moving"