-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(esl-image-utils): create esl-img-container mixin to provide img …
…container functionality Co-authored-by: ala'n (Alexey Stsefanovich) <astsefanovich@exadel.com>
- Loading branch information
Showing
6 changed files
with
124 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
import '@exadel/esl/modules/lib'; | ||
export * from '@exadel/esl'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
--- | ||
layout: content | ||
title: Image Utils | ||
seoTitle: Example image using ESL Image Container Mixin | ||
name: Image Utils | ||
tags: [examples, playground] | ||
icon: examples/image.svg | ||
aside: | ||
components: | ||
- esl-image | ||
--- | ||
{% import 'lorem.njk' as lorem %} | ||
|
||
{% set imageSrcBase = '/assets/' | url %} | ||
|
||
<section class="row"> | ||
<div class="col-12"> | ||
<uip-root> | ||
<script type="text/html" | ||
label="Save ratio mode" | ||
uip-snippet | ||
uip-snippet-js="js-snippet-image-element" | ||
uip-isolated> | ||
<picture class="img-container img-container-16-9"> | ||
<img esl-img-container loading="lazy" alt="img" src="{{ '/assets/nature/forest+clouds.jpg' | url }}"/> | ||
</picture> | ||
</script> | ||
|
||
<script id="js-snippet-image-element" type="text/plain"> | ||
import { ESLImgContainerMixin } from '@exadel/esl'; | ||
ESLImgContainerMixin.register(); | ||
</script> | ||
|
||
<uip-snippets class="uip-toolbar" dropdown-view="@xs"></uip-snippets> | ||
<uip-preview></uip-preview> | ||
<uip-settings label="Settings" resizable vertical="@+sm"> | ||
<uip-select-setting target=".img-container" label="Image ratio:" attribute="class" mode="append"> | ||
<option value="img-container-16-9">16 x 9</option> | ||
<option value="img-container-4-3">4 x 3</option> | ||
<option value="img-container-2-1">2 x 1</option> | ||
<option value="img-container-2-3">2 x 3</option> | ||
<option value="img-container-1-1">1 x 1</option> | ||
</uip-select-setting> | ||
<uip-select-setting target=".cover-mode-image" label="Image vertical alignment:" attribute="class" mode="append"> | ||
<option value="bg-v-top">bg-v-top</option> | ||
<option value="bg-v-center">bg-v-center</option> | ||
<option value="bg-v-bottom">bg-v-bottom</option> | ||
</uip-select-setting> | ||
<uip-select-setting target=".cover-mode-image" label="Image horizontal alignment:" attribute="class" mode="append"> | ||
<option value="bg-h-left">bg-h-left</option> | ||
<option value="bg-h-center">bg-h-center</option> | ||
<option value="bg-h-right">bg-h-right</option> | ||
</uip-select-setting> | ||
<uip-bool-setting label="Border" target=".img-container" mode="append" attribute="class" value="border"></uip-bool-setting> | ||
<uip-bool-setting label="Inscribe" target=".cover-mode-image" mode="append" attribute="class" value="bg-inscribe"></uip-bool-setting> | ||
</uip-settings> | ||
<uip-editor label="Source code (HTML)" collapsible copy></uip-editor> | ||
<uip-editor source="js" label="Source code (JS)" collapsible collapsed copy></uip-editor> | ||
</uip-root> | ||
</div> | ||
</section> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './core/esl-image-container.mixin'; |
59 changes: 59 additions & 0 deletions
59
src/modules/esl-image-utils/core/esl-image-container.mixin.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import {ESLMixinElement} from '../../esl-mixin-element/core'; | ||
import {ESLTraversingQuery} from '../../esl-traversing-query/core'; | ||
import {attr, listen} from '../../esl-utils/decorators'; | ||
import {CSSClassUtils} from '../../esl-utils/dom'; | ||
import {ExportNs} from '../../esl-utils/environment/export-ns'; | ||
|
||
/** | ||
* ESLImgContainerMixin - mixin to provide image container functionality | ||
* @author Anna Barmina, Alexey Stsefanovich (ala'n) | ||
* | ||
* Use example: | ||
* ``` | ||
* <picture class="img-container img-container-16-9"> | ||
* <img esl-img-container loading="lazy" alt="img" src="img.png"/> | ||
* </picture> | ||
* ``` | ||
* | ||
* This mixin is used to enhance an image element by adding specific classes to a target when the image has completely loaded or not | ||
*/ | ||
|
||
@ExportNs('ImgContainer') | ||
export class ESLImgContainerMixin extends ESLMixinElement { | ||
static override is = 'esl-img-container'; | ||
|
||
/** Target element selector ('::parent' by default) */ | ||
@attr({name: ESLImgContainerMixin.is}) public target: string; | ||
/** Class to add to the target element when the image is loaded */ | ||
@attr({name: ESLImgContainerMixin.is + '-cls', defaultValue: 'img-container-loaded'}) public targetCls: string; | ||
/** Class to add to the target element when the image is not loaded */ | ||
@attr({name: ESLImgContainerMixin.is + '-error-cls'}) public targetErrorCls: string; | ||
|
||
public override $host!: HTMLImageElement; | ||
|
||
get $target(): Element | null { | ||
return ESLTraversingQuery.first(this.target || '::parent', this.$host); | ||
} | ||
|
||
protected override connectedCallback(): void { | ||
if (this.$host.tagName !== 'IMG') return; | ||
super.connectedCallback(); | ||
if (this.$host.complete) { | ||
const eventType = this.$host.naturalHeight && this.$host.naturalWidth ? 'load' : 'error'; | ||
this._onReady(new Event(eventType)); | ||
} | ||
else this.$$on(this._onReady); | ||
} | ||
|
||
@listen({ | ||
event: 'load error', | ||
auto: false, | ||
once: true | ||
}) | ||
protected _onReady(event: Event): void { | ||
const {$target} = this; | ||
if (!$target) return; | ||
CSSClassUtils.add($target, this.targetCls); | ||
if (event.type === 'error') CSSClassUtils.add($target, this.targetErrorCls); | ||
} | ||
} |