From 0a92c28bac80a0bddc3f54577fc62670f3974c15 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Tue, 5 May 2020 16:40:11 +0200 Subject: [PATCH] Split up mdi icons (#4379) --- .github/workflows/ci.yaml | 2 +- build-scripts/gulp/app.js | 6 +- build-scripts/gulp/cast.js | 10 +- build-scripts/gulp/demo.js | 17 +- build-scripts/gulp/entry-html.js | 8 - build-scripts/gulp/gallery.js | 6 +- build-scripts/gulp/gather-static.js | 11 ++ build-scripts/gulp/gen-icons-json.js | 109 +++++++++++++ build-scripts/gulp/gen-icons.js | 127 --------------- build-scripts/gulp/hassio.js | 4 +- build-scripts/webpack.js | 1 - cast/src/launcher/entrypoint.ts | 2 - cast/src/launcher/layout/hc-cast.ts | 7 +- cast/src/launcher/layout/hc-connect.ts | 8 +- cast/src/receiver/second-load.ts | 2 - demo/src/configs/teachingbirds/lovelace.ts | 3 +- demo/src/entrypoint.ts | 3 - demo/src/resources/hademo-icons.js | 7 - .../demos/demo-hui-picture-elements-card.ts | 14 +- gallery/src/entrypoint.js | 2 - gallery/src/ha-gallery.js | 16 +- hassio/.gitignore | 1 - hassio/src/addon-store/hassio-addon-store.ts | 7 +- .../addon-store/hassio-repositories-editor.ts | 6 +- .../src/addon-view/hassio-addon-dashboard.ts | 2 +- .../src/addon-view/info/hassio-addon-info.ts | 20 +-- hassio/src/components/hassio-card-content.ts | 20 +-- hassio/src/components/hassio-search-input.ts | 17 +- hassio/src/dashboard/hassio-update.ts | 7 +- .../markdown/dialog-hassio-markdown.ts | 6 +- .../snapshot/dialog-hassio-snapshot.ts | 16 +- hassio/src/entrypoint.ts | 2 - hassio/src/hassio-main.ts | 8 +- .../src/ingress-view/hassio-ingress-view.ts | 2 +- hassio/src/resources/hassio-icons.js | 7 - hassio/src/snapshots/hassio-snapshots.ts | 4 +- package.json | 11 +- src/common/search/search-input.ts | 6 +- .../device/ha-area-devices-picker.ts | 14 +- src/components/device/ha-device-picker.ts | 15 +- src/components/device/ha-devices-picker.ts | 1 - src/components/entity/ha-chart-base.js | 4 +- src/components/entity/ha-entities-picker.ts | 1 - src/components/entity/ha-entity-picker.ts | 15 +- src/components/entity/ha-entity-toggle.ts | 21 ++- src/components/ha-area-picker.ts | 15 +- src/components/ha-climate-control.js | 15 +- src/components/ha-combo-box.js | 12 +- src/components/ha-cover-controls.js | 14 +- src/components/ha-cover-tilt-controls.js | 14 +- src/components/ha-dialog.ts | 6 +- .../ha-form/ha-form-multi_select.ts | 6 +- src/components/ha-form/ha-form-string.ts | 6 +- src/components/ha-icon-button-arrow-next.ts | 23 +++ src/components/ha-icon-button-arrow-prev.ts | 23 +++ src/components/ha-icon-button-next.ts | 23 +++ src/components/ha-icon-button-prev.ts | 23 +++ src/components/ha-icon-button.ts | 56 +++++++ src/components/ha-icon-next.ts | 14 +- src/components/ha-icon-prev.ts | 14 +- src/components/ha-icon.ts | 149 +++++++++++++++--- src/components/ha-iconset-svg.js | 33 ---- src/components/ha-menu-button.ts | 8 +- .../ha-paper-icon-button-arrow-next.ts | 32 ---- .../ha-paper-icon-button-arrow-prev.ts | 38 ----- src/components/ha-paper-icon-button-next.ts | 29 ---- src/components/ha-paper-icon-button-prev.ts | 29 ---- src/components/ha-sidebar.ts | 32 ++-- src/components/ha-svg-icon.ts | 52 ++++++ src/components/ha-water_heater-control.js | 12 +- src/components/map/ha-map.ts | 2 +- src/components/user/ha-user-picker.ts | 2 +- .../config-flow/dialog-data-entry-flow.ts | 8 +- .../more-info/controls/more-info-climate.ts | 6 - .../more-info/controls/more-info-cover.js | 1 - .../more-info/controls/more-info-fan.js | 10 +- .../more-info/controls/more-info-light.js | 5 +- .../controls/more-info-media_player.js | 49 +++--- .../more-info/controls/more-info-vacuum.ts | 14 +- .../controls/more-info-water_heater.js | 10 -- .../more-info/controls/more-info-weather.ts | 18 +-- src/dialogs/more-info/more-info-controls.js | 14 +- .../notifications/notification-drawer.js | 5 +- .../ha-voice-command-dialog.ts | 11 +- src/entrypoints/app.ts | 3 - src/entrypoints/authorize.ts | 1 - src/entrypoints/hass-icons.ts | 1 - src/entrypoints/onboarding.ts | 1 - src/html/authorize.html.template | 2 - src/html/index.html.template | 2 - src/html/onboarding.html.template | 2 - src/layouts/hass-loading-screen.ts | 6 +- src/layouts/hass-subpage.ts | 11 +- src/layouts/hass-tabs-subpage.ts | 9 +- src/onboarding/action-badge.ts | 2 +- .../config/areas/ha-config-area-page.ts | 4 +- .../config/areas/ha-config-areas-dashboard.ts | 4 +- .../action/ha-automation-action-row.ts | 14 +- .../condition/ha-automation-condition-row.ts | 2 +- .../config/automation/ha-automation-editor.ts | 7 +- .../config/automation/ha-automation-picker.ts | 10 +- .../trigger/ha-automation-trigger-row.ts | 6 +- src/panels/config/cloud/alexa/cloud-alexa.ts | 6 +- .../cloud-google-assistant.ts | 6 +- src/panels/config/cloud/login/cloud-login.js | 8 +- src/panels/config/core/ha-config-core.js | 2 +- .../config/customize/ha-config-customize.js | 9 +- .../customize/ha-customize-attribute.js | 6 +- .../customize/types/ha-customize-icon.js | 4 +- .../config/dashboard/ha-config-navigation.ts | 1 - .../config/devices/ha-config-device-page.ts | 18 +-- .../config/entities/dialog-entity-editor.ts | 10 +- .../config/entities/ha-config-entities.ts | 18 +-- .../helpers/forms/ha-input_select-form.ts | 6 +- .../integrations/ha-config-integrations.ts | 4 +- .../integrations/ha-integration-card.ts | 8 +- .../ha-config-lovelace-dashboards.ts | 5 +- src/panels/config/scene/ha-scene-dashboard.ts | 18 +-- src/panels/config/scene/ha-scene-editor.ts | 19 ++- src/panels/config/script/ha-script-editor.ts | 7 +- src/panels/config/script/ha-script-picker.ts | 18 +-- .../ha-config-server-control.js | 1 - src/panels/config/zha/zha-add-devices-page.ts | 6 +- .../config/zha/zha-cluster-attributes.ts | 6 +- src/panels/config/zha/zha-cluster-commands.ts | 6 +- src/panels/config/zha/zha-clusters.ts | 6 +- src/panels/config/zha/zha-device-binding.ts | 6 +- src/panels/config/zha/zha-device-page.ts | 2 - src/panels/config/zha/zha-group-binding.ts | 6 +- src/panels/config/zha/zha-group-page.ts | 6 +- src/panels/config/zha/zha-groups-dashboard.ts | 6 +- src/panels/config/zha/zha-node.ts | 6 +- src/panels/config/zone/ha-config-zone.ts | 10 +- src/panels/config/zwave/ha-config-zwave.js | 12 +- src/panels/config/zwave/zwave-network.ts | 6 +- .../ha-panel-developer-tools.ts | 2 +- .../developer-tools/logs/error-log-card.ts | 8 +- .../developer-tools/logs/system-log-card.ts | 2 +- .../state/developer-tools-state.js | 9 +- src/panels/history/ha-panel-history.js | 1 - src/panels/logbook/ha-panel-logbook.js | 6 +- src/panels/lovelace/cards/hui-button-card.ts | 3 +- src/panels/lovelace/cards/hui-light-card.ts | 14 +- src/panels/lovelace/cards/hui-map-card.ts | 11 +- .../lovelace/cards/hui-media-control-card.ts | 47 +++--- .../lovelace/cards/hui-shopping-list-card.ts | 3 +- .../lovelace/cards/hui-thermostat-card.ts | 10 +- .../cards/hui-weather-forecast-card.ts | 9 +- .../lovelace/components/hui-buttons-base.ts | 4 +- .../lovelace/components/hui-card-options.ts | 18 +-- .../lovelace/components/hui-entity-editor.ts | 10 +- .../components/hui-input-list-editor.ts | 11 +- .../config-elements/hui-stack-card-editor.ts | 14 +- .../editor/view-editor/hui-edit-view.ts | 2 +- .../hui-media-player-entity-row.ts | 34 ++-- src/panels/lovelace/hui-editor.ts | 6 +- src/panels/lovelace/hui-root.ts | 53 ++++--- .../mailbox/ha-dialog-show-audio-message.js | 4 +- src/panels/map/ha-panel-map.js | 4 +- .../ha-long-lived-access-tokens-card.js | 7 +- src/panels/profile/ha-refresh-tokens-card.js | 10 +- .../shopping-list/ha-panel-shopping-list.js | 14 +- src/resources/hass-icons.js | 6 - src/resources/icon-metadata.ts | 4 + src/resources/mdi-icons.js | 6 - src/resources/styles.ts | 4 +- src/types.ts | 5 + yarn.lock | 53 ++++++- 168 files changed, 1102 insertions(+), 1048 deletions(-) create mode 100644 build-scripts/gulp/gen-icons-json.js delete mode 100644 build-scripts/gulp/gen-icons.js delete mode 100644 demo/src/resources/hademo-icons.js delete mode 100644 hassio/src/resources/hassio-icons.js create mode 100644 src/components/ha-icon-button-arrow-next.ts create mode 100644 src/components/ha-icon-button-arrow-prev.ts create mode 100644 src/components/ha-icon-button-next.ts create mode 100644 src/components/ha-icon-button-prev.ts create mode 100644 src/components/ha-icon-button.ts delete mode 100644 src/components/ha-iconset-svg.js delete mode 100644 src/components/ha-paper-icon-button-arrow-next.ts delete mode 100644 src/components/ha-paper-icon-button-arrow-prev.ts delete mode 100644 src/components/ha-paper-icon-button-next.ts delete mode 100644 src/components/ha-paper-icon-button-prev.ts create mode 100644 src/components/ha-svg-icon.ts delete mode 100644 src/entrypoints/hass-icons.ts delete mode 100644 src/resources/hass-icons.js create mode 100644 src/resources/icon-metadata.ts delete mode 100644 src/resources/mdi-icons.js diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 984656a4b0..873b38d08a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -35,7 +35,7 @@ jobs: env: CI: true - name: Build icons - run: ./node_modules/.bin/gulp gen-icons-hassio gen-icons-mdi gen-icons-app + run: ./node_modules/.bin/gulp gen-icons-json - name: Build translations run: ./node_modules/.bin/gulp build-translations - name: Run eslint diff --git a/build-scripts/gulp/app.js b/build-scripts/gulp/app.js index 60540172f8..b5929c289c 100644 --- a/build-scripts/gulp/app.js +++ b/build-scripts/gulp/app.js @@ -5,7 +5,7 @@ const envVars = require("../env"); require("./clean.js"); require("./translations.js"); -require("./gen-icons.js"); +require("./gen-icons-json.js"); require("./gather-static.js"); require("./compress.js"); require("./webpack.js"); @@ -21,7 +21,7 @@ gulp.task( "clean", gulp.parallel( "gen-service-worker-dev", - gulp.parallel("gen-icons-app", "gen-icons-mdi"), + "gen-icons-json", "gen-pages-dev", "gen-index-app-dev", "build-translations" @@ -38,7 +38,7 @@ gulp.task( process.env.NODE_ENV = "production"; }, "clean", - gulp.parallel("gen-icons-app", "gen-icons-mdi", "build-translations"), + gulp.parallel("gen-icons-json", "build-translations"), "copy-static", "webpack-prod-app", ...// Don't compress running tests diff --git a/build-scripts/gulp/cast.js b/build-scripts/gulp/cast.js index 3d632ad414..a97172c906 100644 --- a/build-scripts/gulp/cast.js +++ b/build-scripts/gulp/cast.js @@ -2,7 +2,6 @@ const gulp = require("gulp"); require("./clean.js"); require("./translations.js"); -require("./gen-icons.js"); require("./gather-static.js"); require("./webpack.js"); require("./service-worker.js"); @@ -17,12 +16,7 @@ gulp.task( }, "clean-cast", "translations-enable-merge-backend", - gulp.parallel( - "gen-icons-app", - "gen-icons-mdi", - "gen-index-cast-dev", - "build-translations" - ), + gulp.parallel("gen-icons-json", "build-translations"), "copy-static-cast", "webpack-dev-server-cast" ) @@ -36,7 +30,7 @@ gulp.task( }, "clean-cast", "translations-enable-merge-backend", - gulp.parallel("gen-icons-app", "gen-icons-mdi", "build-translations"), + gulp.parallel("gen-icons-json", "build-translations"), "copy-static-cast", "webpack-prod-cast", "gen-index-cast-prod" diff --git a/build-scripts/gulp/demo.js b/build-scripts/gulp/demo.js index ef7c42cea1..eef9ebbecf 100644 --- a/build-scripts/gulp/demo.js +++ b/build-scripts/gulp/demo.js @@ -3,7 +3,7 @@ const gulp = require("gulp"); require("./clean.js"); require("./translations.js"); -require("./gen-icons.js"); +require("./gen-icons-json.js"); require("./gather-static.js"); require("./webpack.js"); require("./service-worker.js"); @@ -17,13 +17,7 @@ gulp.task( }, "clean-demo", "translations-enable-merge-backend", - gulp.parallel( - "gen-icons-app", - "gen-icons-mdi", - "gen-icons-demo", - "gen-index-demo-dev", - "build-translations" - ), + gulp.parallel("gen-icons-json", "gen-index-demo-dev", "build-translations"), "copy-static-demo", "webpack-dev-server-demo" ) @@ -38,12 +32,7 @@ gulp.task( "clean-demo", // Cast needs to be backwards compatible and older HA has no translations "translations-enable-merge-backend", - gulp.parallel( - "gen-icons-app", - "gen-icons-mdi", - "gen-icons-demo", - "build-translations" - ), + gulp.parallel("gen-icons-json", "build-translations"), "copy-static-demo", "webpack-prod-demo", "gen-index-demo-prod" diff --git a/build-scripts/gulp/entry-html.js b/build-scripts/gulp/entry-html.js index 5ad758e807..71fd5dd0e8 100644 --- a/build-scripts/gulp/entry-html.js +++ b/build-scripts/gulp/entry-html.js @@ -47,11 +47,9 @@ gulp.task("gen-pages-dev", (done) => { for (const page of PAGES) { const content = renderTemplate(page, { latestPageJS: `/frontend_latest/${page}.js`, - latestHassIconsJS: "/frontend_latest/hass-icons.js", es5Compatibility: "/frontend_es5/compatibility.js", es5PageJS: `/frontend_es5/${page}.js`, - es5HassIconsJS: "/frontend_es5/hass-icons.js", }); fs.outputFileSync(path.resolve(config.root, `${page}.html`), content); @@ -66,11 +64,9 @@ gulp.task("gen-pages-prod", (done) => { for (const page of PAGES) { const content = renderTemplate(page, { latestPageJS: latestManifest[`${page}.js`], - latestHassIconsJS: latestManifest["hass-icons.js"], es5Compatibility: es5Manifest["compatibility.js"], es5PageJS: es5Manifest[`${page}.js`], - es5HassIconsJS: es5Manifest["hass-icons.js"], }); fs.outputFileSync( @@ -88,13 +84,11 @@ gulp.task("gen-index-app-dev", (done) => { latestAppJS: "/frontend_latest/app.js", latestCoreJS: "/frontend_latest/core.js", latestCustomPanelJS: "/frontend_latest/custom-panel.js", - latestHassIconsJS: "/frontend_latest/hass-icons.js", es5Compatibility: "/frontend_es5/compatibility.js", es5AppJS: "/frontend_es5/app.js", es5CoreJS: "/frontend_es5/core.js", es5CustomPanelJS: "/frontend_es5/custom-panel.js", - es5HassIconsJS: "/frontend_es5/hass-icons.js", }).replace(/#THEMEC/g, "{{ theme_color }}"); fs.outputFileSync(path.resolve(config.root, "index.html"), content); @@ -108,13 +102,11 @@ gulp.task("gen-index-app-prod", (done) => { latestAppJS: latestManifest["app.js"], latestCoreJS: latestManifest["core.js"], latestCustomPanelJS: latestManifest["custom-panel.js"], - latestHassIconsJS: latestManifest["hass-icons.js"], es5Compatibility: es5Manifest["compatibility.js"], es5AppJS: es5Manifest["app.js"], es5CoreJS: es5Manifest["core.js"], es5CustomPanelJS: es5Manifest["custom-panel.js"], - es5HassIconsJS: es5Manifest["hass-icons.js"], }); const minified = minifyHtml(content).replace(/#THEMEC/g, "{{ theme_color }}"); diff --git a/build-scripts/gulp/gallery.js b/build-scripts/gulp/gallery.js index e337126ff9..559b0debde 100644 --- a/build-scripts/gulp/gallery.js +++ b/build-scripts/gulp/gallery.js @@ -3,7 +3,7 @@ const gulp = require("gulp"); require("./clean.js"); require("./translations.js"); -require("./gen-icons.js"); +require("./gen-icons-json.js"); require("./gather-static.js"); require("./webpack.js"); require("./service-worker.js"); @@ -17,7 +17,7 @@ gulp.task( }, "clean-gallery", "translations-enable-merge-backend", - gulp.parallel("gen-icons-app", "gen-icons-mdi", "build-translations"), + gulp.parallel("gen-icons-json", "build-translations"), "copy-static-gallery", "gen-index-gallery-dev", "webpack-dev-server-gallery" @@ -32,7 +32,7 @@ gulp.task( }, "clean-gallery", "translations-enable-merge-backend", - gulp.parallel("gen-icons-app", "gen-icons-mdi", "build-translations"), + gulp.parallel("gen-icons-json", "build-translations"), "copy-static-gallery", "webpack-prod-gallery", "gen-index-gallery-prod" diff --git a/build-scripts/gulp/gather-static.js b/build-scripts/gulp/gather-static.js index 9c1d843567..179d898775 100644 --- a/build-scripts/gulp/gather-static.js +++ b/build-scripts/gulp/gather-static.js @@ -26,6 +26,13 @@ function copyTranslations(staticDir) { ); } +function copyMdiIcons(staticDir) { + const staticPath = genStaticPath(staticDir); + + // MDI icons output + fs.copySync(polyPath("build/mdi"), staticPath("mdi")); +} + function copyPolyfills(staticDir) { const staticPath = genStaticPath(staticDir); @@ -80,6 +87,7 @@ gulp.task("copy-static", (done) => { copyPolyfills(staticDir); copyFonts(staticDir); copyTranslations(staticDir); + copyMdiIcons(staticDir); // Panel assets copyFileDir( @@ -103,6 +111,7 @@ gulp.task("copy-static-demo", (done) => { copyMapPanel(paths.demo_static); copyFonts(paths.demo_static); copyTranslations(paths.demo_static); + copyMdiIcons(paths.demo_static); done(); }); @@ -115,6 +124,7 @@ gulp.task("copy-static-cast", (done) => { copyMapPanel(paths.cast_static); copyFonts(paths.cast_static); copyTranslations(paths.cast_static); + copyMdiIcons(paths.cast_static); done(); }); @@ -127,5 +137,6 @@ gulp.task("copy-static-gallery", (done) => { copyMapPanel(paths.gallery_static); copyFonts(paths.gallery_static); copyTranslations(paths.gallery_static); + copyMdiIcons(paths.gallery_static); done(); }); diff --git a/build-scripts/gulp/gen-icons-json.js b/build-scripts/gulp/gen-icons-json.js new file mode 100644 index 0000000000..cd4401b503 --- /dev/null +++ b/build-scripts/gulp/gen-icons-json.js @@ -0,0 +1,109 @@ +const gulp = require("gulp"); +const path = require("path"); +const fs = require("fs"); +const hash = require("object-hash"); + +const ICON_PACKAGE_PATH = path.resolve( + __dirname, + "../../node_modules/@mdi/svg/" +); +const META_PATH = path.resolve(ICON_PACKAGE_PATH, "meta.json"); +const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg"); +const OUTPUT_DIR = path.resolve(__dirname, "../../build/mdi"); + +const encoding = "utf8"; + +const getMeta = () => { + const file = fs.readFileSync(META_PATH, { encoding }); + const meta = JSON.parse(file); + return meta.map((icon) => { + const svg = fs.readFileSync(`${ICON_PATH}/${icon.name}.svg`, { + encoding, + }); + return { path: svg.match(/ d="([^"]+)"/)[1], name: icon.name }; + }); +}; + +const splitBySize = (meta) => { + const chunks = []; + const CHUNK_SIZE = 100000; + + let curSize = 0; + let startKey; + let icons = []; + + Object.values(meta).forEach((icon) => { + if (startKey === undefined) { + startKey = icon.name; + } + curSize += icon.path.length; + icons.push(icon); + if (curSize > CHUNK_SIZE) { + chunks.push({ + startKey, + endKey: icon.name, + icons, + }); + curSize = 0; + startKey = undefined; + icons = []; + } + }); + + chunks.push({ + startKey, + icons, + }); + + return chunks; +}; + +const findDifferentiator = (curString, prevString) => { + for (let i = 0; i < curString.length; i++) { + if (curString[i] !== prevString[i]) { + return curString.substring(0, i + 1); + } + } + console.error("Cannot find differentiator", curString, prevString); + return undefined; +}; + +gulp.task("gen-icons-json", (done) => { + const meta = getMeta(); + const split = splitBySize(meta); + + if (!fs.existsSync(OUTPUT_DIR)) { + fs.mkdirSync(OUTPUT_DIR, { recursive: true }); + } + const manifest = []; + + let lastEnd; + split.forEach((chunk) => { + let startKey; + if (lastEnd === undefined) { + chunk.startKey = undefined; + startKey = undefined; + } else { + startKey = findDifferentiator(chunk.startKey, lastEnd); + } + lastEnd = chunk.endKey; + + const output = {}; + chunk.icons.forEach((icon) => { + output[icon.name] = icon.path; + }); + const filename = hash(output); + manifest.push({ start: startKey, file: filename }); + fs.writeFileSync( + path.resolve(OUTPUT_DIR, `${filename}.json`), + JSON.stringify(output) + ); + }); + + fs.writeFileSync( + path.resolve(OUTPUT_DIR, "iconMetadata.json"), + JSON.stringify(manifest) + ); + + done(); +}); diff --git a/build-scripts/gulp/gen-icons.js b/build-scripts/gulp/gen-icons.js deleted file mode 100644 index 8ce9f7612b..0000000000 --- a/build-scripts/gulp/gen-icons.js +++ /dev/null @@ -1,127 +0,0 @@ -const gulp = require("gulp"); -const path = require("path"); -const fs = require("fs"); -const paths = require("../paths"); -const { mapFiles } = require("../util"); - -const ICON_PACKAGE_PATH = path.resolve( - __dirname, - "../../node_modules/@mdi/svg/" -); -const META_PATH = path.resolve(ICON_PACKAGE_PATH, "meta.json"); -const ICON_PATH = path.resolve(ICON_PACKAGE_PATH, "svg"); -const OUTPUT_DIR = path.resolve(__dirname, "../../build"); -const MDI_OUTPUT_PATH = path.resolve(OUTPUT_DIR, "mdi.html"); -const HASS_OUTPUT_PATH = path.resolve(OUTPUT_DIR, "hass-icons.html"); - -const BUILT_IN_PANEL_ICONS = [ - "calendar", // Calendar - "settings", // Config - "home-assistant", // Hass.io - "poll-box", // History panel - "format-list-bulleted-type", // Logbook - "mailbox", // Mailbox - "tooltip-account", // Map - "cart", // Shopping List - "hammer", // developer-tools -]; - -// Given an icon name, load the SVG file -function loadIcon(name) { - const iconPath = path.resolve(ICON_PATH, `${name}.svg`); - try { - return fs.readFileSync(iconPath, "utf-8"); - } catch (err) { - return null; - } -} - -// Given an SVG file, convert it to an iron-iconset-svg definition -function transformXMLtoPolymer(name, xml) { - const start = xml.indexOf(">${pth}`; -} - -// Given an iconset name and icon names, generate a polymer iconset -function generateIconset(iconsetName, iconNames) { - const iconDefs = Array.from(iconNames) - .map((name) => { - const iconDef = loadIcon(name); - if (!iconDef) { - throw new Error(`Unknown icon referenced: ${name}`); - } - return transformXMLtoPolymer(name, iconDef); - }) - .join(""); - return `${iconDefs}`; -} - -// Find all icons used by the project. -function findIcons(searchPath, iconsetName) { - const iconRegex = new RegExp(`${iconsetName}:[\\w-]+`, "g"); - const icons = new Set(); - function processFile(filename) { - const content = fs.readFileSync(filename); - let match; - // eslint-disable-next-line - while ((match = iconRegex.exec(content))) { - // strip off "hass:" and add to set - icons.add(match[0].substr(iconsetName.length + 1)); - } - } - mapFiles(searchPath, ".js", processFile); - mapFiles(searchPath, ".ts", processFile); - return icons; -} - -gulp.task("gen-icons-mdi", (done) => { - const meta = JSON.parse( - fs.readFileSync(path.resolve(ICON_PACKAGE_PATH, META_PATH), "UTF-8") - ); - const iconNames = meta.map((iconInfo) => iconInfo.name); - if (!fs.existsSync(OUTPUT_DIR)) { - fs.mkdirSync(OUTPUT_DIR); - } - fs.writeFileSync(MDI_OUTPUT_PATH, generateIconset("mdi", iconNames)); - done(); -}); - -gulp.task("gen-icons-app", (done) => { - const iconNames = findIcons("./src", "hass"); - BUILT_IN_PANEL_ICONS.forEach((name) => iconNames.add(name)); - if (!fs.existsSync(OUTPUT_DIR)) { - fs.mkdirSync(OUTPUT_DIR); - } - fs.writeFileSync(HASS_OUTPUT_PATH, generateIconset("hass", iconNames)); - done(); -}); - -gulp.task("gen-icons-demo", (done) => { - const iconNames = findIcons(path.resolve(paths.demo_dir, "./src"), "hademo"); - fs.writeFileSync( - path.resolve(paths.demo_dir, "hademo-icons.html"), - generateIconset("hademo", iconNames) - ); - done(); -}); - -gulp.task("gen-icons-hassio", (done) => { - const iconNames = findIcons( - path.resolve(paths.hassio_dir, "./src"), - "hassio" - ); - // Find hassio icons inside HA main repo. - for (const item of findIcons( - path.resolve(paths.polymer_dir, "./src"), - "hassio" - )) { - iconNames.add(item); - } - fs.writeFileSync( - path.resolve(paths.hassio_dir, "hassio-icons.html"), - generateIconset("hassio", iconNames) - ); - done(); -}); diff --git a/build-scripts/gulp/hassio.js b/build-scripts/gulp/hassio.js index 01f165bc29..f0da67e43b 100644 --- a/build-scripts/gulp/hassio.js +++ b/build-scripts/gulp/hassio.js @@ -3,7 +3,7 @@ const gulp = require("gulp"); const envVars = require("../env"); require("./clean.js"); -require("./gen-icons.js"); +require("./gen-icons-json.js"); require("./webpack.js"); require("./compress.js"); @@ -14,7 +14,6 @@ gulp.task( process.env.NODE_ENV = "development"; }, "clean-hassio", - gulp.parallel("gen-icons-hassio", "gen-icons-mdi"), "webpack-watch-hassio" ) ); @@ -26,7 +25,6 @@ gulp.task( process.env.NODE_ENV = "production"; }, "clean-hassio", - gulp.parallel("gen-icons-hassio", "gen-icons-mdi"), "webpack-prod-hassio", ...// Don't compress running tests (envVars.isTravis() ? [] : ["compress-hassio"]) diff --git a/build-scripts/webpack.js b/build-scripts/webpack.js index 5bccece0bc..1bcefa1b58 100644 --- a/build-scripts/webpack.js +++ b/build-scripts/webpack.js @@ -140,7 +140,6 @@ const createAppConfig = ({ isProdBuild, latestBuild, isStatsBuild }) => { core: "./src/entrypoints/core.ts", compatibility: "./src/entrypoints/compatibility.ts", "custom-panel": "./src/entrypoints/custom-panel.ts", - "hass-icons": "./src/entrypoints/hass-icons.ts", }, outputRoot: paths.root, isProdBuild, diff --git a/cast/src/launcher/entrypoint.ts b/cast/src/launcher/entrypoint.ts index db52293458..dd4711e379 100644 --- a/cast/src/launcher/entrypoint.ts +++ b/cast/src/launcher/entrypoint.ts @@ -1,5 +1,3 @@ -import "../../../src/components/ha-iconset-svg"; import "../../../src/resources/ha-style"; -import "../../../src/resources/hass-icons"; import "../../../src/resources/roboto"; import "./layout/hc-connect"; diff --git a/cast/src/launcher/layout/hc-cast.ts b/cast/src/launcher/layout/hc-cast.ts index 2f2cea6576..099c7f70be 100644 --- a/cast/src/launcher/layout/hc-cast.ts +++ b/cast/src/launcher/layout/hc-cast.ts @@ -1,4 +1,3 @@ -import "@polymer/iron-icon"; import "@polymer/paper-item/paper-icon-item"; import "@polymer/paper-listbox/paper-listbox"; import { Auth, Connection } from "home-assistant-js-websocket"; @@ -83,7 +82,7 @@ class HcCast extends LitElement { ? html`

- + Start Casting

@@ -121,7 +120,7 @@ class HcCast extends LitElement { ${this.castManager.status ? html` - + Manage ` @@ -243,7 +242,7 @@ class HcCast extends LitElement { color: var(--secondary-text-color); } - mwc-button iron-icon { + mwc-button ha-icon { margin-right: 8px; height: 18px; } diff --git a/cast/src/launcher/layout/hc-connect.ts b/cast/src/launcher/layout/hc-connect.ts index 1c9ca40e6c..9660f4755a 100644 --- a/cast/src/launcher/layout/hc-connect.ts +++ b/cast/src/launcher/layout/hc-connect.ts @@ -1,5 +1,4 @@ import "@material/mwc-button"; -import "@polymer/iron-icon"; import "@polymer/paper-input/paper-input"; import { Auth, @@ -27,6 +26,7 @@ import { loadTokens, saveTokens, } from "../../../../src/common/auth/token_storage"; +import "../../../../src/components/ha-icon"; import "../../../../src/layouts/loading-screen"; import { registerServiceWorker } from "../../../../src/util/register-service-worker"; import "./hc-layout"; @@ -136,11 +136,11 @@ export class HcConnect extends LitElement {
Show Demo - + >
Authorize @@ -316,7 +316,7 @@ export class HcConnect extends LitElement { color: darkred; } - mwc-button iron-icon { + mwc-button ha-icon { margin-left: 8px; } diff --git a/cast/src/receiver/second-load.ts b/cast/src/receiver/second-load.ts index 7fe5d01e02..39dd115e96 100644 --- a/cast/src/receiver/second-load.ts +++ b/cast/src/receiver/second-load.ts @@ -1,5 +1,3 @@ import "web-animations-js/web-animations-next-lite.min"; -import "../../../src/components/ha-iconset-svg"; -import "../../../src/resources/hass-icons"; import "../../../src/resources/roboto"; import "./layout/hc-lovelace"; diff --git a/demo/src/configs/teachingbirds/lovelace.ts b/demo/src/configs/teachingbirds/lovelace.ts index 5fbe14ff0a..76fb7f959a 100644 --- a/demo/src/configs/teachingbirds/lovelace.ts +++ b/demo/src/configs/teachingbirds/lovelace.ts @@ -63,8 +63,7 @@ export const demoLovelaceTeachingbirds: DemoConfig["lovelace"] = () => ({ elements: [ { style: { - "--iron-icon-width": "100px", - "--iron-icon-height": "100px", + "--mdc-icon-size": "100px", top: "50%", left: "50%", }, diff --git a/demo/src/entrypoint.ts b/demo/src/entrypoint.ts index 20fdcb71ab..e2b8c447ce 100644 --- a/demo/src/entrypoint.ts +++ b/demo/src/entrypoint.ts @@ -1,12 +1,9 @@ import "@polymer/paper-styles/typography"; import "@polymer/polymer/lib/elements/dom-if"; import "@polymer/polymer/lib/elements/dom-repeat"; -import "../../src/components/ha-iconset-svg"; import "../../src/resources/ha-style"; -import "../../src/resources/hass-icons"; import "../../src/resources/roboto"; import "./ha-demo"; -import "./resources/hademo-icons"; /* polyfill for paper-dropdown */ setTimeout(() => { diff --git a/demo/src/resources/hademo-icons.js b/demo/src/resources/hademo-icons.js deleted file mode 100644 index 62397f0a3b..0000000000 --- a/demo/src/resources/hademo-icons.js +++ /dev/null @@ -1,7 +0,0 @@ -import "../../../src/components/ha-iconset-svg"; -import iconSetContent from "../../hademo-icons.html"; - -const documentContainer = document.createElement("template"); -documentContainer.setAttribute("style", "display: none;"); -documentContainer.innerHTML = iconSetContent; -document.head.appendChild(documentContainer.content); diff --git a/gallery/src/demos/demo-hui-picture-elements-card.ts b/gallery/src/demos/demo-hui-picture-elements-card.ts index bed6be4c47..6e0ec3360a 100644 --- a/gallery/src/demos/demo-hui-picture-elements-card.ts +++ b/gallery/src/demos/demo-hui-picture-elements-card.ts @@ -50,10 +50,9 @@ const CONFIGS = [ top: 12% left: 6% transform: rotate(-60deg) scaleX(-1) - --iron-icon-height: 30px - --iron-icon-width: 30px - --iron-icon-stroke-color: black - --iron-icon-fill-color: rgba(50, 50, 50, .75) + --mdc-icon-size: 30px + --mdc-icon-stroke-color: black + --mdc-icon-fill-color: rgba(50, 50, 50, .75) - type: image entity: light.bed_light tap_action: @@ -99,10 +98,9 @@ const CONFIGS = [ top: 12% left: 6% transform: rotate(-60deg) scaleX(-1) - --iron-icon-height: 30px - --iron-icon-width: 30px - --iron-icon-stroke-color: black - --iron-icon-fill-color: rgba(50, 50, 50, .75) + --mdc-icon-size: 30px + --mdc-icon-stroke-color: black + --mdc-icon-fill-color: rgba(50, 50, 50, .75) - type: image entity: light.bed_light tap_action: diff --git a/gallery/src/entrypoint.js b/gallery/src/entrypoint.js index 4cf309e612..f803a3c6a3 100644 --- a/gallery/src/entrypoint.js +++ b/gallery/src/entrypoint.js @@ -1,9 +1,7 @@ import "@polymer/paper-styles/typography"; import "@polymer/polymer/lib/elements/dom-if"; import "@polymer/polymer/lib/elements/dom-repeat"; -import "../../src/components/ha-iconset-svg"; import "../../src/resources/ha-style"; -import "../../src/resources/hass-icons"; import "../../src/resources/roboto"; import "./ha-gallery"; diff --git a/gallery/src/ha-gallery.js b/gallery/src/ha-gallery.js index 1c68e07e33..de8c424e5a 100644 --- a/gallery/src/ha-gallery.js +++ b/gallery/src/ha-gallery.js @@ -1,8 +1,8 @@ import "@polymer/app-layout/app-header-layout/app-header-layout"; import "@polymer/app-layout/app-header/app-header"; import "@polymer/app-layout/app-toolbar/app-toolbar"; -import "@polymer/iron-icon/iron-icon"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "../../src/components/ha-icon-button"; +import "../../src/components/ha-icon"; import "@polymer/paper-item/paper-item"; import "@polymer/paper-item/paper-item-body"; import { html } from "@polymer/polymer/lib/utils/html-tag"; @@ -28,7 +28,7 @@ class HaGallery extends PolymerElement { app-header-layout { min-height: 100vh; } - paper-icon-button.invisible { + ha-icon-button.invisible { visibility: hidden; } @@ -67,11 +67,11 @@ class HaGallery extends PolymerElement { - + >
[[_withDefault(_demo, "Home Assistant Gallery")]]
@@ -98,7 +98,7 @@ class HaGallery extends PolymerElement { {{ item }} - + @@ -114,7 +114,7 @@ class HaGallery extends PolymerElement { {{ item }} - + @@ -130,7 +130,7 @@ class HaGallery extends PolymerElement { {{ item }} - + diff --git a/hassio/.gitignore b/hassio/.gitignore index c3f61fee32..e69de29bb2 100644 --- a/hassio/.gitignore +++ b/hassio/.gitignore @@ -1 +0,0 @@ -hassio-icons.html diff --git a/hassio/src/addon-store/hassio-addon-store.ts b/hassio/src/addon-store/hassio-addon-store.ts index c46b8bc780..1e9985c284 100644 --- a/hassio/src/addon-store/hassio-addon-store.ts +++ b/hassio/src/addon-store/hassio-addon-store.ts @@ -92,12 +92,12 @@ class HassioAddonStore extends LitElement { .tabs=${supervisorTabs} > Add-on store - + > ${repos.length === 0 ? html`` @@ -150,9 +150,6 @@ class HassioAddonStore extends LitElement { hassio-addon-repository { margin-top: 24px; } - hassio-search-input { - --iron-icon-fill-color: var(--primary-text-color); - } `; } } diff --git a/hassio/src/addon-store/hassio-repositories-editor.ts b/hassio/src/addon-store/hassio-repositories-editor.ts index 1a23949cdf..48e151dc34 100644 --- a/hassio/src/addon-store/hassio-repositories-editor.ts +++ b/hassio/src/addon-store/hassio-repositories-editor.ts @@ -1,4 +1,3 @@ -import "@polymer/iron-icon/iron-icon"; import "@polymer/paper-card/paper-card"; import "@polymer/paper-input/paper-input"; import { @@ -19,6 +18,7 @@ import { PolymerChangedEvent } from "../../../src/polymer-types"; import { HomeAssistant } from "../../../src/types"; import "../components/hassio-card-content"; import { hassioStyle } from "../resources/hassio-style"; +import "../../../src/components/ha-icon"; @customElement("hassio-repositories-editor") class HassioRepositoriesEditor extends LitElement { @@ -76,7 +76,7 @@ class HassioRepositoriesEditor extends LitElement {
- + + > ` : html` - + > `} ` : html` ${this.addon.version_latest} `} @@ -387,7 +387,7 @@ class HassioAddonInfo extends LitElement {
Protection mode - + Grant the add-on elevated system access. @@ -562,7 +562,7 @@ class HassioAddonInfo extends LitElement { width: 180px; display: inline-block; } - .state iron-icon { + .state ha-icon { width: 16px; height: 16px; color: var(--secondary-text-color); @@ -570,10 +570,10 @@ class HassioAddonInfo extends LitElement { ha-switch { display: flex; } - iron-icon.running { + ha-icon.running { color: var(--paper-green-400); } - iron-icon.stopped { + ha-icon.stopped { color: var(--google-red-300); } ha-call-api-button { @@ -618,7 +618,7 @@ class HassioAddonInfo extends LitElement { .security ha-label-badge { cursor: pointer; margin-right: 4px; - --iron-icon-height: 45px; + --mdc-icon-size: 45px; --ha-label-badge-padding: 8px 0 0 0; } `, diff --git a/hassio/src/components/hassio-card-content.ts b/hassio/src/components/hassio-card-content.ts index a2174a77e9..3438e07de0 100644 --- a/hassio/src/components/hassio-card-content.ts +++ b/hassio/src/components/hassio-card-content.ts @@ -1,4 +1,3 @@ -import "@polymer/iron-icon/iron-icon"; import { css, CSSResult, @@ -9,6 +8,7 @@ import { TemplateResult, } from "lit-element"; import "../../../src/components/ha-relative-time"; +import "../../../src/components/ha-icon"; import { HomeAssistant } from "../../../src/types"; @customElement("hassio-card-content") @@ -48,11 +48,11 @@ class HassioCardContent extends LitElement {
` : html` - + > `}
@@ -78,25 +78,25 @@ class HassioCardContent extends LitElement { static get styles(): CSSResult { return css` - iron-icon { + ha-icon { margin-right: 24px; margin-left: 8px; margin-top: 12px; float: left; color: var(--secondary-text-color); } - iron-icon.update { + ha-icon.update { color: var(--paper-orange-400); } - iron-icon.running, - iron-icon.installed { + ha-icon.running, + ha-icon.installed { color: var(--paper-green-400); } - iron-icon.hassupdate, - iron-icon.snapshot { + ha-icon.hassupdate, + ha-icon.snapshot { color: var(--paper-item-icon-color); } - iron-icon.not_available { + ha-icon.not_available { color: var(--google-red-500); } .title { diff --git a/hassio/src/components/hassio-search-input.ts b/hassio/src/components/hassio-search-input.ts index ba4ac7c229..cdf69b3607 100644 --- a/hassio/src/components/hassio-search-input.ts +++ b/hassio/src/components/hassio-search-input.ts @@ -1,6 +1,6 @@ import "@material/mwc-button"; -import "@polymer/iron-icon/iron-icon"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "../../../src/components/ha-icon-button"; +import "../../../src/components/ha-icon"; import "@polymer/paper-input/paper-input"; import { css, @@ -24,21 +24,17 @@ class HassioSearchInput extends LitElement { .value=${this.filter} @value-changed=${this._filterInputChanged} > - + ${this.filter && html` - + > `}
@@ -71,6 +67,9 @@ class HassioSearchInput extends LitElement { .prefix { margin: 8px; } + ha-icon { + color: var(--primary-text-color); + } `; } } diff --git a/hassio/src/dashboard/hassio-update.ts b/hassio/src/dashboard/hassio-update.ts index 4a44f7f480..719e03cb9c 100644 --- a/hassio/src/dashboard/hassio-update.ts +++ b/hassio/src/dashboard/hassio-update.ts @@ -1,5 +1,4 @@ import "@material/mwc-button"; -import "@polymer/iron-icon/iron-icon"; import "@polymer/paper-card/paper-card"; import { css, @@ -17,6 +16,7 @@ import { HassioSupervisorInfo, } from "../../../src/data/hassio/supervisor"; import { haStyle } from "../../../src/resources/styles"; +import "../../../src/components/ha-icon"; import { HomeAssistant } from "../../../src/types"; import "../components/hassio-card-content"; import { hassioStyle } from "../resources/hassio-style"; @@ -112,7 +112,7 @@ export class HassioUpdate extends LitElement { ${icon ? html`
- +
` : ""} @@ -158,8 +158,7 @@ export class HassioUpdate extends LitElement { hassioStyle, css` .icon { - --iron-icon-height: 48px; - --iron-icon-width: 48px; + --mdc-icon-size: 48px; float: right; margin: 0 0 2px 10px; color: var(--primary-text-color); diff --git a/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts b/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts index c930ee9a44..93c2c6c354 100644 --- a/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts +++ b/hassio/src/dialogs/markdown/dialog-hassio-markdown.ts @@ -1,7 +1,7 @@ import "@polymer/app-layout/app-toolbar/app-toolbar"; import { PaperDialogElement } from "@polymer/paper-dialog"; import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "../../../../src/components/ha-icon-button"; import { css, CSSResult, @@ -36,10 +36,10 @@ class HassioMarkdownDialog extends LitElement { return html` - + >
${this.title}
diff --git a/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts b/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts index 87f22529a2..d341c9175a 100755 --- a/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts +++ b/hassio/src/dialogs/snapshot/dialog-hassio-snapshot.ts @@ -1,10 +1,10 @@ import "@material/mwc-button"; import "@polymer/app-layout/app-toolbar/app-toolbar"; -import "@polymer/iron-icon/iron-icon"; import { PaperCheckboxElement } from "@polymer/paper-checkbox/paper-checkbox"; import { PaperDialogElement } from "@polymer/paper-dialog"; import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "../../../../src/components/ha-icon-button"; +import "../../../../src/components/ha-icon"; import "@polymer/paper-input/paper-input"; import { css, @@ -119,10 +119,10 @@ class HassioSnapshotDialog extends LitElement { .on-iron-overlay-closed=${this._dialogClosed} > - + >
${this._computeName}
@@ -200,13 +200,13 @@ class HassioSnapshotDialog extends LitElement {
  • - + Download Snapshot
  • - + Restore Selected
  • @@ -214,7 +214,7 @@ class HassioSnapshotDialog extends LitElement { ? html`
  • - + Wipe & restore
  • @@ -222,7 +222,7 @@ class HassioSnapshotDialog extends LitElement { : ""}
  • - + Delete Snapshot
  • diff --git a/hassio/src/entrypoint.ts b/hassio/src/entrypoint.ts index 935d5676d7..1a8e26ea80 100644 --- a/hassio/src/entrypoint.ts +++ b/hassio/src/entrypoint.ts @@ -2,8 +2,6 @@ window.loadES5Adapter().then(() => { // eslint-disable-next-line import(/* webpackChunkName: "roboto" */ "../../src/resources/roboto"); // eslint-disable-next-line - import(/* webpackChunkName: "hassio-icons" */ "./resources/hassio-icons"); - // eslint-disable-next-line import(/* webpackChunkName: "hassio-main" */ "./hassio-main"); }); diff --git a/hassio/src/hassio-main.ts b/hassio/src/hassio-main.ts index d95c1967af..524e55af25 100644 --- a/hassio/src/hassio-main.ts +++ b/hassio/src/hassio-main.ts @@ -1,4 +1,4 @@ -import "@polymer/paper-icon-button"; +import "../../src/components/ha-icon-button"; import { PolymerElement } from "@polymer/polymer"; import { customElement, property, PropertyValues } from "lit-element"; import { applyThemesOnElement } from "../../src/common/dom/apply_themes_on_element"; @@ -34,11 +34,11 @@ import { HomeAssistant } from "../../src/types"; // Don't codesplit it, that way the dashboard always loads fast. import "./hassio-panel"; -// The register callback of the IronA11yKeysBehavior inside paper-icon-button -// is not called, causing _keyBindings to be uninitiliazed for paper-icon-button, +// The register callback of the IronA11yKeysBehavior inside ha-icon-button +// is not called, causing _keyBindings to be uninitiliazed for ha-icon-button, // causing an exception when added to DOM. When transpiled to ES5, this will // break the build. -customElements.get("paper-icon-button").prototype._keyBindings = {}; +customElements.get("ha-icon-button").prototype._keyBindings = {}; @customElement("hassio-main") class HassioMain extends ProvideHassLitMixin(HassRouterPage) { diff --git a/hassio/src/ingress-view/hassio-ingress-view.ts b/hassio/src/ingress-view/hassio-ingress-view.ts index 2dffe09ca3..639b0132ac 100644 --- a/hassio/src/ingress-view/hassio-ingress-view.ts +++ b/hassio/src/ingress-view/hassio-ingress-view.ts @@ -86,7 +86,7 @@ class HassioIngressView extends LitElement { height: 100%; border: 0; } - paper-icon-button { + ha-icon-button { color: var(--text-primary-color); } `; diff --git a/hassio/src/resources/hassio-icons.js b/hassio/src/resources/hassio-icons.js deleted file mode 100644 index ca4a7fa58f..0000000000 --- a/hassio/src/resources/hassio-icons.js +++ /dev/null @@ -1,7 +0,0 @@ -import "../../../src/components/ha-iconset-svg"; -import iconSetContent from "../../hassio-icons.html"; - -const documentContainer = document.createElement("template"); -documentContainer.setAttribute("style", "display: none;"); -documentContainer.innerHTML = iconSetContent; -document.head.appendChild(documentContainer.content); diff --git a/hassio/src/snapshots/hassio-snapshots.ts b/hassio/src/snapshots/hassio-snapshots.ts index f0c7af2ed1..fea4a42fcf 100644 --- a/hassio/src/snapshots/hassio-snapshots.ts +++ b/hassio/src/snapshots/hassio-snapshots.ts @@ -98,12 +98,12 @@ class HassioSnapshots extends LitElement { > Snapshots - + >

    diff --git a/package.json b/package.json index 8818999343..34b6a2294c 100644 --- a/package.json +++ b/package.json @@ -29,8 +29,10 @@ "@material/mwc-checkbox": "^0.13.0", "@material/mwc-dialog": "^0.13.0", "@material/mwc-fab": "^0.13.0", + "@material/mwc-icon-button": "^0.13.0", "@material/mwc-ripple": "^0.13.0", "@material/mwc-switch": "^0.13.0", + "@mdi/js": "4.9.95", "@mdi/svg": "4.9.95", "@polymer/app-layout": "^3.0.2", "@polymer/app-route": "^3.0.2", @@ -39,7 +41,6 @@ "@polymer/iron-autogrow-textarea": "^3.0.1", "@polymer/iron-flex-layout": "^3.0.1", "@polymer/iron-icon": "^3.0.1", - "@polymer/iron-iconset-svg": "^3.0.1", "@polymer/iron-image": "^3.0.1", "@polymer/iron-input": "^3.0.1", "@polymer/iron-label": "^3.0.1", @@ -55,7 +56,6 @@ "@polymer/paper-dialog-scrollable": "^3.0.1", "@polymer/paper-drawer-panel": "^3.0.1", "@polymer/paper-dropdown-menu": "^3.0.1", - "@polymer/paper-icon-button": "^3.0.2", "@polymer/paper-input": "^3.0.1", "@polymer/paper-item": "^3.0.1", "@polymer/paper-listbox": "^3.0.1", @@ -89,6 +89,7 @@ "google-timezones-json": "^1.0.2", "hls.js": "^0.12.4", "home-assistant-js-websocket": "5.0.0", + "idb-keyval": "^3.2.0", "intl-messageformat": "^8.3.9", "js-yaml": "^3.13.1", "leaflet": "^1.4.0", @@ -170,6 +171,7 @@ "map-stream": "^0.0.7", "merge-stream": "^1.0.1", "mocha": "^6.0.2", + "object-hash": "^2.0.3", "parse5": "^5.1.0", "prettier": "^2.0.4", "raw-loader": "^2.0.0", @@ -198,12 +200,15 @@ "lit-html": "^1.1.2", "@material/button": "^5.0.0", "@material/checkbox": "^5.0.0", + "@material/density": "^5.0.0", "@material/dialog": "^5.0.0", "@material/fab": "^5.0.0", + "@material/feature-targeting": "^5.0.0", "@material/switch": "^5.0.0", "@material/ripple": "^5.0.0", "@material/dom": "^5.0.0", - "@material/touch-target": "^5.0.0" + "@material/touch-target": "^5.0.0", + "@material/theme": "^5.0.0" }, "main": "src/home-assistant.js", "husky": { diff --git a/src/common/search/search-input.ts b/src/common/search/search-input.ts index 46f3745335..8b5cfa208f 100644 --- a/src/common/search/search-input.ts +++ b/src/common/search/search-input.ts @@ -1,4 +1,4 @@ -import "@polymer/paper-icon-button/paper-icon-button"; +import "../../components/ha-icon-button"; import "@polymer/paper-input/paper-input"; import { css, @@ -50,14 +50,14 @@ class SearchInput extends LitElement { ${this.filter && html` - + > `} `; diff --git a/src/components/device/ha-area-devices-picker.ts b/src/components/device/ha-area-devices-picker.ts index 907d1ec974..3a0804e637 100644 --- a/src/components/device/ha-area-devices-picker.ts +++ b/src/components/device/ha-area-devices-picker.ts @@ -1,5 +1,5 @@ import "@material/mwc-button/mwc-button"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "../ha-icon-button"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-item"; import "@polymer/paper-item/paper-item-body"; @@ -61,7 +61,7 @@ const rowRenderer = ( margin: -10px 0; padding: 0; } - paper-icon-button { + ha-icon-button { float: right; } .devices { @@ -325,7 +325,7 @@ export class HaAreaDevicesPicker extends SubscribeMixin(LitElement) { > ${this.value ? html` - Clear - + ` : ""} ${areas.length > 0 ? html` - Toggle - + ` : ""} @@ -408,7 +408,7 @@ export class HaAreaDevicesPicker extends SubscribeMixin(LitElement) { static get styles(): CSSResult { return css` - paper-input > paper-icon-button { + paper-input > ha-icon-button { width: 24px; height: 24px; padding: 2px; diff --git a/src/components/device/ha-device-picker.ts b/src/components/device/ha-device-picker.ts index 6d655dc6f1..73686240ec 100644 --- a/src/components/device/ha-device-picker.ts +++ b/src/components/device/ha-device-picker.ts @@ -1,4 +1,4 @@ -import "@polymer/paper-icon-button/paper-icon-button"; +import "../ha-icon-button"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-item"; import "@polymer/paper-item/paper-item-body"; @@ -247,7 +247,7 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) { > ${this.value ? html` - Clear - + ` : ""} ${devices.length > 0 ? html` - Toggle - + ` : ""} @@ -311,9 +311,8 @@ export class HaDevicePicker extends SubscribeMixin(LitElement) { static get styles(): CSSResult { return css` - paper-input > paper-icon-button { - width: 24px; - height: 24px; + paper-input > ha-icon-button { + --mdc-icon-button-size: 24px; padding: 2px; color: var(--secondary-text-color); } diff --git a/src/components/device/ha-devices-picker.ts b/src/components/device/ha-devices-picker.ts index 4f944c4717..4abf6c4eda 100644 --- a/src/components/device/ha-devices-picker.ts +++ b/src/components/device/ha-devices-picker.ts @@ -1,4 +1,3 @@ -import "@polymer/paper-icon-button/paper-icon-button-light"; import { customElement, html, diff --git a/src/components/entity/ha-chart-base.js b/src/components/entity/ha-chart-base.js index e5598b35f7..350ea82c68 100644 --- a/src/components/entity/ha-chart-base.js +++ b/src/components/entity/ha-chart-base.js @@ -1,6 +1,6 @@ /* eslint-plugin-disable lit */ import { IronResizableBehavior } from "@polymer/iron-resizable-behavior/iron-resizable-behavior"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "../ha-icon-button"; import { mixinBehaviors } from "@polymer/polymer/lib/legacy/class"; import { timeOut } from "@polymer/polymer/lib/utils/async"; import { Debouncer } from "@polymer/polymer/lib/utils/debounce"; @@ -107,7 +107,7 @@ class HaChartBase extends mixinBehaviors( margin-right: inherit; margin-left: 4px; } - paper-icon-button { + ha-icon-button { color: var(--secondary-text-color); } diff --git a/src/components/entity/ha-entities-picker.ts b/src/components/entity/ha-entities-picker.ts index 4824bf046e..6f03e48f01 100644 --- a/src/components/entity/ha-entities-picker.ts +++ b/src/components/entity/ha-entities-picker.ts @@ -1,4 +1,3 @@ -import "@polymer/paper-icon-button/paper-icon-button-light"; import type { HassEntity } from "home-assistant-js-websocket"; import { customElement, diff --git a/src/components/entity/ha-entity-picker.ts b/src/components/entity/ha-entity-picker.ts index 3451b7f00f..0cafed4191 100644 --- a/src/components/entity/ha-entity-picker.ts +++ b/src/components/entity/ha-entity-picker.ts @@ -1,4 +1,4 @@ -import "@polymer/paper-icon-button/paper-icon-button"; +import "../ha-icon-button"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-icon-item"; import "@polymer/paper-item/paper-item-body"; @@ -192,7 +192,7 @@ class HaEntityPicker extends LitElement { > ${this.value ? html` - Clear - + ` : ""} - Toggle - + `; @@ -252,9 +252,8 @@ class HaEntityPicker extends LitElement { static get styles(): CSSResult { return css` - paper-input > paper-icon-button { - width: 24px; - height: 24px; + paper-input > ha-icon-button { + --mdc-icon-button-size: 24px; padding: 0px 2px; color: var(--secondary-text-color); } diff --git a/src/components/entity/ha-entity-toggle.ts b/src/components/entity/ha-entity-toggle.ts index 13c269a114..7b19129c7e 100644 --- a/src/components/entity/ha-entity-toggle.ts +++ b/src/components/entity/ha-entity-toggle.ts @@ -1,4 +1,4 @@ -import "@polymer/paper-icon-button/paper-icon-button"; +import "../ha-icon-button"; import { HassEntity } from "home-assistant-js-websocket"; import { css, @@ -37,20 +37,20 @@ class HaEntityToggle extends LitElement { if (this.stateObj.attributes.assumed_state) { return html` - - + + > `; } @@ -144,15 +144,12 @@ class HaEntityToggle extends LitElement { white-space: nowrap; min-width: 38px; } - paper-icon-button { - color: var( - --paper-icon-button-inactive-color, - var(--primary-text-color) - ); + ha-icon-button { + color: var(--ha-icon-button-inactive-color, var(--primary-text-color)); transition: color 0.5s; } - paper-icon-button[state-active] { - color: var(--paper-icon-button-active-color, var(--primary-color)); + ha-icon-button[state-active] { + color: var(--ha-icon-button-active-color, var(--primary-color)); } ha-switch { padding: 13px 5px; diff --git a/src/components/ha-area-picker.ts b/src/components/ha-area-picker.ts index ee891eeccb..77a86a6dae 100644 --- a/src/components/ha-area-picker.ts +++ b/src/components/ha-area-picker.ts @@ -1,4 +1,4 @@ -import "@polymer/paper-icon-button/paper-icon-button"; +import "./ha-icon-button"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-item"; import "@polymer/paper-item/paper-item-body"; @@ -117,7 +117,7 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { > ${this.value ? html` - ${this.hass.localize("ui.components.area-picker.clear")} - + ` : ""} ${this._areas.length > 0 ? html` - ${this.hass.localize("ui.components.area-picker.toggle")} - + ` : ""} @@ -214,9 +214,8 @@ export class HaAreaPicker extends SubscribeMixin(LitElement) { static get styles(): CSSResult { return css` - paper-input > paper-icon-button { - width: 24px; - height: 24px; + paper-input > ha-icon-button { + --mdc-icon-button-size: 24px; padding: 2px; color: var(--secondary-text-color); } diff --git a/src/components/ha-climate-control.js b/src/components/ha-climate-control.js index aba4135cce..399f46d7b1 100644 --- a/src/components/ha-climate-control.js +++ b/src/components/ha-climate-control.js @@ -1,5 +1,5 @@ import "@polymer/iron-flex-layout/iron-flex-layout-classes"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "./ha-icon-button"; import { html } from "@polymer/polymer/lib/utils/html-tag"; /* eslint-plugin-disable lit */ import { PolymerElement } from "@polymer/polymer/polymer-element"; @@ -31,9 +31,8 @@ class HaClimateControl extends EventsMixin(PolymerElement) { font-size: 200%; text-align: right; } - paper-icon-button { - height: 48px; - width: 48px; + ha-icon-button { + --mdc-icon-size: 32px; } @@ -41,16 +40,16 @@ class HaClimateControl extends EventsMixin(PolymerElement) {
    [[value]] [[units]]
    - + >
    - + >
    `; diff --git a/src/components/ha-combo-box.js b/src/components/ha-combo-box.js index bf6450c161..711ad35e6f 100644 --- a/src/components/ha-combo-box.js +++ b/src/components/ha-combo-box.js @@ -1,4 +1,4 @@ -import "@polymer/paper-icon-button/paper-icon-button"; +import "./ha-icon-button"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-item"; import { html } from "@polymer/polymer/lib/utils/html-tag"; @@ -11,7 +11,7 @@ class HaComboBox extends EventsMixin(PolymerElement) { static get template() { return html`
    - - + - + + >
    `; } diff --git a/src/components/ha-cover-tilt-controls.js b/src/components/ha-cover-tilt-controls.js index b3328963ce..e1497fb105 100644 --- a/src/components/ha-cover-tilt-controls.js +++ b/src/components/ha-cover-tilt-controls.js @@ -1,5 +1,5 @@ import "@polymer/iron-flex-layout/iron-flex-layout-classes"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "./ha-icon-button"; import { html } from "@polymer/polymer/lib/utils/html-tag"; /* eslint-plugin-disable lit */ import { PolymerElement } from "@polymer/polymer/polymer-element"; @@ -18,30 +18,30 @@ class HaCoverTiltControls extends PolymerElement { visibility: hidden !important; } - - + - + + > `; } diff --git a/src/components/ha-dialog.ts b/src/components/ha-dialog.ts index f65b9f273b..dadfec76b1 100644 --- a/src/components/ha-dialog.ts +++ b/src/components/ha-dialog.ts @@ -1,7 +1,7 @@ import "@material/mwc-dialog"; import type { Dialog } from "@material/mwc-dialog"; import { style } from "@material/mwc-dialog/mwc-dialog-css"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "./ha-icon-button"; import { css, CSSResult, customElement, html } from "lit-element"; import type { Constructor, HomeAssistant } from "../types"; @@ -9,12 +9,12 @@ const MwcDialog = customElements.get("mwc-dialog") as Constructor; export const createCloseHeading = (hass: HomeAssistant, title: string) => html` ${title} - + > `; @customElement("ha-dialog") diff --git a/src/components/ha-form/ha-form-multi_select.ts b/src/components/ha-form/ha-form-multi_select.ts index 8ef4ed95bf..99fa3e905e 100644 --- a/src/components/ha-form/ha-form-multi_select.ts +++ b/src/components/ha-form/ha-form-multi_select.ts @@ -1,4 +1,3 @@ -import "@polymer/iron-icon/iron-icon"; import "@polymer/paper-checkbox/paper-checkbox"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-icon-item"; @@ -21,6 +20,7 @@ import { HaFormMultiSelectData, HaFormMultiSelectSchema, } from "./ha-form"; +import "../ha-icon"; @customElement("ha-form-multi_select") export class HaFormMultiSelect extends LitElement implements HaFormElement { @@ -64,11 +64,11 @@ export class HaFormMultiSelect extends LitElement implements HaFormElement { input-aria-haspopup="listbox" autocomplete="off" > - + >

    - - + ` : html` diff --git a/src/components/ha-icon-button-arrow-next.ts b/src/components/ha-icon-button-arrow-next.ts new file mode 100644 index 0000000000..269b7792a5 --- /dev/null +++ b/src/components/ha-icon-button-arrow-next.ts @@ -0,0 +1,23 @@ +import { HaIconButton } from "./ha-icon-button"; + +export class HaIconButtonArrowNext extends HaIconButton { + public connectedCallback() { + super.connectedCallback(); + + // wait to check for direction since otherwise direction is wrong even though top level is RTL + setTimeout(() => { + this.icon = + window.getComputedStyle(this).direction === "ltr" + ? "hass:arrow-right" + : "hass:arrow-left"; + }, 100); + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-icon-button-arrow-next": HaIconButtonArrowNext; + } +} + +customElements.define("ha-icon-button-arrow-next", HaIconButtonArrowNext); diff --git a/src/components/ha-icon-button-arrow-prev.ts b/src/components/ha-icon-button-arrow-prev.ts new file mode 100644 index 0000000000..c9d47a0f02 --- /dev/null +++ b/src/components/ha-icon-button-arrow-prev.ts @@ -0,0 +1,23 @@ +import { HaIconButton } from "./ha-icon-button"; + +export class HaIconButtonArrowPrev extends HaIconButton { + public connectedCallback() { + super.connectedCallback(); + + // wait to check for direction since otherwise direction is wrong even though top level is RTL + setTimeout(() => { + this.icon = + window.getComputedStyle(this).direction === "ltr" + ? "hass:arrow-left" + : "hass:arrow-right"; + }, 100); + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-icon-button-arrow-prev": HaIconButtonArrowPrev; + } +} + +customElements.define("ha-icon-button-arrow-prev", HaIconButtonArrowPrev); diff --git a/src/components/ha-icon-button-next.ts b/src/components/ha-icon-button-next.ts new file mode 100644 index 0000000000..68bfa5004c --- /dev/null +++ b/src/components/ha-icon-button-next.ts @@ -0,0 +1,23 @@ +import { HaIconButton } from "./ha-icon-button"; + +export class HaIconButtonNext extends HaIconButton { + public connectedCallback() { + super.connectedCallback(); + + // wait to check for direction since otherwise direction is wrong even though top level is RTL + setTimeout(() => { + this.icon = + window.getComputedStyle(this).direction === "ltr" + ? "hass:chevron-right" + : "hass:chevron-left"; + }, 100); + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-icon-button-next": HaIconButtonNext; + } +} + +customElements.define("ha-icon-button-next", HaIconButtonNext); diff --git a/src/components/ha-icon-button-prev.ts b/src/components/ha-icon-button-prev.ts new file mode 100644 index 0000000000..675719fc6e --- /dev/null +++ b/src/components/ha-icon-button-prev.ts @@ -0,0 +1,23 @@ +import { HaIconButton } from "./ha-icon-button"; + +export class HaIconButtonPrev extends HaIconButton { + public connectedCallback() { + super.connectedCallback(); + + // wait to check for direction since otherwise direction is wrong even though top level is RTL + setTimeout(() => { + this.icon = + window.getComputedStyle(this).direction === "ltr" + ? "hass:chevron-left" + : "hass:chevron-right"; + }, 100); + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-icon-button-prev": HaIconButtonPrev; + } +} + +customElements.define("ha-icon-button-prev", HaIconButtonPrev); diff --git a/src/components/ha-icon-button.ts b/src/components/ha-icon-button.ts new file mode 100644 index 0000000000..d1e9d46979 --- /dev/null +++ b/src/components/ha-icon-button.ts @@ -0,0 +1,56 @@ +import "@material/mwc-icon-button"; +import { + customElement, + html, + TemplateResult, + property, + LitElement, + CSSResult, + css, +} from "lit-element"; +import "./ha-icon"; + +@customElement("ha-icon-button") +export class HaIconButton extends LitElement { + @property({ type: Boolean, reflect: true }) disabled = false; + + @property({ type: String }) icon = ""; + + @property({ type: String }) label = ""; + + protected render(): TemplateResult { + return html` + + + + `; + } + + private _handleClick(ev) { + if (this.disabled) { + ev.stopPropagation(); + } + } + + static get styles(): CSSResult { + return css` + :host { + display: inline-block; + } + ha-icon { + display: inline-flex; + vertical-align: initial; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "ha-icon-button": HaIconButton; + } +} diff --git a/src/components/ha-icon-next.ts b/src/components/ha-icon-next.ts index f1c216450f..742f342e91 100644 --- a/src/components/ha-icon-next.ts +++ b/src/components/ha-icon-next.ts @@ -1,18 +1,16 @@ -import "@polymer/iron-icon/iron-icon"; -// Not duplicate, this is for typing. -// eslint-disable-next-line -import { HaIcon } from "./ha-icon"; +import { HaSvgIcon } from "./ha-svg-icon"; +import { mdiChevronRight, mdiChevronLeft } from "@mdi/js"; -export class HaIconNext extends HaIcon { +export class HaIconNext extends HaSvgIcon { public connectedCallback() { super.connectedCallback(); // wait to check for direction since otherwise direction is wrong even though top level is RTL setTimeout(() => { - this.icon = + this.path = window.getComputedStyle(this).direction === "ltr" - ? "hass:chevron-right" - : "hass:chevron-left"; + ? mdiChevronRight + : mdiChevronLeft; }, 100); } } diff --git a/src/components/ha-icon-prev.ts b/src/components/ha-icon-prev.ts index 1d896882d7..df800fd52d 100644 --- a/src/components/ha-icon-prev.ts +++ b/src/components/ha-icon-prev.ts @@ -1,18 +1,16 @@ -import "@polymer/iron-icon/iron-icon"; -// Not duplicate, this is for typing. -// eslint-disable-next-line -import { HaIcon } from "./ha-icon"; +import { HaSvgIcon } from "./ha-svg-icon"; +import { mdiChevronRight, mdiChevronLeft } from "@mdi/js"; -export class HaIconPrev extends HaIcon { +export class HaIconPrev extends HaSvgIcon { public connectedCallback() { super.connectedCallback(); // wait to check for direction since otherwise direction is wrong even though top level is RTL setTimeout(() => { - this.icon = + this.path = window.getComputedStyle(this).direction === "ltr" - ? "hass:chevron-left" - : "hass:chevron-right"; + ? mdiChevronLeft + : mdiChevronRight; }, 100); } } diff --git a/src/components/ha-icon.ts b/src/components/ha-icon.ts index a707af0dc4..7d4b31d1e0 100644 --- a/src/components/ha-icon.ts +++ b/src/components/ha-icon.ts @@ -1,34 +1,133 @@ import "@polymer/iron-icon/iron-icon"; -import type { IronIconElement } from "@polymer/iron-icon/iron-icon"; -import { Constructor } from "../types"; +import { get, Store } from "idb-keyval"; +import { + customElement, + LitElement, + property, + PropertyValues, + html, + TemplateResult, + css, + CSSResult, +} from "lit-element"; +import "./ha-svg-icon"; +import { debounce } from "../common/util/debounce"; +import { iconMetadata } from "../resources/icon-metadata"; +import { IconMetadata } from "../types"; -const ironIconClass = customElements.get("iron-icon") as Constructor< - IronIconElement ->; - -let loaded = false; - -export class HaIcon extends ironIconClass { - private _iconsetName?: string; - - public listen( - node: EventTarget | null, - eventName: string, - methodName: string - ): void { - super.listen(node, eventName, methodName); - - if (!loaded && this._iconsetName === "mdi") { - loaded = true; - import(/* webpackChunkName: "mdi-icons" */ "../resources/mdi-icons"); - } - } +interface Icons { + [key: string]: string; } +interface Chunks { + [key: string]: Promise; +} + +const iconStore = new Store("hass-icon-db", "mdi-icon-store"); +const chunks: Chunks = {}; +const MDI_PREFIXES = ["mdi", "hass", "hassio"]; + +const findIconChunk = (icon): string => { + let lastChunk: IconMetadata; + for (const chunk of iconMetadata) { + if (chunk.start !== undefined && icon < chunk.start) { + break; + } + lastChunk = chunk; + } + return lastChunk!.file; +}; + +const debouncedWriteCache = debounce(async () => { + const keys = Object.keys(chunks); + const iconsSets: Icons[] = await Promise.all(Object.values(chunks)); + // We do a batch opening the store just once, for (considerable) performance + iconStore._withIDBStore("readwrite", (store) => { + iconsSets.forEach((icons, idx) => { + Object.entries(icons).forEach(([name, path]) => { + store.put(path, name); + }); + delete chunks[keys[idx]]; + }); + }); +}, 2000); + +@customElement("ha-icon") +export class HaIcon extends LitElement { + @property() public icon?: string; + + @property() private _path?: string; + + @property() private _noMdi = false; + + protected updated(changedProps: PropertyValues) { + if (changedProps.has("icon")) { + this._loadIcon(); + } + } + + protected render(): TemplateResult { + if (!this.icon) { + return html``; + } + if (this._noMdi) { + return html``; + } + return html``; + } + + private async _loadIcon() { + if (!this.icon) { + return; + } + const icon = this.icon.split(":", 2); + if (!MDI_PREFIXES.includes(icon[0])) { + this._noMdi = true; + return; + } + + this._noMdi = false; + + const iconName = icon[1]; + const cachedPath: string = await get(iconName, iconStore); + if (cachedPath) { + this._path = cachedPath; + return; + } + const chunk = findIconChunk(iconName); + + if (chunk in chunks) { + this._setPath(chunks[chunk], iconName); + return; + } + const iconPromise = fetch(`/static/mdi/${chunk}.json`).then((response) => + response.json() + ); + chunks[chunk] = iconPromise; + this._setPath(iconPromise, iconName); + debouncedWriteCache(); + } + + private async _setPath(promise: Promise, iconName: string) { + const iconPack = await promise; + this._path = iconPack[iconName]; + } + + static get styles(): CSSResult { + return css` + :host { + display: inline-flex; + align-items: center; + justify-content: center; + position: relative; + vertical-align: middle; + fill: currentcolor; + } + `; + } +} declare global { interface HTMLElementTagNameMap { "ha-icon": HaIcon; } } - -customElements.define("ha-icon", HaIcon); diff --git a/src/components/ha-iconset-svg.js b/src/components/ha-iconset-svg.js deleted file mode 100644 index ae2b414a25..0000000000 --- a/src/components/ha-iconset-svg.js +++ /dev/null @@ -1,33 +0,0 @@ -import "@polymer/iron-iconset-svg/iron-iconset-svg"; - -const IronIconsetClass = customElements.get("iron-iconset-svg"); - -class HaIconset extends IronIconsetClass { - /** - * Fire 'iron-iconset-added' event at next microtask. - */ - _fireIronIconsetAdded() { - this.async(() => this.fire("iron-iconset-added", this, { node: window })); - } - - /** - * - * When name is changed, register iconset metadata - * - */ - _nameChanged() { - this._meta.value = null; - this._meta.key = this.name; - this._meta.value = this; - if (this.ownerDocument && this.ownerDocument.readyState === "loading") { - // Document still loading. It could be that not all icons in the iconset are parsed yet. - this.ownerDocument.addEventListener("DOMContentLoaded", () => { - this._fireIronIconsetAdded(); - }); - } else { - this._fireIronIconsetAdded(); - } - } -} - -customElements.define("ha-iconset-svg", HaIconset); diff --git a/src/components/ha-menu-button.ts b/src/components/ha-menu-button.ts index 239bfd7e9f..0111cdef2c 100644 --- a/src/components/ha-menu-button.ts +++ b/src/components/ha-menu-button.ts @@ -1,4 +1,3 @@ -import "@polymer/paper-icon-button/paper-icon-button"; import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { css, @@ -13,6 +12,7 @@ import { fireEvent } from "../common/dom/fire_event"; import { computeDomain } from "../common/entity/compute_domain"; import { subscribeNotifications } from "../data/persistent_notification"; import { HomeAssistant } from "../types"; +import "./ha-icon-button"; @customElement("ha-menu-button") class HaMenuButton extends LitElement { @@ -55,11 +55,11 @@ class HaMenuButton extends LitElement { (entityId) => computeDomain(entityId) === "configurator" )); return html` - + > ${hasNotifications ? html`
    ` : ""} `; } diff --git a/src/components/ha-paper-icon-button-arrow-next.ts b/src/components/ha-paper-icon-button-arrow-next.ts deleted file mode 100644 index 99cbd85ad8..0000000000 --- a/src/components/ha-paper-icon-button-arrow-next.ts +++ /dev/null @@ -1,32 +0,0 @@ -import "@polymer/paper-icon-button/paper-icon-button"; -import type { PaperIconButtonElement } from "@polymer/paper-icon-button/paper-icon-button"; -import type { Constructor } from "../types"; - -const paperIconButtonClass = customElements.get( - "paper-icon-button" -) as Constructor; - -export class HaPaperIconButtonArrowNext extends paperIconButtonClass { - public connectedCallback() { - super.connectedCallback(); - - // wait to check for direction since otherwise direction is wrong even though top level is RTL - setTimeout(() => { - this.icon = - window.getComputedStyle(this).direction === "ltr" - ? "hass:arrow-right" - : "hass:arrow-left"; - }, 100); - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-paper-icon-button-arrow-next": HaPaperIconButtonArrowNext; - } -} - -customElements.define( - "ha-paper-icon-button-arrow-next", - HaPaperIconButtonArrowNext -); diff --git a/src/components/ha-paper-icon-button-arrow-prev.ts b/src/components/ha-paper-icon-button-arrow-prev.ts deleted file mode 100644 index 7fe19dea59..0000000000 --- a/src/components/ha-paper-icon-button-arrow-prev.ts +++ /dev/null @@ -1,38 +0,0 @@ -import "@polymer/paper-icon-button/paper-icon-button"; -import type { PaperIconButtonElement } from "@polymer/paper-icon-button/paper-icon-button"; -import type { Constructor } from "../types"; - -const paperIconButtonClass = customElements.get( - "paper-icon-button" -) as Constructor; - -export class HaPaperIconButtonArrowPrev extends paperIconButtonClass { - public hassio?: boolean; - - public connectedCallback() { - super.connectedCallback(); - - // wait to check for direction since otherwise direction is wrong even though top level is RTL - setTimeout(() => { - this.icon = - window.getComputedStyle(this).direction === "ltr" - ? this.hassio - ? "hassio:arrow-left" - : "hass:arrow-left" - : this.hassio - ? "hassio:arrow-right" - : "hass:arrow-right"; - }, 100); - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-paper-icon-button-arrow-prev": HaPaperIconButtonArrowPrev; - } -} - -customElements.define( - "ha-paper-icon-button-arrow-prev", - HaPaperIconButtonArrowPrev -); diff --git a/src/components/ha-paper-icon-button-next.ts b/src/components/ha-paper-icon-button-next.ts deleted file mode 100644 index e119c7f4ce..0000000000 --- a/src/components/ha-paper-icon-button-next.ts +++ /dev/null @@ -1,29 +0,0 @@ -import "@polymer/paper-icon-button/paper-icon-button"; -import type { PaperIconButtonElement } from "@polymer/paper-icon-button/paper-icon-button"; -import type { Constructor } from "../types"; - -const paperIconButtonClass = customElements.get( - "paper-icon-button" -) as Constructor; - -export class HaPaperIconButtonNext extends paperIconButtonClass { - public connectedCallback() { - super.connectedCallback(); - - // wait to check for direction since otherwise direction is wrong even though top level is RTL - setTimeout(() => { - this.icon = - window.getComputedStyle(this).direction === "ltr" - ? "hass:chevron-right" - : "hass:chevron-left"; - }, 100); - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-paper-icon-button-next": HaPaperIconButtonNext; - } -} - -customElements.define("ha-paper-icon-button-next", HaPaperIconButtonNext); diff --git a/src/components/ha-paper-icon-button-prev.ts b/src/components/ha-paper-icon-button-prev.ts deleted file mode 100644 index b2567f6c5f..0000000000 --- a/src/components/ha-paper-icon-button-prev.ts +++ /dev/null @@ -1,29 +0,0 @@ -import "@polymer/paper-icon-button/paper-icon-button"; -import type { PaperIconButtonElement } from "@polymer/paper-icon-button/paper-icon-button"; -import type { Constructor } from "../types"; - -const paperIconButtonClass = customElements.get( - "paper-icon-button" -) as Constructor; - -export class HaPaperIconButtonPrev extends paperIconButtonClass { - public connectedCallback() { - super.connectedCallback(); - - // wait to check for direction since otherwise direction is wrong even though top level is RTL - setTimeout(() => { - this.icon = - window.getComputedStyle(this).direction === "ltr" - ? "hass:chevron-left" - : "hass:chevron-right"; - }, 100); - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-paper-icon-button-prev": HaPaperIconButtonPrev; - } -} - -customElements.define("ha-paper-icon-button-prev", HaPaperIconButtonPrev); diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts index e3ba42aa8c..8702bdae91 100644 --- a/src/components/ha-sidebar.ts +++ b/src/components/ha-sidebar.ts @@ -1,5 +1,6 @@ +import { mdiBell, mdiCellphoneSettingsVariant } from "@mdi/js"; import "@polymer/app-layout/app-toolbar/app-toolbar"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "./ha-icon-button"; import "@polymer/paper-item/paper-icon-item"; import type { PaperIconItemElement } from "@polymer/paper-item/paper-icon-item"; import "@polymer/paper-item/paper-item"; @@ -28,6 +29,7 @@ import { getExternalConfig, } from "../external_app/external_config"; import type { HomeAssistant, PanelInfo } from "../types"; +import "./ha-svg-icon"; import "./ha-icon"; import "./ha-menu-button"; import "./user/ha-user-badge"; @@ -151,13 +153,13 @@ class HaSidebar extends LitElement { diff --git a/src/dialogs/more-info/controls/more-info-light.js b/src/dialogs/more-info/controls/more-info-light.js index cc7590c197..83a0abf115 100644 --- a/src/dialogs/more-info/controls/more-info-light.js +++ b/src/dialogs/more-info/controls/more-info-light.js @@ -11,6 +11,7 @@ import "../../../components/ha-labeled-slider"; import "../../../components/ha-paper-dropdown-menu"; import { EventsMixin } from "../../../mixins/events-mixin"; import LocalizeMixin from "../../../mixins/localize-mixin"; +import "../../../components/ha-icon-button"; const FEATURE_CLASS_NAMES = { 1: "has-brightness", @@ -168,11 +169,11 @@ class MoreInfoLight extends LocalizeMixin(EventsMixin(PolymerElement)) { saturation-segments="{{saturationSegments}}" > - + >
diff --git a/src/dialogs/more-info/controls/more-info-media_player.js b/src/dialogs/more-info/controls/more-info-media_player.js index 0dbf26764f..d2643b2833 100644 --- a/src/dialogs/more-info/controls/more-info-media_player.js +++ b/src/dialogs/more-info/controls/more-info-media_player.js @@ -1,6 +1,5 @@ import "@polymer/iron-flex-layout/iron-flex-layout-classes"; -import "@polymer/iron-icon/iron-icon"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "../../../components/ha-icon-button"; import "@polymer/paper-item/paper-item"; import "@polymer/paper-listbox/paper-listbox"; import { html } from "@polymer/polymer/lib/utils/html-tag"; @@ -11,6 +10,7 @@ import { attributeClassNames } from "../../../common/entity/attribute_class_name import { computeRTLDirection } from "../../../common/util/compute_rtl"; import "../../../components/ha-paper-dropdown-menu"; import "../../../components/ha-paper-slider"; +import "../../../components/ha-icon"; import { EventsMixin } from "../../../mixins/events-mixin"; import LocalizeMixin from "../../../mixins/localize-mixin"; import HassMediaPlayerEntity from "../../../util/hass-media-player-model"; @@ -28,7 +28,7 @@ class MoreInfoMediaPlayer extends LocalizeMixin(EventsMixin(PolymerElement)) { text-transform: capitalize; } - paper-icon-button[highlight] { + ha-icon-button[highlight] { color: var(--accent-color); } @@ -44,7 +44,7 @@ class MoreInfoMediaPlayer extends LocalizeMixin(EventsMixin(PolymerElement)) { max-height: 40px; } - iron-icon.source-input { + ha-icon.source-input { padding: 7px; margin-top: 15px; } @@ -65,34 +65,34 @@ class MoreInfoMediaPlayer extends LocalizeMixin(EventsMixin(PolymerElement)) {
- + >
@@ -101,36 +101,36 @@ class MoreInfoMediaPlayer extends LocalizeMixin(EventsMixin(PolymerElement)) { class="volume_buttons center horizontal layout" hidden$="[[computeHideVolumeButtons(playerObj)]]" > - - + - + + >
- + > - + diff --git a/src/panels/shopping-list/ha-panel-shopping-list.js b/src/panels/shopping-list/ha-panel-shopping-list.js index 6be4c26bff..791b516864 100644 --- a/src/panels/shopping-list/ha-panel-shopping-list.js +++ b/src/panels/shopping-list/ha-panel-shopping-list.js @@ -2,7 +2,7 @@ import "@polymer/app-layout/app-header-layout/app-header-layout"; import "@polymer/app-layout/app-header/app-header"; import "@polymer/app-layout/app-toolbar/app-toolbar"; import "@polymer/paper-checkbox/paper-checkbox"; -import "@polymer/paper-icon-button/paper-icon-button"; +import "../../components/ha-icon-button"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-item/paper-icon-item"; import "@polymer/paper-item/paper-item"; @@ -74,22 +74,22 @@ class HaPanelShoppingList extends LocalizeMixin(PolymerElement) { >
[[localize('panel.shopping_list')]]
- + > - + > [[localize('ui.panel.shopping-list.clear_completed')]] - + > = 2.1.2 < 3" +idb-keyval@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-3.2.0.tgz#cbbf354deb5684b6cdc84376294fc05932845bd6" + integrity sha512-slx8Q6oywCCSfKgPgL0sEsXtPVnSbTLWpyiDcu6msHOyKOLari1TD1qocXVCft80umnkk3/Qqh3lwoFt8T/BPQ== + ieee754@^1.1.4: version "1.1.13" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" @@ -10746,6 +10780,11 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-hash@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea" + integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg== + object-inspect@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"