@tet/tet-components 1.4.140-testing → 1.4.141-testing
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/dist/cjs/loader.cjs.js +1 -1
- package/dist/cjs/tet-assembler.cjs.entry.js +11 -2
- package/dist/cjs/tet-compare-card-v3.cjs.entry.js +7 -3
- package/dist/cjs/tet-components.cjs.js +1 -1
- package/dist/cjs/tet-sticky-offer.cjs.entry.js +138 -71
- package/dist/collection/components/advanced/cards/tet-assembler/tet-assembler.js +41 -2
- package/dist/collection/components/advanced/cards/tet-compare-card-v3/tet-compare-card-v3.js +24 -3
- package/dist/collection/components/simple/misc/tet-sticky-offer/tet-sticky-offer.css +22 -13
- package/dist/collection/components/simple/misc/tet-sticky-offer/tet-sticky-offer.js +212 -92
- package/dist/components/tet-assembler.js +1 -1
- package/dist/components/tet-compare-card-v3.js +1 -1
- package/dist/components/tet-sticky-offer.js +1 -1
- package/dist/esm/loader.js +1 -1
- package/dist/esm/tet-assembler.entry.js +11 -2
- package/dist/esm/tet-compare-card-v3.entry.js +7 -3
- package/dist/esm/tet-components.js +1 -1
- package/dist/esm/tet-sticky-offer.entry.js +138 -71
- package/dist/tet-components/p-755491fc.entry.js +1 -0
- package/dist/tet-components/p-77fb52c5.entry.js +1 -0
- package/dist/tet-components/p-7da3d5fb.entry.js +1 -0
- package/dist/tet-components/tet-components.esm.js +1 -1
- package/dist/types/components/advanced/cards/tet-assembler/tet-assembler.d.ts +2 -0
- package/dist/types/components/advanced/cards/tet-compare-card-v3/tet-compare-card-v3.d.ts +2 -0
- package/dist/types/components/simple/misc/tet-sticky-offer/tet-sticky-offer.d.ts +27 -13
- package/dist/types/components.d.ts +28 -7
- package/package.json +1 -1
- package/dist/tet-components/p-0690117e.entry.js +0 -1
- package/dist/tet-components/p-8a9d5ef1.entry.js +0 -1
- package/dist/tet-components/p-b17d4f71.entry.js +0 -1
|
@@ -450,6 +450,15 @@ export class TetAssembler {
|
|
|
450
450
|
primaryButtonUrl: this.getProductFormUrl(product, contractTerm, selectedContractTermId)
|
|
451
451
|
});
|
|
452
452
|
}
|
|
453
|
+
/** Returns the current selection and summary without emitting assemblerChange. */
|
|
454
|
+
async getSelection() {
|
|
455
|
+
return {
|
|
456
|
+
selectedContractTermId: this.selectedContractTermId,
|
|
457
|
+
selectedSwitchKeys: [...this.selectedSwitchKeys],
|
|
458
|
+
selectedProductCode: this.selectedProductCode,
|
|
459
|
+
summary: { ...this.currentSummary }
|
|
460
|
+
};
|
|
461
|
+
}
|
|
453
462
|
emitChange(source, changedKey, selectedContractTermId = this.selectedContractTermId, selectedSwitchKeys = this.selectedSwitchKeys, summary = this.currentSummary) {
|
|
454
463
|
this.assemblerChange.emit({
|
|
455
464
|
source,
|
|
@@ -769,13 +778,13 @@ export class TetAssembler {
|
|
|
769
778
|
!!this.getResolvedCollapsedDescription();
|
|
770
779
|
const hasContractSidePanel = Boolean(expandableSection?.items.some((item) => item.type === 'contract_term'));
|
|
771
780
|
const hasInformationalSidePanel = this.hasInformationalSidePanel();
|
|
772
|
-
return (h(Host, { key: '
|
|
781
|
+
return (h(Host, { key: '4e828a530bf518148a4848e073910ca9b0a38234' }, h("div", { key: 'c8fd3dac1ebe6f2f43ceb1cde520b0d9d837ff41', class: {
|
|
773
782
|
'assembler-layout': true,
|
|
774
783
|
'has-contract-side-panel': hasContractSidePanel,
|
|
775
784
|
'has-informational-side-panel': hasInformationalSidePanel,
|
|
776
785
|
'has-side-panel': hasSidePanel,
|
|
777
786
|
'is-expanded': this.expanded
|
|
778
|
-
} }, this.renderSidePanel(), h("div", { key: '
|
|
787
|
+
} }, this.renderSidePanel(), h("div", { key: '85df750dc67e4b96c881021c25c97d57cd4ef087', class: "assembler" }, h("div", { key: 'dbc219c05a8c32df0be8b063683cff8afc1827dd', class: "assembler__configuration" }, h("div", { key: '319099df513b590fad405011bb2a036ebc2f4564', class: "assembler__content" }, visibleSections.map((section) => this.renderSection(section)))), this.renderSummary()))));
|
|
779
788
|
}
|
|
780
789
|
static get is() { return "tet-assembler"; }
|
|
781
790
|
static get encapsulation() { return "shadow"; }
|
|
@@ -917,6 +926,36 @@ export class TetAssembler {
|
|
|
917
926
|
}
|
|
918
927
|
}];
|
|
919
928
|
}
|
|
929
|
+
static get methods() {
|
|
930
|
+
return {
|
|
931
|
+
"getSelection": {
|
|
932
|
+
"complexType": {
|
|
933
|
+
"signature": "() => Promise<Omit<AssemblerChangeEventInterface, \"source\" | \"changedKey\">>",
|
|
934
|
+
"parameters": [],
|
|
935
|
+
"references": {
|
|
936
|
+
"Promise": {
|
|
937
|
+
"location": "global",
|
|
938
|
+
"id": "global::Promise"
|
|
939
|
+
},
|
|
940
|
+
"Omit": {
|
|
941
|
+
"location": "global",
|
|
942
|
+
"id": "global::Omit"
|
|
943
|
+
},
|
|
944
|
+
"AssemblerChangeEventInterface": {
|
|
945
|
+
"location": "local",
|
|
946
|
+
"path": "/__w/internal-tet-web-components-tet-components/internal-tet-web-components-tet-components/src/src/components/advanced/cards/tet-assembler/tet-assembler.tsx",
|
|
947
|
+
"id": "src/components/advanced/cards/tet-assembler/tet-assembler.tsx::AssemblerChangeEventInterface"
|
|
948
|
+
}
|
|
949
|
+
},
|
|
950
|
+
"return": "Promise<Omit<AssemblerChangeEventInterface, \"source\" | \"changedKey\">>"
|
|
951
|
+
},
|
|
952
|
+
"docs": {
|
|
953
|
+
"text": "Returns the current selection and summary without emitting assemblerChange.",
|
|
954
|
+
"tags": []
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
};
|
|
958
|
+
}
|
|
920
959
|
static get elementRef() { return "host"; }
|
|
921
960
|
static get watchers() {
|
|
922
961
|
return [{
|
package/dist/collection/components/advanced/cards/tet-compare-card-v3/tet-compare-card-v3.js
CHANGED
|
@@ -214,6 +214,10 @@ export class TetCompareCardV3 {
|
|
|
214
214
|
return [...productOptions, ...(option.dropdownOptions?.length ? option.dropdownOptions : [option])];
|
|
215
215
|
}, []);
|
|
216
216
|
}
|
|
217
|
+
/** Returns whether the initial loaded render has completed and cardLoaded has been emitted. */
|
|
218
|
+
async isLoaded() {
|
|
219
|
+
return this.didEmitCardLoaded;
|
|
220
|
+
}
|
|
217
221
|
/** Returns loaded API product data with a complete form URL for each contract term. */
|
|
218
222
|
async getProductByCode(code) {
|
|
219
223
|
const option = this.getProductOptions().find(option => option.productCode === code);
|
|
@@ -625,10 +629,10 @@ export class TetCompareCardV3 {
|
|
|
625
629
|
? this.getCompleteUrl(manualProductData.formUrl, null)
|
|
626
630
|
: this.getCompleteUrl(baseUrl, selectedOption?.productCode ?? '', contractTermData);
|
|
627
631
|
const titleBadgeText = selectedOption?.titleBadge;
|
|
628
|
-
return (h("div", { class: "content content__top" }, (mainTitle || titleBadgeText) && (h("div", { class: "title-container" }, mainTitle && h("h3", { class: "title" }, mainTitle), titleBadgeText && (h("span", { class: "title-badge" }, h("tet-icon", { class: "title-badge__icon", name: "tc-info-circle" }), titleBadgeText)))), this.renderPrice(priceData), this.renderCardLabel(selectedOption), h("div", { class: "button-wrapper" }, h("tet-button", { class: "button", type: "primary", theme: "light", size: this.buttonSize, url: link, urlTarget: this.linkOpenBlank ? '_blank' : '_self' }, this.buttonTitle)), shouldRenderSecondaryLink && (h("div", { class: "secondary-link" }, h("a", { class: "tet-link", href: secondaryLink, target: secondaryLinkTarget, rel: secondaryLinkRel }, this.secondaryLinkText)))));
|
|
632
|
+
return (h("div", { key: "content-top", class: "content content__top" }, (mainTitle || titleBadgeText) && (h("div", { class: "title-container" }, mainTitle && h("h3", { class: "title" }, mainTitle), titleBadgeText && (h("span", { class: "title-badge" }, h("tet-icon", { class: "title-badge__icon", name: "tc-info-circle" }), titleBadgeText)))), this.renderPrice(priceData), this.renderCardLabel(selectedOption), h("div", { class: "button-wrapper" }, h("tet-button", { class: "button", type: "primary", theme: "light", size: this.buttonSize, url: link, urlTarget: this.linkOpenBlank ? '_blank' : '_self' }, this.buttonTitle)), shouldRenderSecondaryLink && (h("div", { class: "secondary-link" }, h("a", { class: "tet-link", href: secondaryLink, target: secondaryLinkTarget, rel: secondaryLinkRel }, this.secondaryLinkText)))));
|
|
629
633
|
}
|
|
630
634
|
renderContentBottom() {
|
|
631
|
-
return (h("div", { class: "content content__bottom" }, this.showControlsFirst
|
|
635
|
+
return (h("div", { key: "content-bottom", class: "content content__bottom" }, this.showControlsFirst
|
|
632
636
|
? [this.renderControls(), this.renderBonuses()]
|
|
633
637
|
: [this.renderBonuses(), this.renderControls()]));
|
|
634
638
|
}
|
|
@@ -655,7 +659,7 @@ export class TetCompareCardV3 {
|
|
|
655
659
|
return (h("tet-placeholder", { class: { 'card__placeholder': true, 'single-card': this.cardType === 'single-card' }, height: "100%", width: "100%", darkTheme: this.theme === 'dark' }));
|
|
656
660
|
}
|
|
657
661
|
render() {
|
|
658
|
-
return (h(Host, { key: '
|
|
662
|
+
return (h(Host, { key: '681b0b3acd21c3eeb254b3789708ac511f6c8cf9', "data-contains-focusable-content": true }, this.showLoader ? this.renderLoader() : this.renderCard()));
|
|
659
663
|
}
|
|
660
664
|
static get is() { return "tet-compare-card-v3"; }
|
|
661
665
|
static get encapsulation() { return "shadow"; }
|
|
@@ -1088,6 +1092,23 @@ export class TetCompareCardV3 {
|
|
|
1088
1092
|
}
|
|
1089
1093
|
static get methods() {
|
|
1090
1094
|
return {
|
|
1095
|
+
"isLoaded": {
|
|
1096
|
+
"complexType": {
|
|
1097
|
+
"signature": "() => Promise<boolean>",
|
|
1098
|
+
"parameters": [],
|
|
1099
|
+
"references": {
|
|
1100
|
+
"Promise": {
|
|
1101
|
+
"location": "global",
|
|
1102
|
+
"id": "global::Promise"
|
|
1103
|
+
}
|
|
1104
|
+
},
|
|
1105
|
+
"return": "Promise<boolean>"
|
|
1106
|
+
},
|
|
1107
|
+
"docs": {
|
|
1108
|
+
"text": "Returns whether the initial loaded render has completed and cardLoaded has been emitted.",
|
|
1109
|
+
"tags": []
|
|
1110
|
+
}
|
|
1111
|
+
},
|
|
1091
1112
|
"getProductByCode": {
|
|
1092
1113
|
"complexType": {
|
|
1093
1114
|
"signature": "(code: string) => Promise<ProductComparisonWithCompleteUrl | undefined>",
|
|
@@ -354,15 +354,14 @@
|
|
|
354
354
|
display: block;
|
|
355
355
|
max-width: 113.5rem;
|
|
356
356
|
position: fixed;
|
|
357
|
-
bottom: var(--bottom-offset);
|
|
357
|
+
bottom: calc(var(--bottom-offset) + var(--boundary-bottom, 0rem));
|
|
358
358
|
right: 0.5rem;
|
|
359
359
|
left: 0.5rem;
|
|
360
360
|
z-index: 10;
|
|
361
361
|
margin: 0 auto;
|
|
362
|
-
transform: translateY(calc(100% + var(--bottom-offset) + 0.125rem));
|
|
363
|
-
visibility: hidden;
|
|
362
|
+
transform: translateY(calc(100% + var(--bottom-offset) + var(--boundary-bottom, 0rem) + 0.125rem));
|
|
364
363
|
pointer-events: none;
|
|
365
|
-
transition: transform var(--animation-duration) ease
|
|
364
|
+
transition: transform var(--animation-duration) ease;
|
|
366
365
|
}
|
|
367
366
|
@media screen and (min-width: 31.25rem) {
|
|
368
367
|
:host {
|
|
@@ -376,37 +375,47 @@
|
|
|
376
375
|
left: 2rem;
|
|
377
376
|
}
|
|
378
377
|
}
|
|
379
|
-
@media screen and (min-width:
|
|
378
|
+
@media screen and (min-width: 90rem) {
|
|
380
379
|
:host {
|
|
381
380
|
right: 2.25rem;
|
|
382
381
|
left: 2.25rem;
|
|
383
382
|
}
|
|
384
383
|
}
|
|
385
384
|
|
|
386
|
-
:host(
|
|
385
|
+
:host(.offer-docked) {
|
|
386
|
+
position: relative;
|
|
387
|
+
left: var(--dock-left);
|
|
388
|
+
right: auto;
|
|
389
|
+
width: var(--dock-width);
|
|
390
|
+
bottom: auto;
|
|
391
|
+
margin: 0;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
:host(.offer-visible) {
|
|
387
395
|
transform: translateY(0);
|
|
388
|
-
visibility: visible;
|
|
389
396
|
pointer-events: auto;
|
|
390
|
-
transition:
|
|
397
|
+
transition: none;
|
|
391
398
|
animation: sticky-offer-slide-in var(--animation-duration) ease;
|
|
392
399
|
}
|
|
393
400
|
|
|
394
|
-
:host(
|
|
401
|
+
:host(.offer-visible) .sticky-offer {
|
|
395
402
|
visibility: visible;
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
:host([visible]:not(.scroll-hidden)) .sticky-offer {
|
|
403
|
+
transition: visibility 0s;
|
|
399
404
|
box-shadow: 0 4px 28.8px 0 rgba(0, 0, 0, 0.25);
|
|
400
405
|
}
|
|
401
406
|
|
|
402
407
|
@media (prefers-reduced-motion: reduce) {
|
|
403
408
|
:host,
|
|
404
|
-
:host(
|
|
409
|
+
:host(.offer-visible),
|
|
410
|
+
.sticky-offer,
|
|
411
|
+
:host(.offer-visible) .sticky-offer {
|
|
405
412
|
transition: none;
|
|
406
413
|
animation: none;
|
|
407
414
|
}
|
|
408
415
|
}
|
|
409
416
|
.sticky-offer {
|
|
417
|
+
visibility: hidden;
|
|
418
|
+
transition: visibility 0s linear var(--animation-duration);
|
|
410
419
|
display: flex;
|
|
411
420
|
flex-direction: column;
|
|
412
421
|
gap: 0.5rem;
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import { h, Host } from "@stencil/core";
|
|
2
|
-
const HIDE_SCROLL_DISTANCE = 205;
|
|
3
|
-
const SHOW_SCROLL_DISTANCE = 24;
|
|
4
2
|
/** Offer anchored to the bottom of the viewport. */
|
|
5
3
|
export class TetStickyOffer {
|
|
6
4
|
host;
|
|
7
5
|
/** Shows the offer when true and slides it out of view when false. */
|
|
8
6
|
visible = true;
|
|
9
|
-
/** Hides the offer after scrolling down and shows it when scrolling up. Set to false to disable. */
|
|
10
|
-
hideOnScroll = true;
|
|
11
7
|
/** Offer name displayed in the banner. */
|
|
12
8
|
offerName = '';
|
|
13
9
|
/** Formatted price amount, without the suffix. */
|
|
@@ -20,93 +16,158 @@ export class TetStickyOffer {
|
|
|
20
16
|
actionUrl = '';
|
|
21
17
|
/** Browsing context for actionUrl when it is set. */
|
|
22
18
|
actionTarget = '_self';
|
|
23
|
-
|
|
19
|
+
/** Scrolling element whose top must pass above the top boundary's bottom before the offer appears. */
|
|
20
|
+
triggerElement;
|
|
21
|
+
/** Element whose bottom defines the visibility threshold when a trigger is provided. Defaults to the viewport top. */
|
|
22
|
+
topBoundaryElement;
|
|
23
|
+
/** Footer before which the offer docks, matching the preceding module's bottom padding. */
|
|
24
|
+
bottomBoundaryElement;
|
|
24
25
|
/** Emitted when the offer action is activated. */
|
|
25
26
|
applyClick;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
boundaryVisible = true;
|
|
28
|
+
boundaryBottom = 0;
|
|
29
|
+
docked = false;
|
|
30
|
+
dockingSpace;
|
|
31
|
+
moving = false;
|
|
32
|
+
fixedBottomOffset = 0;
|
|
33
|
+
refreshDockSize = false;
|
|
34
|
+
boundaryObserver;
|
|
35
|
+
boundaryFrame = null;
|
|
36
|
+
hasLoaded = false;
|
|
37
|
+
detectedModule = null;
|
|
38
|
+
componentWillLoad() {
|
|
39
|
+
this.updateBoundaries();
|
|
33
40
|
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
this.scrollFrame = null;
|
|
38
|
-
}
|
|
41
|
+
componentDidLoad() {
|
|
42
|
+
this.hasLoaded = true;
|
|
43
|
+
this.setupDockingSpace();
|
|
39
44
|
}
|
|
40
|
-
|
|
41
|
-
if (this.
|
|
42
|
-
|
|
43
|
-
this.scrollFrame = null;
|
|
45
|
+
connectedCallback() {
|
|
46
|
+
if (this.hasLoaded && !this.moving) {
|
|
47
|
+
this.setupDockingSpace();
|
|
44
48
|
}
|
|
45
|
-
this.scrollHidden = false;
|
|
46
|
-
this.scrollDistance = 0;
|
|
47
|
-
this.scrollDirection = 0;
|
|
48
|
-
this.lastScrollY = Math.max(0, window.scrollY);
|
|
49
|
-
this.lastDocumentHeight = this.getDocumentHeight();
|
|
50
49
|
}
|
|
51
|
-
|
|
52
|
-
if (
|
|
50
|
+
disconnectedCallback() {
|
|
51
|
+
if (this.moving) {
|
|
53
52
|
return;
|
|
54
53
|
}
|
|
55
|
-
this.
|
|
54
|
+
this.dockingSpace?.remove();
|
|
55
|
+
this.dockingSpace = undefined;
|
|
56
|
+
this.detectedModule = null;
|
|
57
|
+
this.docked = false;
|
|
58
|
+
this.host.classList.remove('offer-docked');
|
|
59
|
+
this.boundaryObserver?.disconnect();
|
|
60
|
+
if (this.boundaryFrame !== null) {
|
|
61
|
+
cancelAnimationFrame(this.boundaryFrame);
|
|
62
|
+
this.boundaryFrame = null;
|
|
63
|
+
}
|
|
56
64
|
}
|
|
57
|
-
|
|
58
|
-
this.
|
|
59
|
-
const scrollY = Math.max(0, window.scrollY);
|
|
60
|
-
const documentHeight = this.getDocumentHeight();
|
|
61
|
-
if (documentHeight !== this.lastDocumentHeight) {
|
|
62
|
-
this.lastDocumentHeight = documentHeight;
|
|
63
|
-
this.lastScrollY = scrollY;
|
|
64
|
-
this.scrollDistance = 0;
|
|
65
|
-
this.scrollDirection = 0;
|
|
65
|
+
setupDockingSpace() {
|
|
66
|
+
if (!this.hasLoaded || this.dockingSpace) {
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
this.
|
|
72
|
-
this.
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
if (this.bottomBoundaryElement?.parentNode) {
|
|
70
|
+
this.dockingSpace = document.createElement('div');
|
|
71
|
+
this.dockingSpace.style.boxSizing = 'border-box';
|
|
72
|
+
this.bottomBoundaryElement.parentNode.insertBefore(this.dockingSpace, this.bottomBoundaryElement);
|
|
73
|
+
this.moving = true;
|
|
74
|
+
try {
|
|
75
|
+
this.dockingSpace.appendChild(this.host);
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
this.moving = false;
|
|
79
|
+
}
|
|
75
80
|
}
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
this.observeBoundaries();
|
|
82
|
+
}
|
|
83
|
+
observeBoundaries() {
|
|
84
|
+
if (!this.hasLoaded) {
|
|
78
85
|
return;
|
|
79
86
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
87
|
+
this.boundaryObserver?.disconnect();
|
|
88
|
+
if (this.triggerElement || this.bottomBoundaryElement) {
|
|
89
|
+
this.boundaryObserver = new ResizeObserver(() => this.scheduleBoundaryUpdate(true));
|
|
90
|
+
const elements = [this.host, this.triggerElement, this.topBoundaryElement, this.bottomBoundaryElement, document.body];
|
|
91
|
+
for (const element of elements) {
|
|
92
|
+
if (element) {
|
|
93
|
+
this.boundaryObserver.observe(element);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
83
96
|
}
|
|
84
|
-
this.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
this.
|
|
88
|
-
|
|
89
|
-
|
|
97
|
+
this.updateBoundaries();
|
|
98
|
+
}
|
|
99
|
+
updateBoundaries() {
|
|
100
|
+
this.boundaryVisible = this.triggerElement
|
|
101
|
+
? this.triggerElement.getBoundingClientRect().top <= (this.topBoundaryElement?.getBoundingClientRect().bottom ?? 0)
|
|
102
|
+
: true;
|
|
103
|
+
if (this.dockingSpace) {
|
|
104
|
+
this.boundaryBottom = 0;
|
|
105
|
+
this.updateDocking();
|
|
106
|
+
return;
|
|
90
107
|
}
|
|
91
|
-
|
|
92
|
-
|
|
108
|
+
this.boundaryBottom = this.bottomBoundaryElement
|
|
109
|
+
? Math.max(0, window.innerHeight - this.bottomBoundaryElement.getBoundingClientRect().top)
|
|
110
|
+
: 0;
|
|
111
|
+
}
|
|
112
|
+
onScroll() {
|
|
113
|
+
if (this.dockingSpace) {
|
|
114
|
+
this.updateBoundaries();
|
|
93
115
|
}
|
|
94
116
|
else {
|
|
117
|
+
this.scheduleBoundaryUpdate();
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
onResize() {
|
|
121
|
+
this.scheduleBoundaryUpdate(true);
|
|
122
|
+
}
|
|
123
|
+
scheduleBoundaryUpdate(refreshDockSize = false) {
|
|
124
|
+
this.refreshDockSize ||= refreshDockSize;
|
|
125
|
+
if ((!this.triggerElement && !this.bottomBoundaryElement) || this.boundaryFrame !== null) {
|
|
95
126
|
return;
|
|
96
127
|
}
|
|
97
|
-
this.
|
|
128
|
+
this.boundaryFrame = requestAnimationFrame(() => {
|
|
129
|
+
this.boundaryFrame = null;
|
|
130
|
+
this.updateBoundaries();
|
|
131
|
+
this.refreshDockSize = false;
|
|
132
|
+
});
|
|
98
133
|
}
|
|
99
|
-
|
|
100
|
-
|
|
134
|
+
updateDocking() {
|
|
135
|
+
if (!this.dockingSpace)
|
|
136
|
+
return;
|
|
137
|
+
const space = this.dockingSpace;
|
|
138
|
+
const spaceRect = space.getBoundingClientRect();
|
|
139
|
+
const module = this.getModuleAboveDock(spaceRect);
|
|
140
|
+
if (!this.docked || this.refreshDockSize) {
|
|
141
|
+
this.host.classList.remove('offer-docked');
|
|
142
|
+
const rect = this.host.getBoundingClientRect();
|
|
143
|
+
this.fixedBottomOffset = Number.parseFloat(getComputedStyle(this.host).bottom) || 0;
|
|
144
|
+
space.style.setProperty('--dock-left', `${rect.left - spaceRect.left}px`);
|
|
145
|
+
space.style.setProperty('--dock-width', `${rect.width}px`);
|
|
146
|
+
if (this.docked) {
|
|
147
|
+
this.host.classList.add('offer-docked');
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const gap = (module ? Number.parseFloat(getComputedStyle(module).paddingBottom) : 0) || this.fixedBottomOffset;
|
|
151
|
+
const height = this.host.getBoundingClientRect().height;
|
|
152
|
+
const show = this.visible && this.boundaryVisible;
|
|
153
|
+
space.style.minHeight = `${show ? height + gap : 0}px`;
|
|
154
|
+
space.style.paddingBottom = `${show ? gap : 0}px`;
|
|
155
|
+
const viewportHeight = document.documentElement.clientHeight || window.innerHeight;
|
|
156
|
+
this.docked = show && spaceRect.top <= viewportHeight - height - this.fixedBottomOffset;
|
|
157
|
+
this.host.classList[this.docked ? 'add' : 'remove']('offer-docked');
|
|
101
158
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
this.
|
|
105
|
-
|
|
159
|
+
getModuleAboveDock(rect) {
|
|
160
|
+
const module = document.elementsFromPoint(rect.left + rect.width / 2, rect.top - 1)
|
|
161
|
+
.filter(element => element !== this.host && !this.host.contains(element) && element !== this.dockingSpace)
|
|
162
|
+
.map(element => element.closest('.module-inner'))
|
|
163
|
+
.find(element => element && element.getBoundingClientRect().height > 0);
|
|
164
|
+
if (module) {
|
|
165
|
+
this.detectedModule = module;
|
|
106
166
|
}
|
|
167
|
+
return this.detectedModule;
|
|
107
168
|
}
|
|
108
169
|
render() {
|
|
109
|
-
return (h(Host, { key: '
|
|
170
|
+
return (h(Host, { key: '050e9efaa967642b61ef5af7af8a4352a46677f1', class: { 'offer-visible': this.visible && this.boundaryVisible }, style: { '--boundary-bottom': `${this.boundaryBottom}px` } }, h("div", { key: 'ca93b30409a5adb481d88197268981e4942730f3', class: "sticky-offer", inert: !this.visible || !this.boundaryVisible }, h("span", { key: 'b7f96b13d94d9138ccf6bd221c67a49bb57ab479', class: "sticky-offer__name", "aria-live": "polite", "aria-atomic": "true" }, this.offerName), h("div", { key: '9522bf5ad6df226b09ff3cc338217d2863c883f8', class: "sticky-offer__inner-container" }, h("div", { key: 'c7650ad7d5b115a51dfc0f510febb7a9116d57bb', class: "sticky-offer__price-container", "aria-live": "polite", "aria-atomic": "true" }, h("span", { key: '56a29f81f29d3ef7acced8755dbd327b895d4901', class: "sticky-offer__price" }, this.price), this.priceSuffix && (h("span", { key: '20c863ee368d698e4ec34c009914306feb33a719', class: "sticky-offer__price-suffix" }, this.priceSuffix))), h("tet-button", { key: '871d4e641f1c507656f10343dce8abc919922c85', size: "small", theme: "light", breakpointConfig: {
|
|
110
171
|
lg: { size: 'medium' },
|
|
111
172
|
xl: { size: 'large' },
|
|
112
173
|
}, url: this.actionUrl, urlTarget: this.actionTarget, onClick: () => this.applyClick.emit() }, this.actionLabel)))));
|
|
@@ -145,26 +206,6 @@ export class TetStickyOffer {
|
|
|
145
206
|
"attribute": "visible",
|
|
146
207
|
"defaultValue": "true"
|
|
147
208
|
},
|
|
148
|
-
"hideOnScroll": {
|
|
149
|
-
"type": "boolean",
|
|
150
|
-
"mutable": false,
|
|
151
|
-
"complexType": {
|
|
152
|
-
"original": "boolean",
|
|
153
|
-
"resolved": "boolean",
|
|
154
|
-
"references": {}
|
|
155
|
-
},
|
|
156
|
-
"required": false,
|
|
157
|
-
"optional": false,
|
|
158
|
-
"docs": {
|
|
159
|
-
"tags": [],
|
|
160
|
-
"text": "Hides the offer after scrolling down and shows it when scrolling up. Set to false to disable."
|
|
161
|
-
},
|
|
162
|
-
"getter": false,
|
|
163
|
-
"setter": false,
|
|
164
|
-
"reflect": false,
|
|
165
|
-
"attribute": "hide-on-scroll",
|
|
166
|
-
"defaultValue": "true"
|
|
167
|
-
},
|
|
168
209
|
"offerName": {
|
|
169
210
|
"type": "string",
|
|
170
211
|
"mutable": false,
|
|
@@ -284,12 +325,79 @@ export class TetStickyOffer {
|
|
|
284
325
|
"reflect": false,
|
|
285
326
|
"attribute": "action-target",
|
|
286
327
|
"defaultValue": "'_self'"
|
|
328
|
+
},
|
|
329
|
+
"triggerElement": {
|
|
330
|
+
"type": "unknown",
|
|
331
|
+
"mutable": false,
|
|
332
|
+
"complexType": {
|
|
333
|
+
"original": "HTMLElement",
|
|
334
|
+
"resolved": "HTMLElement",
|
|
335
|
+
"references": {
|
|
336
|
+
"HTMLElement": {
|
|
337
|
+
"location": "global",
|
|
338
|
+
"id": "global::HTMLElement"
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
},
|
|
342
|
+
"required": false,
|
|
343
|
+
"optional": true,
|
|
344
|
+
"docs": {
|
|
345
|
+
"tags": [],
|
|
346
|
+
"text": "Scrolling element whose top must pass above the top boundary's bottom before the offer appears."
|
|
347
|
+
},
|
|
348
|
+
"getter": false,
|
|
349
|
+
"setter": false
|
|
350
|
+
},
|
|
351
|
+
"topBoundaryElement": {
|
|
352
|
+
"type": "unknown",
|
|
353
|
+
"mutable": false,
|
|
354
|
+
"complexType": {
|
|
355
|
+
"original": "HTMLElement",
|
|
356
|
+
"resolved": "HTMLElement",
|
|
357
|
+
"references": {
|
|
358
|
+
"HTMLElement": {
|
|
359
|
+
"location": "global",
|
|
360
|
+
"id": "global::HTMLElement"
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
"required": false,
|
|
365
|
+
"optional": true,
|
|
366
|
+
"docs": {
|
|
367
|
+
"tags": [],
|
|
368
|
+
"text": "Element whose bottom defines the visibility threshold when a trigger is provided. Defaults to the viewport top."
|
|
369
|
+
},
|
|
370
|
+
"getter": false,
|
|
371
|
+
"setter": false
|
|
372
|
+
},
|
|
373
|
+
"bottomBoundaryElement": {
|
|
374
|
+
"type": "unknown",
|
|
375
|
+
"mutable": false,
|
|
376
|
+
"complexType": {
|
|
377
|
+
"original": "HTMLElement",
|
|
378
|
+
"resolved": "HTMLElement",
|
|
379
|
+
"references": {
|
|
380
|
+
"HTMLElement": {
|
|
381
|
+
"location": "global",
|
|
382
|
+
"id": "global::HTMLElement"
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
},
|
|
386
|
+
"required": false,
|
|
387
|
+
"optional": true,
|
|
388
|
+
"docs": {
|
|
389
|
+
"tags": [],
|
|
390
|
+
"text": "Footer before which the offer docks, matching the preceding module's bottom padding."
|
|
391
|
+
},
|
|
392
|
+
"getter": false,
|
|
393
|
+
"setter": false
|
|
287
394
|
}
|
|
288
395
|
};
|
|
289
396
|
}
|
|
290
397
|
static get states() {
|
|
291
398
|
return {
|
|
292
|
-
"
|
|
399
|
+
"boundaryVisible": {},
|
|
400
|
+
"boundaryBottom": {}
|
|
293
401
|
};
|
|
294
402
|
}
|
|
295
403
|
static get events() {
|
|
@@ -313,17 +421,29 @@ export class TetStickyOffer {
|
|
|
313
421
|
static get elementRef() { return "host"; }
|
|
314
422
|
static get watchers() {
|
|
315
423
|
return [{
|
|
316
|
-
"propName": "
|
|
317
|
-
"methodName": "
|
|
424
|
+
"propName": "bottomBoundaryElement",
|
|
425
|
+
"methodName": "setupDockingSpace"
|
|
426
|
+
}, {
|
|
427
|
+
"propName": "triggerElement",
|
|
428
|
+
"methodName": "observeBoundaries"
|
|
429
|
+
}, {
|
|
430
|
+
"propName": "topBoundaryElement",
|
|
431
|
+
"methodName": "observeBoundaries"
|
|
318
432
|
}, {
|
|
319
|
-
"propName": "
|
|
320
|
-
"methodName": "
|
|
433
|
+
"propName": "visible",
|
|
434
|
+
"methodName": "updateBoundaries"
|
|
321
435
|
}];
|
|
322
436
|
}
|
|
323
437
|
static get listeners() {
|
|
324
438
|
return [{
|
|
325
439
|
"name": "scroll",
|
|
326
|
-
"method": "
|
|
440
|
+
"method": "onScroll",
|
|
441
|
+
"target": "window",
|
|
442
|
+
"capture": true,
|
|
443
|
+
"passive": true
|
|
444
|
+
}, {
|
|
445
|
+
"name": "resize",
|
|
446
|
+
"method": "onResize",
|
|
327
447
|
"target": "window",
|
|
328
448
|
"capture": false,
|
|
329
449
|
"passive": true
|