Skip to content

Instantly share code, notes, and snippets.

@rianadon
Last active August 10, 2023 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save rianadon/83a341fbbf94c7dedd60d7f58b6d84e0 to your computer and use it in GitHub Desktop.
Save rianadon/83a341fbbf94c7dedd60d7f58b6d84e0 to your computer and use it in GitHub Desktop.
Multicolor Icons for Home Assistant
// This is likely the hackiest code you'll see for a long time.
// Good luck writing anything worse than this.
// Icons are multicolorized by overwriting the render method of the <ha-svg-icon> component with an edited version.
// When this edited version sees an icon it recognizes, it returns a special multicolored path instead.
// The --accent-color and --primary-color variables are used to add the extra color
// Because this module loads as a custom component, it can only affect what's changed after it loads.
// That's right. CAVEAT: THIS ONLY WORKS ON CUSTOM COMPONENTS. And maybe even only some custom components.
// But only a Sith deals in absolutes. 1 in 20 times I have seen this affect Home Assistant components.
// I have no idea what determines the order in which things load. Maybe it's alphabetical? By file size?
// I wouldn't even bet a dollar on it.
// Well maybe a dollar would be alright ... But DO NOT EXPECT THIS TO BE RELIABLE.
// I warned you.
// And if you are a developer of Home Assistant are are rightfully cursing at me right now,
// I sadly don't have anything to say to you. I'm not sorry. This was fun. Maybe one day we'll
// officially have multicolor icons. Wouldn't that be nice?
// Defining the svg function from lit right here because, well..., it was easier than setting up npm.
const svg = (strings, ...values) => ({
_$litType$: 2,
strings,
values,
});
// You can add more icons here.
const replacements = {
'M10 10H14V22H10V10M7 9H9V7H7V9M4 8H6V6H4V8M4 11H6V9H4V11M1 13H3V11H1V13M1 7H3V5H1V7M1 10H3V8H1V10M18 11H20V9H18V11M21 10H23V8H21V10M21 5V7H23V5H21M21 13H23V11H21V13M15 9H17V7H15V9M18 8H20V6H18V8M10 7H10.33L11 9H13L13.67 7H14V6H10V7Z': svg`<path d="M10 10H14V22H10V10"/><path fill="var(--accent-color)" d="M7 9H9V7H7V9M4 8H6V6H4V8M4 11H6V9H4V11M1 13H3V11H1V13M1 7H3V5H1V7M1 10H3V8H1V10M18 11H20V9H18V11M21 10H23V8H21V10M21 5V7H23V5H21M21 13H23V11H21V13M15 9H17V7H15V9M18 8H20V6H18V8"/><path fill="var(--primary-color)" d="M10 7H10.33L11 9H13L13.67 7H14V6H10V7Z"/>`,
};
// CustomElementRegistry.get() is experimental according to MDN. Sounds like the perfect function to call!
const iconConstructor = customElements.get('ha-svg-icon');
// Here's the magic code smoke!
iconConstructor.prototype.render = function() {
let path = "";
if (this.path) path = replacements[this.path] || svg`<path d=${this.path}></path>`;
return svg`
<svg
viewBox=${this.viewBox || "0 0 24 24"}
preserveAspectRatio="xMidYMid meet"
focusable="false">
<g>${path}</g>
</svg>`;
}

Download and copy multicolor-icons.js to your config/www folder. Then add /local/multicolor-icons.js to your Lovelace resources like any other frontend extension (either through resources in yaml or the advanced configuration -> lovelace -> resources gui). That's all!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment