@salesforcedevs/dx-components 0.53.0 → 0.53.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +12 -0
- package/lwc.config.json +0 -5
- package/package.json +3 -2
- package/src/modules/dx/cardBlogPost/cardBlogPost.css +1 -1
- package/src/modules/dx/cardContent/cardContent.css +1 -1
- package/src/modules/dx/cardTrailheadModule/cardTrailheadModule.css +1 -1
- package/src/modules/dx/cardVideoPreview/cardVideoPreview.css +1 -1
- package/src/modules/dx/cardVideoPreview/cardVideoPreview.html +1 -0
- package/src/modules/dx/cardVideoPreview/cardVideoPreview.ts +1 -1
- package/src/modules/dx/contentArchive/contentArchive.ts +1 -0
- package/src/modules/dx/podcastSubscription/podcastSubscription.ts +8 -14
- package/src/modules/dx/section/section.css +1 -1
- package/src/modules/dx/section/section.ts +9 -9
- package/src/modules/dx/vimeoPlayer/vimeoPlayer.html +1 -1
- package/src/modules/helpers/card/card.css +21 -16
- package/src/modules/dx/cardGrid/cardGrid.css +0 -89
- package/src/modules/dx/cardGrid/cardGrid.html +0 -46
- package/src/modules/dx/cardGrid/cardGrid.ts +0 -140
- package/src/modules/dx/featureGrid/featureGrid.html +0 -3
- package/src/modules/dx/featureGrid/featureGrid.ts +0 -15
- package/src/modules/dx/groupBio/groupBio.css +0 -49
- package/src/modules/dx/groupBio/groupBio.html +0 -29
- package/src/modules/dx/groupBio/groupBio.ts +0 -41
- package/src/modules/dx/headTags/headTags.html +0 -3
- package/src/modules/dx/headTags/headTags.ts +0 -39
- package/src/modules/dx/interactiveImage/interactiveImage.css +0 -59
- package/src/modules/dx/interactiveImage/interactiveImage.html +0 -32
- package/src/modules/dx/interactiveImage/interactiveImage.ts +0 -71
- package/src/modules/dx/lazy/lazy.html +0 -5
- package/src/modules/dx/lazy/lazy.ts +0 -163
package/LICENSE
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Copyright (c) 2020, Salesforce.com, Inc.
|
|
2
|
+
All rights reserved.
|
|
3
|
+
|
|
4
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
5
|
+
|
|
6
|
+
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
7
|
+
|
|
8
|
+
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
9
|
+
|
|
10
|
+
* Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
11
|
+
|
|
12
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
package/lwc.config.json
CHANGED
|
@@ -29,7 +29,6 @@
|
|
|
29
29
|
"dx/emptyState",
|
|
30
30
|
"dx/feature",
|
|
31
31
|
"dx/featuredContentHeader",
|
|
32
|
-
"dx/featureGrid",
|
|
33
32
|
"dx/featuresList",
|
|
34
33
|
"dx/filterMenu",
|
|
35
34
|
"dx/banner",
|
|
@@ -37,13 +36,11 @@
|
|
|
37
36
|
"dx/newsletterForm",
|
|
38
37
|
"dx/formattedDateTime",
|
|
39
38
|
"dx/grid",
|
|
40
|
-
"dx/groupBio",
|
|
41
39
|
"dx/groupText",
|
|
42
40
|
"dx/header",
|
|
43
41
|
"dx/headerMobileNavMenu",
|
|
44
42
|
"dx/headerNav",
|
|
45
43
|
"dx/headerSearch",
|
|
46
|
-
"dx/headTags",
|
|
47
44
|
"dx/helmet",
|
|
48
45
|
"dx/hr",
|
|
49
46
|
"dx/icon",
|
|
@@ -51,8 +48,6 @@
|
|
|
51
48
|
"dx/imageAndLabel",
|
|
52
49
|
"dx/input",
|
|
53
50
|
"dx/instrumentation",
|
|
54
|
-
"dx/interactiveImage",
|
|
55
|
-
"dx/lazy",
|
|
56
51
|
"dx/logo",
|
|
57
52
|
"dx/modalDrawer",
|
|
58
53
|
"dx/pagination",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforcedevs/dx-components",
|
|
3
|
-
"version": "0.53.
|
|
3
|
+
"version": "0.53.5",
|
|
4
4
|
"description": "DX Lightning web components",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"engines": {
|
|
@@ -27,5 +27,6 @@
|
|
|
27
27
|
"@types/debounce": "^1.2.0",
|
|
28
28
|
"@types/lodash.get": "^4.4.6",
|
|
29
29
|
"@types/vimeo__player": "^2.16.2"
|
|
30
|
-
}
|
|
30
|
+
},
|
|
31
|
+
"gitHead": "57c0600131ffd0be710b781c677bef1b093dc9d8"
|
|
31
32
|
}
|
|
@@ -2,7 +2,7 @@ import { LightningElement, api } from "lwc";
|
|
|
2
2
|
|
|
3
3
|
export default class CardVideoPreview extends LightningElement {
|
|
4
4
|
@api body?: string | null = null;
|
|
5
|
-
@api datetime
|
|
5
|
+
@api datetime?: string;
|
|
6
6
|
@api featured?: boolean = false;
|
|
7
7
|
@api href!: string;
|
|
8
8
|
@api imgAlt?: string;
|
|
@@ -3,14 +3,12 @@ import { LightningElement } from "lwc";
|
|
|
3
3
|
export default class PodcastSubscription extends LightningElement {
|
|
4
4
|
badgeLinks = [
|
|
5
5
|
{
|
|
6
|
-
href:
|
|
7
|
-
"https://podcasts.apple.com/us/podcast/salesforce-developer-podcast/id1482325260",
|
|
6
|
+
href: "https://podcasts.apple.com/us/podcast/salesforce-developer-podcast/id1482325260",
|
|
8
7
|
imgAlt: "Listen on Apple Podcasts",
|
|
9
8
|
imgSrc: "/assets/svg/podcasts-subscription-apple.svg"
|
|
10
9
|
},
|
|
11
10
|
{
|
|
12
|
-
href:
|
|
13
|
-
"https://www.google.com/podcasts?feed=aHR0cHM6Ly9zYWxlc2ZvcmNlZGV2cG9kY2FzdC5saWJzeW4uY29tL3Jzcw%3D%3D",
|
|
11
|
+
href: "https://www.google.com/podcasts?feed=aHR0cHM6Ly9zYWxlc2ZvcmNlZGV2cG9kY2FzdC5saWJzeW4uY29tL3Jzcw%3D%3D",
|
|
14
12
|
imgAlt: "Listen on Google Podcasts",
|
|
15
13
|
imgSrc: "/assets/svg/podcasts-subscription-google.svg"
|
|
16
14
|
},
|
|
@@ -27,28 +25,24 @@ export default class PodcastSubscription extends LightningElement {
|
|
|
27
25
|
text: "Stitcher"
|
|
28
26
|
},
|
|
29
27
|
{
|
|
30
|
-
href:
|
|
31
|
-
"https://www.amazon.com/Emerald-City-Productions-Salesforce-Developer/dp/B082PPXMLN/",
|
|
28
|
+
href: "https://www.amazon.com/Emerald-City-Productions-Salesforce-Developer/dp/B082PPXMLN/",
|
|
32
29
|
text: "Alexa"
|
|
33
30
|
},
|
|
34
31
|
{
|
|
35
|
-
href:
|
|
36
|
-
"https://www.pandora.com/podcast/salesforce-developer-podcast/PC:34746",
|
|
32
|
+
href: "https://www.pandora.com/podcast/salesforce-developer-podcast/PC:34746",
|
|
37
33
|
text: "Pandora"
|
|
38
34
|
},
|
|
39
35
|
{
|
|
40
|
-
href:
|
|
41
|
-
"https://www.iheart.com/podcast/263-salesforce-developer-podca-56252827",
|
|
36
|
+
href: "https://www.iheart.com/podcast/263-salesforce-developer-podca-56252827",
|
|
42
37
|
text: "iHeartRadio"
|
|
43
38
|
},
|
|
44
39
|
{
|
|
45
|
-
href:
|
|
46
|
-
"https://tunein.com/podcasts/Technology-Podcasts/Salesforce-Developer-Podcast-p1255006/",
|
|
40
|
+
href: "https://tunein.com/podcasts/Technology-Podcasts/Salesforce-Developer-Podcast-p1255006/",
|
|
47
41
|
text: "Tune-in"
|
|
48
42
|
},
|
|
49
43
|
{
|
|
50
|
-
href: "https://
|
|
51
|
-
text: "
|
|
44
|
+
href: "https://player.fm/series/salesforce-developer-podcast",
|
|
45
|
+
text: "PlayerFM"
|
|
52
46
|
},
|
|
53
47
|
{
|
|
54
48
|
href: "https://dev.to/salesforce_developers_podcast",
|
|
@@ -3,16 +3,16 @@ import cx from "classnames";
|
|
|
3
3
|
import { toDxColor } from "utils/css";
|
|
4
4
|
|
|
5
5
|
export default class Section extends LightningElement {
|
|
6
|
-
@api backgroundColor
|
|
7
|
-
@api dark
|
|
6
|
+
@api backgroundColor: string = "transparent";
|
|
7
|
+
@api dark: boolean = false;
|
|
8
8
|
@api headingLevel: "1" | "2" | "3" | "4" | "5" = "3";
|
|
9
|
-
@api label?: string
|
|
10
|
-
@api subtitle?: string
|
|
11
|
-
@api textAlign
|
|
12
|
-
@api title?: string
|
|
13
|
-
@api topGraphic
|
|
14
|
-
@api graphicOverlap
|
|
15
|
-
@api bottomGraphic
|
|
9
|
+
@api label?: string;
|
|
10
|
+
@api subtitle?: string;
|
|
11
|
+
@api textAlign: "center" | "left" = "left";
|
|
12
|
+
@api title?: string;
|
|
13
|
+
@api topGraphic: boolean = false;
|
|
14
|
+
@api graphicOverlap: boolean = false;
|
|
15
|
+
@api bottomGraphic: boolean = false;
|
|
16
16
|
|
|
17
17
|
private get style(): string {
|
|
18
18
|
return `--dx-c-section-background-color: ${toDxColor(
|
|
@@ -184,18 +184,6 @@ a.dx-card-base:hover dx-card-title {
|
|
|
184
184
|
|
|
185
185
|
/* Desktop Only */
|
|
186
186
|
@media screen and (min-width: 1024px) {
|
|
187
|
-
.dx-card-base_layout-horizontal .dx-card-base_borderless-image_link {
|
|
188
|
-
align-self: flex-start;
|
|
189
|
-
flex-shrink: 0;
|
|
190
|
-
width: 0;
|
|
191
|
-
height: unset;
|
|
192
|
-
margin-right: var(--dx-g-card-img-spacing);
|
|
193
|
-
margin-bottom: unset;
|
|
194
|
-
padding-top: unset;
|
|
195
|
-
padding-right: 45%;
|
|
196
|
-
padding-bottom: 22.5%;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
187
|
.dx-card-base_featured dx-card-title {
|
|
200
188
|
--dx-c-card-title-letter-spacing: -0.6px;
|
|
201
189
|
--dx-c-card-title-font-size: 32px;
|
|
@@ -216,6 +204,21 @@ a.dx-card-base:hover dx-card-title {
|
|
|
216
204
|
}
|
|
217
205
|
}
|
|
218
206
|
|
|
207
|
+
/* Tablet + Desktop Only */
|
|
208
|
+
@media screen and (min-width: 764px) {
|
|
209
|
+
.dx-card-base_layout-horizontal .dx-card-base_borderless-image_link {
|
|
210
|
+
align-self: flex-start;
|
|
211
|
+
flex-shrink: 0;
|
|
212
|
+
width: 0;
|
|
213
|
+
height: unset;
|
|
214
|
+
margin-right: var(--dx-g-card-img-spacing);
|
|
215
|
+
margin-bottom: unset;
|
|
216
|
+
padding-top: unset;
|
|
217
|
+
padding-right: 45%;
|
|
218
|
+
padding-bottom: 22.5%;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
219
222
|
/* Tablet */
|
|
220
223
|
@media screen and (max-width: 1024px) {
|
|
221
224
|
:host {
|
|
@@ -223,10 +226,6 @@ a.dx-card-base:hover dx-card-title {
|
|
|
223
226
|
--dx-g-card-img-spacing: 16px;
|
|
224
227
|
}
|
|
225
228
|
|
|
226
|
-
.dx-card-base_borderless-image {
|
|
227
|
-
min-height: unset;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
229
|
/* text resp */
|
|
231
230
|
.dx-text-body-2,
|
|
232
231
|
.dx-text-body-3 {
|
|
@@ -256,3 +255,9 @@ a.dx-card-base:hover dx-card-title {
|
|
|
256
255
|
font-size: var(--dx-g-text-sm);
|
|
257
256
|
}
|
|
258
257
|
}
|
|
258
|
+
|
|
259
|
+
@media screen and (max-width: 764px) {
|
|
260
|
+
.dx-card-base_borderless-image {
|
|
261
|
+
min-height: unset;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
@import "helpers/reset";
|
|
2
|
-
@import "helpers/text";
|
|
3
|
-
|
|
4
|
-
.docs-action-bar {
|
|
5
|
-
display: flex;
|
|
6
|
-
justify-content: space-between;
|
|
7
|
-
align-items: flex-end;
|
|
8
|
-
padding: var(--dx-g-spacing-md) 0 var(--dx-g-spacing-lg);
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
.docs-action-bar > .records-container {
|
|
12
|
-
margin-right: auto;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.docs-action-bar .filters-container {
|
|
16
|
-
display: flex;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.filter-checkbox-group,
|
|
20
|
-
.filter-button::part(container) {
|
|
21
|
-
--dx-c-checkbox-text-transform: capitalize;
|
|
22
|
-
|
|
23
|
-
text-transform: var(--dx-c-checkbox-text-transform);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.docs-action-bar .filters-container > *:not(:first-child),
|
|
27
|
-
.docs-search-input {
|
|
28
|
-
margin-left: var(--dx-g-spacing-sm);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.docs-search-input {
|
|
32
|
-
--dx-c-input-width: 285px;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.docs-card {
|
|
36
|
-
--dx-c-body-max-lines: 4;
|
|
37
|
-
--dx-c-heading-max-lines: 2;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
.pagination-container {
|
|
41
|
-
max-width: fit-content;
|
|
42
|
-
max-width: -moz-fit-content;
|
|
43
|
-
margin: var(--dx-g-spacing-lg) auto;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
@media screen and (max-width: 1024px) {
|
|
47
|
-
.docs-card {
|
|
48
|
-
--dx-c-body-max-lines: 3;
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
@media screen and (max-width: 768px) {
|
|
53
|
-
.docs-action-bar {
|
|
54
|
-
flex-direction: column-reverse;
|
|
55
|
-
width: 100%;
|
|
56
|
-
padding: 0;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.docs-search-input {
|
|
60
|
-
--dx-c-input-width: 100%;
|
|
61
|
-
|
|
62
|
-
width: 100%;
|
|
63
|
-
margin-bottom: var(--dx-g-spacing-md);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
.docs-action-bar .records-container {
|
|
67
|
-
transform: translateY(-100%);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
@media screen and (max-width: 600px) {
|
|
72
|
-
.pagination-container {
|
|
73
|
-
width: 100%;
|
|
74
|
-
overflow: hidden;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
.pagination-container > * {
|
|
78
|
-
position: absolute;
|
|
79
|
-
left: 50%;
|
|
80
|
-
transform: translateX(-50%);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
@media screen and (max-width: 460px) {
|
|
85
|
-
.docs-action-bar .records-container {
|
|
86
|
-
transform: initial;
|
|
87
|
-
padding: var(--dx-g-spacing-md) 0;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="card-grid">
|
|
3
|
-
<div class="docs-action-bar">
|
|
4
|
-
<div class="records-container">
|
|
5
|
-
<span if:true={endingRecord}>
|
|
6
|
-
Showing { startingRecord } to { endingRecord } of {
|
|
7
|
-
cards.length }
|
|
8
|
-
</span>
|
|
9
|
-
</div>
|
|
10
|
-
<div class="filters-container">
|
|
11
|
-
<slot name="filters"></slot>
|
|
12
|
-
</div>
|
|
13
|
-
<dx-input
|
|
14
|
-
size="small"
|
|
15
|
-
placeholder="Search..."
|
|
16
|
-
icon-symbol="search"
|
|
17
|
-
shortcut-key="j"
|
|
18
|
-
class="docs-search-input"
|
|
19
|
-
onchange={handleSearchChange}
|
|
20
|
-
value={searchTerm}
|
|
21
|
-
></dx-input>
|
|
22
|
-
</div>
|
|
23
|
-
<dx-grid
|
|
24
|
-
columns={tileColumns}
|
|
25
|
-
if:false={showEmptyState}
|
|
26
|
-
class="card-container"
|
|
27
|
-
></dx-grid>
|
|
28
|
-
<div style="display: none">
|
|
29
|
-
<slot name="cards" onslotchange={onSlotChange}></slot>
|
|
30
|
-
</div>
|
|
31
|
-
<div class="pagination-container" if:false={showEmptyState}>
|
|
32
|
-
<dx-pagination
|
|
33
|
-
current-page={page}
|
|
34
|
-
total-pages={totalPages}
|
|
35
|
-
pages-to-show={pagesToShow}
|
|
36
|
-
onpagechange={goToPage}
|
|
37
|
-
if:false={hidePagination}
|
|
38
|
-
></dx-pagination>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
<dx-empty-state
|
|
42
|
-
title="Beep boop. That did not compute."
|
|
43
|
-
subtitle={emptyStateSubtitle}
|
|
44
|
-
if:true={showEmptyState}
|
|
45
|
-
></dx-empty-state>
|
|
46
|
-
</template>
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
import { LightningElement, api } from "lwc";
|
|
2
|
-
|
|
3
|
-
export default class CardGrid extends LightningElement {
|
|
4
|
-
@api pageSize = 24;
|
|
5
|
-
@api searchDebounce = 500;
|
|
6
|
-
page = 1;
|
|
7
|
-
|
|
8
|
-
private searchTerm = "";
|
|
9
|
-
private matchDesktop!: MediaQueryList;
|
|
10
|
-
private matchMobile!: MediaQueryList;
|
|
11
|
-
private matchMobileSmall!: MediaQueryList;
|
|
12
|
-
private deviceType: "desktop" | "mobile" | "mobile-small" = "desktop";
|
|
13
|
-
private searchTimeout?: number;
|
|
14
|
-
private cards: any[] = [];
|
|
15
|
-
|
|
16
|
-
private get startingRecord() {
|
|
17
|
-
return this.page === 1
|
|
18
|
-
? this.page
|
|
19
|
-
: (this.page - 1) * this.pageSize + 1;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
private get endingRecord() {
|
|
23
|
-
const defaultEndingRecord = this.pageSize * this.page;
|
|
24
|
-
return defaultEndingRecord > this.cards.length
|
|
25
|
-
? this.cards.length
|
|
26
|
-
: defaultEndingRecord;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
private get totalPages() {
|
|
30
|
-
return Math.ceil(this.cards.length / this.pageSize);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
private get hidePagination() {
|
|
34
|
-
return this.totalPages < 2;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
private get emptyStateSubtitle() {
|
|
38
|
-
return (
|
|
39
|
-
"No results" +
|
|
40
|
-
(this.searchTerm !== "" ? ` for "${this.searchTerm}"` : "")
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
private get showEmptyState() {
|
|
45
|
-
return !this.cards.length;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private get tileColumns() {
|
|
49
|
-
return this.deviceType === "desktop" ? "three" : "two";
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
private get pagesToShow() {
|
|
53
|
-
return this.deviceType === "mobile-small" ? 3 : 5;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
connectedCallback(): void {
|
|
57
|
-
this.matchDesktop = window.matchMedia("(min-width: 1024px)");
|
|
58
|
-
this.matchDesktop.addEventListener("change", this.handleDesktopView);
|
|
59
|
-
|
|
60
|
-
this.matchMobile = window.matchMedia(
|
|
61
|
-
"(min-width: 401px) and (max-width: 1023px)"
|
|
62
|
-
);
|
|
63
|
-
this.matchMobile.addEventListener("change", this.handleMobileView);
|
|
64
|
-
|
|
65
|
-
this.matchMobileSmall = window.matchMedia("(max-width: 340px)");
|
|
66
|
-
this.matchMobileSmall.addEventListener(
|
|
67
|
-
"change",
|
|
68
|
-
this.handleMobileSmallView
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
if (this.matchMobile.matches) {
|
|
72
|
-
this.deviceType = "mobile";
|
|
73
|
-
}
|
|
74
|
-
if (this.matchMobileSmall.matches) {
|
|
75
|
-
this.deviceType = "mobile-small";
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
disconnectedCallback(): void {
|
|
80
|
-
this.matchDesktop.removeEventListener("change", this.handleDesktopView);
|
|
81
|
-
this.matchMobile.removeEventListener("change", this.handleMobileView);
|
|
82
|
-
this.matchMobileSmall.removeEventListener(
|
|
83
|
-
"change",
|
|
84
|
-
this.handleMobileSmallView
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
renderedCallback(): void {
|
|
89
|
-
this.displayCurrentPage();
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
onSlotChange() {
|
|
93
|
-
const slots = Array.from(
|
|
94
|
-
this.template.querySelectorAll("slot")
|
|
95
|
-
) as HTMLSlotElement[];
|
|
96
|
-
this.cards = Array.from(slots[1].assignedElements()[0].children);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
handleDesktopView = (e: MediaQueryListEvent | MediaQueryList) => {
|
|
100
|
-
if (e.matches) {
|
|
101
|
-
this.deviceType = "desktop";
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
handleMobileView = (e: MediaQueryListEvent | MediaQueryList) => {
|
|
106
|
-
if (e.matches) {
|
|
107
|
-
this.deviceType = "mobile";
|
|
108
|
-
}
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
handleMobileSmallView = (e: MediaQueryListEvent | MediaQueryList) => {
|
|
112
|
-
if (e.matches) {
|
|
113
|
-
this.deviceType = "mobile-small";
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
|
|
117
|
-
handleSearchChange(event: InputEvent): void {
|
|
118
|
-
window.clearTimeout(this.searchTimeout);
|
|
119
|
-
this.searchTimeout = window.setTimeout(() => {
|
|
120
|
-
this.dispatchEvent(
|
|
121
|
-
new CustomEvent("searchchange", { detail: event.detail })
|
|
122
|
-
);
|
|
123
|
-
}, this.searchDebounce);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
goToPage(e: CustomEvent) {
|
|
127
|
-
this.page = e.detail;
|
|
128
|
-
this.displayCurrentPage();
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
displayCurrentPage() {
|
|
132
|
-
const cardContainer = this.template.querySelector(".card-container");
|
|
133
|
-
if (cardContainer) {
|
|
134
|
-
cardContainer.innerHTML = "";
|
|
135
|
-
this.cards
|
|
136
|
-
.slice(this.startingRecord - 1, this.endingRecord)
|
|
137
|
-
.map((node) => cardContainer?.appendChild(node));
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { LightningElement } from "lwc";
|
|
2
|
-
import { LightningSlotElement } from "typings/custom";
|
|
3
|
-
|
|
4
|
-
export default class FeatureGrid extends LightningElement {
|
|
5
|
-
private onSlotChange(e: LightningSlotElement) {
|
|
6
|
-
// @ts-ignore
|
|
7
|
-
const slot = e.target;
|
|
8
|
-
slot.assignedElements().forEach(
|
|
9
|
-
(featureElement: any, index: number) => {
|
|
10
|
-
featureElement.descriptionPosition =
|
|
11
|
-
index % 2 === 0 ? "left" : "right";
|
|
12
|
-
}
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
@import "helpers/reset";
|
|
2
|
-
@import "helpers/text";
|
|
3
|
-
|
|
4
|
-
.container {
|
|
5
|
-
display: flex;
|
|
6
|
-
flex-direction: column;
|
|
7
|
-
align-items: center;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
.avatar {
|
|
11
|
-
border-radius: 9999px;
|
|
12
|
-
margin-bottom: var(--dx-g-spacing-md);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.name {
|
|
16
|
-
margin-bottom: var(--dx-g-spacing-sm);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.avatar.size-small {
|
|
20
|
-
width: 50px;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.avatar.size-medium {
|
|
24
|
-
width: 100px;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.avatar.size-large {
|
|
28
|
-
width: 200px;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.body {
|
|
32
|
-
text-align: center;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.position {
|
|
36
|
-
color: var(--dx-g-blue-vibrant-50);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.position.condensed {
|
|
40
|
-
color: inherit;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.descriptors {
|
|
44
|
-
margin-top: var(--dx-g-spacing-sm);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
.descriptors > *:not(:last-child) {
|
|
48
|
-
margin-bottom: var(--dx-g-spacing-xs);
|
|
49
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="container">
|
|
3
|
-
<div if:true={imgSrc}>
|
|
4
|
-
<img class={imgClass} src={imgSrc} alt={imgAlt} />
|
|
5
|
-
</div>
|
|
6
|
-
<div class="body">
|
|
7
|
-
<p if:true={name} class={nameClass}>{name}</p>
|
|
8
|
-
<p if:true={position} class={positionClass}>{position}</p>
|
|
9
|
-
<div
|
|
10
|
-
if:false={isCondensedVariant}
|
|
11
|
-
class="descriptors dx-text-body-2"
|
|
12
|
-
>
|
|
13
|
-
<p if:true={descriptor1}>{descriptor1}</p>
|
|
14
|
-
<p if:true={descriptor2}>{descriptor2}</p>
|
|
15
|
-
<p if:true={descriptor3}>{descriptor3}</p>
|
|
16
|
-
<p if:true={profileHref}>
|
|
17
|
-
<dx-button
|
|
18
|
-
href={profileHref}
|
|
19
|
-
target={profileTarget}
|
|
20
|
-
rel={profileRel}
|
|
21
|
-
variant="inline-inherit"
|
|
22
|
-
>
|
|
23
|
-
{profileText}
|
|
24
|
-
</dx-button>
|
|
25
|
-
</p>
|
|
26
|
-
</div>
|
|
27
|
-
</div>
|
|
28
|
-
</div>
|
|
29
|
-
</template>
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { LightningElement, api } from "lwc";
|
|
2
|
-
|
|
3
|
-
export default class GroupBio extends LightningElement {
|
|
4
|
-
@api imgSrc: string = "";
|
|
5
|
-
@api imgAlt: string = "";
|
|
6
|
-
@api imgSize: "small" | "medium" | "large" = "large";
|
|
7
|
-
@api variant: "condensed" | "default" = "default";
|
|
8
|
-
@api name: string = "";
|
|
9
|
-
@api position: string = "";
|
|
10
|
-
@api descriptor1: string = "";
|
|
11
|
-
@api descriptor2: string = "";
|
|
12
|
-
@api descriptor3: string = "";
|
|
13
|
-
@api profileHref: string = "";
|
|
14
|
-
@api profileText: string = "";
|
|
15
|
-
@api profileTarget: string = "_blank";
|
|
16
|
-
@api profileRel: string = "noopener";
|
|
17
|
-
|
|
18
|
-
private get imgClass(): string {
|
|
19
|
-
return `avatar size-${this.imgSize}`;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
private get nameClass(): string {
|
|
23
|
-
return `name ${
|
|
24
|
-
this.variant === "condensed"
|
|
25
|
-
? "condensed dx-text-label-1"
|
|
26
|
-
: "dx-text-heading-4"
|
|
27
|
-
}`;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
private get positionClass(): string {
|
|
31
|
-
return `position ${
|
|
32
|
-
this.variant === "condensed"
|
|
33
|
-
? "condensed dx-text-body-3"
|
|
34
|
-
: "dx-text-heading-5"
|
|
35
|
-
}`;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
private get isCondensedVariant(): boolean {
|
|
39
|
-
return this.variant === "condensed";
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { LightningElement } from "lwc";
|
|
2
|
-
|
|
3
|
-
const syncElementAttributes = (elementA: Element, elementB: Element) => {
|
|
4
|
-
if (elementB.textContent) {
|
|
5
|
-
elementA.textContent = elementB.textContent;
|
|
6
|
-
}
|
|
7
|
-
const names = elementB.getAttributeNames();
|
|
8
|
-
names.forEach((name: string) => {
|
|
9
|
-
const val = elementB.getAttribute(name);
|
|
10
|
-
if (val) {
|
|
11
|
-
elementA.setAttribute(name, val);
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export default class HeadTags extends LightningElement {
|
|
17
|
-
connectedCallback() {
|
|
18
|
-
const innerElements = this.querySelectorAll("*");
|
|
19
|
-
if (innerElements) {
|
|
20
|
-
Array.from(innerElements).forEach((innerElement) => {
|
|
21
|
-
const elementName = innerElement.getAttribute("name");
|
|
22
|
-
let existingElement = null;
|
|
23
|
-
if (elementName) {
|
|
24
|
-
existingElement = document.head.querySelector(
|
|
25
|
-
`meta[name="${elementName}"]`
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
if (innerElement.tagName === "TITLE") {
|
|
29
|
-
existingElement = document.head.querySelector("title");
|
|
30
|
-
}
|
|
31
|
-
if (existingElement) {
|
|
32
|
-
syncElementAttributes(existingElement, innerElement);
|
|
33
|
-
return;
|
|
34
|
-
}
|
|
35
|
-
document.head.appendChild(innerElement);
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
@import "helpers/reset";
|
|
2
|
-
@import "helpers/text";
|
|
3
|
-
|
|
4
|
-
article {
|
|
5
|
-
border: 1px solid var(--dx-g-gray-90);
|
|
6
|
-
border-radius: 0.3125rem;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
header {
|
|
10
|
-
display: flex;
|
|
11
|
-
align-items: flex-start;
|
|
12
|
-
justify-content: space-between;
|
|
13
|
-
border-radius: 0.3125rem 0.3125rem 0 0;
|
|
14
|
-
background-color: var(--dx-g-gray-95);
|
|
15
|
-
font-family: var(--dx-g-font-sans);
|
|
16
|
-
color: var(--dx-g-gray-10);
|
|
17
|
-
padding: var(--dx-g-spacing-sm);
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
header span {
|
|
21
|
-
padding: var(--dx-g-spacing-sm) var(--dx-g-spacing-md);
|
|
22
|
-
font-size: var(--dx-g-text-sm);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
footer {
|
|
26
|
-
border-radius: 0 0 0.3125rem 0.3125rem;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.body {
|
|
30
|
-
margin: var(--dx-g-spacing-md);
|
|
31
|
-
overflow-x: auto;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
.body img {
|
|
35
|
-
min-width: 650px;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.controls {
|
|
39
|
-
display: flex;
|
|
40
|
-
align-items: center;
|
|
41
|
-
justify-content: flex-end;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/* Breakpoints for mobile */
|
|
45
|
-
|
|
46
|
-
@media screen and (max-width: 640px) {
|
|
47
|
-
header {
|
|
48
|
-
flex-direction: column;
|
|
49
|
-
align-items: flex-end;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
@media screen and (max-width: 320px) {
|
|
54
|
-
.controls,
|
|
55
|
-
.controls dx-dropdown,
|
|
56
|
-
.controls dx-button {
|
|
57
|
-
width: 100%;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<article>
|
|
3
|
-
<header>
|
|
4
|
-
<span>{title}</span>
|
|
5
|
-
<div class="controls">
|
|
6
|
-
<template if:true={isSingleDownload}>
|
|
7
|
-
<dx-button
|
|
8
|
-
icon-symbol="download"
|
|
9
|
-
href={singleDownloadHref}
|
|
10
|
-
download={singleDownloadFilename}
|
|
11
|
-
>
|
|
12
|
-
{downloadButtonLabel}
|
|
13
|
-
</dx-button>
|
|
14
|
-
</template>
|
|
15
|
-
<template if:false={isSingleDownload}>
|
|
16
|
-
<dx-dropdown
|
|
17
|
-
options={urls}
|
|
18
|
-
onchange={handleDownloadOptionChange}
|
|
19
|
-
placement="bottom-end"
|
|
20
|
-
>
|
|
21
|
-
<dx-button variant="primary" icon-symbol="chevrondown">
|
|
22
|
-
{downloadButtonLabel}
|
|
23
|
-
</dx-button>
|
|
24
|
-
</dx-dropdown>
|
|
25
|
-
</template>
|
|
26
|
-
</div>
|
|
27
|
-
</header>
|
|
28
|
-
<div class="body">
|
|
29
|
-
<img src={featuredSrc} alt={title} />
|
|
30
|
-
</div>
|
|
31
|
-
</article>
|
|
32
|
-
</template>
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { LightningElement, api } from "lwc";
|
|
2
|
-
|
|
3
|
-
// Extracts filename and extension from a file URL
|
|
4
|
-
const FILENAME_FROM_URL_REGEX = /(?=\w+\.\w{3,4}$).+/;
|
|
5
|
-
const EXTENSION_FROM_URL_REGEX = /\.([^.]*)$/;
|
|
6
|
-
|
|
7
|
-
export default class InteractiveImage extends LightningElement {
|
|
8
|
-
@api title!: string;
|
|
9
|
-
@api featuredSrc!: string;
|
|
10
|
-
|
|
11
|
-
@api
|
|
12
|
-
set downloadUrls(values: any) {
|
|
13
|
-
// Normalize input values
|
|
14
|
-
let urls;
|
|
15
|
-
if (typeof values === "string") {
|
|
16
|
-
if (values.startsWith("[")) {
|
|
17
|
-
urls = JSON.parse(values);
|
|
18
|
-
} else {
|
|
19
|
-
urls = [values];
|
|
20
|
-
}
|
|
21
|
-
} else {
|
|
22
|
-
urls = values;
|
|
23
|
-
}
|
|
24
|
-
// Ensure that we have some URLs
|
|
25
|
-
if (!urls || urls.length === 0) {
|
|
26
|
-
throw new Error(
|
|
27
|
-
`No download url found for interactive image with title "${this.title}"`
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
// Prepare download options with labels
|
|
31
|
-
this.urls = urls.map((url: string) => {
|
|
32
|
-
return {
|
|
33
|
-
label: this.getDownloadLabelFromUrl(url),
|
|
34
|
-
id: url
|
|
35
|
-
};
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
get downloadUrls() {
|
|
39
|
-
return this.urls;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private urls: { label: string; id: string }[] = [];
|
|
43
|
-
|
|
44
|
-
private get isSingleDownload() {
|
|
45
|
-
return this.urls.length === 1;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private get singleDownloadHref() {
|
|
49
|
-
return this.urls[0].id;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
private get singleDownloadFilename() {
|
|
53
|
-
const pathParts = this.urls[0].id.match(FILENAME_FROM_URL_REGEX);
|
|
54
|
-
return pathParts ? pathParts[0] : "";
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
private get downloadButtonLabel() {
|
|
58
|
-
return this.isSingleDownload ? this.urls[0].label : "Download as...";
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private handleDownloadOptionChange(event: CustomEvent) {
|
|
62
|
-
window.open(event.detail, "_blank");
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
private getDownloadLabelFromUrl(url: string): string {
|
|
66
|
-
const urlParts = url.match(EXTENSION_FROM_URL_REGEX);
|
|
67
|
-
return urlParts
|
|
68
|
-
? `Download as ${urlParts[1].toUpperCase()}`
|
|
69
|
-
: "Download";
|
|
70
|
-
}
|
|
71
|
-
}
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { LightningElement, api } from "lwc";
|
|
2
|
-
|
|
3
|
-
import { LazyMode } from "typings/custom";
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Defines a fallback for BackgroundTasksAPI for browsers that doesn't support it.
|
|
7
|
-
* Currently BackgroundTasksAPI is supported by all major browsers
|
|
8
|
-
* except in Safari where it can be enabled in Experimental (WebKit) Features.
|
|
9
|
-
* See also: https://developer.mozilla.org/en-US/docs/Web/API/Background_Tasks_API
|
|
10
|
-
*/
|
|
11
|
-
function defineBackgroundTasksAPI() {
|
|
12
|
-
// Fallback to using setTimeout
|
|
13
|
-
window.requestIdleCallback =
|
|
14
|
-
window.requestIdleCallback ||
|
|
15
|
-
function (handler: any) {
|
|
16
|
-
const startTime = Date.now();
|
|
17
|
-
|
|
18
|
-
return setTimeout(function () {
|
|
19
|
-
handler({
|
|
20
|
-
didTimeout: false,
|
|
21
|
-
timeRemaining: function () {
|
|
22
|
-
return Math.max(0, 50.0 - (Date.now() - startTime));
|
|
23
|
-
}
|
|
24
|
-
});
|
|
25
|
-
}, 1);
|
|
26
|
-
};
|
|
27
|
-
window.cancelIdleCallback =
|
|
28
|
-
window.cancelIdleCallback ||
|
|
29
|
-
function (id: any) {
|
|
30
|
-
clearTimeout(id);
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export default class Lazy extends LightningElement {
|
|
35
|
-
@api mode: LazyMode = "idle";
|
|
36
|
-
|
|
37
|
-
// intersection mode api
|
|
38
|
-
@api rootId: string | undefined;
|
|
39
|
-
@api rootMargin: string = "0px";
|
|
40
|
-
@api threshold: number = 0;
|
|
41
|
-
|
|
42
|
-
@api
|
|
43
|
-
get placeholderSize() {
|
|
44
|
-
return this._placeholderSize;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
set placeholderSize(value) {
|
|
48
|
-
this._placeholderSize = value;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* 'rendered' marks the first call made to renderedCallback()
|
|
53
|
-
*/
|
|
54
|
-
private rendered: boolean = false;
|
|
55
|
-
/**
|
|
56
|
-
* 'renderSlot' controls whether the dx-lazy slot contents get rendered
|
|
57
|
-
*/
|
|
58
|
-
private renderSlot: boolean = false;
|
|
59
|
-
/**
|
|
60
|
-
* 'connectedCallbackCalled' marks the first call made to connectedCallback()
|
|
61
|
-
*/
|
|
62
|
-
private connectedCallbackCalled: boolean = false;
|
|
63
|
-
/**
|
|
64
|
-
* The handle as returned by calling window.requestIdleCallback()
|
|
65
|
-
*/
|
|
66
|
-
private idleCallbackHandle: any;
|
|
67
|
-
/**
|
|
68
|
-
* The Intersection Observer if instantiated, else undefined
|
|
69
|
-
*/
|
|
70
|
-
private observer: IntersectionObserver | undefined;
|
|
71
|
-
/**
|
|
72
|
-
* The size of the placeholder for the lazy container in pixels
|
|
73
|
-
*/
|
|
74
|
-
private _placeholderSize: number = 200;
|
|
75
|
-
|
|
76
|
-
constructor() {
|
|
77
|
-
super();
|
|
78
|
-
this.updateHostStyle();
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
connectedCallback() {
|
|
82
|
-
if (!this.connectedCallbackCalled) {
|
|
83
|
-
this.connectedCallbackCalled = true;
|
|
84
|
-
if (this.mode === "idle") {
|
|
85
|
-
defineBackgroundTasksAPI();
|
|
86
|
-
this.waitForIdle();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
renderedCallback() {
|
|
92
|
-
if (!this.rendered) {
|
|
93
|
-
this.rendered = true;
|
|
94
|
-
if (this.mode === "intersection") {
|
|
95
|
-
this.observeIntersection();
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
disconnectedCallback() {
|
|
101
|
-
if (this.observer) {
|
|
102
|
-
this.observer.disconnect();
|
|
103
|
-
}
|
|
104
|
-
if (this.idleCallbackHandle) {
|
|
105
|
-
window.cancelIdleCallback(this.idleCallbackHandle);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
private waitForIdle() {
|
|
110
|
-
this.idleCallbackHandle = window.requestIdleCallback(
|
|
111
|
-
this.idleCallback.bind(this),
|
|
112
|
-
{ timeout: 1000 }
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
private idleCallback() {
|
|
117
|
-
this.doRender();
|
|
118
|
-
window.cancelIdleCallback(this.idleCallbackHandle);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
private observeIntersection() {
|
|
122
|
-
let root = null; // root with a value of null means to use the viewport
|
|
123
|
-
if (this.rootId && typeof this.rootId === "string") {
|
|
124
|
-
root = document.querySelector(`#${this.rootId}`);
|
|
125
|
-
}
|
|
126
|
-
this.observer = new IntersectionObserver(
|
|
127
|
-
this.intersectionCallback.bind(this),
|
|
128
|
-
{
|
|
129
|
-
root,
|
|
130
|
-
rootMargin: this.rootMargin,
|
|
131
|
-
threshold: this.threshold
|
|
132
|
-
}
|
|
133
|
-
);
|
|
134
|
-
this.observer.observe(this.template.host);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
private intersectionCallback(
|
|
138
|
-
entries: IntersectionObserverEntry[],
|
|
139
|
-
observer: IntersectionObserver
|
|
140
|
-
) {
|
|
141
|
-
entries.forEach((entry: IntersectionObserverEntry) => {
|
|
142
|
-
if (entry.isIntersecting) {
|
|
143
|
-
this.doRender();
|
|
144
|
-
observer.disconnect();
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
private updateHostStyle() {
|
|
150
|
-
if (this.renderSlot) {
|
|
151
|
-
this.template.host.style.display = "";
|
|
152
|
-
this.template.host.style.minHeight = "";
|
|
153
|
-
} else {
|
|
154
|
-
this.template.host.style.display = "block";
|
|
155
|
-
this.template.host.style.minHeight = `${this._placeholderSize}px`;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
private doRender() {
|
|
160
|
-
this.renderSlot = true;
|
|
161
|
-
this.updateHostStyle();
|
|
162
|
-
}
|
|
163
|
-
}
|