@exadel/esl
Version:
Exadel Smart Library (ESL) is the lightweight custom elements library that provide a set of super-flexible components
90 lines (89 loc) • 3.48 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var ESLImageContainerMixin_1;
import { ESLMixinElement } from '../../esl-mixin-element/core';
import { jsonAttr, listen, memoize } from '../../esl-utils/decorators';
import { ExportNs } from '../../esl-utils/environment/export-ns';
import { findAll } from '../../esl-utils/dom/traversing';
/**
* ESLImageContainerMixin - mixin to provide image loading state class functionality
* @author Anna Barmina, Alexey Stsefanovich (ala'n)
*
* Use example:
* ```
* <picture class="img-container img-container-16-9" esl-image-container>
* <img loading="lazy" alt="img" src="img.png"/>
* </picture>
* ```
*
* This mixin is used to enhance native image developer experience by adding specific classes when the image has completely loaded or not
*/
let ESLImageContainerMixin = ESLImageContainerMixin_1 = class ESLImageContainerMixin extends ESLMixinElement {
/** Merged configuration object */
get config() {
return Object.assign(Object.assign({}, ESLImageContainerMixin_1.DEFAULT_CONFIG), this.rawConfig);
}
/** Image element */
get $images() {
if (this.$host.tagName === 'IMG') {
return this.$host.matches(this.config.selector) ? [this.$host] : [];
}
return findAll(this.$host, this.config.selector);
}
/** Check if all images are loaded */
get complete() {
return this.$images.every((img) => img.complete);
}
/** Check if any image has loading error */
get hasError() {
return this.$images.some((img) => !img.naturalHeight && !img.naturalWidth);
}
connectedCallback() {
super.connectedCallback();
this._onReady();
}
attributeChangedCallback(name) {
if (name !== ESLImageContainerMixin_1.is)
return;
memoize.clear(this, ['config', '$images']);
this._onReady();
}
_onReady() {
if (!this.complete)
return;
this.$$off();
this.$$cls(this.config.readyCls, true);
this.$$cls(this.config.errorCls, this.hasError);
}
};
ESLImageContainerMixin.is = 'esl-image-container';
/** Default configuration object */
ESLImageContainerMixin.DEFAULT_CONFIG = {
readyCls: 'img-container-loaded',
errorCls: '',
selector: 'img',
};
__decorate([
jsonAttr({ name: ESLImageContainerMixin.is })
], ESLImageContainerMixin.prototype, "rawConfig", void 0);
__decorate([
memoize()
], ESLImageContainerMixin.prototype, "config", null);
__decorate([
memoize()
], ESLImageContainerMixin.prototype, "$images", null);
__decorate([
listen({
event: 'load error',
target: (that) => that.$images,
condition: (that) => !!that.$images.length
})
], ESLImageContainerMixin.prototype, "_onReady", null);
ESLImageContainerMixin = ESLImageContainerMixin_1 = __decorate([
ExportNs('ImageContainer')
], ESLImageContainerMixin);
export { ESLImageContainerMixin };