set img src based on element width

This commit is contained in:
Mads Rasmussen
2024-09-04 14:19:05 +02:00
parent e6ce873195
commit a8b54bec30

View File

@@ -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>`;
}