mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-17 22:36:35 +00:00
Thermostat Card LoveLace (#1814)
* POC/WIP: Thermostat Card * Fix jQuery imports * Cleaning out testing code and working on reviews * Colors Dynamic + mode dynamic * Minor changes * adding html prefix * Dynamic Text size and colors - getting somwhere slowly. * Review Changes - Working version (i think) * Updating Gallery Entry * Travies Review * Remove provide plugin, move CSS to JS * Add provideHass to demo * Demo fixes * tweak margins * Travis changes * Style Tweaks * Update to client Width range
This commit is contained in:
parent
c42d9385d1
commit
741c0c08b9
@ -99,6 +99,21 @@ export class CoverEntity extends Entity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class ClimateEntity extends Entity {
|
||||||
|
async handleService(domain, service, data) {
|
||||||
|
if (domain !== this.domain) return;
|
||||||
|
|
||||||
|
if (service === "set_operation_mode") {
|
||||||
|
this.update(
|
||||||
|
data.operation_mode === "heat" ? "heat" : data.operation_mode,
|
||||||
|
Object.assign(this.attributes, {
|
||||||
|
operation_mode: data.operation_mode,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class GroupEntity extends Entity {
|
export class GroupEntity extends Entity {
|
||||||
async handleService(domain, service, data) {
|
async handleService(domain, service, data) {
|
||||||
if (!["homeassistant", this.domain].includes(domain)) return;
|
if (!["homeassistant", this.domain].includes(domain)) return;
|
||||||
@ -115,6 +130,7 @@ export class GroupEntity extends Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const TYPES = {
|
const TYPES = {
|
||||||
|
climate: ClimateEntity,
|
||||||
light: LightEntity,
|
light: LightEntity,
|
||||||
lock: LockEntity,
|
lock: LockEntity,
|
||||||
cover: CoverEntity,
|
cover: CoverEntity,
|
||||||
|
88
gallery/src/demos/demo-hui-thermostat-card.js
Normal file
88
gallery/src/demos/demo-hui-thermostat-card.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import { html } from "@polymer/polymer/lib/utils/html-tag.js";
|
||||||
|
import { PolymerElement } from "@polymer/polymer/polymer-element.js";
|
||||||
|
|
||||||
|
import getEntity from "../data/entity.js";
|
||||||
|
import provideHass from "../data/provide_hass.js";
|
||||||
|
import "../components/demo-cards.js";
|
||||||
|
|
||||||
|
const ENTITIES = [
|
||||||
|
getEntity("climate", "ecobee", "auto", {
|
||||||
|
current_temperature: 73,
|
||||||
|
min_temp: 45,
|
||||||
|
max_temp: 95,
|
||||||
|
temperature: null,
|
||||||
|
target_temp_high: 75,
|
||||||
|
target_temp_low: 70,
|
||||||
|
fan_mode: "Auto Low",
|
||||||
|
fan_list: ["On Low", "On High", "Auto Low", "Auto High", "Off"],
|
||||||
|
operation_mode: "auto",
|
||||||
|
operation_list: ["heat", "cool", "auto", "off"],
|
||||||
|
hold_mode: "home",
|
||||||
|
swing_mode: "Auto",
|
||||||
|
swing_list: ["Auto", "1", "2", "3", "Off"],
|
||||||
|
friendly_name: "Ecobee",
|
||||||
|
supported_features: 1014,
|
||||||
|
}),
|
||||||
|
getEntity("climate", "nest", "heat", {
|
||||||
|
current_temperature: 17,
|
||||||
|
min_temp: 15,
|
||||||
|
max_temp: 25,
|
||||||
|
temperature: 19,
|
||||||
|
fan_mode: "Auto Low",
|
||||||
|
fan_list: ["On Low", "On High", "Auto Low", "Auto High", "Off"],
|
||||||
|
operation_mode: "heat",
|
||||||
|
operation_list: ["heat", "cool", "auto", "off"],
|
||||||
|
hold_mode: "home",
|
||||||
|
swing_mode: "Auto",
|
||||||
|
swing_list: ["Auto", "1", "2", "3", "Off"],
|
||||||
|
friendly_name: "Nest",
|
||||||
|
supported_features: 1014,
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
const CONFIGS = [
|
||||||
|
{
|
||||||
|
heading: "Range example",
|
||||||
|
config: `
|
||||||
|
- type: thermostat
|
||||||
|
entity: climate.ecobee
|
||||||
|
- type: thermostat
|
||||||
|
entity: climate.nest
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
heading: "Single temp example",
|
||||||
|
config: `
|
||||||
|
- type: thermostat
|
||||||
|
entity: climate.nest
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
class DemoThermostatEntity extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<demo-cards
|
||||||
|
id='demos'
|
||||||
|
configs="[[_configs]]"
|
||||||
|
></demo-cards>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
_configs: {
|
||||||
|
type: Object,
|
||||||
|
value: CONFIGS,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
const hass = provideHass(this.$.demos);
|
||||||
|
hass.addEntities(ENTITIES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("demo-hui-thermostat-card", DemoThermostatEntity);
|
@ -17,6 +17,10 @@ module.exports = {
|
|||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
babelLoaderConfig({ latestBuild: true }),
|
babelLoaderConfig({ latestBuild: true }),
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: "raw-loader",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: /\.(html)$/,
|
test: /\.(html)$/,
|
||||||
use: {
|
use: {
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
"fecha": "^2.3.3",
|
"fecha": "^2.3.3",
|
||||||
"home-assistant-js-websocket": "^3.1.4",
|
"home-assistant-js-websocket": "^3.1.4",
|
||||||
"intl-messageformat": "^2.2.0",
|
"intl-messageformat": "^2.2.0",
|
||||||
|
"jquery": "^3.3.1",
|
||||||
"js-yaml": "^3.12.0",
|
"js-yaml": "^3.12.0",
|
||||||
"leaflet": "^1.3.4",
|
"leaflet": "^1.3.4",
|
||||||
"lit-html": "^0.12.0",
|
"lit-html": "^0.12.0",
|
||||||
@ -85,6 +86,7 @@
|
|||||||
"preact-compat": "^3.18.4",
|
"preact-compat": "^3.18.4",
|
||||||
"react-big-calendar": "^0.19.2",
|
"react-big-calendar": "^0.19.2",
|
||||||
"regenerator-runtime": "^0.12.1",
|
"regenerator-runtime": "^0.12.1",
|
||||||
|
"round-slider": "^1.3.2",
|
||||||
"unfetch": "^4.0.1",
|
"unfetch": "^4.0.1",
|
||||||
"web-animations-js": "^2.3.1",
|
"web-animations-js": "^2.3.1",
|
||||||
"xss": "^1.0.3"
|
"xss": "^1.0.3"
|
||||||
|
349
src/panels/lovelace/cards/hui-thermostat-card.ts
Normal file
349
src/panels/lovelace/cards/hui-thermostat-card.ts
Normal file
@ -0,0 +1,349 @@
|
|||||||
|
import { html, LitElement } from "@polymer/lit-element";
|
||||||
|
import { classMap } from "lit-html/directives/classMap.js";
|
||||||
|
import { jQuery } from "../../../resources/jquery";
|
||||||
|
|
||||||
|
import "../../../components/ha-card.js";
|
||||||
|
import "../../../components/ha-icon.js";
|
||||||
|
import { roundSliderStyle } from "../../../resources/jquery.roundslider";
|
||||||
|
|
||||||
|
import { HomeAssistant } from "../../../types.js";
|
||||||
|
import { hassLocalizeLitMixin } from "../../../mixins/lit-localize-mixin";
|
||||||
|
import { LovelaceCard, LovelaceConfig } from "../types.js";
|
||||||
|
|
||||||
|
const thermostatConfig = {
|
||||||
|
radius: 150,
|
||||||
|
step: 1,
|
||||||
|
circleShape: "pie",
|
||||||
|
startAngle: 315,
|
||||||
|
width: 5,
|
||||||
|
lineCap: "round",
|
||||||
|
handleSize: "+10",
|
||||||
|
showTooltip: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const modeIcons = {
|
||||||
|
auto: "hass:autorenew",
|
||||||
|
heat: "hass:fire",
|
||||||
|
cool: "hass:snowflake",
|
||||||
|
off: "hass:fan-off",
|
||||||
|
};
|
||||||
|
|
||||||
|
interface Config extends LovelaceConfig {
|
||||||
|
entity: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatTemp(temps) {
|
||||||
|
return temps.filter(Boolean).join("-");
|
||||||
|
}
|
||||||
|
|
||||||
|
export class HuiThermostatCard extends hassLocalizeLitMixin(LitElement)
|
||||||
|
implements LovelaceCard {
|
||||||
|
public hass?: HomeAssistant;
|
||||||
|
protected config?: Config;
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: {},
|
||||||
|
config: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCardSize() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setConfig(config: Config) {
|
||||||
|
if (!config.entity || config.entity.split(".")[0] !== "climate") {
|
||||||
|
throw new Error("Specify an entity from within the climate domain.");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
if (!this.hass || !this.config) {
|
||||||
|
return html``;
|
||||||
|
}
|
||||||
|
const stateObj = this.hass.states[this.config.entity];
|
||||||
|
const broadCard = this.clientWidth > 390;
|
||||||
|
return html`
|
||||||
|
${this.renderStyle()}
|
||||||
|
<ha-card
|
||||||
|
class="${classMap({
|
||||||
|
[stateObj.attributes.operation_mode]: true,
|
||||||
|
large: broadCard,
|
||||||
|
small: !broadCard,
|
||||||
|
})}">
|
||||||
|
<div id="root">
|
||||||
|
<div id="thermostat"></div>
|
||||||
|
<div id="tooltip">
|
||||||
|
<div class="title">Upstairs</div>
|
||||||
|
<div class="current-temperature">
|
||||||
|
<span class="current-temperature-text">${
|
||||||
|
stateObj.attributes.current_temperature
|
||||||
|
}
|
||||||
|
<span class="uom">${
|
||||||
|
this.hass.config.unit_system.temperature
|
||||||
|
}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div class="climate-info">
|
||||||
|
<div id="set-temperature"></div>
|
||||||
|
<div class="current-mode">${this.localize(
|
||||||
|
`state.climate.${stateObj.state}`
|
||||||
|
)}</div>
|
||||||
|
<div class="modes">
|
||||||
|
${stateObj.attributes.operation_list.map((modeItem) =>
|
||||||
|
this._renderIcon(modeItem, stateObj.attributes.operation_mode)
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected shouldUpdate(changedProps) {
|
||||||
|
if (changedProps.get("hass")) {
|
||||||
|
return changedProps.get("hass").states[this.config!.entity] !==
|
||||||
|
this.hass!.states[this.config!.entity]
|
||||||
|
? true
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
return changedProps;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected firstUpdated() {
|
||||||
|
const stateObj = this.hass!.states[this.config!.entity];
|
||||||
|
|
||||||
|
const _sliderType =
|
||||||
|
stateObj.attributes.target_temp_low &&
|
||||||
|
stateObj.attributes.target_temp_high
|
||||||
|
? "range"
|
||||||
|
: "min-range";
|
||||||
|
|
||||||
|
jQuery("#thermostat", this.shadowRoot).roundSlider({
|
||||||
|
...thermostatConfig,
|
||||||
|
radius: this.clientWidth / 3,
|
||||||
|
min: stateObj.attributes.min_temp,
|
||||||
|
max: stateObj.attributes.max_temp,
|
||||||
|
sliderType: _sliderType,
|
||||||
|
change: (value) => this._setTemperature(value),
|
||||||
|
drag: (value) => this._dragEvent(value),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected updated() {
|
||||||
|
const attrs = this.hass!.states[this.config!.entity].attributes;
|
||||||
|
|
||||||
|
let sliderValue;
|
||||||
|
let uiValue;
|
||||||
|
|
||||||
|
if (attrs.target_temp_low && attrs.target_temp_high) {
|
||||||
|
sliderValue = `${attrs.target_temp_low}, ${attrs.target_temp_high}`;
|
||||||
|
uiValue = formatTemp([attrs.target_temp_low, attrs.target_temp_high]);
|
||||||
|
} else {
|
||||||
|
sliderValue = uiValue = attrs.temperature;
|
||||||
|
}
|
||||||
|
|
||||||
|
jQuery("#thermostat", this.shadowRoot).roundSlider({
|
||||||
|
value: sliderValue,
|
||||||
|
});
|
||||||
|
this.shadowRoot!.querySelector("#set-temperature")!.innerHTML = uiValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private renderStyle() {
|
||||||
|
return html`
|
||||||
|
${roundSliderStyle}
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
ha-card {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#root {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.auto {
|
||||||
|
--mode-color: green;
|
||||||
|
}
|
||||||
|
.cool {
|
||||||
|
--mode-color: #2b9af9;
|
||||||
|
}
|
||||||
|
.heat {
|
||||||
|
--mode-color: #FF8100;
|
||||||
|
}
|
||||||
|
.off {
|
||||||
|
--mode-color: #8a8a8a;
|
||||||
|
}
|
||||||
|
.large {
|
||||||
|
--thermostat-padding-top: 25px;
|
||||||
|
--thermostat-margin-bottom: 25px;
|
||||||
|
--title-font-size: 28px;
|
||||||
|
--title-margin-top: 20%;
|
||||||
|
--climate-info-margin-top: 17%;
|
||||||
|
--modes-margin-top: 2%;
|
||||||
|
--set-temperature-font-size: 25px;
|
||||||
|
--current-temperature-font-size: 71px;
|
||||||
|
--current-temperature-margin-top: 10%;
|
||||||
|
--current-temperature-text-padding-left: 15px;
|
||||||
|
--uom-font-size: 20px;
|
||||||
|
--uom-margin-left: -18px;
|
||||||
|
--current-mode-font-size: 18px;
|
||||||
|
--set-temperature-padding-bottom: 5px;
|
||||||
|
}
|
||||||
|
.small {
|
||||||
|
--thermostat-padding-top: 15px;
|
||||||
|
--thermostat-margin-bottom: 15px;
|
||||||
|
--title-font-size: 18px;
|
||||||
|
--title-margin-top: 20%;
|
||||||
|
--climate-info-margin-top: 7.5%;
|
||||||
|
--modes-margin-top: 1%;
|
||||||
|
--set-temperature-font-size: 16px;
|
||||||
|
--current-temperature-font-size: 25px;
|
||||||
|
--current-temperature-margin-top: 5%;
|
||||||
|
--current-temperature-text-padding-left: 7px;
|
||||||
|
--uom-font-size: 12px;
|
||||||
|
--uom-margin-left: -5px;
|
||||||
|
--current-mode-font-size: 14px;
|
||||||
|
--set-temperature-padding-bottom: 0px;
|
||||||
|
}
|
||||||
|
#thermostat {
|
||||||
|
margin: 0 auto var(--thermostat-margin-bottom);
|
||||||
|
padding-top: var(--thermostat-padding-top);
|
||||||
|
}
|
||||||
|
#thermostat .rs-range-color {
|
||||||
|
background-color: var(--mode-color, var(--disabled-text-color));
|
||||||
|
}
|
||||||
|
#thermostat .rs-path-color {
|
||||||
|
background-color: #d6d6d6;
|
||||||
|
}
|
||||||
|
#thermostat .rs-handle {
|
||||||
|
background-color: #FFF;
|
||||||
|
padding: 7px;
|
||||||
|
border: 2px solid #d6d6d6;
|
||||||
|
}
|
||||||
|
#thermostat .rs-handle.rs-focus {
|
||||||
|
border-color: var(--mode-color, var(--disabled-text-color));
|
||||||
|
}
|
||||||
|
#thermostat .rs-handle:after {
|
||||||
|
border-color: var(--mode-color, var(--disabled-text-color));
|
||||||
|
background-color: var(--mode-color, var(--disabled-text-color));
|
||||||
|
}
|
||||||
|
#thermostat .rs-border {
|
||||||
|
border-color: transparent;
|
||||||
|
}
|
||||||
|
#thermostat .rs-bar.rs-transition.rs-first, .rs-bar.rs-transition.rs-second{
|
||||||
|
z-index: 20 !important;
|
||||||
|
}
|
||||||
|
#tooltip {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 100%;
|
||||||
|
text-align: center;
|
||||||
|
z-index: 15;
|
||||||
|
}
|
||||||
|
#set-temperature {
|
||||||
|
font-size: var(--set-temperature-font-size);
|
||||||
|
padding-bottom: var(--set-temperature-padding-bottom);
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
font-size: var(--title-font-size);
|
||||||
|
margin-top: var(--title-margin-top);
|
||||||
|
}
|
||||||
|
.climate-info {
|
||||||
|
margin-top: var(--climate-info-margin-top);
|
||||||
|
}
|
||||||
|
.current-mode {
|
||||||
|
font-size: var(--current-mode-font-size);
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
|
.modes {
|
||||||
|
margin-top: var(--modes-margin-top);
|
||||||
|
}
|
||||||
|
.modes ha-icon {
|
||||||
|
color: var(--disabled-text-color);
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
.modes ha-icon.selected-icon {
|
||||||
|
color: var(--mode-color);
|
||||||
|
}
|
||||||
|
.current-temperature {
|
||||||
|
margin-top: var(--current-temperature-margin-top);
|
||||||
|
font-size: var(--current-temperature-font-size);
|
||||||
|
}
|
||||||
|
.current-temperature-text {
|
||||||
|
padding-left: var(--current-temperature-text-padding-left);
|
||||||
|
}
|
||||||
|
.uom {
|
||||||
|
font-size: var(--uom-font-size);
|
||||||
|
vertical-align: top;
|
||||||
|
margin-left: var(--uom-margin-left);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _dragEvent(e) {
|
||||||
|
this.shadowRoot!.querySelector("#set-temperature")!.innerHTML = formatTemp(
|
||||||
|
String(e.value).split(",")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _setTemperature(e) {
|
||||||
|
const stateObj = this.hass!.states[this.config!.entity];
|
||||||
|
if (
|
||||||
|
stateObj.attributes.target_temp_low &&
|
||||||
|
stateObj.attributes.target_temp_high
|
||||||
|
) {
|
||||||
|
if (e.handle.index === 1) {
|
||||||
|
this.hass!.callService("climate", "set_temperature", {
|
||||||
|
entity_id: this.config!.entity,
|
||||||
|
target_temp_low: e.handle.value,
|
||||||
|
target_temp_high: stateObj.attributes.target_temp_high,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.hass!.callService("climate", "set_temperature", {
|
||||||
|
entity_id: this.config!.entity,
|
||||||
|
target_temp_low: stateObj.attributes.target_temp_low,
|
||||||
|
target_temp_high: e.handle.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.hass!.callService("climate", "set_temperature", {
|
||||||
|
entity_id: this.config!.entity,
|
||||||
|
temperature: e.value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private _renderIcon(mode, currentMode) {
|
||||||
|
return html`<ha-icon
|
||||||
|
class="${classMap({ "selected-icon": currentMode === mode })}"
|
||||||
|
.mode="${mode}"
|
||||||
|
.icon="${modeIcons[mode]}"
|
||||||
|
@click="${this._handleModeClick}"
|
||||||
|
></ha-icon>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _handleModeClick(e: MouseEvent) {
|
||||||
|
this.hass!.callService("climate", "set_operation_mode", {
|
||||||
|
entity_id: this.config!.entity,
|
||||||
|
operation_mode: (e.currentTarget as any).mode,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"hui-thermostat-card": HuiThermostatCard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define("hui-thermostat-card", HuiThermostatCard);
|
@ -20,6 +20,7 @@ import "../cards/hui-picture-glance-card";
|
|||||||
import "../cards/hui-plant-status-card.js";
|
import "../cards/hui-plant-status-card.js";
|
||||||
import "../cards/hui-sensor-card.js";
|
import "../cards/hui-sensor-card.js";
|
||||||
import "../cards/hui-vertical-stack-card.ts";
|
import "../cards/hui-vertical-stack-card.ts";
|
||||||
|
import "../cards/hui-thermostat-card.ts";
|
||||||
import "../cards/hui-weather-forecast-card";
|
import "../cards/hui-weather-forecast-card";
|
||||||
import "../cards/hui-gauge-card.js";
|
import "../cards/hui-gauge-card.js";
|
||||||
|
|
||||||
@ -46,6 +47,7 @@ const CARD_TYPES = new Set([
|
|||||||
"picture-glance",
|
"picture-glance",
|
||||||
"plant-status",
|
"plant-status",
|
||||||
"sensor",
|
"sensor",
|
||||||
|
"thermostat",
|
||||||
"vertical-stack",
|
"vertical-stack",
|
||||||
"weather-forecast",
|
"weather-forecast",
|
||||||
]);
|
]);
|
||||||
|
6
src/resources/jquery.roundslider.js
Normal file
6
src/resources/jquery.roundslider.js
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { html } from "@polymer/lit-element";
|
||||||
|
import "./jquery";
|
||||||
|
import "round-slider";
|
||||||
|
import roundSliderCSS from "round-slider/dist/roundslider.min.css";
|
||||||
|
|
||||||
|
export const roundSliderStyle = html`<style>${roundSliderCSS}</style>`;
|
5
src/resources/jquery.ts
Normal file
5
src/resources/jquery.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import jQuery_ from "jquery";
|
||||||
|
|
||||||
|
(window as any).jQuery = jQuery_;
|
||||||
|
|
||||||
|
export const jQuery = jQuery_;
|
@ -63,6 +63,10 @@ function createConfig(isProdBuild, latestBuild) {
|
|||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
babelLoaderConfig({ latestBuild }),
|
babelLoaderConfig({ latestBuild }),
|
||||||
|
{
|
||||||
|
test: /\.css$/,
|
||||||
|
use: "raw-loader",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: /\.(html)$/,
|
test: /\.(html)$/,
|
||||||
use: {
|
use: {
|
||||||
|
12
yarn.lock
12
yarn.lock
@ -9080,6 +9080,11 @@ joi@^11.1.1:
|
|||||||
isemail "3.x.x"
|
isemail "3.x.x"
|
||||||
topo "2.x.x"
|
topo "2.x.x"
|
||||||
|
|
||||||
|
"jquery@>= 1.4.1", jquery@^3.3.1:
|
||||||
|
version "3.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca"
|
||||||
|
integrity sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==
|
||||||
|
|
||||||
js-levenshtein@^1.1.3:
|
js-levenshtein@^1.1.3:
|
||||||
version "1.1.4"
|
version "1.1.4"
|
||||||
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.4.tgz#3a56e3cbf589ca0081eb22cd9ba0b1290a16d26e"
|
resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.4.tgz#3a56e3cbf589ca0081eb22cd9ba0b1290a16d26e"
|
||||||
@ -12838,6 +12843,13 @@ rollup@^0.58.2:
|
|||||||
"@types/estree" "0.0.38"
|
"@types/estree" "0.0.38"
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
round-slider@^1.3.2:
|
||||||
|
version "1.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/round-slider/-/round-slider-1.3.2.tgz#8fb363f4fe2ab653b8160a13aa4d493634bac050"
|
||||||
|
integrity sha512-JAUSXwuxiLv/kliHNP2GbnXID87hFqoxac38UIcvkpyYTwSzpTKlqvMKLB7xWnDOgX/9MCD7B2Ab41pk6cGiWQ==
|
||||||
|
dependencies:
|
||||||
|
jquery ">= 1.4.1"
|
||||||
|
|
||||||
run-async@^2.0.0, run-async@^2.2.0:
|
run-async@^2.0.0, run-async@^2.2.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
|
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user