diff --git a/.gitignore b/.gitignore index 3249a919..9f1fb2db 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ dist/.DS_Store +.DS_Store diff --git a/dist/weather-card-editor.js b/dist/weather-card-editor.js old mode 100644 new mode 100755 index 10733239..2c21f0fb --- a/dist/weather-card-editor.js +++ b/dist/weather-card-editor.js @@ -1,216 +1,232 @@ const fireEvent = (node, type, detail, options) => { - options = options || {}; - detail = detail === null || detail === undefined ? {} : detail; - const event = new Event(type, { - bubbles: options.bubbles === undefined ? true : options.bubbles, - cancelable: Boolean(options.cancelable), - composed: options.composed === undefined ? true : options.composed, - }); - event.detail = detail; - node.dispatchEvent(event); - return event; + options = options || {}; + detail = detail === null || detail === undefined ? {} : detail; + const event = new Event(type, { + bubbles: options.bubbles === undefined ? true : options.bubbles, + cancelable: Boolean(options.cancelable), + composed: options.composed === undefined ? true : options.composed, + }); + event.detail = detail; + node.dispatchEvent(event); + return event; }; if ( - !customElements.get("ha-switch") && - customElements.get("paper-toggle-button") + !customElements.get("ha-switch") && + customElements.get("paper-toggle-button") ) { - customElements.define("ha-switch", customElements.get("paper-toggle-button")); + customElements.define("ha-switch", customElements.get("paper-toggle-button")); } -const LitElement = customElements.get("hui-masonry-view") ? Object.getPrototypeOf(customElements.get("hui-masonry-view")) : Object.getPrototypeOf(customElements.get("hui-view")); +const LitElement = customElements.get("hui-masonry-view") + ? Object.getPrototypeOf(customElements.get("hui-masonry-view")) + : Object.getPrototypeOf(customElements.get("hui-view")); const html = LitElement.prototype.html; const css = LitElement.prototype.css; const HELPERS = window.loadCardHelpers(); export class WeatherCardEditor extends LitElement { - setConfig(config) { - this._config = { ...config }; - } - - static get properties() { - return { hass: {}, _config: {} }; - } - - get _entity() { - return this._config.entity || ""; - } - - get _name() { - return this._config.name || ""; - } - - get _icons() { - return this._config.icons || ""; - } - - get _current() { - return this._config.current !== false; - } - - get _details() { - return this._config.details !== false; - } - - get _forecast() { - return this._config.forecast !== false; - } - - get _hourly_forecast() { - return this._config.hourly_forecast !== false; - } - - get _number_of_forecasts() { - return this._config.number_of_forecasts || 5; - } - - firstUpdated() { - HELPERS.then(help => { - if (help.importMoreInfoControl) { - help.importMoreInfoControl("fan"); - } - }) - } - - render() { - if (!this.hass) { - return html``; - } - - const entities = Object.keys(this.hass.states).filter( - (eid) => eid.substr(0, eid.indexOf(".")) === "weather" - ); - - return html` -
-
- - - ${customElements.get("ha-entity-picker") - ? html` - - ` - : html` - - - ${entities.map((entity) => { - return html` ${entity} `; - })} - - - `} -
-
- Show current -
-
- Show details -
-
- Show forecast -
-
- Show hourly forecast -
-
- -
-
- `; - } - - _valueChanged(ev) { - if (!this._config || !this.hass) { - return; - } - const target = ev.target; - if (this[`_${target.configValue}`] === target.value) { - return; - } - if (target.configValue) { - if (target.value === "") { - delete this._config[target.configValue]; - } else { - this._config = { - ...this._config, - [target.configValue]: - target.checked !== undefined ? target.checked : target.value, - }; - } - } - fireEvent(this, "config-changed", { config: this._config }); - } - - static get styles() { - return css` - .switches { - margin: 8px 0; - display: flex; - justify-content: space-between; - } - .switch { - display: flex; - align-items: center; - justify-items: center; - } - .switches span { - padding: 0 16px; - } - `; - } + setConfig(config) { + this._config = { ...config }; + } + + static get properties() { + return { hass: {}, _config: {} }; + } + + get _entity() { + return this._config.entity || ""; + } + + get _name() { + return this._config.name || ""; + } + + get _icons() { + return this._config.icons || ""; + } + + get _current() { + return this._config.current !== false; + } + + get _details() { + return this._config.details !== false; + } + + get _forecast() { + return this._config.forecast !== false; + } + + get _hourly_forecast() { + return this._config.hourly_forecast !== false; + } + + get _hide_unused() { + return this._config.hide_unused !== false; + } + + get _number_of_forecasts() { + return this._config.number_of_forecasts || 5; + } + + firstUpdated() { + HELPERS.then((help) => { + if (help.importMoreInfoControl) { + help.importMoreInfoControl("fan"); + } + }); + } + + render() { + if (!this.hass) { + return html``; + } + + const entities = Object.keys(this.hass.states).filter( + (eid) => eid.substr(0, eid.indexOf(".")) === "weather", + ); + + return html` +
+
+ + + ${customElements.get("ha-entity-picker") + ? html` + + ` + : html` + + + ${entities.map((entity) => { + return html` ${entity} `; + })} + + + `} +
+
+ Show current +
+
+ Show details +
+
+ Show forecast +
+
+
+
+ Show hourly forecast +
+
+ Hide unused +
+
+ +
+
+ `; + } + + _valueChanged(ev) { + if (!this._config || !this.hass) { + return; + } + const target = ev.target; + if (this[`_${target.configValue}`] === target.value) { + return; + } + if (target.configValue) { + if (target.value === "") { + delete this._config[target.configValue]; + } else { + this._config = { + ...this._config, + [target.configValue]: + target.checked !== undefined ? target.checked : target.value, + }; + } + } + fireEvent(this, "config-changed", { config: this._config }); + } + + static get styles() { + return css` + .switches { + margin: 8px 0; + display: flex; + justify-content: space-between; + } + .switch { + display: flex; + align-items: center; + justify-items: center; + } + .switches span { + padding: 0 16px; + } + `; + } } customElements.define("weather-card-editor", WeatherCardEditor); diff --git a/dist/weather-card.js b/dist/weather-card.js old mode 100644 new mode 100755 index 32939505..0fcc8205 --- a/dist/weather-card.js +++ b/dist/weather-card.js @@ -1,535 +1,541 @@ -const LitElement = customElements.get("ha-panel-lovelace") ? Object.getPrototypeOf(customElements.get("ha-panel-lovelace")) : Object.getPrototypeOf(customElements.get("hc-lovelace")); +const LitElement = customElements.get("hui-masonry-view") + ? Object.getPrototypeOf(customElements.get("hui-masonry-view")) + : Object.getPrototypeOf(customElements.get("hui-view")); const html = LitElement.prototype.html; const css = LitElement.prototype.css; const weatherIconsDay = { - clear: "day", - "clear-night": "night", - cloudy: "cloudy", - fog: "cloudy", - hail: "rainy-7", - lightning: "thunder", - "lightning-rainy": "thunder", - partlycloudy: "cloudy-day-3", - pouring: "rainy-6", - rainy: "rainy-5", - snowy: "snowy-6", - "snowy-rainy": "rainy-7", - sunny: "day", - windy: "cloudy", - "windy-variant": "cloudy-day-3", - exceptional: "!!", + clear: "day", + "clear-night": "night", + cloudy: "cloudy", + fog: "cloudy", + hail: "rainy-7", + lightning: "thunder", + "lightning-rainy": "thunder", + partlycloudy: "cloudy-day-3", + pouring: "rainy-6", + rainy: "rainy-5", + snowy: "snowy-6", + "snowy-rainy": "rainy-7", + sunny: "day", + windy: "cloudy", + "windy-variant": "cloudy-day-3", + exceptional: "!!", }; const weatherIconsNight = { - ...weatherIconsDay, - clear: "night", - sunny: "night", - partlycloudy: "cloudy-night-3", - "windy-variant": "cloudy-night-3", + ...weatherIconsDay, + clear: "night", + sunny: "night", + partlycloudy: "cloudy-night-3", + "windy-variant": "cloudy-night-3", }; const windDirections = [ - "N", - "NNE", - "NE", - "ENE", - "E", - "ESE", - "SE", - "SSE", - "S", - "SSW", - "SW", - "WSW", - "W", - "WNW", - "NW", - "NNW", - "N", + "N", + "NNE", + "NE", + "ENE", + "E", + "ESE", + "SE", + "SSE", + "S", + "SSW", + "SW", + "WSW", + "W", + "WNW", + "NW", + "NNW", + "N", ]; window.customCards = window.customCards || []; window.customCards.push({ - type: "weather-card", - name: "Weather Card", - description: "A custom weather card with animated icons.", - preview: true, - documentationURL: "https://github.com/bramkragten/weather-card", + type: "weather-card", + name: "Weather Card", + description: "A custom weather card with animated icons.", + preview: true, + documentationURL: "https://github.com/bramkragten/weather-card", }); const fireEvent = (node, type, detail, options) => { - options = options || {}; - detail = detail === null || detail === undefined ? {} : detail; - const event = new Event(type, { - bubbles: options.bubbles === undefined ? true : options.bubbles, - cancelable: Boolean(options.cancelable), - composed: options.composed === undefined ? true : options.composed, - }); - event.detail = detail; - node.dispatchEvent(event); - return event; + options = options || {}; + detail = detail === null || detail === undefined ? {} : detail; + const event = new Event(type, { + bubbles: options.bubbles === undefined ? true : options.bubbles, + cancelable: Boolean(options.cancelable), + composed: options.composed === undefined ? true : options.composed, + }); + event.detail = detail; + node.dispatchEvent(event); + return event; }; function hasConfigOrEntityChanged(element, changedProps) { - if (changedProps.has("_config")) { - return true; - } - - const oldHass = changedProps.get("hass"); - if (oldHass) { - return ( - oldHass.states[element._config.entity] !== - element.hass.states[element._config.entity] || - oldHass.states["sun.sun"] !== element.hass.states["sun.sun"] - ); - } - - return true; + if (changedProps.has("_config")) { + return true; + } + + const oldHass = changedProps.get("hass"); + if (oldHass) { + return ( + oldHass.states[element._config.entity] !== + element.hass.states[element._config.entity] || + oldHass.states["sun.sun"] !== element.hass.states["sun.sun"] + ); + } + + return true; } class WeatherCard extends LitElement { - static get properties() { - return { - _config: {}, - hass: {}, - }; - } - - static async getConfigElement() { - await import("./weather-card-editor.js"); - return document.createElement("weather-card-editor"); - } - - static getStubConfig(hass, unusedEntities, allEntities) { - let entity = unusedEntities.find((eid) => eid.split(".")[0] === "weather"); - if (!entity) { - entity = allEntities.find((eid) => eid.split(".")[0] === "weather"); - } - return { entity }; - } - - setConfig(config) { - if (!config.entity) { - throw new Error("Please define a weather entity"); - } - this._config = config; - } - - shouldUpdate(changedProps) { - return hasConfigOrEntityChanged(this, changedProps); - } - - render() { - if (!this._config || !this.hass) { - return html``; - } - - this.numberElements = 0; - - const lang = this.hass.selectedLanguage || this.hass.language; - const stateObj = this.hass.states[this._config.entity]; - - if (!stateObj) { - return html` - - -
- Entity not available: ${this._config.entity} -
-
- `; - } - - return html` - - ${this._config.current !== false ? this.renderCurrent(stateObj) : ""} - ${this._config.details !== false ? this.renderDetails(stateObj, lang) : ""} - ${this._config.forecast !== false - ? this.renderForecast(stateObj.attributes.forecast, lang) - : ""} - - `; - } - - renderCurrent(stateObj) { - this.numberElements++; - - return html` -
- ${stateObj.state} - - ${this._config.name - ? html` ${this._config.name} ` - : ""} - ${this.getUnit("temperature") == "°F" - ? Math.round(stateObj.attributes.temperature) - : stateObj.attributes.temperature} - ${this.getUnit("temperature")} -
- `; - } - - renderDetails(stateObj, lang) { - const sun = this.hass.states["sun.sun"]; - let next_rising; - let next_setting; - - if (sun) { - next_rising = new Date(sun.attributes.next_rising).toLocaleTimeString(lang, { - hour: "2-digit", - minute: "2-digit", - }); - next_setting = new Date(sun.attributes.next_setting).toLocaleTimeString(lang, { - hour: "2-digit", - minute: "2-digit", - }); - } - - this.numberElements++; - - return html` - - `; - } - - renderForecast(forecast, lang) { - if (!forecast || forecast.length === 0) { - return html``; - } - - this.numberElements++; - return html` -
- ${forecast - .slice( - 0, - this._config.number_of_forecasts - ? this._config.number_of_forecasts - : 5 - ) - .map( - (daily) => html` -
-
- ${this._config.hourly_forecast - ? new Date(daily.datetime).toLocaleTimeString(lang, { - hour: "2-digit", - minute: "2-digit", - }) - : new Date(daily.datetime).toLocaleDateString(lang, { - weekday: "short", - })} -
- -
- ${daily.temperature}${this.getUnit("temperature")} -
- ${daily.templow !== undefined - ? html` -
- ${daily.templow}${this.getUnit("temperature")} -
- ` - : ""} - ${!this._config.hide_precipitation && - daily.precipitation !== undefined && - daily.precipitation !== null - ? html` -
- ${Math.round(daily.precipitation*10)/10} ${this.getUnit("precipitation")} -
- ` - : ""} - ${!this._config.hide_precipitation && - daily.precipitation_probability !== undefined && - daily.precipitation_probability !== null - ? html` -
- ${Math.round(daily.precipitation_probability)} ${this.getUnit("precipitation_probability")} -
- ` - : ""} -
- ` - )} -
- `; - } - - getWeatherIcon(condition, sun) { - return `${ - this._config.icons - ? this._config.icons - : "https://cdn.jsdelivr.net/gh/bramkragten/weather-card/dist/icons/" - }${ - sun && sun.state == "below_horizon" - ? weatherIconsNight[condition] - : weatherIconsDay[condition] - }.svg`; - } - - getUnit(measure) { - const lengthUnit = this.hass.config.unit_system.length; - switch (measure) { - case "air_pressure": - return lengthUnit === "km" ? "hPa" : "inHg"; - case "length": - return lengthUnit; - case "precipitation": - return lengthUnit === "km" ? "mm" : "in"; - case "precipitation_probability": - return "%"; - default: - return this.hass.config.unit_system[measure] || ""; - } - } - - _handleClick() { - fireEvent(this, "hass-more-info", { entityId: this._config.entity }); - } - - getCardSize() { - return 3; - } - - static get styles() { - return css` - ha-card { - cursor: pointer; - margin: auto; - overflow: hidden; - padding-top: 1.3em; - padding-bottom: 1.3em; - padding-left: 1em; - padding-right: 1em; - position: relative; - } - - .spacer { - padding-top: 1em; - } - - .clear { - clear: both; - } - - .title { - position: absolute; - left: 3em; - font-weight: 300; - font-size: 3em; - color: var(--primary-text-color); - } - - .temp { - font-weight: 300; - font-size: 4em; - color: var(--primary-text-color); - position: absolute; - right: 1em; - } - - .tempc { - font-weight: 300; - font-size: 1.5em; - vertical-align: super; - color: var(--primary-text-color); - position: absolute; - right: 1em; - margin-top: -14px; - margin-right: 7px; - } - - @media (max-width: 460px) { - .title { - font-size: 2.2em; - left: 4em; - } - .temp { - font-size: 3em; - } - .tempc { - font-size: 1em; - } - } - - .current { - padding: 1.2em 0; - margin-bottom: 3.5em; - } - - .variations { - display: flex; - flex-flow: row wrap; - justify-content: space-between; - font-weight: 300; - color: var(--primary-text-color); - list-style: none; - padding: 0 1em; - margin: 0; - } - - .variations ha-icon { - height: 22px; - margin-right: 5px; - color: var(--paper-item-icon-color); - } - - .variations li { - flex-basis: auto; - width: 50%; - } - - .variations li:nth-child(2n) { - text-align: right; - } - - .variations li:nth-child(2n) ha-icon { - margin-right: 0; - margin-left: 8px; - float: right; - } - - .unit { - font-size: 0.8em; - } - - .forecast { - width: 100%; - margin: 0 auto; - display: flex; - } - - .day { - flex: 1; - display: block; - text-align: center; - color: var(--primary-text-color); - border-right: 0.1em solid #d9d9d9; - line-height: 2; - box-sizing: border-box; - } - - .dayname { - text-transform: uppercase; - } - - .forecast .day:first-child { - margin-left: 0; - } - - .forecast .day:nth-last-child(1) { - border-right: none; - margin-right: 0; - } - - .highTemp { - font-weight: bold; - } - - .lowTemp { - color: var(--secondary-text-color); - } - - .precipitation { - color: var(--primary-text-color); - font-weight: 300; - } - - .icon.bigger { - width: 10em; - height: 10em; - margin-top: -4em; - position: absolute; - left: 0em; - } - - .icon { - width: 50px; - height: 50px; - margin-right: 5px; - display: inline-block; - vertical-align: middle; - background-size: contain; - background-position: center center; - background-repeat: no-repeat; - text-indent: -9999px; - } - - .weather { - font-weight: 300; - font-size: 1.5em; - color: var(--primary-text-color); - text-align: left; - position: absolute; - top: -0.5em; - left: 6em; - word-wrap: break-word; - width: 30%; - } - `; - } + static get properties() { + return { + _config: {}, + hass: {}, + }; + } + + static async getConfigElement() { + await import("./weather-card-editor.js"); + return document.createElement("weather-card-editor"); + } + + static getStubConfig(hass, unusedEntities, allEntities) { + let entity = unusedEntities.find((eid) => eid.split(".")[0] === "weather"); + if (!entity) { + entity = allEntities.find((eid) => eid.split(".")[0] === "weather"); + } + return { entity }; + } + + setConfig(config) { + if (!config.entity) { + throw new Error("Please define a weather entity"); + } + this._config = config; + } + + shouldUpdate(changedProps) { + return hasConfigOrEntityChanged(this, changedProps); + } + + render() { + if (!this._config || !this.hass) { + return html``; + } + + this.numberElements = 0; + + const stateObj = this.hass.states[this._config.entity]; + + if (!stateObj) { + return html` + + +
+ Entity not available: ${this._config.entity} +
+
+ `; + } + + return html` + + ${this._config.current !== false ? this.renderCurrent(stateObj) : ""} + ${this._config.details !== false ? this.renderDetails(stateObj) : ""} + ${this._config.forecast !== false + ? this.renderForecast(stateObj.attributes.forecast) + : ""} + + `; + } + + renderCurrent(stateObj) { + this.numberElements++; + + return html` +
+ ${stateObj.state} + + ${this._config.name + ? html` ${this._config.name} ` + : ""} + ${this.getUnit("temperature") == "°F" + ? Math.round(stateObj.attributes.temperature) + : stateObj.attributes.temperature} + ${this.getUnit("temperature")} +
+ `; + } + + renderDetails(stateObj) { + const sun = this.hass.states["sun.sun"]; + let next_rising; + let next_setting; + + if (sun) { + next_rising = new Date(sun.attributes.next_rising); + next_setting = new Date(sun.attributes.next_setting); + } + + this.numberElements++; + + const details = [ + { + value: `${stateObj.attributes.humidity}`, + icon: "mdi:water-percent", + unit: "%", + }, + { + value: `${ + windDirections[ + parseInt((stateObj.attributes.wind_bearing + 11.25) / 22.5) + ] ?? "" + } ${stateObj.attributes.wind_speed}`, + icon: "mdi:weather-windy", + unit: `${this.getUnit("length")}/h`, + }, + { + value: `${stateObj.attributes.pressure ?? ""}`, + icon: "mdi:gauge", + unit: this.getUnit("air_pressure"), + }, + { + value: `${stateObj.attributes.visibility ?? ""}`, + icon: "mdi:weather-fog", + unit: this.getUnit("length"), + }, + { + value: next_rising?.toLocaleTimeString() ?? "", + icon: "mdi:weather-sunset-up", + unit: "", + }, + { + value: next_setting?.toLocaleTimeString() ?? "", + icon: "mdi:weather-sunset-down", + unit: "", + }, + ]; + + return html` + + `; + } + + renderForecast(forecast) { + if (!forecast || forecast.length === 0) { + return html``; + } + + const lang = this.hass.selectedLanguage || this.hass.language; + + this.numberElements++; + return html` +
+ ${forecast + .slice( + 0, + this._config.number_of_forecasts + ? this._config.number_of_forecasts + : 5, + ) + .map( + (daily) => html` +
+
+ ${this._config.hourly_forecast + ? new Date(daily.datetime).toLocaleTimeString(lang, { + hour: "2-digit", + minute: "2-digit", + }) + : new Date(daily.datetime).toLocaleDateString(lang, { + weekday: "short", + })} +
+ +
+ ${daily.temperature}${this.getUnit("temperature")} +
+ ${daily.templow !== undefined + ? html` +
+ ${daily.templow}${this.getUnit("temperature")} +
+ ` + : ""} + ${!this._config.hide_precipitation && + daily.precipitation !== undefined && + daily.precipitation !== null + ? html` +
+ ${Math.round(daily.precipitation * 10) / 10} + ${this.getUnit("precipitation")} +
+ ` + : ""} + ${!this._config.hide_precipitation && + daily.precipitation_probability !== undefined && + daily.precipitation_probability !== null + ? html` +
+ ${Math.round(daily.precipitation_probability)} + ${this.getUnit("precipitation_probability")} +
+ ` + : ""} +
+ `, + )} +
+ `; + } + + getWeatherIcon(condition, sun) { + return `${ + this._config.icons + ? this._config.icons + : "https://cdn.jsdelivr.net/gh/bramkragten/weather-card/dist/icons/" + }${ + sun && sun.state == "below_horizon" + ? weatherIconsNight[condition] + : weatherIconsDay[condition] + }.svg`; + } + + getUnit(measure) { + const lengthUnit = this.hass.config.unit_system.length; + switch (measure) { + case "air_pressure": + return lengthUnit === "km" ? "hPa" : "inHg"; + case "length": + return lengthUnit; + case "precipitation": + return lengthUnit === "km" ? "mm" : "in"; + case "precipitation_probability": + return "%"; + default: + return this.hass.config.unit_system[measure] || ""; + } + } + + _handleClick() { + fireEvent(this, "hass-more-info", { entityId: this._config.entity }); + } + + getCardSize() { + return 3; + } + + static get styles() { + return css` + ha-card { + cursor: pointer; + margin: auto; + overflow: hidden; + padding-top: 1.3em; + padding-bottom: 1.3em; + padding-left: 1em; + padding-right: 1em; + position: relative; + } + + .spacer { + padding-top: 1em; + } + + .clear { + clear: both; + } + + .title { + position: absolute; + left: 3em; + font-weight: 300; + font-size: 3em; + color: var(--primary-text-color); + } + + .temp { + font-weight: 300; + font-size: 4em; + color: var(--primary-text-color); + position: absolute; + right: 1em; + } + + .tempc { + font-weight: 300; + font-size: 1.5em; + vertical-align: super; + color: var(--primary-text-color); + position: absolute; + right: 1em; + margin-top: -14px; + margin-right: 7px; + } + + @media (max-width: 460px) { + .title { + font-size: 2.2em; + left: 4em; + } + .temp { + font-size: 3em; + } + .tempc { + font-size: 1em; + } + } + + .current { + padding: 1.2em 0; + margin-bottom: 3.5em; + } + + .variations { + display: flex; + flex-flow: row wrap; + justify-content: space-between; + font-weight: 300; + color: var(--primary-text-color); + list-style: none; + padding: 0 1em; + margin: 0; + } + + .variations ha-icon { + height: 22px; + margin-right: 5px; + color: var(--paper-item-icon-color); + } + + .variations li { + flex-basis: auto; + width: 50%; + } + + .variations li:nth-child(2n) { + text-align: right; + } + + .variations li:nth-child(2n) ha-icon { + margin-right: 0; + margin-left: 8px; + float: right; + } + + .unit { + font-size: 0.8em; + } + + .forecast { + width: 100%; + margin: 0 auto; + display: flex; + } + + .day { + flex: 1; + display: block; + text-align: center; + color: var(--primary-text-color); + border-right: 0.1em solid #d9d9d9; + line-height: 2; + box-sizing: border-box; + } + + .dayname { + text-transform: uppercase; + } + + .forecast .day:first-child { + margin-left: 0; + } + + .forecast .day:nth-last-child(1) { + border-right: none; + margin-right: 0; + } + + .highTemp { + font-weight: bold; + } + + .lowTemp { + color: var(--secondary-text-color); + } + + .precipitation { + color: var(--primary-text-color); + font-weight: 300; + } + + .icon.bigger { + width: 10em; + height: 10em; + margin-top: -4em; + position: absolute; + left: 0em; + } + + .icon { + width: 50px; + height: 50px; + margin-right: 5px; + display: inline-block; + vertical-align: middle; + background-size: contain; + background-position: center center; + background-repeat: no-repeat; + text-indent: -9999px; + } + + .weather { + font-weight: 300; + font-size: 1.5em; + color: var(--primary-text-color); + text-align: left; + position: absolute; + top: -0.5em; + left: 6em; + word-wrap: break-word; + width: 30%; + } + `; + } } customElements.define("weather-card", WeatherCard);