Last active
June 11, 2025 09:11
-
-
Save andrioid/2fbc52d5a0e72c8cfbee5d273df087ee to your computer and use it in GitHub Desktop.
svg-icon.mjs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** | |
| * Usage, import as module and use like <svg-icon href="/icons/icon.svg#icon></svg-icon>. | |
| * Note: Due to browser quirks, the icon file requires a top-level id for the fragment. Otherwise it wont work in Firefox. | |
| */ | |
| class IconElement extends HTMLElement { | |
| constructor() { | |
| super(); | |
| this._href = "" | |
| } | |
| static get observedAttributes() { | |
| return ['href']; | |
| } | |
| // lucide question mark document | |
| defaultIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M12 17h.01M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7z"/><path d="M9.1 9a3 3 0 0 1 5.82 1c0 2-3 3-3 3"/></g></svg>` | |
| connectedCallback() { | |
| this._href = this.getAttribute('href') ?? "" | |
| this.render() | |
| } | |
| attributeChangedCallback(name, oldVal, newVal) { | |
| if (oldVal === newVal) return | |
| switch (name) { | |
| case 'href': | |
| if (typeof newVal === "string" && !newVal.match(/#.*$/)) { | |
| console.warn("svg-icon cannot render. 'href' must include a fragment (e.g. icon.svg#icon) and it must exist inside your icon") | |
| console.debug("Firefox does not support root element references") | |
| this._href = ""; | |
| this.render() | |
| return; | |
| } | |
| this._href = newVal | |
| this.render() | |
| break; | |
| } | |
| } | |
| render() { | |
| let rendering = `<svg height="1em" viewbox="0 0 24 24">` | |
| if (this._href !== "") { | |
| rendering += `<use width="100%" height="100%" href="${this._href}"></use>` | |
| } else { | |
| rendering += this.defaultIcon | |
| } | |
| rendering += `</svg>` | |
| this.innerHTML = rendering; | |
| } | |
| } | |
| customElements.define("svg-icon", IconElement) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment