@liquidcommercedev/rmn-sdk 1.4.6-beta.1 → 1.4.6-beta.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. package/dist/index.cjs +1360 -645
  2. package/dist/index.esm.js +1360 -645
  3. package/dist/types/enums.d.ts +57 -1
  4. package/dist/types/modules/element/component/carousel/carousel.component.d.ts +3 -0
  5. package/dist/types/modules/element/component/carousel/carousel.interface.d.ts +31 -0
  6. package/dist/types/modules/element/component/carousel/carousel.style.d.ts +2 -0
  7. package/dist/types/modules/element/component/carousel/index.d.ts +3 -0
  8. package/dist/types/modules/element/component/spot/index.d.ts +2 -0
  9. package/dist/types/modules/element/component/spot/spot.component.d.ts +3 -0
  10. package/dist/types/modules/element/component/spot/spot.interface.d.ts +10 -0
  11. package/dist/types/modules/{spot/html/constants/html.constant.d.ts → element/element.constant.d.ts} +2 -5
  12. package/dist/types/modules/element/element.interface.d.ts +41 -0
  13. package/dist/types/modules/element/element.service.d.ts +40 -0
  14. package/dist/types/modules/element/index.d.ts +3 -0
  15. package/dist/types/modules/element/template/helper.d.ts +3 -0
  16. package/dist/types/modules/element/template/index.d.ts +1 -0
  17. package/dist/types/modules/element/template/reservebar/collection-banner-without-text-block.template.d.ts +3 -0
  18. package/dist/types/modules/element/template/reservebar/homepage-hero-full-image.template.d.ts +3 -0
  19. package/dist/types/modules/element/template/reservebar/homepage-hero-three-tile.template.d.ts +3 -0
  20. package/dist/types/modules/element/template/reservebar/homepage-hero-two-tile.template.d.ts +3 -0
  21. package/dist/types/modules/element/template/reservebar/large-category-image-tout.template.d.ts +3 -0
  22. package/dist/types/modules/element/template/reservebar/navigation-banner.template.d.ts +3 -0
  23. package/dist/types/modules/element/template/reservebar/small-category-image-tout.template.d.ts +3 -0
  24. package/dist/types/modules/element/template/reservebar/small-discover-tout.template.d.ts +3 -0
  25. package/dist/types/modules/element/template/template.service.d.ts +10 -0
  26. package/dist/types/modules/element/template/template.type.d.ts +11 -0
  27. package/dist/types/modules/event/event.constant.d.ts +1 -0
  28. package/dist/types/modules/event/event.interface.d.ts +5 -0
  29. package/dist/types/modules/event/event.service.d.ts +5 -0
  30. package/dist/types/modules/event/helpers/index.d.ts +2 -0
  31. package/dist/types/modules/event/helpers/intersection.service.d.ts +8 -0
  32. package/dist/types/modules/event/helpers/resize.service.d.ts +30 -0
  33. package/dist/types/modules/event/index.d.ts +3 -0
  34. package/dist/types/modules/selection/index.d.ts +4 -0
  35. package/dist/types/modules/selection/selection.constant.d.ts +1 -0
  36. package/dist/types/modules/{spot/spot.interface.d.ts → selection/selection.interface.d.ts} +4 -11
  37. package/dist/types/modules/selection/selection.service.d.ts +16 -0
  38. package/dist/types/modules/{spot/spot.type.d.ts → selection/selection.type.d.ts} +1 -1
  39. package/dist/types/rmn-client.d.ts +41 -19
  40. package/dist/types/static.constant.d.ts +3 -0
  41. package/dist/types/types.d.ts +7 -5
  42. package/package.json +2 -2
  43. package/umd/liquidcommerce-rmn-sdk.min.js +1 -1
  44. package/dist/types/modules/spot/html/constants/index.d.ts +0 -1
  45. package/dist/types/modules/spot/html/index.d.ts +0 -1
  46. package/dist/types/modules/spot/html/spot.element.service.d.ts +0 -7
  47. package/dist/types/modules/spot/html/templates/index.d.ts +0 -1
  48. package/dist/types/modules/spot/html/templates/reservebar/collection-banner-without-text-block.template.d.ts +0 -2
  49. package/dist/types/modules/spot/html/templates/reservebar/homepage-hero-full-image.template.d.ts +0 -2
  50. package/dist/types/modules/spot/html/templates/reservebar/homepage-hero-three-tile.template.d.ts +0 -2
  51. package/dist/types/modules/spot/html/templates/reservebar/homepage-hero-two-tile.template.d.ts +0 -2
  52. package/dist/types/modules/spot/html/templates/reservebar/large-category-image-tout.template.d.ts +0 -2
  53. package/dist/types/modules/spot/html/templates/reservebar/navigation-banner.template.d.ts +0 -2
  54. package/dist/types/modules/spot/html/templates/reservebar/small-category-image-tout.template.d.ts +0 -2
  55. package/dist/types/modules/spot/html/templates/reservebar/small-discover-tout.template.d.ts +0 -2
  56. package/dist/types/modules/spot/html/templates/spot.template.d.ts +0 -21
  57. package/dist/types/modules/spot/index.d.ts +0 -6
  58. package/dist/types/modules/spot/spot.constant.d.ts +0 -4
  59. package/dist/types/modules/spot/spot.enum.d.ts +0 -57
  60. package/dist/types/modules/spot/spot.html.service.d.ts +0 -22
  61. package/dist/types/modules/spot/spot.selection.service.d.ts +0 -15
  62. /package/dist/types/modules/{spot/html/templates → element/template}/iab/billboard/billboard-v1.template.d.ts +0 -0
  63. /package/dist/types/modules/{spot/html/templates → element/template}/iab/billboard/billboard-v2.template.d.ts +0 -0
  64. /package/dist/types/modules/{spot/html/templates → element/template}/iab/billboard/billboard-v3.template.d.ts +0 -0
  65. /package/dist/types/modules/{spot/html/templates → element/template}/iab/billboard/index.d.ts +0 -0
  66. /package/dist/types/modules/{spot/html/templates → element/template}/iab/in-text/in-text-v1.template.d.ts +0 -0
  67. /package/dist/types/modules/{spot/html/templates → element/template}/iab/in-text/index.d.ts +0 -0
  68. /package/dist/types/modules/{spot/html/templates → element/template}/iab/index.d.ts +0 -0
  69. /package/dist/types/modules/{spot/html/templates → element/template}/iab/large-leaderboard/index.d.ts +0 -0
  70. /package/dist/types/modules/{spot/html/templates → element/template}/iab/large-leaderboard/large-leaderboard-v1.template.d.ts +0 -0
  71. /package/dist/types/modules/{spot/html/templates → element/template}/iab/large-leaderboard/large-leaderboard-v2.template.d.ts +0 -0
  72. /package/dist/types/modules/{spot/html/templates → element/template}/iab/large-rectangle/index.d.ts +0 -0
  73. /package/dist/types/modules/{spot/html/templates → element/template}/iab/large-rectangle/large-rectangle-v1.template.d.ts +0 -0
  74. /package/dist/types/modules/{spot/html/templates → element/template}/iab/square/index.d.ts +0 -0
  75. /package/dist/types/modules/{spot/html/templates → element/template}/iab/square/square-v1.template.d.ts +0 -0
  76. /package/dist/types/modules/{spot/html/templates → element/template}/iab/square/square-v2.template.d.ts +0 -0
  77. /package/dist/types/modules/{spot/html/templates → element/template}/iab/vertical-rectangle/index.d.ts +0 -0
  78. /package/dist/types/modules/{spot/html/templates → element/template}/iab/vertical-rectangle/vertical-rectangle-v1.template.d.ts +0 -0
  79. /package/dist/types/modules/{spot/html/templates → element/template}/iab/wide-skyscraper/index.d.ts +0 -0
  80. /package/dist/types/modules/{spot/html/templates → element/template}/iab/wide-skyscraper/wide-skyscraper-v1.template.d.ts +0 -0
  81. /package/dist/types/modules/{spot/html/templates → element/template}/reservebar/index.d.ts +0 -0
package/dist/index.cjs CHANGED
@@ -62,7 +62,6 @@ exports.RMN_SPOT_EVENT = void 0;
62
62
  RMN_SPOT_EVENT["ADD_TO_WISHLIST"] = "ADD_TO_WISHLIST";
63
63
  RMN_SPOT_EVENT["BUY_NOW"] = "BUY_NOW";
64
64
  })(exports.RMN_SPOT_EVENT || (exports.RMN_SPOT_EVENT = {}));
65
-
66
65
  exports.RMN_ENV = void 0;
