Skip to content

Commit 344eb8c

Browse files
authored
feat(esl-lazy-template): introducing esl-lazy-template mixin to load HTML parts lazy and asynchronous (#2535)
1 parent c07ac38 commit 344eb8c

File tree

17 files changed

+505
-2
lines changed

17 files changed

+505
-2
lines changed

.commitlintrc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ rules:
4141
- esl-forms
4242
- esl-image
4343
- esl-image-utils
44+
- esl-lazy-template
4445
- esl-media
4546
- esl-media-query
4647
- esl-mixin-element
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import {ESLMixinElement} from '@exadel/esl/modules/esl-mixin-element/core';
2+
import {ready} from '@exadel/esl/modules/esl-utils/decorators';
3+
import {ESLEventUtils} from '@exadel/esl/modules/esl-utils/dom/events';
4+
import {Rect} from '@exadel/esl/modules/esl-utils/dom/rect';
5+
import {getWindowRect} from '@exadel/esl/modules/esl-utils/dom/window';
6+
import {getViewportForEl} from '@exadel/esl/modules/esl-utils/dom/scroll';
7+
8+
export class ESLDemoDistanceToViewportAlert extends ESLMixinElement {
9+
public static override is = 'distance-to-viewport-alert';
10+
11+
@ready
12+
protected override connectedCallback(): void {
13+
super.connectedCallback();
14+
this.showAlert();
15+
}
16+
17+
protected calculateDistance(): number {
18+
let topDistance;
19+
let bottomDistance;
20+
const elementRect = Rect.from(this.$host.getBoundingClientRect());
21+
const $root = getViewportForEl(this.$host) as HTMLElement;
22+
if (!$root) { // window
23+
const windowRect = getWindowRect();
24+
topDistance = elementRect.top - windowRect.height;
25+
bottomDistance = -elementRect.bottom;
26+
} else {
27+
const windowRect = Rect.from($root.getBoundingClientRect());
28+
topDistance = elementRect.top - windowRect.bottom;
29+
bottomDistance = -elementRect.bottom;
30+
}
31+
return Math.max(topDistance, bottomDistance);
32+
}
33+
34+
protected showAlert(): void {
35+
const distance = this.calculateDistance();
36+
const text = distance < 0
37+
? `The element with id="${this.$host.id}" was connected to DOM when it was in viewport`
38+
: `The element with id="${this.$host.id}" was connected to DOM at the distance ${distance}px from the viewport`;
39+
40+
const detail = {
41+
text,
42+
cls: 'alert-info',
43+
hideDelay: 5000
44+
};
45+
ESLEventUtils.dispatch(document.body, 'esl:alert:show', {detail});
46+
}
47+
}

site/src/site.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,15 @@ import {
3636
ESLAnimateMixin,
3737
ESLRelatedTarget,
3838
ESLOpenState,
39-
4039
ESLCarousel,
4140
ESLCarouselNavDots,
4241
ESLCarouselNavMixin,
4342
ESLCarouselTouchMixin,
4443
ESLCarouselWheelMixin,
4544
ESLCarouselKeyboardMixin,
4645
ESLCarouselRelateToMixin,
47-
ESLCarouselAutoplayMixin
46+
ESLCarouselAutoplayMixin,
47+
ESLLazyTemplate
4848
} from '@exadel/esl/modules/all';
4949

5050
import {ESLRandomText} from '@exadel/esl/modules/esl-random-text/core';
@@ -65,6 +65,7 @@ import {ESLDemoAnchorLink} from './anchor/anchor-link';
6565
import {ESLDemoBanner} from './banner/banner';
6666
import {ESLDemoSwipeArea, ESLDemoWheelArea} from './esl-events-demo/esl-events-demo';
6767
import {ESLDemoPopupGame} from './esl-popup/esl-d-popup-game';
68+
import {ESLDemoDistanceToViewportAlert} from './esl-lazy-template-demo/distance-to-viewport-alert';
6869

6970
if (!CSS.supports('(height: 100dvh) or (width: 100dvw)')) ESLVSizeCSSProxy.observe();
7071

@@ -81,6 +82,7 @@ ESLDemoBanner.register();
8182
ESLDemoSwipeArea.register();
8283
ESLDemoWheelArea.register();
8384
ESLDemoPopupGame.register();
85+
ESLDemoDistanceToViewportAlert.register();
8486

8587
// Test Content
8688
ESLRandomText.register('lorem-ipsum');
@@ -136,6 +138,7 @@ ESLAnimateMixin.register();
136138
// Register ESL Mixins
137139
ESLRelatedTarget.register();
138140
ESLOpenState.register();
141+
ESLLazyTemplate.register();
139142

140143
// Share component loading
141144
import(/* webpackChunkName: 'common/esl-share' */'./esl-share/esl-share');
Lines changed: 1 addition & 0 deletions
Loading

site/static/assets/lazy-templates/animated-geometric-shapes-background.svg

Lines changed: 5 additions & 0 deletions
Loading
Lines changed: 59 additions & 0 deletions
Loading
Lines changed: 29 additions & 0 deletions
Loading
Lines changed: 36 additions & 0 deletions
Loading
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<div id="template-from-url-1"
2+
class="text-center"
3+
distance-to-viewport-alert
4+
style="background: lightyellow; border: 3px dashed darkorange;">
5+
<p>...</p>
6+
<p>I am content No.1 which was added to DOM by the lazy template and loaded from the specified URL</p>
7+
<p>I am inside DIV with id="template-from-url-1".</p>
8+
<p>...</p>
9+
</div>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<div id="template-from-url-2"
2+
class="text-center"
3+
distance-to-viewport-alert
4+
style="background: lightyellow; border: 3px dashed darkorange;">
5+
<p>...</p>
6+
<p>I am content No.2 which was added to DOM by the lazy template and loaded from the specified URL</p>
7+
<p>I am inside DIV with id="template-from-url-2".</p>
8+
<p>...</p>
9+
</div>

0 commit comments

Comments
 (0)