set img src based on element width
This commit is contained in:
@@ -1,6 +1,17 @@
|
||||
import type { UmbUserKindType } from '../../utils/index.js';
|
||||
import { UmbUserKind } from '../../utils/index.js';
|
||||
import { css, html, customElement, property, ifDefined, state, classMap } from '@umbraco-cms/backoffice/external/lit';
|
||||
import type { UUIAvatarElement } from '@umbraco-cms/backoffice/external/uui';
|
||||
import type { PropertyValues } from '@umbraco-cms/backoffice/external/lit';
|
||||
import {
|
||||
css,
|
||||
html,
|
||||
customElement,
|
||||
property,
|
||||
ifDefined,
|
||||
state,
|
||||
classMap,
|
||||
query,
|
||||
} from '@umbraco-cms/backoffice/external/lit';
|
||||
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
|
||||
|
||||
const elementName = 'umb-user-avatar';
|
||||
@@ -18,45 +29,76 @@ export class UmbUserAvatarElement extends UmbLitElement {
|
||||
}
|
||||
public set imgUrls(value: Array<string>) {
|
||||
this.#imgUrls = value;
|
||||
this.#setUrls();
|
||||
this.hasImgUrls = value.length > 0;
|
||||
this.#setImgSrcSizes();
|
||||
}
|
||||
#imgUrls: Array<string> = [];
|
||||
|
||||
@state()
|
||||
private _imgSrc: Array<{ scale: string; url: string }> = [];
|
||||
private _imgSrcSizes: Array<{ w: number; url: string }> = [];
|
||||
|
||||
@state()
|
||||
private _imbSrcSet = '';
|
||||
private _imgSrc = '';
|
||||
|
||||
@state()
|
||||
private hasImgUrls = false;
|
||||
|
||||
#setUrls() {
|
||||
this._imbSrcSet = '';
|
||||
@query('uui-avatar')
|
||||
avatarElement!: UUIAvatarElement;
|
||||
|
||||
#setImgSrcSizes() {
|
||||
if (this.#imgUrls.length === 0) {
|
||||
this._imgSrc = [];
|
||||
this.hasImgUrls = false;
|
||||
this._imgSrcSizes = [];
|
||||
return;
|
||||
}
|
||||
|
||||
this._imgSrc = [
|
||||
this._imgSrcSizes = [
|
||||
{
|
||||
scale: '1x',
|
||||
w: 30,
|
||||
url: this.#imgUrls[0],
|
||||
},
|
||||
{
|
||||
w: 60,
|
||||
url: this.#imgUrls[1],
|
||||
},
|
||||
{
|
||||
scale: '2x',
|
||||
w: 90,
|
||||
url: this.#imgUrls[2],
|
||||
},
|
||||
{
|
||||
scale: '3x',
|
||||
w: 150,
|
||||
url: this.#imgUrls[3],
|
||||
},
|
||||
{
|
||||
w: 300,
|
||||
url: this.#imgUrls[4],
|
||||
},
|
||||
];
|
||||
|
||||
this._imgSrc.forEach((url) => (this._imbSrcSet += `${url.url} ${url.scale},`));
|
||||
this.hasImgUrls = true;
|
||||
this.#setImgSrc();
|
||||
}
|
||||
|
||||
protected override firstUpdated(): void {
|
||||
this.#setImgSrc();
|
||||
}
|
||||
|
||||
async #setImgSrc() {
|
||||
if (!this.hasImgUrls) return;
|
||||
if (!this.avatarElement) return;
|
||||
|
||||
setTimeout(() => {
|
||||
// TODO: look into img sizes="auto" to let the browser handle the correct image size based on the element size
|
||||
const elementSize = this.avatarElement.getBoundingClientRect();
|
||||
const elementWidth = elementSize.width;
|
||||
|
||||
const matchingSizes = this._imgSrcSizes.filter((size) => {
|
||||
// we multiply the element width to make sure we have a good quality image
|
||||
return elementWidth * 1.5 <= size.w;
|
||||
});
|
||||
|
||||
// We use the smallest image that is larger than the element width
|
||||
this._imgSrc = matchingSizes[0]?.url;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
override render() {
|
||||
@@ -68,8 +110,7 @@ export class UmbUserAvatarElement extends UmbLitElement {
|
||||
|
||||
return html`<uui-avatar
|
||||
.name=${this.name || 'Unknown'}
|
||||
img-src=${ifDefined(this.hasImgUrls ? this._imgSrc[0].url : undefined)}
|
||||
img-srcset=${ifDefined(this.hasImgUrls ? this._imbSrcSet : undefined)}
|
||||
img-src=${ifDefined(this._imgSrc ? this._imgSrc : undefined)}
|
||||
class=${classMap(classes)}></uui-avatar>`;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user