67
66
  (function (RMN_ENV) {
68
67
  RMN_ENV["LOCAL"] = "local";
@@ -14999,7 +14998,7 @@ class BaseApi extends BaseApiAbstract {
14999
14998
  */
15000
14999
  async post(path, data, configOverrides) {
15001
15000
  let requestData = data;
15002
- if (this.authInfo.env !== exports.RMN_ENV.DEVELOPMENT) {
15001
+ if (this.authInfo.env !== exports.RMN_ENV.LOCAL) {
15003
15002
  const timestamp = new Date().getTime();
15004
15003
  configOverrides = {
15005
15004
  ...configOverrides,
@@ -15152,9 +15151,7 @@ class AuthService extends BaseApi {
15152
15151
  }
15153
15152
 
15154
15153
  const SPOT_ELEMENT_TAG = 'spot-element';
15155
- const SPOT_ELEMENT_SLOT_NAME = `${SPOT_ELEMENT_TAG}-custom-content`;
15156
- const SPOTS_SELECTION_API_PATH = '/spots/selection';
15157
-
15154
+ const CAROUSEL_ELEMENT_TAG = 'spot-carousel-element';
15158
15155
  const GFONT_PRECONNECT = `
15159
15156
  <link rel="preconnect" href="https://fonts.googleapis.com">
15160
15157
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
@@ -15165,42 +15162,724 @@ const GFONT_SOURCE_SANS_3 = `
15165
15162
  const GFONT_CORMORANT = `
15166
15163
  <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,300..700;1,300..700&family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap">
15167
15164
  `;
15168
- const SPOT_ELEMENT_TEMPLATE = (width, height, hasCustomContent) => {
15169
- const style = document.createElement('style');
15170
- style.textContent = `
15171
- :host {
15172
- display: block;
15173
- position: relative;
15174
- container-type: inline-size;
15175
- overflow: hidden;
15165
+
15166
+ class ResizeObserverService {
15167
+ constructor({ element, maxSize, minScale }) {
15168
+ this.element = element;
15169
+ if (!element.parentElement) {
15170
+ throw new Error('RmnSdk: Spot element must have a parent container.');
15171
+ }
15172
+ this.container = element.parentElement;
15173
+ this.setDimensions(maxSize, minScale);
15174
+ this.resizeObserver = new ResizeObserver(() => this.updateElementSize());
15175
+ this.resizeObserver.observe(this.container);
15176
+ // Initial size update
15177
+ this.updateElementSize();
15178
+ }
15179
+ setDimensions(maxSize, minScale) {
15180
+ if (minScale <= 0 || minScale > 1) {
15181
+ throw new Error('RmnSdk: Invalid minScale value');
15182
+ }
15183
+ const minSize = {
15184
+ width: maxSize.width * minScale,
15185
+ height: maxSize.height * minScale,
15186
+ };
15187
+ if (maxSize.width <= 0 || maxSize.height <= 0 || minSize.width <= 0 || minSize.height <= 0) {
15188
+ throw new Error('RmnSdk: Invalid dimensions');
15189
+ }
15190
+ if (minSize.width > maxSize.width || minSize.height > maxSize.height) {
15191
+ throw new Error('RmnSdk: Minimum size cannot be greater than maximum size');
15192
+ }
15193
+ this.maxSize = maxSize;
15194
+ this.minSize = minSize;
15195
+ this.aspectRatio = this.maxSize.width / this.maxSize.height;
15196
+ }
15197
+ updateElementSize() {
15198
+ const { clientWidth: containerWidth, clientHeight: containerHeight } = this.container;
15199
+ let newWidth;
15200
+ let newHeight;
15201
+ // First, try to fit the maximum width
15202
+ newWidth = Math.min(containerWidth, this.maxSize.width);
15203
+ newHeight = newWidth / this.aspectRatio;
15204
+ // If the height exceeds the container, adjust based on height
15205
+ if (newHeight > containerHeight) {
15206
+ newHeight = containerHeight;
15207
+ newWidth = newHeight * this.aspectRatio;
15208
+ }
15209
+ // Ensure we're not going below minimum dimensions
15210
+ newWidth = Math.max(newWidth, this.minSize.width);
15211
+ newHeight = Math.max(newHeight, this.minSize.height);
15212
+ this.element.style.width = `${newWidth}px`;
15213
+ this.element.style.height = `${newHeight}px`;
15214
+ // Calculate the scale percentage
15215
+ const scaleWidth = newWidth / this.maxSize.width;
15216
+ const scaleHeight = newHeight / this.maxSize.height;
15217
+ const scale = Math.min(scaleWidth, scaleHeight);
15218
+ // Dispatch a custom event
15219
+ this.element.dispatchEvent(new CustomEvent('spotSizeChanged', {
15220
+ detail: {
15221
+ width: this.maxSize.width,
15222
+ height: this.maxSize.height,
15223
+ newWidth,
15224
+ newHeight,
15225
+ scale,
15226
+ },
15227
+ }));
15176
15228
  }
15177
- :host([fluid="true"]) {
15178
- width: 100%;
15179
- height: 100%;
15229
+ disconnect() {
15230
+ this.resizeObserver.disconnect();
15180
15231
  }
15181
- :host([fluid="false"]) {
15182
- width: ${width}px;
15183
- height: ${height}px;
15232
+ }
15233
+
15234
+ const CAROUSEL_COMPONENT_STYLE = ({ width, height, fluid }) => `
15235
+ :host {
15236
+ position: relative;
15237
+ display: inline-block;
15238
+ margin: 0;
15239
+ overflow: hidden;
15240
+ width: ${fluid ? '100%' : `${width}px`};
15241
+ height: ${fluid ? '100%' : `${height}px`};
15184
15242
  }
15185
- `;
15186
- const wrapper = document.createElement('div');
15187
- wrapper.className = 'wrapper';
15188
- const slot = document.createElement('slot');
15189
- slot.name = SPOT_ELEMENT_SLOT_NAME;
15190
- if (!hasCustomContent) {
15191
- style.textContent += `
15192
- :host .wrapper {
15193
- position: absolute;
15194
- top: 0;
15195
- left: 0;
15243
+
15244
+ .slides {
15245
+ position: relative;
15246
+ height: 100%;
15196
15247
  width: 100%;
15248
+ }
15249
+
15250
+ .slide {
15251
+ display: none;
15252
+
15253
+ justify-content: center;
15254
+ align-items: center;
15197
15255
  height: 100%;
15198
- overflow: hidden;
15199
- }
15200
- `;
15256
+ width: 100%;
15201
15257
  }
15202
- return { style, wrapper, slot };
15203
- };
15258
+
15259
+ .slide.active {
15260
+ display: flex;
15261
+ }
15262
+
15263
+ .dots {
15264
+ position: absolute;
15265
+ display: flex;
15266
+ align-items: center;
15267
+ gap: 8px;
15268
+ }
15269
+
15270
+ .dots .dot {
15271
+ width: 12px;
15272
+ height: 12px;
15273
+ border-radius: 50%;
15274
+ cursor: pointer;
15275
+ transition: all 0.3s ease;
15276
+ }
15277
+
15278
+ .dots.top-left,
15279
+ .dots.bottom-left {
15280
+ left: 10px;
15281
+ }
15282
+
15283
+ .dots.top-center,
15284
+ .dots.bottom-center {
15285
+ left: 50%;
15286
+ transform: translateX(-50%);
15287
+ }
15288
+
15289
+ .dots.top-right,
15290
+ .dots.bottom-right {
15291
+ right: 10px;
15292
+ }
15293
+
15294
+ .dots.top-left,
15295
+ .dots.top-center,
15296
+ .dots.top-right {
15297
+ top: 10px;
15298
+ }
15299
+
15300
+ .dots.bottom-left,
15301
+ .dots.bottom-center,
15302
+ .dots.bottom-right {
15303
+ bottom: 10px;
15304
+ }
15305
+
15306
+ .dots.middle-left {
15307
+ left: 10px;
15308
+ top: 50%;
15309
+ transform: translateY(-50%);
15310
+ flex-direction: column;
15311
+ }
15312
+
15313
+ .dots.middle-right {
15314
+ right: 10px;
15315
+ top: 50%;
15316
+ transform: translateY(-50%);
15317
+ flex-direction: column;
15318
+ }
15319
+
15320
+ .buttons button {
15321
+ background-color: #00000080;
15322
+ color: #fff;
15323
+ border: none;
15324
+ padding: 10px;
15325
+ cursor: pointer;
15326
+ transition: background-color 0.3s ease;
15327
+ }
15328
+
15329
+ .buttons button:hover {
15330
+ background-color: #000000b3;
15331
+ }
15332
+
15333
+ .buttons.buttons-separate button {
15334
+ position: absolute;
15335
+ top: 50%;
15336
+ transform: translateY(-50%);
15337
+ }
15338
+
15339
+ .buttons.buttons-separate .prev-button {
15340
+ left: 10px;
15341
+ }
15342
+
15343
+ .buttons.buttons-separate .next-button {
15344
+ right: 10px;
15345
+ }
15346
+
15347
+ .buttons.buttons-together {
15348
+ position: absolute;
15349
+ display: flex;
15350
+ gap: 10px;
15351
+ }
15352
+
15353
+ .buttons.buttons-together.top-left,
15354
+ .buttons.buttons-together.bottom-left {
15355
+ left: 10px;
15356
+ }
15357
+
15358
+ .buttons.buttons-together.top-center,
15359
+ .buttons.buttons-together.bottom-center {
15360
+ left: 50%;
15361
+ transform: translateX(-50%);
15362
+ }
15363
+
15364
+ .buttons.buttons-together.top-right,
15365
+ .buttons.buttons-together.bottom-right {
15366
+ right: 10px;
15367
+ }
15368
+
15369
+ .buttons.buttons-together.top-left,
15370
+ .buttons.buttons-together.top-center,
15371
+ .buttons.buttons-together.top-right {
15372
+ top: 10px;
15373
+ }
15374
+
15375
+ .buttons.buttons-together.bottom-left,
15376
+ .buttons.buttons-together.bottom-center,
15377
+ .buttons.buttons-together.bottom-right {
15378
+ bottom: 10px;
15379
+ }
15380
+
15381
+ .buttons.buttons-together.middle-left,
15382
+ .buttons.buttons-together.middle-right {
15383
+ top: 50%;
15384
+ transform: translateY(-50%);
15385
+ flex-direction: column;
15386
+ }
15387
+
15388
+ .buttons.buttons-together.middle-left {
15389
+ left: 10px;
15390
+ }
15391
+
15392
+ .buttons.buttons-together.middle-right {
15393
+ right: 10px;
15394
+ }
15395
+
15396
+ @media (max-width: 768px) {
15397
+ .buttons button {
15398
+ padding: 8px 12px;
15399
+ font-size: 14px;
15400
+ }
15401
+
15402
+ .dots .dot {
15403
+ width: 8px;
15404
+ height: 8px;
15405
+ }
15406
+ }
15407
+ `;
15408
+
15409
+ let CarouselElement;
15410
+ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined') {
15411
+ class CustomCarouselElement extends HTMLElement {
15412
+ constructor() {
15413
+ super();
15414
+ this.currentSlide = 0;
15415
+ this.dotElements = [];
15416
+ this.prevButton = null;
15417
+ this.nextButton = null;
15418
+ this.autoplayInterval = null;
15419
+ this.useDots = false;
15420
+ this.useButtons = false;
15421
+ this.attachShadow({ mode: 'open' });
15422
+ }
15423
+ connectedCallback() {
15424
+ this.initializeOptions();
15425
+ this.setupResizeObserver();
15426
+ this.render();
15427
+ this.setupCarousel();
15428
+ }
15429
+ disconnectedCallback() {
15430
+ var _a;
15431
+ this.stopAutoplay();
15432
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
15433
+ }
15434
+ initializeOptions() {
15435
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
15436
+ this.useDots = ((_a = this.data) === null || _a === void 0 ? void 0 : _a.useDots) === true || typeof ((_b = this.data) === null || _b === void 0 ? void 0 : _b.useDots) === 'object';
15437
+ this.useButtons = ((_c = this.data) === null || _c === void 0 ? void 0 : _c.useButtons) === true || typeof ((_d = this.data) === null || _d === void 0 ? void 0 : _d.useButtons) === 'object';
15438
+ this.autoplay = (_f = (_e = this.data) === null || _e === void 0 ? void 0 : _e.autoplay) !== null && _f !== void 0 ? _f : true;
15439
+ this.interval = (_h = (_g = this.data) === null || _g === void 0 ? void 0 : _g.interval) !== null && _h !== void 0 ? _h : CustomCarouselElement.defaultInterval;
15440
+ this.dotsOptions = {
15441
+ position: 'bottom-center',
15442
+ color: '#d9d9d9',
15443
+ activeColor: '#b5914a',
15444
+ ...(typeof ((_j = this.data) === null || _j === void 0 ? void 0 : _j.useDots) === 'object' ? this.data.useDots : {}),
15445
+ };
15446
+ this.buttonsOptions = {
15447
+ together: false,
15448
+ position: 'middle-sides',
15449
+ textColor: '#000000',
15450
+ backgroundColor: '#ffffff',
15451
+ borderRadius: '50%',
15452
+ prev: 'Prev',
15453
+ next: 'Next',
15454
+ ...(typeof ((_k = this.data) === null || _k === void 0 ? void 0 : _k.useButtons) === 'object' ? this.data.useButtons : {}),
15455
+ };
15456
+ this.validateOptions();
15457
+ }
15458
+ setupResizeObserver() {
15459
+ if (this.data) {
15460
+ this.resizeObserver = new ResizeObserverService({
15461
+ element: this,
15462
+ maxSize: {
15463
+ width: this.data.width,
15464
+ height: this.data.height,
15465
+ },
15466
+ minScale: this.data.minScale,
15467
+ });
15468
+ this.addEventListener('spotSizeChanged', this.handleCarouselSizeChanged.bind(this));
15469
+ }
15470
+ }
15471
+ handleCarouselSizeChanged(event) {
15472
+ console.info('Carousel Size Changed', event);
15473
+ }
15474
+ render() {
15475
+ var _a;
15476
+ if (!this.shadowRoot)
15477
+ return;
15478
+ const style = document.createElement('style');
15479
+ style.textContent = CAROUSEL_COMPONENT_STYLE(this.data);
15480
+ this.shadowRoot.appendChild(style);
15481
+ const slides = this.renderSlides();
15482
+ this.shadowRoot.appendChild(slides);
15483
+ this.slidesContainer = (_a = this.shadowRoot.querySelector('.slides')) !== null && _a !== void 0 ? _a : undefined;
15484
+ if (this.useDots) {
15485
+ const dots = this.renderDots();
15486
+ if (dots)
15487
+ this.shadowRoot.appendChild(dots);
15488
+ }
15489
+ if (this.useButtons) {
15490
+ const buttons = this.renderButtons();
15491
+ if (buttons)
15492
+ this.shadowRoot.appendChild(buttons);
15493
+ }
15494
+ }
15495
+ setupCarousel() {
15496
+ this.setupDots();
15497
+ this.setupButtons();
15498
+ if (this.autoplay) {
15499
+ this.startAutoplay();
15500
+ }
15501
+ this.updateCarousel();
15502
+ }
15503
+ renderSlides() {
15504
+ const slidesContainer = document.createElement('div');
15505
+ slidesContainer.className = 'slides';
15506
+ this.slides.forEach((slide, index) => {
15507
+ const slideElement = document.createElement('div');
15508
+ slideElement.className = `slide ${index === this.currentSlide ? 'active' : ''}`;
15509
+ if (slide instanceof HTMLElement) {
15510
+ slideElement.appendChild(slide);
15511
+ }
15512
+ slidesContainer.appendChild(slideElement);
15513
+ });
15514
+ return slidesContainer;
15515
+ }
15516
+ renderDots() {
15517
+ const dotsContainer = document.createElement('div');
15518
+ dotsContainer.className = `dots ${this.dotsOptions.position}`;
15519
+ this.slides.forEach((_, index) => {
15520
+ const dot = document.createElement('span');
15521
+ dot.className = `dot ${index === this.currentSlide ? 'active' : ''}`;
15522
+ dot.style.backgroundColor = this.dotsOptions.color;
15523
+ dotsContainer.appendChild(dot);
15524
+ });
15525
+ return dotsContainer;
15526
+ }
15527
+ renderButtons() {
15528
+ const buttonsContainer = document.createElement('div');
15529
+ const buttonsClass = this.buttonsOptions.together
15530
+ ? `buttons-together ${this.buttonsOptions.position}`
15531
+ : 'buttons-separate';
15532
+ buttonsContainer.className = `buttons ${buttonsClass}`;
15533
+ this.prevButton = this.createButton('prev-button', this.buttonsOptions.prev);
15534
+ this.nextButton = this.createButton('next-button', this.buttonsOptions.next);
15535
+ buttonsContainer.appendChild(this.prevButton);
15536
+ buttonsContainer.appendChild(this.nextButton);
15537
+ return buttonsContainer;
15538
+ }
15539
+ createButton(className, text) {
15540
+ const button = document.createElement('button');
15541
+ button.className = className;
15542
+ button.textContent = text;
15543
+ button.style.color = this.buttonsOptions.textColor;
15544
+ button.style.backgroundColor = this.buttonsOptions.backgroundColor;
15545
+ button.style.borderRadius = this.buttonsOptions.borderRadius;
15546
+ return button;
15547
+ }
15548
+ setupDots() {
15549
+ if (!this.shadowRoot || !this.useDots)
15550
+ return;
15551
+ this.dotElements = Array.from(this.shadowRoot.querySelectorAll('.dot'));
15552
+ this.dotElements.forEach((dot, index) => {
15553
+ dot.addEventListener('click', () => {
15554
+ this.goToSlide(index);
15555
+ this.resetAutoplay();
15556
+ });
15557
+ });
15558
+ }
15559
+ setupButtons() {
15560
+ var _a, _b;
15561
+ if (!this.useButtons)
15562
+ return;
15563
+ (_a = this.prevButton) === null || _a === void 0 ? void 0 : _a.addEventListener('click', () => {
15564
+ this.prevSlide();
15565
+ this.resetAutoplay();
15566
+ });
15567
+ (_b = this.nextButton) === null || _b === void 0 ? void 0 : _b.addEventListener('click', () => {
15568
+ this.nextSlide();
15569
+ this.resetAutoplay();
15570
+ });
15571
+ }
15572
+ nextSlide() {
15573
+ this.goToSlide((this.currentSlide + 1) % this.slides.length);
15574
+ }
15575
+ prevSlide() {
15576
+ this.goToSlide((this.currentSlide - 1 + this.slides.length) % this.slides.length);
15577
+ }
15578
+ goToSlide(index) {
15579
+ this.currentSlide = index;
15580
+ this.updateCarousel();
15581
+ }
15582
+ updateCarousel() {
15583
+ if (!this.slidesContainer)
15584
+ return;
15585
+ const slides = Array.from(this.slidesContainer.children);
15586
+ slides.forEach((slide, index) => {
15587
+ slide.classList.toggle('active', index === this.currentSlide);
15588
+ });
15589
+ this.updateDots();
15590
+ }
15591
+ updateDots() {
15592
+ if (!this.useDots)
15593
+ return;
15594
+ this.dotElements.forEach((dot, index) => {
15595
+ const isActive = index === this.currentSlide;
15596
+ dot.classList.toggle('active', isActive);
15597
+ dot.style.backgroundColor = isActive
15598
+ ? this.dotsOptions.activeColor
15599
+ : this.dotsOptions.color;
15600
+ });
15601
+ }
15602
+ startAutoplay() {
15603
+ this.autoplayInterval = window.setInterval(() => this.nextSlide(), this.interval);
15604
+ }
15605
+ stopAutoplay() {
15606
+ if (this.autoplayInterval !== null) {
15607
+ window.clearInterval(this.autoplayInterval);
15608
+ this.autoplayInterval = null;
15609
+ }
15610
+ }
15611
+ resetAutoplay() {
15612
+ if (this.autoplay) {
15613
+ this.stopAutoplay();
15614
+ this.startAutoplay();
15615
+ }
15616
+ }
15617
+ validateOptions() {
15618
+ this.validatePosition(this.dotsOptions.position, 'dotsPosition', 'bottom-center');
15619
+ this.validateButtonsPosition();
15620
+ }
15621
+ validatePosition(position, optionName, defaultValue) {
15622
+ if (!CustomCarouselElement.validPositions.includes(position)) {
15623
+ console.warn(`Invalid ${optionName}: ${position}. Defaulting to '${defaultValue}'.`);
15624
+ if (optionName === 'dotsPosition') {
15625
+ this.dotsOptions.position = defaultValue;
15626
+ }
15627
+ else if (optionName === 'buttonsPosition') {
15628
+ this.buttonsOptions.position = defaultValue;
15629
+ }
15630
+ }
15631
+ }
15632
+ validateButtonsPosition() {
15633
+ if (this.useButtons) {
15634
+ if (this.buttonsOptions.together) {
15635
+ this.validatePosition(this.buttonsOptions.position, 'buttonsPosition', 'bottom-center');
15636
+ }
15637
+ else if (this.buttonsOptions.position !== 'middle-sides') {
15638
+ console.warn(`Invalid buttonsPosition: ${this.buttonsOptions.position}. When buttons are not together, only 'middle-sides' is allowed. Defaulting to 'middle-sides'.`);
15639
+ this.buttonsOptions.position = 'middle-sides';
15640
+ }
15641
+ }
15642
+ }
15643
+ }
15644
+ CustomCarouselElement.defaultInterval = 5000;
15645
+ CustomCarouselElement.validPositions = [
15646
+ 'top-left',
15647
+ 'top-center',
15648
+ 'top-right',
15649
+ 'bottom-left',
15650
+ 'bottom-center',
15651
+ 'bottom-right',
15652
+ 'middle-left',
15653
+ 'middle-right',
15654
+ 'middle-sides',
15655
+ ];
15656
+ CarouselElement = CustomCarouselElement;
15657
+ }
15658
+
15659
+ let SpotElement;
15660
+ if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined') {
15661
+ class CustomSpotElement extends HTMLElement {
15662
+ constructor() {
15663
+ super();
15664
+ this.originalFontSizes = new Map();
15665
+ this.attachShadow({ mode: 'open' });
15666
+ }
15667
+ connectedCallback() {
15668
+ this.setupResizeObserver();
15669
+ this.render();
15670
+ }
15671
+ disconnectedCallback() {
15672
+ var _a;
15673
+ this.removeEventListener('spotSizeChanged', this.handleSpotSizeChanged);
15674
+ (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
15675
+ }
15676
+ /**
15677
+ * Setup observers for the spot element
15678
+ * #########################################################
15679
+ */
15680
+ setupResizeObserver() {
15681
+ if (this.data) {
15682
+ this.resizeObserver = new ResizeObserverService({
15683
+ element: this,
15684
+ maxSize: {
15685
+ width: this.data.width,
15686
+ height: this.data.height,
15687
+ },
15688
+ minScale: this.data.minScale,
15689
+ });
15690
+ this.addEventListener('spotSizeChanged', this.handleSpotSizeChanged.bind(this));
15691
+ }
15692
+ }
15693
+ /**
15694
+ * Observer additional event handlers
15695
+ * #########################################################
15696
+ */
15697
+ handleSpotSizeChanged(event) {
15698
+ console.info('Spot Size Changed', event);
15699
+ // Adjust text elements font size based on the scale factor
15700
+ this.adjustFontSize(event.detail.scale);
15701
+ }
15702
+ adjustFontSize(elementScale) {
15703
+ var _a;
15704
+ const scaleFactor = this.calculateScaleFactor(elementScale);
15705
+ // Find all text elements within the shadow root
15706
+ const elements = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelectorAll('h1, h2, h3, h4, p, span');
15707
+ elements === null || elements === void 0 ? void 0 : elements.forEach((element) => {
15708
+ if (element instanceof HTMLElement) {
15709
+ if (!this.originalFontSizes.has(element)) {
15710
+ const orignalSize = parseFloat(window.getComputedStyle(element).fontSize);
15711
+ this.originalFontSizes.set(element, orignalSize);
15712
+ }
15713
+ const originalSize = this.originalFontSizes.get(element);
15714
+ const newFontSize = originalSize * scaleFactor;
15715
+ element.style.fontSize = `${newFontSize}px`;
15716
+ }
15717
+ });
15718
+ }
15719
+ calculateScaleFactor(elementScale) {
15720
+ // Step 1: Apply square root for non-linear scaling
15721
+ // This creates a more gradual scaling effect, especially for larger changes
15722
+ // For example:
15723
+ // - elementScale of 0.25 (1/4 size) becomes 0.5
15724
+ // - elementScale of 1 (unchanged) remains 1
15725
+ // - elementScale of 4 (4x size) becomes 2
15726
+ const baseFactor = Math.sqrt(elementScale);
15727
+ // Step 2: Apply additional dampening to further soften the scaling effect
15728
+ // The dampening factor (0.5) can be adjusted:
15729
+ // - Lower values (closer to 0) make scaling more subtle
15730
+ // - Higher values (closer to 1) make scaling more pronounced
15731
+ const dampening = 0.5;
15732
+ // Calculate the scaleFactor:
15733
+ // 1. (baseFactor - 1) represents the change from the original size
15734
+ // 2. Multiply by dampening to reduce the effect
15735
+ // 3. Add 1 to center the scaling around the original size
15736
+ // For example, if baseFactor is 2:
15737
+ // scaleFactor = 1 + (2 - 1) * 0.5 = 1.5
15738
+ const scaleFactor = 1 + (baseFactor - 1) * dampening;
15739
+ // Step 3: Define the allowed range for the scale factor
15740
+ // This ensures that the font size never changes too drastically
15741
+ const minScale = 0.5; // Font will never be smaller than 90% of original
15742
+ const maxScale = 1.5; // Font will never be larger than 110% of original
15743
+ // Step 4: Clamp the scale factor to the defined range
15744
+ // Math.min ensures the value doesn't exceed maxScale
15745
+ // Math.max ensures the value isn't less than minScale
15746
+ return Math.max(minScale, Math.min(maxScale, scaleFactor));
15747
+ }
15748
+ /**
15749
+ * Spot element rendering
15750
+ * #########################################################
15751
+ */
15752
+ render() {
15753
+ if (!this.shadowRoot || !this.data || !this.content)
15754
+ return;
15755
+ const style = this.getTemplateStyle(this.data.width, this.data.height);
15756
+ if (this.content instanceof HTMLElement) {
15757
+ this.shadowRoot.replaceChildren(style, this.content);
15758
+ }
15759
+ }
15760
+ getTemplateStyle(width, height) {
15761
+ const style = document.createElement('style');
15762
+ style.textContent = `
15763
+ :host {
15764
+ display: block;
15765
+ position: relative;
15766
+ box-sizing: border-box;
15767
+ overflow: hidden;
15768
+ width: ${this.data.fluid ? '100%' : `${width}px`};
15769
+ height: ${this.data.fluid ? '100%' : `${height}px`};
15770
+ }
15771
+ `;
15772
+ return style;
15773
+ }
15774
+ }
15775
+ SpotElement = CustomSpotElement;
15776
+ }
15777
+
15778
+ class ElementService {
15779
+ static getInstance() {
15780
+ return SingletonManager.getInstance('ElementService', () => new ElementService());
15781
+ }
15782
+ /**
15783
+ * Creates the html element based on the provided data, content and configs using shadow dom.
15784
+ *
15785
+ * This method is only available in browser environments.
15786
+ *
15787
+ * @param {ICreateSpotElementParams} params - The parameters to create the final element.
15788
+ *
15789
+ * @return {HTMLElement | null} - The html element or null if the browser environment is not available.
15790
+ */
15791
+ createSpotElement({ content, config }) {
15792
+ var _a;
15793
+ if (!this.ensureBrowserEnvironmentAndDefineElement()) {
15794
+ return null;
15795
+ }
15796
+ const spot = document.createElement(SPOT_ELEMENT_TAG);
15797
+ spot.data = {
15798
+ fluid: (_a = config === null || config === void 0 ? void 0 : config.fluid) !== null && _a !== void 0 ? _a : false,
15799
+ ...config,
15800
+ };
15801
+ spot.content = content;
15802
+ return spot;
15803
+ }
15804
+ /**
15805
+ * Creates the carousel html element based on the provided slides and configs using shadow dom.
15806
+ *
15807
+ * This method is only available in browser environments.
15808
+ *
15809
+ * @param {ICreateCarouselElementParams} params - The parameters to create the final element.
15810
+ *
15811
+ * @return {HTMLElement | null} - The html element or null if the browser environment is not available.
15812
+ */
15813
+ createCarouselElement({ slides, config, }) {
15814
+ if (!this.ensureBrowserEnvironmentAndDefineElement()) {
15815
+ return null;
15816
+ }
15817
+ const carousel = document.createElement(CAROUSEL_ELEMENT_TAG);
15818
+ carousel.data = {
15819
+ fluid: false,
15820
+ ...config,
15821
+ };
15822
+ carousel.slides = slides;
15823
+ return carousel;
15824
+ }
15825
+ /**
15826
+ * Overrides the spot colors with the provided colors.
15827
+ *
15828
+ * @param {ISpot} spot - The spot data.
15829
+ * @param {ISpotColors} colors - The colors to override.
15830
+ *
15831
+ * @return {ISpot} - The spot data with the colors overridden.
15832
+ */
15833
+ overrideSpotColors(spot, colors) {
15834
+ if (!colors)
15835
+ return spot;
15836
+ const { textColor, backgroundColor, ctaTextColor, ctaBorderColor } = colors;
15837
+ return {
15838
+ ...spot,
15839
+ textColor: textColor !== null && textColor !== void 0 ? textColor : spot.textColor,
15840
+ backgroundColor: backgroundColor !== null && backgroundColor !== void 0 ? backgroundColor : spot.backgroundColor,
15841
+ ctaTextColor: ctaTextColor !== null && ctaTextColor !== void 0 ? ctaTextColor : spot.ctaTextColor,
15842
+ ctaBorderColor: ctaBorderColor !== null && ctaBorderColor !== void 0 ? ctaBorderColor : spot.ctaBorderColor,
15843
+ };
15844
+ }
15845
+ /**
15846
+ * @returns {boolean} - True if the browser environment is available and the element is defined.
15847
+ */
15848
+ ensureBrowserEnvironmentAndDefineElement() {
15849
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
15850
+ console.warn('LiquidCommerce Rmn Sdk: Methods which create elements are only available in browser environments.');
15851
+ return false;
15852
+ }
15853
+ if (!window.customElements.get(SPOT_ELEMENT_TAG)) {
15854
+ window.customElements.define(SPOT_ELEMENT_TAG, SpotElement);
15855
+ }
15856
+ if (!window.customElements.get(CAROUSEL_ELEMENT_TAG)) {
15857
+ window.customElements.define(CAROUSEL_ELEMENT_TAG, CarouselElement);
15858
+ }
15859
+ return true;
15860
+ }
15861
+ }
15862
+
15863
+ function linearGradientColorStop(overlay, fallback) {
15864
+ if (!overlay || overlay.length === 0) {
15865
+ return fallback;
15866
+ }
15867
+ return overlay.map(({ color, colorStop }) => `${color} ${colorStop}`).join(', ');
15868
+ }
15869
+ function spotHtmlStringToElement(htmlString) {
15870
+ const spot = document.createElement('div');
15871
+ spot.className = 'spot';
15872
+ spot.innerHTML = htmlString;
15873
+ Object.assign(spot.style, {
15874
+ position: 'relative',
15875
+ display: 'block',
15876
+ width: '100%',
15877
+ height: '100%',
15878
+ margin: '0',
15879
+ padding: '0',
15880
+ });
15881
+ return spot;
15882
+ }
15204
15883
 
15205
15884
  const STYLES$i = ({ primaryImage, secondaryImage }) => `
15206
15885
  <style>
@@ -16019,175 +16698,214 @@ function wideSkyscraperV1Template(spot) {
16019
16698
  `;
16020
16699
  }
16021
16700
 
16022
- const STYLES$7 = ({ primaryImage, mobilePrimaryImage = primaryImage }) => `
16023
- <style>
16024
- :host {
16025
- min-width: 320px;
16026
- min-height: 223px;
16027
- }
16028
- .content {
16029
- display: block;
16030
- width: 100%;
16031
- height: 100%;
16032
- background-image: url("${mobilePrimaryImage}");
16033
- background-size: cover;
16034
- background-repeat: no-repeat;
16035
- background-position: center;
16036
- cursor: pointer;
16037
- }
16038
- @media (min-width: 640px) {
16039
- .content {
16040
- background-image: url("${primaryImage}");
16041
- }
16701
+ const STYLES$7 = ({ primaryImage, mobilePrimaryImage = primaryImage }, { prefix }) => `
16702
+ <style>
16703
+ :host {
16704
+ min-width: 320px;
16705
+ min-height: 223px;
16706
+ }
16707
+
16708
+ .${prefix}__content {
16709
+ display: block;
16710
+ width: 100%;
16711
+ height: 100%;
16712
+ background-image: url("${mobilePrimaryImage}");
16713
+ background-size: cover;
16714
+ background-repeat: no-repeat;
16715
+ background-position: center;
16716
+ cursor: pointer;
16717
+ }
16718
+
16719
+ @media (min-width: 640px) {
16720
+ .${prefix}__content {
16721
+ background-image: url("${primaryImage}");
16042
16722
  }
16043
- </style>
16723
+ }
16724
+ </style>
16044
16725
  `;
16045
- function rbCollectionBannerWithoutTextBlockTemplate(spot) {
16726
+ function rbCollectionBannerWithoutTextBlockTemplate(spot, config) {
16727
+ const { prefix = '' } = config;
16046
16728
  return `
16047
- ${STYLES$7(spot)}
16048
- <div class="content"></div>
16729
+ ${STYLES$7(spot, config)}
16730
+ <div class="${prefix}__content"></div>
16049
16731
  `;
16050
16732
  }
16051
16733
 
16052
- const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderColor = ctaTextColor, primaryImage, mobilePrimaryImage = primaryImage, }) => `
16053
- <style>
16054
- :host {
16055
- min-width: 320px;
16056
- min-height: 388px;
16057
- }
16058
- .content {
16059
- display: flex;
16060
- flex-direction: column;
16061
- justify-content: flex-end;
16062
- align-items: flex-start;
16063
- width: 100%;
16064
- height: 100%;
16065
- background-image: url("${mobilePrimaryImage}");
16066
- background-size: cover;
16067
- background-repeat: no-repeat;
16068
- background-position: center;
16069
- padding: 3%;
16070
- box-sizing: border-box;
16071
- color: ${textColor};
16072
- cursor: pointer;
16073
- }
16074
- .text {
16075
- display: flex;
16076
- flex-direction: column;
16077
- justify-content: flex-start;
16078
- align-items: flex-start;
16079
- width: 100%;
16080
- height: fit-content;
16081
- gap: 5px;
16082
- }
16083
- .header {
16084
- font-size: 18px;
16085
- margin: 0;
16086
- font-family: "Cormorant";
16087
- font-style: normal;
16088
- font-weight: 300;
16089
- line-height: normal;
16090
- }
16091
- .description {
16092
- font-size: 10px;
16093
- font-family: "Source Sans 3", system-ui;
16094
- font-style: normal;
16095
- font-weight: 400;
16096
- line-height: 20px;
16097
- margin: 0;
16098
- }
16099
- .cta-button {
16100
- font-size: 8px;
16101
- font-family: "Source Sans 3", system-ui;
16102
- font-style: normal;
16103
- font-weight: 400;
16104
- line-height: 18px;
16105
- border-radius: 5px;
16106
- border: 0.5px solid ${ctaBorderColor};
16107
- display: inline-block;
16108
- padding: 7px 20px;
16109
- color: ${ctaTextColor};
16110
- transition: background-color 0.3s ease;
16111
- }
16112
- .content:hover .cta-button {
16113
- background-color: ${ctaBorderColor.length === 7 ? `${ctaBorderColor}15` : `${ctaBorderColor}`};
16114
- }
16115
- @media (min-width: 640px) {
16116
- .content {
16117
- background-image: url("${primaryImage}");
16118
- }
16119
- }
16120
- @media (min-width: 768px) {
16121
- .primary-image {
16122
- width: 66.66666%;
16734
+ const STYLES$6 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderColor = ctaTextColor, primaryImage, mobilePrimaryImage = primaryImage, }, { prefix, overlay }) => {
16735
+ const linearGradient = linearGradientColorStop(overlay || [], 'rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 40%');
16736
+ return `
16737
+ <style>
16738
+ .${prefix} {
16739
+ min-width: 320px;
16740
+ min-height: 388px;
16741
+ width: 100%;
16123
16742
  height: 100%;
16743
+ display: block;
16744
+ position: relative;
16745
+ container-type: inline-size;
16124
16746
  }
16125
- .main {
16747
+
16748
+ .${prefix}__content {
16749
+ display: flex;
16126
16750
  flex-direction: column;
16751
+ justify-content: flex-end;
16752
+ align-items: flex-start;
16753
+ width: 100%;
16127
16754
  height: 100%;
16128
- width: 33.33333%;
16755
+ background-image: linear-gradient(to top, ${linearGradient}), url("${mobilePrimaryImage}");
16756
+ background-size: cover;
16757
+ background-repeat: no-repeat;
16758
+ background-position: center;
16759
+ padding: 3%;
16760
+ box-sizing: border-box;
16761
+ color: ${textColor};
16762
+ cursor: pointer;
16129
16763
  }
16130
- .secondary-image {
16764
+
16765
+ .${prefix}__text {
16766
+ display: flex;
16767
+ flex-direction: column;
16768
+ justify-content: flex-start;
16769
+ align-items: flex-start;
16131
16770
  width: 100%;
16132
- height: 50%;
16133
- }
16134
- .header {
16135
- font-size: 22px;
16771
+ height: fit-content;
16772
+ gap: 5px;
16136
16773
  }
16137
- .description {
16138
- font-size: 12px;
16774
+
16775
+ .${prefix}__header {
16776
+ font-size: 18px;
16777
+ margin: 0;
16778
+ font-family: "Cormorant";
16779
+ font-style: normal;
16780
+ font-weight: 300;
16781
+ line-height: normal;
16139
16782
  }
16140
- .cta-button {
16141
- font-size: 12px;
16783
+
16784
+ .${prefix}__description {
16785
+ font-size: 10px;
16786
+ font-family: "Source Sans 3", system-ui;
16787
+ font-style: normal;
16788
+ font-weight: 400;
16789
+ line-height: 20px;
16790
+ margin: 0;
16142
16791
  }
16143
- }
16144
- @media (min-width: 1024px) {
16145
- .header {
16146
- font-size: 24px;
16792
+
16793
+ .${prefix}__cta-button {
16794
+ font-size: 8px;
16795
+ font-family: "Source Sans 3", system-ui;
16796
+ font-style: normal;
16797
+ font-weight: 400;
16798
+ line-height: 18px;
16799
+ border-radius: 5px;
16800
+ border: 0.5px solid ${ctaBorderColor};
16801
+ display: inline-block;
16802
+ padding: 7px 20px;
16803
+ color: ${ctaTextColor};
16804
+ transition: background-color 0.3s ease;
16147
16805
  }
16148
- .description {
16149
- font-size: 13px;
16806
+
16807
+ .${prefix}__content:hover .cta-button {
16808
+ background-color: ${ctaBorderColor.length === 7 ? `${ctaBorderColor}15` : `${ctaBorderColor}`};
16150
16809
  }
16151
- .cta-button {
16152
- font-size: 13px;
16810
+
16811
+ @media (min-width: 640px) {
16812
+ .${prefix}__content {
16813
+ background-image: linear-gradient(to top, ${linearGradient}), url("${primaryImage}");
16814
+ }
16153
16815
  }
16154
- }
16155
- @media (min-width: 1280px) {
16156
- .header {
16157
- font-size: 28px;
16816
+
16817
+ @media (min-width: 768px) {
16818
+ .${prefix}__primary-image {
16819
+ width: 66.66666%;
16820
+ height: 100%;
16821
+ }
16822
+
16823
+ .${prefix}__main {
16824
+ flex-direction: column;
16825
+ height: 100%;
16826
+ width: 33.33333%;
16827
+ }
16828
+
16829
+ .${prefix}__secondary-image {
16830
+ width: 100%;
16831
+ height: 50%;
16832
+ }
16833
+
16834
+ .${prefix}__header {
16835
+ font-size: 22px;
16836
+ }
16837
+
16838
+ .${prefix}__description {
16839
+ font-size: 12px;
16840
+ }
16841
+
16842
+ .${prefix}__cta-button {
16843
+ font-size: 12px;
16844
+ }
16158
16845
  }
16159
- .description {
16160
- font-size: 14px;
16846
+
16847
+ @media (min-width: 1024px) {
16848
+ .${prefix}__header {
16849
+ font-size: 24px;
16850
+ }
16851
+
16852
+ .${prefix}__description {
16853
+ font-size: 13px;
16854
+ }
16855
+
16856
+ .${prefix}__cta-button {
16857
+ font-size: 13px;
16858
+ }
16161
16859
  }
16162
- .cta-button {
16163
- font-size: 14px;
16860
+
16861
+ @media (min-width: 1280px) {
16862
+ .${prefix}__header {
16863
+ font-size: 28px;
16864
+ }
16865
+
16866
+ .${prefix}__description {
16867
+ font-size: 14px;
16868
+ }
16869
+
16870
+ .${prefix}__cta-button {
16871
+ font-size: 14px;
16872
+ }
16164
16873
  }
16165
- }
16166
- </style>
16167
- `;
16168
- function rbHomepageHeroFullImageTemplate(spot) {
16874
+ </style>
16875
+ `;
16876
+ };
16877
+ function rbHomepageHeroFullImageTemplate(spot, config) {
16878
+ const { prefix = '' } = config;
16169
16879
  return `
16170
16880
  ${GFONT_PRECONNECT}
16171
16881
  ${GFONT_SOURCE_SANS_3}
16172
16882
  ${GFONT_CORMORANT}
16173
- ${STYLES$6(spot)}
16174
- <div class="content">
16175
- <div class="text">
16176
- ${spot.header ? `<h2 class="header">${spot.header}</h2>` : ''}
16177
- ${spot.description ? `<p class="description">${spot.description}</p>` : ''}
16178
- ${spot.ctaText ? `<span class="cta-button">${spot.ctaText}</span>` : ''}
16883
+ ${STYLES$6(spot, config)}
16884
+ <div class="${prefix}">
16885
+ <div class="${prefix}__content">
16886
+ <div class="${prefix}__text">
16887
+ ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
16888
+ ${spot.description ? `<p class="${prefix}__description">${spot.description}</p>` : ''}
16889
+ ${spot.ctaText ? `<span class="${prefix}__cta-button">${spot.ctaText}</span>` : ''}
16890
+ </div>
16179
16891
  </div>
16180
16892
  </div>
16181
16893
  `;
16182
16894
  }
16183
16895
 
16184
- const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextColor = textColor, primaryImage, mobilePrimaryImage = primaryImage, secondaryImage, mobileSecondaryImage = secondaryImage, }) => `
16185
- <style>
16186
- :host {
16896
+ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextColor = textColor, primaryImage, mobilePrimaryImage = primaryImage, secondaryImage, mobileSecondaryImage = secondaryImage, }, { prefix }) => `
16897
+ <style>
16898
+ .${prefix} {
16187
16899
  min-width: 320px;
16188
16900
  min-height: 388px;
16901
+ width: 100%;
16902
+ height: 100%;
16903
+ display: block;
16904
+ position: relative;
16905
+ container-type: inline-size;
16189
16906
  }
16190
- .content {
16907
+
16908
+ .${prefix}__content {
16191
16909
  width: 100%;
16192
16910
  height: 100%;
16193
16911
  display: flex;
@@ -16197,7 +16915,8 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16197
16915
  color: inherit;
16198
16916
  cursor: pointer;
16199
16917
  }
16200
- .primary-image {
16918
+
16919
+ .${prefix}__primary-image {
16201
16920
  width: 100%;
16202
16921
  height: 60%;
16203
16922
  background-image: url("${mobilePrimaryImage}");
@@ -16205,14 +16924,16 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16205
16924
  background-repeat: no-repeat;
16206
16925
  background-size: cover;
16207
16926
  }
16208
- .main {
16927
+
16928
+ .${prefix}__main {
16209
16929
  width: 100%;
16210
16930
  height: 40%;
16211
16931
  display: flex;
16212
16932
  flex-direction: row;
16213
16933
  gap: 5px;
16214
16934
  }
16215
- .secondary-image {
16935
+
16936
+ .${prefix}__secondary-image {
16216
16937
  width: 50%;
16217
16938
  height: 100%;
16218
16939
  background-image: url("${mobileSecondaryImage}");
@@ -16220,7 +16941,8 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16220
16941
  background-repeat: no-repeat;
16221
16942
  background-size: cover;
16222
16943
  }
16223
- .text {
16944
+
16945
+ .${prefix}__text {
16224
16946
  color: ${textColor};
16225
16947
  background-color: ${backgroundColor};
16226
16948
  text-align: center;
@@ -16234,7 +16956,8 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16234
16956
  padding: 0 10px;
16235
16957
  box-sizing: border-box;
16236
16958
  }
16237
- .header {
16959
+
16960
+ .${prefix}__header {
16238
16961
  color: inherit;
16239
16962
  margin: 0;
16240
16963
  font-size: 18px;
@@ -16243,7 +16966,8 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16243
16966
  font-weight: 700;
16244
16967
  line-height: normal;
16245
16968
  }
16246
- .description {
16969
+
16970
+ .${prefix}__description {
16247
16971
  color: inherit;
16248
16972
  margin: 0;
16249
16973
  font-size: 10px;
@@ -16251,7 +16975,8 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16251
16975
  font-style: normal;
16252
16976
  font-weight: 400;
16253
16977
  }
16254
- .cta-button {
16978
+
16979
+ .${prefix}__cta-button {
16255
16980
  color: ${ctaTextColor};
16256
16981
  background-color: transparent;
16257
16982
  font-size: 8px;
@@ -16266,99 +16991,85 @@ const STYLES$5 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16266
16991
  padding: 0;
16267
16992
  transition: opacity 0.3s ease;
16268
16993
  }
16269
- .content:hover .cta-button {
16994
+
16995
+ .${prefix}__content:hover .${prefix}__cta-button {
16270
16996
  opacity: 0.8;
16271
16997
  }
16998
+
16272
16999
  @media (min-width: 640px) {
16273
- .primary-image {
17000
+ .${prefix}__primary-image {
16274
17001
  background-image: url("${primaryImage}");
16275
17002
  }
16276
- .secondary-image {
17003
+
17004
+ .${prefix}__secondary-image {
16277
17005
  background-image: url("${secondaryImage}");
16278
17006
  }
16279
17007
  }
17008
+
16280
17009
  @media (min-width: 768px) {
16281
- .content {
17010
+ .${prefix}__content {
16282
17011
  flex-direction: row;
16283
17012
  }
16284
- .primary-image {
17013
+
17014
+ .${prefix}__primary-image {
16285
17015
  width: 66.66666%;
16286
17016
  height: 100%;
16287
17017
  }
16288
- .main {
17018
+
17019
+ .${prefix}__main {
16289
17020
  flex-direction: column;
16290
17021
  height: 100%;
16291
17022
  width: 33.33333%;
16292
17023
  }
16293
- .secondary-image {
17024
+
17025
+ .${prefix}__secondary-image {
16294
17026
  width: 100%;
16295
17027
  height: 50%;
16296
17028
  }
16297
- .text {
17029
+
17030
+ .${prefix}__text {
16298
17031
  width: 100%;
16299
17032
  height: 50%;
16300
17033
  }
16301
- .header {
16302
- font-size: 22px;
16303
- }
16304
- .description {
16305
- font-size: 12px;
16306
- }
16307
- .cta-button {
16308
- font-size: 12px;
16309
- }
16310
- }
16311
- @media (min-width: 1024px) {
16312
- .header {
16313
- font-size: 24px;
16314
- }
16315
- .description {
16316
- font-size: 13px;
16317
- }
16318
- .cta-button {
16319
- font-size: 13px;
16320
- }
16321
- }
16322
- @media (min-width: 1280px) {
16323
- .header {
16324
- font-size: 28px;
16325
- }
16326
- .description {
16327
- font-size: 14px;
16328
- }
16329
- .cta-button {
16330
- font-size: 14px;
16331
- }
16332
17034
  }
16333
- </style>
17035
+ </style>
16334
17036
  `;
16335
- function rbHomepageHeroThreeTileTemplate(spot) {
17037
+ function rbHomepageHeroThreeTileTemplate(spot, config) {
17038
+ const { prefix = '' } = config;
16336
17039
  return `
16337
17040
  ${GFONT_PRECONNECT}
16338
17041
  ${GFONT_SOURCE_SANS_3}
16339
17042
  ${GFONT_CORMORANT}
16340
- ${STYLES$5(spot)}
16341
- <div class="content">
16342
- <div class="primary-image"></div>
16343
- <div class="main">
16344
- <div class="secondary-image"></div>
16345
- <div class="text">
16346
- ${spot.header ? `<h2 class="header">${spot.header}</h2>` : ''}
16347
- ${spot.description ? `<p class="description">${spot.description}</p>` : ''}
16348
- ${spot.ctaText ? `<span class="cta-button">${spot.ctaText}</span>` : ''}
17043
+ ${STYLES$5(spot, config)}
17044
+ <div class="${prefix}">
17045
+ <div class="${prefix}__content">
17046
+ <div class="${prefix}__primary-image"></div>
17047
+ <div class="${prefix}__main">
17048
+ <div class="${prefix}__secondary-image"></div>
17049
+ <div class="${prefix}__text">
17050
+ ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
17051
+ ${spot.description ? `<p class="${prefix}__description">${spot.description}</p>` : ''}
17052
+ ${spot.ctaText ? `<span class="${prefix}__cta-button">${spot.ctaText}</span>` : ''}
17053
+ </div>
16349
17054
  </div>
16350
17055
  </div>
16351
17056
  </div>
16352
17057
  `;
16353
17058
  }
16354
17059
 
16355
- const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextColor = textColor, primaryImage, mobilePrimaryImage = primaryImage, }) => `
17060
+ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextColor = textColor, primaryImage, mobilePrimaryImage = primaryImage, }, { prefix }) => `
16356
17061
  <style>
16357
- :host {
17062
+ .${prefix} {
16358
17063
  min-width: 320px;
16359
17064
  min-height: 388px;
17065
+ width: 100%;
17066
+ height: 100%;
17067
+ display: block;
17068
+ position: relative;
17069
+ container-type: inline-size;
16360
17070
  }
16361
- .content {
17071
+
17072
+ .${prefix}__content {
16362
17073
  width: 100%;
16363
17074
  height: 100%;
16364
17075
  display: flex;
@@ -16367,7 +17078,8 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16367
17078
  gap: 5px;
16368
17079
  cursor: pointer;
16369
17080
  }
16370
- .image {
17081
+
17082
+ .${prefix}__image {
16371
17083
  width: 100%;
16372
17084
  height: 100%;
16373
17085
  background-image: url("${mobilePrimaryImage}");
@@ -16375,7 +17087,8 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16375
17087
  background-repeat: no-repeat;
16376
17088
  background-size: cover;
16377
17089
  }
16378
- .text {
17090
+
17091
+ .${prefix}__text {
16379
17092
  color: ${textColor};
16380
17093
  background-color: ${backgroundColor};
16381
17094
  text-align: center;
@@ -16389,7 +17102,8 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16389
17102
  padding: 0 10px;
16390
17103
  box-sizing: border-box;
16391
17104
  }
16392
- .header {
17105
+
17106
+ .${prefix}__header {
16393
17107
  font-size: 18px;
16394
17108
  margin: 0;
16395
17109
  color: inherit;
@@ -16398,7 +17112,8 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16398
17112
  font-weight: 700;
16399
17113
  line-height: normal;
16400
17114
  }
16401
- .description {
17115
+
17116
+ .${prefix}__description {
16402
17117
  color: inherit;
16403
17118
  margin: 0;
16404
17119
  font-size: 10px;
@@ -16406,7 +17121,8 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16406
17121
  font-style: normal;
16407
17122
  font-weight: 400;
16408
17123
  }
16409
- .cta-button {
17124
+
17125
+ .${prefix}__cta-button {
16410
17126
  color: ${ctaTextColor};
16411
17127
  background-color: transparent;
16412
17128
  font-size: 8px;
@@ -16421,205 +17137,204 @@ const STYLES$4 = ({ textColor = '#212121', backgroundColor = '#e8e6de', ctaTextC
16421
17137
  padding: 0;
16422
17138
  transition: opacity 0.3s ease;
16423
17139
  }
16424
- .content:hover .cta-button {
17140
+
17141
+ .${prefix}__content:hover .${prefix}__cta-button {
16425
17142
  opacity: 0.8;
16426
17143
  }
17144
+
16427
17145
  @media (min-width: 640px) {
16428
- .image {
17146
+ .${prefix}__image {
16429
17147
  background-image: url("${primaryImage}");
16430
17148
  }
16431
17149
  }
16432
17150
  @media (min-width: 768px) {
16433
- .content {
17151
+ .${prefix}__content {
16434
17152
  flex-direction: row;
16435
17153
  }
16436
- .image {
17154
+
17155
+ .${prefix}__image {
16437
17156
  width: 66.66666%;
16438
17157
  height: 100%;
16439
17158
  }
16440
- .text {
16441
- width: 33.333%;
17159
+
17160
+ .${prefix}__text {
17161
+ width: 33.33333%;
16442
17162
  height: 100%;
16443
17163
  }
16444
- .header {
16445
- font-size: 22px;
16446
- }
16447
- .description {
16448
- font-size: 12px;
16449
- }
16450
- .cta-button {
16451
- font-size: 12px;
16452
- }
16453
- }
16454
- @media (min-width: 1024px) {
16455
- .header {
16456
- font-size: 24px;
16457
- }
16458
- .description {
16459
- font-size: 13px;
16460
- }
16461
- .cta-button {
16462
- font-size: 13px;
16463
- }
16464
- }
16465
- @media (min-width: 1280px) {
16466
- .header {
16467
- font-size: 28px;
16468
- }
16469
- .description {
16470
- font-size: 14px;
16471
- }
16472
- .cta-button {
16473
- font-size: 14px;
16474
- }
16475
17164
  }
16476
17165
  </style>
16477
17166
  `;
16478
- function rbHomepageHeroTwoTileTemplate(spot) {
17167
+ function rbHomepageHeroTwoTileTemplate(spot, config) {
17168
+ const { prefix = '' } = config;
16479
17169
  return `
16480
17170
  ${GFONT_PRECONNECT}
16481
17171
  ${GFONT_SOURCE_SANS_3}
16482
17172
  ${GFONT_CORMORANT}
16483
- ${STYLES$4(spot)}
16484
- <div class="content">
16485
- <div class="text">
16486
- ${spot.header ? `<h2 class="header">${spot.header}</h2>` : ''}
16487
- ${spot.description ? `<p class="description">${spot.description}</p>` : ''}
16488
- ${spot.ctaText ? `<span class="cta-button">${spot.ctaText}</span>` : ''}
17173
+ ${STYLES$4(spot, config)}
17174
+ <div class="${prefix}">
17175
+ <div class="${prefix}__content">
17176
+ <div class="${prefix}__text">
17177
+ ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
17178
+ ${spot.description ? `<p class="${prefix}__description">${spot.description}</p>` : ''}
17179
+ ${spot.ctaText ? `<span class="${prefix}__cta-button">${spot.ctaText}</span>` : ''}
17180
+ </div>
17181
+ <div class="${prefix}__image"></div>
16489
17182
  </div>
16490
- <div class="image"></div>
16491
17183
  </div>
16492
17184
  `;
16493
17185
  }
16494
17186
 
16495
- const STYLES$3 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderColor = ctaTextColor, primaryImage, mobilePrimaryImage = primaryImage, }) => `
16496
- <style>
16497
- :host {
16498
- min-width: 320px;
16499
- min-height: 334px;
16500
- }
16501
- .content {
16502
- width: 100%;
16503
- height: 100%;
16504
- display: flex;
16505
- flex-direction: column;
16506
- justify-content: flex-end;
16507
- background-image: url("${mobilePrimaryImage}");
16508
- background-size: cover;
16509
- background-repeat: no-repeat;
16510
- background-position: center;
16511
- border-radius: 5px;
16512
- overflow: hidden;
16513
- cursor: pointer;
16514
- color: ${textColor};
16515
- }
16516
- .text {
16517
- padding: 20px;
16518
- width: 70%;
16519
- display: flex;
16520
- flex-direction: column;
16521
- justify-content: center;
16522
- align-items: flex-start;
16523
- gap: 10px;
16524
- }
16525
- .header {
16526
- color: inherit;
16527
- margin: 0;
16528
- font-size: 20px;
16529
- font-family: "Cormorant";
16530
- font-style: normal;
16531
- font-weight: 300;
16532
- line-height: normal;
16533
- }
16534
- .description {
16535
- color: inherit;
16536
- font-size: 12px;
16537
- line-height: 16px;
16538
- font-family: "Source Sans 3", system-ui;
16539
- font-style: normal;
16540
- font-weight: 400;
16541
- margin: 0;
16542
- }
16543
- .cta-button {
16544
- width: fit-content;
16545
- display: inline-block;
16546
- padding: 7px 20px;
16547
- border: 0.5px solid ${ctaBorderColor};
16548
- border-radius: 5px;
16549
- color: ${ctaTextColor};
16550
- font-size: 8px;
16551
- transition: background-color 0.3s ease;
16552
- font-family: "Source Sans 3", system-ui;
16553
- font-style: normal;
16554
- font-weight: 400;
16555
- }
16556
- .content:hover .cta-button {
16557
- background-color: ${ctaBorderColor.length === 7 ? `${ctaBorderColor}15` : `${ctaBorderColor}`};
16558
- }
16559
- @media (min-width: 640px) {
16560
- .content {
16561
- background-image: url("${primaryImage}");
17187
+ const STYLES$3 = ({ textColor = '#ffffff', ctaTextColor = textColor, ctaBorderColor = ctaTextColor, primaryImage, mobilePrimaryImage = primaryImage, }, { prefix, overlay }) => {
17188
+ const linearGradient = linearGradientColorStop(overlay || [], 'rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 30%');
17189
+ return `
17190
+ <style>
17191
+ :host {
17192
+ min-width: 320px;
17193
+ min-height: 334px;
16562
17194
  }
16563
- }
16564
- @media (min-width: 768px) {
16565
- .text {
16566
- padding: 25px;
17195
+
17196
+ .${prefix}__content {
17197
+ width: 100%;
17198
+ height: 100%;
17199
+ display: flex;
17200
+ flex-direction: column;
17201
+ justify-content: flex-end;
17202
+ background-image: linear-gradient(to top, ${linearGradient}), url("${mobilePrimaryImage}");
17203
+ background-size: cover;
17204
+ background-repeat: no-repeat;
17205
+ background-position: center;
17206
+ border-radius: 5px;
17207
+ overflow: hidden;
17208
+ cursor: pointer;
17209
+ color: ${textColor};
16567
17210
  }
16568
- .header {
16569
- font-size: 24px;
17211
+
17212
+ .${prefix}__text {
17213
+ padding: 20px;
17214
+ width: 70%;
17215
+ display: flex;
17216
+ flex-direction: column;
17217
+ justify-content: center;
17218
+ align-items: flex-start;
17219
+ gap: 10px;
16570
17220
  }
16571
- .description {
16572
- font-size: 13px;
16573
- line-height: 18px;
17221
+
17222
+ .${prefix}__header {
17223
+ color: inherit;
17224
+ margin: 0;
17225
+ font-size: 20px;
17226
+ font-family: "Cormorant";
17227
+ font-style: normal;
17228
+ font-weight: 300;
17229
+ line-height: normal;
16574
17230
  }
16575
- .cta-button {
17231
+
17232
+ .${prefix}__description {
17233
+ color: inherit;
16576
17234
  font-size: 12px;
17235
+ line-height: 16px;
17236
+ font-family: "Source Sans 3", system-ui;
17237
+ font-style: normal;
17238
+ font-weight: 400;
17239
+ margin: 0;
16577
17240
  }
16578
- }
16579
- @media (min-width: 1024px) {
16580
- .text {
16581
- padding: 30px;
17241
+
17242
+ .${prefix}__cta-button {
17243
+ width: fit-content;
17244
+ display: inline-block;
17245
+ padding: 7px 20px;
17246
+ border: 0.5px solid ${ctaBorderColor};
17247
+ border-radius: 5px;
17248
+ color: ${ctaTextColor};
17249
+ font-size: 8px;
17250
+ transition: background-color 0.3s ease;
17251
+ font-family: "Source Sans 3", system-ui;
17252
+ font-style: normal;
17253
+ font-weight: 400;
16582
17254
  }
16583
- .header {
16584
- font-size: 28px;
17255
+
17256
+ .${prefix}__content:hover .${prefix}__cta-button {
17257
+ background-color: ${ctaBorderColor.length === 7 ? `${ctaBorderColor}15` : `${ctaBorderColor}`};
16585
17258
  }
16586
- .description {
16587
- font-size: 14px;
17259
+
17260
+ @media (min-width: 640px) {
17261
+ .${prefix}__content {
17262
+ background-image: linear-gradient(to top, ${linearGradient}), url("${primaryImage}");
17263
+ }
16588
17264
  }
16589
- .cta-button {
16590
- font-size: 13px;
17265
+
17266
+ @media (min-width: 768px) {
17267
+ .${prefix}__text {
17268
+ padding: 25px;
17269
+ }
17270
+
17271
+ .${prefix}__header {
17272
+ font-size: 24px;
17273
+ }
17274
+
17275
+ .${prefix}__description {
17276
+ font-size: 13px;
17277
+ line-height: 18px;
17278
+ }
17279
+
17280
+ .${prefix}__cta-button {
17281
+ font-size: 12px;
17282
+ }
16591
17283
  }
16592
- }
16593
- @media (min-width: 1280px) {
16594
- .cta-button {
16595
- font-size: 14px;
17284
+
17285
+ @media (min-width: 1024px) {
17286
+ .${prefix}__text {
17287
+ padding: 30px;
17288
+ }
17289
+
17290
+ .${prefix}__header {
17291
+ font-size: 28px;
17292
+ }
17293
+
17294
+ .${prefix}__description {
17295
+ font-size: 14px;
17296
+ }
17297
+
17298
+ .${prefix}__cta-button {
17299
+ font-size: 13px;
17300
+ }
16596
17301
  }
16597
- }
16598
- </style>
16599
- `;
16600
- function rbLargeCategoryImageToutTemplate(spot) {
17302
+
17303
+ @media (min-width: 1280px) {
17304
+ .${prefix}__cta-button {
17305
+ font-size: 14px;
17306
+ }
17307
+ }
17308
+ </style>
17309
+ `;
17310
+ };
17311
+ function rbLargeCategoryImageToutTemplate(spot, config) {
17312
+ const { prefix = '' } = config;
16601
17313
  return `
16602
17314
  ${GFONT_PRECONNECT}
16603
17315
  ${GFONT_SOURCE_SANS_3}
16604
17316
  ${GFONT_CORMORANT}
16605
- ${STYLES$3(spot)}
16606
- <div class="content">
16607
- <div class="text">
16608
- ${spot.header ? `<h2 class="header">${spot.header}</h2>` : ''}
16609
- ${spot.description ? `<p class="description">${spot.description}</p>` : ''}
16610
- ${spot.ctaText ? `<span class="cta-button">${spot.ctaText}</span>` : ''}
17317
+ ${STYLES$3(spot, config)}
17318
+ <div class="${prefix}__content">
17319
+ <div class="${prefix}__text">
17320
+ ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
17321
+ ${spot.description ? `<p class="${prefix}__description">${spot.description}</p>` : ''}
17322
+ ${spot.ctaText ? `<span class="${prefix}__cta-button">${spot.ctaText}</span>` : ''}
16611
17323
  </div>
16612
17324
  </div>
16613
17325
  `;
16614
17326
  }
16615
17327
 
16616
- const STYLES$2 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = primaryImage, }) => `
17328
+ const STYLES$2 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = primaryImage }, { prefix, overlay }) => {
17329
+ const linearGradient = linearGradientColorStop(overlay || [], 'rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 30%');
17330
+ return `
16617
17331
  <style>
16618
17332
  :host {
16619
17333
  min-width: 320px;
16620
17334
  min-height: 150px;
16621
17335
  }
16622
- .content {
17336
+
17337
+ .${prefix}__content {
16623
17338
  width: 100%;
16624
17339
  height: 100%;
16625
17340
  display: flex;
@@ -16628,17 +17343,18 @@ const STYLES$2 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = pr
16628
17343
  border-radius: 5px;
16629
17344
  overflow: hidden;
16630
17345
  cursor: pointer;
16631
- background-image: url("${mobilePrimaryImage}");
17346
+ background-image: linear-gradient(to top, ${linearGradient}), url("${mobilePrimaryImage}");
16632
17347
  background-size: cover;
16633
17348
  background-position: center;
16634
- background-blend-mode: overlay;
16635
17349
  background-repeat: no-repeat;
16636
17350
  }
16637
- .text {
17351
+
17352
+ .${prefix}__text {
16638
17353
  padding: 15px 10%;
16639
17354
  width: fit-content;
16640
17355
  }
16641
- .header {
17356
+
17357
+ .${prefix}__header {
16642
17358
  font-size: 16px;
16643
17359
  color: ${textColor};
16644
17360
  line-height: 20px;
@@ -16647,102 +17363,117 @@ const STYLES$2 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = pr
16647
17363
  font-style: normal;
16648
17364
  margin: 0;
16649
17365
  }
17366
+
16650
17367
  @media (min-width: 640px) {
16651
- .content {
16652
- background-image: url("${primaryImage}");
17368
+ .${prefix}__content {
17369
+ background-image: linear-gradient(to top, ${linearGradient}), url("${primaryImage}");
16653
17370
  }
16654
17371
  }
17372
+
16655
17373
  @media (min-width: 768px) {
16656
- .header {
17374
+ .${prefix}__header {
16657
17375
  font-size: 22px;
16658
17376
  }
16659
17377
  }
17378
+
16660
17379
  @media (min-width: 1024px) {
16661
- .header {
17380
+ .${prefix}__header {
16662
17381
  font-size: 24px;
16663
17382
  }
16664
17383
  }
17384
+
16665
17385
  @media (min-width: 1280px) {
16666
- .header {
17386
+ .${prefix}__header {
16667
17387
  font-size: 28px;
16668
17388
  }
16669
17389
  }
16670
17390
  </style>
16671
17391
  `;
16672
- function rbNavigationBannerTemplate(spot) {
17392
+ };
17393
+ function rbNavigationBannerTemplate(spot, config) {
17394
+ const { prefix = '' } = config;
16673
17395
  return `
16674
17396
  ${GFONT_PRECONNECT}
16675
17397
  ${GFONT_SOURCE_SANS_3}
16676
- ${STYLES$2(spot)}
16677
- <div class="content">
16678
- <div class="text">
16679
- ${spot.header ? `<h2 class="header">${spot.header}</h2>` : ''}
17398
+ ${STYLES$2(spot, config)}
17399
+ <div class="${prefix}__content">
17400
+ <div class="${prefix}__text">
17401
+ ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
16680
17402
  </div>
16681
17403
  </div>
16682
17404
  `;
16683
17405
  }
16684
17406
 
16685
- const STYLES$1 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = primaryImage, }) => `
16686
- <style>
16687
- :host {
16688
- min-width: 165px;
16689
- min-height: 300px;
16690
- }
16691
- .content {
16692
- width: 100%;
16693
- height: 100%;
16694
- display: flex;
16695
- flex-direction: column;
16696
- justify-content: flex-end;
16697
- background-image: url("${mobilePrimaryImage}");
16698
- background-size: cover;
16699
- background-repeat: no-repeat;
16700
- background-position: center;
16701
- border-radius: 5px;
16702
- overflow: hidden;
16703
- cursor: pointer;
16704
- }
16705
- .text {
16706
- padding: 10px;
16707
- width: 70%;
16708
- }
16709
- .header {
16710
- font-size: 12px;
16711
- color: ${textColor};
16712
- line-height: 16px;
16713
- font-family: "Source Sans 3", system-ui;
16714
- font-style: normal;
16715
- font-weight: 400;
16716
- line-height: normal;
16717
- margin: 0;
16718
- }
16719
- @media (min-width: 640px) {
16720
- .content {
16721
- background-image: url("${primaryImage}");
17407
+ const STYLES$1 = ({ textColor = '#ffffff', primaryImage, mobilePrimaryImage = primaryImage }, { prefix, overlay }) => {
17408
+ const linearGradient = linearGradientColorStop(overlay || [], 'rgba(0, 0, 0, 1) 0%, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0) 30%');
17409
+ return `
17410
+ <style>
17411
+ :host {
17412
+ min-width: 165px;
17413
+ min-height: 300px;
16722
17414
  }
16723
- }
16724
- </style>
16725
- `;
16726
- function rbSmallCategoryImageToutTemplate(spot) {
17415
+
17416
+ .${prefix}__content {
17417
+ width: 100%;
17418
+ height: 100%;
17419
+ display: flex;
17420
+ flex-direction: column;
17421
+ justify-content: flex-end;
17422
+ background-image: linear-gradient(to top, ${linearGradient}), url("${mobilePrimaryImage}");
17423
+ background-size: cover;
17424
+ background-repeat: no-repeat;
17425
+ background-position: center;
17426
+ border-radius: 5px;
17427
+ overflow: hidden;
17428
+ cursor: pointer;
17429
+ }
17430
+
17431
+ .${prefix}__text {
17432
+ padding: 10px;
17433
+ width: 70%;
17434
+ }
17435
+
17436
+ .${prefix}__header {
17437
+ font-size: 12px;
17438
+ color: ${textColor};
17439
+ line-height: 16px;
17440
+ font-family: "Source Sans 3", system-ui;
17441
+ font-style: normal;
17442
+ font-weight: 400;
17443
+ line-height: normal;
17444
+ margin: 0;
17445
+ }
17446
+
17447
+ @media (min-width: 640px) {
17448
+ .${prefix}__content {
17449
+ background-image: linear-gradient(to top, ${linearGradient}), url("${primaryImage}");
17450
+ }
17451
+ }
17452
+ </style>
17453
+ `;
17454
+ };
17455
+ function rbSmallCategoryImageToutTemplate(spot, config) {
17456
+ const { prefix = '' } = config;
16727
17457
  return `
16728
17458
  ${GFONT_PRECONNECT}
16729
17459
  ${GFONT_CORMORANT}
16730
- ${STYLES$1(spot)}
16731
- <div class="content">
16732
- <div class="text">
16733
- ${spot.header ? `<h2 class="header">${spot.header}</h2>` : ''}
17460
+ ${STYLES$1(spot, config)}
17461
+ <div class="${prefix}__content">
17462
+ <div class="${prefix}__text">
17463
+ ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
16734
17464
  </div>
16735
17465
  </div>
16736
17466
  `;
16737
17467
  }
16738
17468
 
16739
- const STYLES = ({ textColor = '#000000', backgroundColor = 'transparent', primaryImage, mobilePrimaryImage = primaryImage, }) => `
17469
+ const STYLES = ({ textColor = '#000000', backgroundColor = 'transparent', primaryImage, mobilePrimaryImage = primaryImage, }, { prefix }) => `
16740
17470
  <style>
16741
17471
  :host {
16742
17472
  min-width: 165px;
16743
17473
  min-height: 250px;
16744
17474
  }
16745
- .content {
17475
+
17476
+ .${prefix}__content {
16746
17477
  width: 100%;
16747
17478
  height: 100%;
16748
17479
  background-color: ${backgroundColor};
@@ -16751,7 +17482,8 @@ const STYLES = ({ textColor = '#000000', backgroundColor = 'transparent', primar
16751
17482
  flex-direction: column;
16752
17483
  border-radius: 5px;
16753
17484
  }
16754
- .image {
17485
+
17486
+ .${prefix}__image {
16755
17487
  width: 100%;
16756
17488
  height: 100%;
16757
17489
  background-image: url("${mobilePrimaryImage}");
@@ -16760,7 +17492,8 @@ const STYLES = ({ textColor = '#000000', backgroundColor = 'transparent', primar
16760
17492
  background-position: center;
16761
17493
  border-radius: 5px;
16762
17494
  }
16763
- .text {
17495
+
17496
+ .${prefix}__text {
16764
17497
  text-align: left;
16765
17498
  display: flex;
16766
17499
  flex-direction: row;
@@ -16770,7 +17503,8 @@ const STYLES = ({ textColor = '#000000', backgroundColor = 'transparent', primar
16770
17503
  height: fit-content;
16771
17504
  position: relative;
16772
17505
  }
16773
- .header {
17506
+
17507
+ .${prefix}__header {
16774
17508
  font-size: 12px;
16775
17509
  color: ${textColor};
16776
17510
  padding-top: 5px;
@@ -16781,43 +17515,39 @@ const STYLES = ({ textColor = '#000000', backgroundColor = 'transparent', primar
16781
17515
  line-height: normal;
16782
17516
  margin: 0;
16783
17517
  }
17518
+
16784
17519
  @media (min-width: 640px) {
16785
- .image {
17520
+ .${prefix}__image {
16786
17521
  background-image: url("${primaryImage}");
16787
17522
  }
16788
17523
  }
16789
17524
  </style>
16790
17525
  `;
16791
- function rbSmallDiscoverToutTemplate(spot) {
17526
+ function rbSmallDiscoverToutTemplate(spot, config) {
17527
+ const { prefix = '' } = config;
16792
17528
  return `
16793
17529
  ${GFONT_PRECONNECT}
16794
17530
  ${GFONT_CORMORANT}
16795
- ${STYLES(spot)}
16796
- <div class="content">
16797
- <div class="image"></div>
16798
- <div class="text">
16799
- ${spot.header ? `<h2 class="header">${spot.header}</h2>` : ''}
17531
+ ${STYLES(spot, config)}
17532
+ <div class="${prefix}__content">
17533
+ <div class="${prefix}__image"></div>
17534
+ <div class="${prefix}__text">
17535
+ ${spot.header ? `<h2 class="${prefix}__header">${spot.header}</h2>` : ''}
16800
17536
  </div>
16801
17537
  </div>
16802
17538
  `;
16803
17539
  }
16804
17540
 
16805
- var ENUM_SPOT_ELEMENT_ATTRIBUTE;
16806
- (function (ENUM_SPOT_ELEMENT_ATTRIBUTE) {
16807
- ENUM_SPOT_ELEMENT_ATTRIBUTE["WIDTH"] = "width";
16808
- ENUM_SPOT_ELEMENT_ATTRIBUTE["HEIGHT"] = "height";
16809
- ENUM_SPOT_ELEMENT_ATTRIBUTE["FLUID"] = "fluid";
16810
- ENUM_SPOT_ELEMENT_ATTRIBUTE["REDIRECT_ON_CLICK"] = "redirect-on-click";
16811
- })(ENUM_SPOT_ELEMENT_ATTRIBUTE || (ENUM_SPOT_ELEMENT_ATTRIBUTE = {}));
16812
17541
  /**
16813
17542
  * Creates the spot html string based on the provided spot data.
16814
17543
  *
16815
- * @param {ISpot} data - The spot data.
17544
+ * @param {ISpot} spot - The spot data.
16816
17545
  *
16817
17546
  * @return {string} - The spot html string.
16818
17547
  */
16819
- const GET_SPOT_TEMPLATE_HTML_STRING = (data) => {
17548
+ const SPOT_TEMPLATE_HTML_ELEMENT = (spot, config) => {
16820
17549
  const templates = {
17550
+ // Reserve Bar Spot Templates
16821
17551
  [exports.RMN_SPOT_TYPE.RB_HOMEPAGE_HERO_THREE_TILE]: {
16822
17552
  rbHomepageHeroThreeTile: rbHomepageHeroThreeTileTemplate,
16823
17553
  },
@@ -16845,6 +17575,7 @@ const GET_SPOT_TEMPLATE_HTML_STRING = (data) => {
16845
17575
  [exports.RMN_SPOT_TYPE.RB_PRODUCT_UPCS]: {
16846
17576
  rbProductUpcs: () => '', // No template for this spot type, it will be handled by ReserveBar App.
16847
17577
  },
17578
+ // IAB Standard Spot Templates
16848
17579
  [exports.RMN_SPOT_TYPE.BILLBOARD]: {
16849
17580
  billboardV1: billboardV1Template,
16850
17581
  billboardV2: billboardV2Template,
@@ -16871,178 +17602,28 @@ const GET_SPOT_TEMPLATE_HTML_STRING = (data) => {
16871
17602
  inTextV1: inTextV1Template,
16872
17603
  },
16873
17604
  };
16874
- const spotVariants = templates[data.spot];
17605
+ const spotVariants = templates[spot.spot];
16875
17606
  if (!spotVariants) {
16876
- return '';
17607
+ return null;
16877
17608
  }
16878
- const variantTemplate = spotVariants[data.variant];
17609
+ const variantTemplate = spotVariants[spot.variant];
16879
17610
  if (!variantTemplate) {
16880
- return '';
17611
+ return null;
16881
17612
  }
16882
- return variantTemplate(data);
17613
+ // Generate a random prefix to avoid conflicts with other elements.
17614
+ const prefix = 's' + Math.random().toString(36).substring(6);
17615
+ const spotHtmlString = variantTemplate(spot, { ...config, prefix });
17616
+ return spotHtmlStringToElement(spotHtmlString);
16883
17617
  };
16884
17618
 
16885
- let SpotElement;
16886
- if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined') {
16887
- class CustomSpotElement extends HTMLElement {
16888
- constructor() {
16889
- super();
16890
- this.hasCustomContent = false;
16891
- this.handleClick = this.handleClick.bind(this);
16892
- this.attachShadow({ mode: 'open' });
16893
- }
16894
- connectedCallback() {
16895
- this.hasCustomContent = Boolean(this.customContent);
16896
- this.addEventListener('click', this.handleClick);
16897
- this.setupIntersectionObserver();
16898
- this.render();
16899
- }
16900
- disconnectedCallback() {
16901
- var _a;
16902
- (_a = this.observer) === null || _a === void 0 ? void 0 : _a.disconnect();
16903
- this.removeEventListener('click', this.handleClick);
16904
- }
16905
- attributeChangedCallback(_name, oldValue, newValue) {
16906
- if (oldValue !== newValue) {
16907
- this.render();
16908
- }
16909
- }
16910
- render() {
16911
- if (!this.shadowRoot || !this.data)
16912
- return;
16913
- const { style, wrapper, slot } = SPOT_ELEMENT_TEMPLATE(this.data.width, this.data.height, this.hasCustomContent);
16914
- this.shadowRoot.replaceChildren(style, slot);
16915
- if (this.hasCustomContent) {
16916
- this.setCustomContent();
16917
- }
16918
- if (!this.hasCustomContent) {
16919
- wrapper.innerHTML = GET_SPOT_TEMPLATE_HTML_STRING(this.data);
16920
- this.shadowRoot.appendChild(wrapper);
16921
- }
16922
- }
16923
- setCustomContent() {
16924
- const wrapper = document.createElement('div');
16925
- wrapper.setAttribute('slot', SPOT_ELEMENT_SLOT_NAME);
16926
- if (typeof this.customContent === 'string') {
16927
- wrapper.innerHTML = this.customContent;
16928
- }
16929
- if (this.customContent instanceof HTMLElement) {
16930
- wrapper.appendChild(this.customContent);
16931
- }
16932
- this.appendChild(wrapper);
16933
- }
16934
- setupIntersectionObserver() {
16935
- const options = {
16936
- root: null,
16937
- rootMargin: '0px',
16938
- threshold: 0.5, // The element is considered visible when 50% of it is visible
16939
- };
16940
- this.observer = new IntersectionObserver((entries) => {
16941
- var _a;
16942
- if (entries[0].isIntersecting) {
16943
- this.registerEvent(exports.RMN_SPOT_EVENT.IMPRESSION);
16944
- (_a = this.observer) === null || _a === void 0 ? void 0 : _a.disconnect();
16945
- }
16946
- }, options);
16947
- this.observer.observe(this);
16948
- }
16949
- handleClick() {
16950
- this.registerEvent(exports.RMN_SPOT_EVENT.CLICK);
16951
- }
16952
- async registerEvent(event) {
16953
- var _a, _b;
16954
- if (!this.data)
16955
- return;
16956
- const shouldRedirectOnClick = this.getAttribute(ENUM_SPOT_ELEMENT_ATTRIBUTE.REDIRECT_ON_CLICK) === 'true';
16957
- const eventUrl = (_b = (_a = this.data.events.find((e) => e.event === event)) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : '';
16958
- try {
16959
- const options = {
16960
- method: 'POST',
16961
- redirect: event === exports.RMN_SPOT_EVENT.CLICK && shouldRedirectOnClick ? 'follow' : 'manual',
16962
- };
16963
- const response = await fetch(eventUrl, options);
16964
- if (response.ok && event === exports.RMN_SPOT_EVENT.CLICK && shouldRedirectOnClick) {
16965
- window.location.href = this.getRedirectUrlFromPayload(eventUrl);
16966
- }
16967
- }
16968
- catch (error) {
16969
- console.error(`Rmn error sending ${event} event:`, error);
16970
- }
16971
- }
16972
- getRedirectUrlFromPayload(url) {
16973
- var _a, _b;
16974
- const base64String = (_a = new URL(url).searchParams.get('e')) !== null && _a !== void 0 ? _a : '';
16975
- try {
16976
- const data = JSON.parse(atob(base64String));
16977
- return (_b = data.ur) !== null && _b !== void 0 ? _b : '';
16978
- }
16979
- catch (_c) {
16980
- return '';
16981
- }
16982
- }
16983
- }
16984
- CustomSpotElement.observedAttributes = Object.values(ENUM_SPOT_ELEMENT_ATTRIBUTE);
16985
- SpotElement = CustomSpotElement;
16986
- }
16987
-
16988
- class SpotHtmlService {
16989
- static getInstance() {
16990
- return SingletonManager.getInstance('SpotHtmlService', () => new SpotHtmlService());
16991
- }
16992
- /**
16993
- * Creates the html element based on the provided spot data using shadow dom.
16994
- *
16995
- * This method is only available in browser environments.
16996
- *
16997
- * @param {ISpot} spot - The spot data.
16998
- * @param {ICreateSpotElementConfig} config - The configuration object.
16999
- * @param {ICreateSpotElementConfig.fluid} config.fluid - If the spot should be fluid or not.
17000
- * @param {ICreateSpotElementConfig.customContent} config.customContent - Use a custom html element/string.
17001
- * @param {ICreateSpotElementConfig.redirectOnClick} config.redirectOnClick - If the spot should redirect on click.
17002
- *
17003
- * @return {HTMLElement | null} - The spot html element or null if the browser environment is not available.
17004
- */
17005
- createSpotHtmlElement(spot, config) {
17006
- var _a, _b;
17007
- if (!this.ensureBrowserEnvironmentAndDefineElement()) {
17008
- return null;
17009
- }
17010
- const isFluid = (_a = config === null || config === void 0 ? void 0 : config.fluid) !== null && _a !== void 0 ? _a : false;
17011
- const shouldRedirectOnClick = (_b = config === null || config === void 0 ? void 0 : config.redirectOnClick) !== null && _b !== void 0 ? _b : true;
17012
- const element = document.createElement(SPOT_ELEMENT_TAG);
17013
- element.setAttribute(ENUM_SPOT_ELEMENT_ATTRIBUTE.WIDTH, spot.width.toString());
17014
- element.setAttribute(ENUM_SPOT_ELEMENT_ATTRIBUTE.HEIGHT, spot.height.toString());
17015
- element.setAttribute(ENUM_SPOT_ELEMENT_ATTRIBUTE.FLUID, isFluid.toString());
17016
- element.setAttribute(ENUM_SPOT_ELEMENT_ATTRIBUTE.REDIRECT_ON_CLICK, shouldRedirectOnClick.toString());
17017
- // Share the spot data with the element
17018
- element.data = spot;
17019
- // Set custom content
17020
- if (config === null || config === void 0 ? void 0 : config.customContent) {
17021
- element.customContent = config.customContent;
17022
- }
17023
- return element;
17024
- }
17025
- /**
17026
- * @returns {boolean} - True if the browser environment is available and the element is defined.
17027
- */
17028
- ensureBrowserEnvironmentAndDefineElement() {
17029
- if (typeof window === 'undefined' || typeof document === 'undefined') {
17030
- console.warn('LiquidCommerce Rmn Sdk: createSpotElement is only available in browser environments!!!');
17031
- return false;
17032
- }
17033
- if (!customElements.get(SPOT_ELEMENT_TAG)) {
17034
- customElements.define(SPOT_ELEMENT_TAG, SpotElement);
17035
- }
17036
- return true;
17037
- }
17038
- }
17619
+ const SELECTION_API_PATH = '/spots/selection';
17039
17620
 
17040
- class SpotSelectionService extends BaseApi {
17621
+ class SelectionService extends BaseApi {
17041
17622
  constructor(auth) {
17042
17623
  super(auth);
17043
17624
  }
17044
17625
  static getInstance(auth) {
17045
- return SingletonManager.getInstance('SpotSelectionService', () => new SpotSelectionService(auth));
17626
+ return SingletonManager.getInstance('SelectionService', () => new SelectionService(auth));
17046
17627
  }
17047
17628
  /**
17048
17629
  * Makes a selection request on our server based on the provided data.
@@ -17052,7 +17633,7 @@ class SpotSelectionService extends BaseApi {
17052
17633
  * @return {Promise<ISpots>} - The spots response object.
17053
17634
  */
17054
17635
  async spotSelection(data) {
17055
- const { isOk, val, isErr } = await this.post(SPOTS_SELECTION_API_PATH, data, {});
17636
+ const { isOk, val, isErr } = await this.post(SELECTION_API_PATH, data, {});
17056
17637
  if (isErr) {
17057
17638
  throw new Error(`There was an error during spot selection: (${isErr === null || isErr === void 0 ? void 0 : isErr.errorMessage})`);
17058
17639
  }
@@ -17067,8 +17648,8 @@ class SpotSelectionService extends BaseApi {
17067
17648
 
17068
17649
  class LiquidCommerceRmnClient {
17069
17650
  constructor(auth) {
17070
- this.spotSelectionService = SpotSelectionService.getInstance(auth);
17071
- this.spotHtmlService = SpotHtmlService.getInstance();
17651
+ this.selectionService = SelectionService.getInstance(auth);
17652
+ this.elementService = ElementService.getInstance();
17072
17653
  }
17073
17654
  /**
17074
17655
  * Makes a selection request on our server based on the provided data.
@@ -17080,23 +17661,145 @@ class LiquidCommerceRmnClient {
17080
17661
  * @return {Promise<ISpots>} - The spots response object.
17081
17662
  */
17082
17663
  async spotSelection(data) {
17083
- return this.spotSelectionService.spotSelection(data);
17664
+ return this.selectionService.spotSelection(data);
17665
+ }
17666
+ /**
17667
+ * Injects the spot elements into their provided placement.
17668
+ *
17669
+ * @param {IInjectSpotElement[]} data - The spot element's data.
17670
+ * @param {IInjectSpotElementConfig} config - The configuration object.
17671
+ *
17672
+ * @return {Promise<void>} - A promise that resolves when the spot elements are injected.
17673
+ */
17674
+ async injectSpotElement(data, config) {
17675
+ if (!data.length) {
17676
+ console.warn('RmnSdk: Failed to request spot selection. No spot elements provided.');
17677
+ return;
17678
+ }
17679
+ const spotSelectionRequest = data.map((item) => {
17680
+ var _a;
17681
+ return ({
17682
+ spot: item.spotType,
17683
+ count: (_a = item === null || item === void 0 ? void 0 : item.count) !== null && _a !== void 0 ? _a : 1,
17684
+ });
17685
+ });
17686
+ const response = await this.spotSelection({
17687
+ spots: spotSelectionRequest,
17688
+ url: config === null || config === void 0 ? void 0 : config.url,
17689
+ });
17690
+ const normalizedData = this.normalizeDataSpotType(data);
17691
+ for (const item of normalizedData) {
17692
+ const spots = response[item.spotType];
17693
+ if (!(spots === null || spots === void 0 ? void 0 : spots.length)) {
17694
+ console.warn(`RmnSdk: Failed to inject spot element. No spots found for type "${item.spotType}".`);
17695
+ continue;
17696
+ }
17697
+ const placementId = item.placementId.replace('#', '');
17698
+ const placement = document.getElementById(placementId);
17699
+ if (!placement) {
17700
+ console.warn(`RmnSdk: Failed to inject spot element. Placement not found for id "#${placementId}".`);
17701
+ continue;
17702
+ }
17703
+ if (spots.length === 1) {
17704
+ this.injectOneSpotElement(item, placement, spots[0], config);
17705
+ }
17706
+ if (spots.length > 1) {
17707
+ this.injectCarouselSpotElement(placement, spots, config);
17708
+ }
17709
+ }
17084
17710
  }
17085
17711
  /**
17086
- * Creates the spot html element based on the provided data using shadow dom.
17712
+ * Injects a carousel element with the provided spots into the placement.
17713
+ *
17714
+ * @param {HTMLElement} placement - The placement element.
17715
+ * @param {ISpot[]} spots - The spot data.
17716
+ * @param {IInjectSpotElementConfig} config - The configuration object.
17087
17717
  *
17088
- * This method is useful when you are initializing the client in a browser environment, so you can create the spot html element directly from the RmnClient instance.
17718
+ * @return {void}
17719
+ */
17720
+ injectCarouselSpotElement(placement, spots, config) {
17721
+ var _a;
17722
+ const carouselSlides = [];
17723
+ for (const spotItem of spots) {
17724
+ const spot = this.elementService.overrideSpotColors(spotItem, config === null || config === void 0 ? void 0 : config.colors);
17725
+ const content = SPOT_TEMPLATE_HTML_ELEMENT(spot, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
17726
+ if (!content) {
17727
+ console.warn(`RmnSdk: Failed to inject carousel spot element. Could not create element for type "${spot.spot}".`);
17728
+ return;
17729
+ }
17730
+ carouselSlides.push(content);
17731
+ }
17732
+ const { maxWidth, maxHeight } = spots.reduce((max, spot) => ({
17733
+ maxWidth: Math.max(max.maxWidth, spot.width),
17734
+ maxHeight: Math.max(max.maxHeight, spot.height),
17735
+ }), { maxWidth: 0, maxHeight: 0 });
17736
+ const carouselElement = this.elementService.createCarouselElement({
17737
+ slides: carouselSlides,
17738
+ config: {
17739
+ width: maxWidth,
17740
+ height: maxHeight,
17741
+ minScale: (_a = config === null || config === void 0 ? void 0 : config.minScale) !== null && _a !== void 0 ? _a : 0.25, // Scale down to 25% of the original size
17742
+ ...config === null || config === void 0 ? void 0 : config.carousel,
17743
+ },
17744
+ });
17745
+ if (!carouselElement) {
17746
+ console.warn(`RmnSdk: Failed to inject spot carousel element. Could not create spot carousel element.`);
17747
+ return;
17748
+ }
17749
+ placement.replaceChildren(carouselElement);
17750
+ }
17751
+ /**
17752
+ * Injects a single spot element into the provided placement.
17089
17753
  *
17754
+ * @param {IInjectSpotElement} injectItem - The inject item data.
17755
+ * @param {HTMLElement} placement - The placement element.
17090
17756
  * @param {ISpot} spot - The spot data.
17091
- * @param {ICreateSpotElementConfig} config - The configuration object.
17092
- * @param {ICreateSpotElementConfig.fluid} config.fluid - If the spot should be fluid or not.
17093
- * @param {ICreateSpotElementConfig.customContent} config.customContent - Use a custom html element/string.
17094
- * @param {ICreateSpotElementConfig.redirectOnClick} config.redirectOnClick - If the spot should redirect on click.
17757
+ * @param {IInjectSpotElementConfig} config - The configuration object.
17758
+ *
17759
+ * @return {void}
17760
+ */
17761
+ injectOneSpotElement(injectItem, placement, spot, config) {
17762
+ var _a;
17763
+ const spotData = this.elementService.overrideSpotColors(spot, config === null || config === void 0 ? void 0 : config.colors);
17764
+ const content = SPOT_TEMPLATE_HTML_ELEMENT(spotData, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
17765
+ if (!content) {
17766
+ console.warn(`RmnSdk: Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`);
17767
+ return;
17768
+ }
17769
+ const spotElement = this.elementService.createSpotElement({
17770
+ content,
17771
+ config: {
17772
+ width: spot.width,
17773
+ height: spot.height,
17774
+ minScale: (_a = config === null || config === void 0 ? void 0 : config.minScale) !== null && _a !== void 0 ? _a : 0.25, // Scale down to 25% of the original size
17775
+ },
17776
+ });
17777
+ if (!spotElement) {
17778
+ console.warn(`RmnSdk: Failed to inject spot element. Could not create element for type "${injectItem.spotType}".`);
17779
+ return;
17780
+ }
17781
+ placement.replaceChildren(spotElement);
17782
+ }
17783
+ /**
17784
+ * Normalizes the spot type data by adding a number suffix to the spot type.
17095
17785
  *
17096
- * @return {HTMLElement | null} - The spot html element or null if the browser environment is not available.
17786
+ * @param {IInjectSpotElement[]} spots - The spot type data.
17787
+ *
17788
+ * @return {IInjectSpotElement[]} - The normalized spot type data.
17097
17789
  */
17098
- createSpotElement(spot, config) {
17099
- return this.spotHtmlService.createSpotHtmlElement(spot, config);
17790
+ normalizeDataSpotType(spots) {
17791
+ const spotTypeCounts = {};
17792
+ return spots.map((spot) => {
17793
+ const { spotType } = spot;
17794
+ spotTypeCounts[spotType] = (spotTypeCounts[spotType] || 0) + 1;
17795
+ if (spotTypeCounts[spotType] === 1) {
17796
+ return spot;
17797
+ }
17798
+ return {
17799
+ ...spot,
17800
+ spotType: `${spotType}${spotTypeCounts[spotType]}`,
17801
+ };
17802
+ });
17100
17803
  }
17101
17804
  }
17102
17805
  /**
@@ -17116,20 +17819,32 @@ async function RmnClient(apiKey, config) {
17116
17819
  * Creates the spot html element based on the provided data using shadow dom.
17117
17820
  *
17118
17821
  * This method is useful when you are initializing the client in a non-browser environment.
17119
- * When you request a spot selection, you will receive the spot data in server-side and return them back to the client.
17822
+ * When you request a spot selection, you will receive the spot data in server-side and return them to the client.
17120
17823
  * Then you can use this function to create the spot html element based on the provided data without the need of the RmnClient instance.
17121
17824
  *
17122
17825
  * @param {ISpot} spot - The spot data.
17123
- * @param {ICreateSpotElementConfig} config - The configuration object.
17124
- * @param {ICreateSpotElementConfig.fluid} config.fluid - If the spot should be fluid or not.
17125
- * @param {ICreateSpotElementConfig.customContent} config.customContent - Use a custom html element/string.
17126
- * @param {ICreateSpotElementConfig.redirectOnClick} config.redirectOnClick - If the spot should redirect on click.
17826
+ * @param {IRmnCreateSpotElementConfig} config - The configuration object.
17127
17827
  *
17128
17828
  * @return {HTMLElement | null} - The spot html element or null if the browser environment is not available.
17129
17829
  */
17130
17830
  function RmnCreateSpotElement(spot, config) {
17131
- const spotHtmlService = SpotHtmlService.getInstance();
17132
- return spotHtmlService.createSpotHtmlElement(spot, config);
17831
+ var _a;
17832
+ const elementService = ElementService.getInstance();
17833
+ const spotData = elementService.overrideSpotColors(spot, config === null || config === void 0 ? void 0 : config.colors);
17834
+ const content = SPOT_TEMPLATE_HTML_ELEMENT(spotData, { overlay: config === null || config === void 0 ? void 0 : config.overlay });
17835
+ if (!content) {
17836
+ console.warn(`RmnSdk: Failed to create spot element for type "${spotData.spot}".`);
17837
+ return null;
17838
+ }
17839
+ return elementService.createSpotElement({
17840
+ content,
17841
+ config: {
17842
+ fluid: true,
17843
+ width: spot.width,
17844
+ height: spot.height,
17845
+ minScale: (_a = config === null || config === void 0 ? void 0 : config.minScale) !== null && _a !== void 0 ? _a : 0.25, // Scale down to 25% of the original size
17846
+ },
17847
+ });
17133
17848
  }
17134
17849
 
17135
17850
  exports.LiquidCommerceRmnClient = LiquidCommerceRmnClient;