diff --git a/README.md b/README.md index 1ab27b7..0defa03 100644 --- a/README.md +++ b/README.md @@ -1 +1,15 @@ -# tp-element +# tp-avatar + +A custom element for displaying avatars. + +## Installation + +```bash +npm i @tp/tp-avatar +``` + +## Usage + +```html + +``` diff --git a/package.json b/package.json index 24f0225..80a1ca7 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,14 @@ { - "name": "@tp/tp-element", - "version": "0.0.1", + "name": "@tp/tp-avatar", + "version": "1.0.0", "description": "", - "main": "tp-element.js", + "main": "tp-avatar.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { "type": "git", - "url": "https://gitea.codeblob.work/tp-elements/tp-element.git" + "url": "https://gitea.codeblob.work/tp-elements/tp-avatar.git" }, "author": "trading_peter", "license": "Apache-2.0", diff --git a/tp-avatar.js b/tp-avatar.js new file mode 100644 index 0000000..5e2cd9b --- /dev/null +++ b/tp-avatar.js @@ -0,0 +1,128 @@ +/** +@license +Copyright (c) 2024 trading_peter +This program is available under Apache License Version 2.0 +*/ + +import '@tp/tp-icon/tp-icon.js'; +import { LitElement, html, css, svg } from 'lit'; +import { classMap } from 'lit/directives/class-map.js'; + +class EfAvatar extends LitElement { + static get styles() { + return [ + css` + :host { + display: inline-block; + position: relative; + border-radius: 50%; + } + + :host [hidden] { + display: none; + } + + #avatarImg { + width: var(--era-avatar-size, 32px); + height: var(--era-avatar-size, 32px); + background-size: cover; + background-position: center center; + border-radius: 50%; + opacity: 0; + } + + #avatarImg.visible { + transition: opacity 300ms; + opacity: 1; + } + + tp-icon { + opacity: 1; + transition: opacity 100ms; + color: #BDBDBD; + + position: absolute; + inset: 0; + --tp-icon-height: var(--ef-avatar-size, 32px); + --tp-icon-width: var(--ef-avatar-size, 32px); + } + + tp-icon.hidden { + opacity: 0; + transition: opacity 300ms linear 0ms; + } + ` + ]; + } + + render() { + const { loaded, hasSrc } = this; + + return html` +
+ + `; + } + + static get properties() { + return { + loaded: { type: Boolean }, + baseUrl: { type: String }, + loading: { type: Boolean }, + hasSrc: { type: Boolean }, + src: { type: String }, + }; + } + + static get defaultAccountIcon() { + return svg``; + } + + updated(changes) { + if (changes.has('src')) { + if (!this.src) { + this.hasSrc = false; + return; + } + + if (this.src !== changes.get('src')) { + this.hasSrc = true; + + if (newSrc.indexOf(this.baseUrl) !== 0 && !this.hasSchema(newSrc)) { + this.src = this.baseUrl + this.src; + return; + } + + this.loaded = false; + if (Boolean(newSrc)) { + this.loadImage(); + } + } + } + } + + hasSchema(src) { + return src.indexOf('http://') === 0 || src.indexOf('https://') === 0; + } + + loadedChanged() { + if (this.loaded) { + this.$.avatarImg.style.backgroundImage = `url("${this.src}")`; + } + } + + loadImage() { + var img = new Image(); + img.src = this.src; + + this.loading = true; + + img.onload = function() { + this.loading = false; + this.loaded = true; + this.loadedChanged(); + }.bind(this); + } +} + +window.customElements.define('ef-avatar', EfAvatar); diff --git a/tp-element.js b/tp-element.js deleted file mode 100644 index 6195006..0000000 --- a/tp-element.js +++ /dev/null @@ -1,35 +0,0 @@ -/** -@license -Copyright (c) 2024 trading_peter -This program is available under Apache License Version 2.0 -*/ - -import { LitElement, html, css } from 'lit'; - -class TpElement extends LitElement { - static get styles() { - return [ - css` - :host { - display: block; - } - ` - ]; - } - - render() { - const { } = this; - - return html` - - `; - } - - static get properties() { - return { }; - } - - -} - -window.customElements.define('tp-element', TpElement);