import {choose} from 'lit/directives/choose.js'; import {classMap} from "lit/directives/class-map.js"; import {type CSSResultGroup, html, render, unsafeCSS} from 'lit'; import {md5} from '../../utilities/md5'; import {property} from 'lit/decorators.js'; import {styleMap} from "lit/directives/style-map.js"; import ZincElement from '../../internal/zinc-element'; import styles from './icon.scss'; type IconLibrary = "src" | "material" | "material-outlined" | "material-round" | "material-sharp" | "material-two-tone" | "material-symbols-outlined" | "gravatar" | "libravatar" | "avatar" | "brands" | "line"; export type IconColor = "default" | "primary" | "accent" | "info" | "warning" | "error" | "success" | "white" | "disabled" | "red" | "blue" | "green" | "orange" | "yellow" | "indigo" | "violet" | "pink" | "grey" | (string & {}); /** * @summary Short summary of the component's intended use. * @documentation https://zinc.style/components/icon * @status experimental * @since 1.0 * * @dependency zn-example * * @event zn-event-name - Emitted as an example. * * @slot - The default slot. * @slot example - An example slot. * * @csspart base - The component's base wrapper. * * @cssproperty --example - An example CSS custom property. */ export default class ZnIcon extends ZincElement { static styles: CSSResultGroup = unsafeCSS(styles); @property({reflect: true}) src: string; @property({reflect: true}) alt: string; @property({type: Number, reflect: true}) size: number = 24; @property({type: Boolean, reflect: true}) round = false; @property({type: Boolean, reflect: true}) tile = false; @property({type: Boolean, reflect: true}) depth = false; @property({reflect: true}) library: IconLibrary; @property({reflect: true}) color: IconColor; @property({type: Boolean}) padded: boolean = false; @property({type: Boolean}) blink: boolean = false; @property({type: Boolean}) squared: boolean = false; private static readonly presetColors = new Set([ 'default', 'primary', 'accent', 'info', 'warning', 'error', 'success', 'white', 'disabled', 'red', 'blue', 'green', 'orange', 'yellow', 'indigo', 'violet', 'pink', 'grey', ]); private isPresetColor(color: string): boolean { return ZnIcon.presetColors.has(color); } gravatarOptions = ""; defaultLibrary: IconLibrary = "material-symbols-outlined"; convertToLibrary(input: string): IconLibrary { switch (input) { case "material": case "mat": case "m": return "material"; case "material-outlined": case "mo": return "material-outlined"; case "material-round": case "mr": return "material-round"; case "material-sharp": case "ms": return "material-sharp"; case "material-two-tone": case "mt": case "m2": return "material-two-tone"; case "material-symbols-outlined": case "mso": return "material-symbols-outlined"; case "gravatar": case "grav": return "gravatar"; case "libravatar": return "libravatar"; case "avatar": case "av": return "avatar"; case "line": return "line"; case 'brand': case 'brands': return "brands"; } return this.defaultLibrary } connectedCallback() { super.connectedCallback(); if (this.src && this.src.includes('#')) { const split = this.src.split('#'); this.src = split[0]; const attributes = split[1].split(','); attributes.forEach(attr => { if (attr === "round") { this.round = true; } if (attr === "tile") { this.tile = true; } if (attr === "depth") { this.depth = true; } }); } if (this.src && this.src.includes('@')) { const split = this.src.split('@'); if (split[1].includes('.')) { this.library = "gravatar"; } else if ((this.library === undefined) && split[1] !== "") { // if split[1] is a valid library name, set it this.library = this.convertToLibrary(split[1]); this.src = split[0]; } if (this.library === "gravatar" || this.library === "libravatar") { this.ravatarOptions(); this.src = md5(this.src); } } else if (!this.library && this.src && !this.src.includes('/')) { this.library = this.defaultLibrary; } // load the material icons font if the library is set to material render(html` `, document.head); this.ravatarOptions(); } ravatarOptions() { if ((this.library === "gravatar" || this.library === "libravatar") && this.src.includes('#')) { const split = this.src.split('#'); this.gravatarOptions = "&d=" + split[1]; this.src = split[0]; } } render() { return html`