From 74b8970c8dd93e995aaf7557f8c1a7d8c53cb9f7 Mon Sep 17 00:00:00 2001 From: Karl Herrick Date: Thu, 8 Nov 2018 21:52:41 -0500 Subject: [PATCH] extract x-forecast-item component --- package-lock.json | 113 ++++++++++++++---------------- package.json | 2 +- src/components/x-forecast-item.js | 77 ++++++++++++++++++++ src/components/x-forecast.js | 87 +++++++---------------- src/main.js | 4 +- 5 files changed, 158 insertions(+), 125 deletions(-) create mode 100644 src/components/x-forecast-item.js diff --git a/package-lock.json b/package-lock.json index 38eef02..bef4ee3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "x-weather", - "version": "0.1.1", + "version": "1.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -103,9 +103,9 @@ "dev": true }, "@types/node": { - "version": "10.12.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.2.tgz", - "integrity": "sha512-53ElVDSnZeFUUFIYzI8WLQ25IhWzb6vbddNp8UHlXQyU0ET2RhV5zg0NfubzU7iNMh5bBXb0htCzfvrSVNgzaQ==", + "version": "10.12.5", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.5.tgz", + "integrity": "sha512-GzdHjq3t3eGLMv92Al90Iq+EoLL+86mPfQhuglbBFO7HiLdC/rkt+zrzJJumAiBF6nsrBWhou22rPW663AAyFw==", "dev": true }, "@webcomponents/webcomponentsjs": { @@ -193,7 +193,7 @@ }, "ansi-escapes": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", "dev": true }, @@ -293,12 +293,6 @@ "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", "dev": true }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -1261,9 +1255,9 @@ "dev": true }, "bluebird": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", - "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", "dev": true }, "body-parser": { @@ -1948,9 +1942,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30000904", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000904.tgz", - "integrity": "sha512-M4sXvogCoY5Fp6fuXIaQG/MIexlEFQ3Lgwban+KlqiQUbUIkSmjAB8ZJIP79aj2cdqz2F1Lb+Z+5GwHvCrbLtg==", + "version": "1.0.30000907", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000907.tgz", + "integrity": "sha512-No5sQ/OB2Nmka8MNOOM6nJx+Hxt6MQ6h7t7kgJFu9oTuwjykyKRSBP/+i/QAyFHxeHB+ddE0Da1CG5ihx9oehQ==", "dev": true }, "chalk": { @@ -2392,18 +2386,25 @@ } }, "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", "dev": true, "requires": { - "globby": "^5.0.0", + "globby": "^6.1.0", "is-path-cwd": "^1.0.0", "is-path-in-cwd": "^1.0.0", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", "rimraf": "^2.2.8" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } } }, "depd": { @@ -2477,9 +2478,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.83", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.83.tgz", - "integrity": "sha512-DqJoDarxq50dcHsOOlMLNoy+qQitlMNbYb6wwbE0oUw2veHdRkpNrhmngiUYKMErdJ8SJ48rpJsZTQgy5SoEAA==", + "version": "1.3.84", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.84.tgz", + "integrity": "sha512-IYhbzJYOopiTaNWMBp7RjbecUBsbnbDneOP86f3qvS0G0xfzwNSvMJpTrvi5/Y1gU7tg2NAgeg8a8rCYvW9Whw==", "dev": true }, "encodeurl": { @@ -2514,7 +2515,7 @@ }, "engine.io-client": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "resolved": "http://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", "dev": true, "requires": { @@ -3002,13 +3003,13 @@ } }, "flat-cache": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", - "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.2.tgz", + "integrity": "sha512-KByBY8c98sLUAGpnmjEdWTrtrLZRtZdwds+kAL/ciFXTCb7AZgqKsAnVnYFQj1hxepwO8JKN/8AsRWwLq+RK0A==", "dev": true, "requires": { "circular-json": "^0.3.1", - "del": "^2.0.2", + "del": "^3.0.0", "graceful-fs": "^4.1.2", "write": "^0.2.1" } @@ -3684,19 +3685,6 @@ "universalify": "^0.1.0" } }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "^1.0.1", - "glob": "^7.0.3", - "object-assign": "^4.0.1", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" - } - }, "graceful-fs": { "version": "4.1.11", "resolved": "http://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", @@ -3771,13 +3759,12 @@ "dev": true }, "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", "dev": true, "requires": { "array-union": "^1.0.1", - "arrify": "^1.0.0", "glob": "^7.0.3", "object-assign": "^4.0.1", "pify": "^2.0.0", @@ -3785,9 +3772,9 @@ } }, "graceful-fs": { - "version": "4.1.14", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.14.tgz", - "integrity": "sha512-ns/IGcSmmGNPP085JCheg0Nombh1QPvSCnlx+2V+byQWRQEIL4ZB5jXJMNIHOFVS1roi85HIi5Ka0h43iWXfcQ==", + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", "dev": true }, "has-ansi": { @@ -3927,7 +3914,7 @@ }, "humanize-url": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", "integrity": "sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8=", "dev": true, "requires": { @@ -4485,7 +4472,7 @@ }, "jsesc": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true }, @@ -5142,7 +5129,7 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, @@ -5159,7 +5146,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, @@ -5204,6 +5191,12 @@ "p-limit": "^1.1.0" } }, + "p-map": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", + "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "dev": true + }, "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", @@ -5280,7 +5273,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -5945,7 +5938,7 @@ "dependencies": { "jsesc": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true } @@ -5998,7 +5991,7 @@ }, "require-uncached": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "resolved": "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { @@ -6696,7 +6689,7 @@ }, "socket.io-parser": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "resolved": "http://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", "dev": true, "requires": { diff --git a/package.json b/package.json index 755cd7c..e027e38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "x-weather", - "version": "0.1.1", + "version": "1.0.0", "description": "A collection of web components implementing portions of the OpenWeatherMap API.", "files": [ "lib", diff --git a/src/components/x-forecast-item.js b/src/components/x-forecast-item.js new file mode 100644 index 0000000..d4e74c9 --- /dev/null +++ b/src/components/x-forecast-item.js @@ -0,0 +1,77 @@ +import { loadComponent } from '../utilities.js' + +const template = ` + + + +` + +const XForecastItem = class extends HTMLElement { + constructor() { + super() + + const container = document.createElement('div') + container.innerHTML = template + + this.attachShadow({ mode: 'open' }).appendChild(container) + } + + attributeChangedCallback(attrName, oldVal, newVal) { + switch (attrName) { + case 'day': + this.shadowRoot.getElementById('day').textContent = newVal + break; + case 'description': + this.shadowRoot.getElementById('icon').alt = newVal + break; + case 'forecast-date': + this.shadowRoot.getElementById('forecastDate').textContent = newVal + break; + case 'icon': + this.shadowRoot.getElementById('icon').src = newVal + break; + case 'night': + this.shadowRoot.getElementById('night').textContent = newVal + break; + case 'scale': + this.shadowRoot.querySelectorAll('[data-scale]').forEach(element => { + element.textContent = newVal + }) + break; + } + } + + static get observedAttributes() { + return [ 'day', 'description', 'forecast-date', 'icon', 'night', 'scale' ] + } +} + +export const load = () => loadComponent({ + customElements: customElements, + tagName: 'x-forecast-item', + element: XForecastItem +}) + +export default XForecastItem diff --git a/src/components/x-forecast.js b/src/components/x-forecast.js index 8a737ab..499b0df 100644 --- a/src/components/x-forecast.js +++ b/src/components/x-forecast.js @@ -10,15 +10,6 @@ const template = ` div[data-x-forecast] h3 { padding-left: 0.5rem; } - - div[data-x-forecast] ul { - list-style-type: none; - padding: 0 0 1rem 1.5rem; - } - - div[data-x-forecast] ul > li { - padding: 0.5rem 0 0 0; - }
@@ -106,48 +97,6 @@ const XForecast = class extends HTMLElement { this.setAttribute('scale', scale) } - _buildDayOfWeek({ dt, today }) { - const dayOfWeek = document.createElement('u') - const timestamp = unixEpochToDate(dt) - const current = dateTime(timestamp).Y('-').m('-').d().getResults() - - if (current === today) { - dayOfWeek.textContent = 'Today:' - } else { - const weekDay = dateTime(timestamp)['date'].toLocaleString('en-US', { weekday: 'long'} ) - const ddMM = dateTime(timestamp).m('/').d().getResults() - - dayOfWeek.textContent = `${weekDay} (${ddMM}):` - } - - const dayOfWeekItem = document.createElement('li') - dayOfWeekItem.appendChild(dayOfWeek) - - return dayOfWeekItem - } - - _buildWeatherIcon({ description, icon }) { - const iconAlt = description - const iconSrc = `https://openweathermap.org/img/w/${icon}.png` - - const weatherImg = document.createElement('img') - weatherImg.setAttribute('src', iconSrc) - weatherImg.setAttribute('alt', iconAlt) - - const weatherIcon = document.createElement('li') - weatherIcon.appendChild(weatherImg) - - return weatherIcon - } - - _buildTimeOfDayForecast({ timeOfDayTemp, type }) { - const temp = this.scale === 'F' ? convertTemperature(timeOfDayTemp, 'cToF') : timeOfDayTemp - const dayListItem = document.createElement('li') - dayListItem.textContent = `${type}: ${Number.parseFloat(temp).toFixed(2)}°${this.scale}` - - return dayListItem - } - _buildDateContainer(forecast, days) { const dateContainer = document.createElement('div') dateContainer.setAttribute('data-x-forecast-date-container', '') @@ -165,25 +114,37 @@ const XForecast = class extends HTMLElement { forecast.forEach(props => { const { dt, temp, pressure, humidity, weather, speed, deg, clouds, rain } = props // eslint-disable-line no-unused-vars - const dateItem = document.createElement('ul') + const dateItem = document.createElement('x-forecast-item') + dateItem.setAttribute('day', this._convertForecast({ scale: this.scale, timeOfDayTemp: temp.day })) + dateItem.setAttribute('description', weather[0].description) + dateItem.setAttribute('forecast-date', this._getDayOfWeek({ dt, today })) + dateItem.setAttribute('icon', `https://openweathermap.org/img/w/${weather[0].icon}.png`) + dateItem.setAttribute('night', this._convertForecast({ scale: this.scale, timeOfDayTemp: temp.night })) + dateItem.setAttribute('scale', this.scale) - const dayOfWeekItem = this._buildDayOfWeek({ dt, today }) - dateItem.appendChild(dayOfWeekItem) + dateContainer.appendChild(dateItem) + }) + } - const weatherIcon = this._buildWeatherIcon(weather[0]) - dateItem.appendChild(weatherIcon) + return dateContainer + } - const dayListItem = this._buildTimeOfDayForecast({ timeOfDayTemp: temp.day, type: 'Day' }) - dateItem.appendChild(dayListItem) + _convertForecast({ scale, timeOfDayTemp }) { + return `${Number.parseFloat(scale === 'F' ? convertTemperature(timeOfDayTemp, 'cToF') : timeOfDayTemp).toFixed(2)}` + } - const nightListItem = this._buildTimeOfDayForecast({ timeOfDayTemp: temp.night, type: 'Night' }) - dateItem.appendChild(nightListItem) + _getDayOfWeek({ dt, today }) { + const timestamp = unixEpochToDate(dt) + const current = dateTime(timestamp).Y('-').m('-').d().getResults() - dateContainer.appendChild(dateItem) - }) + if (current === today) { + return 'Today:' } - return dateContainer + const weekDay = dateTime(timestamp)['date'].toLocaleString('en-US', { weekday: 'long'} ) + const ddMM = dateTime(timestamp).m('/').d().getResults() + + return `${weekDay} (${ddMM}):` } _getForecast({ appid, host, location }) { diff --git a/src/main.js b/src/main.js index 19c57da..df7c83a 100644 --- a/src/main.js +++ b/src/main.js @@ -1,13 +1,15 @@ // get components import XCurrent, { load as XCurrentLoad } from './components/x-current.js' +import XForecastItem, { load as XForecastItemLoad } from './components/x-forecast-item.js' import XForecast, { load as XForecastLoad } from './components/x-forecast.js' import XWeather, { load as XWeatherLoad } from './components/x-weather.js' XCurrentLoad() +XForecastItemLoad() XForecastLoad() XWeatherLoad() export default { - XCurrent, XForecast, XWeather + XCurrent, XForecastItem, XForecast, XWeather }