@behold/widget 0.5.56 → 0.5.57

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,1905 @@
1
+ import { t as throttle, e as getClosestShadowRootOrDocument, c as createElement, a as setClasses, f as forceLayout, p as pushWithLimit, j as getMostVisible, B as BaseElement, k as announceToScreenReader, l as getTruncatedText, h as hasChanges } from './index-R4lEDZFo.js';
2
+ import { a as Video, c as Image, R as RGBStringToHSLArray } from './base-GZO73SkY.js';
3
+ import { c as caretLeftIcon, a as caretRightIcon } from './caret-right-S2XSTDFy.js';
4
+
5
+ let root = document;
6
+ let containerEl = null;
7
+ let tabbableEls = new Set();
8
+ let excludedEls = new Set();
9
+ let mutationObserver = new MutationObserver(handleMutation);
10
+ let trapped = false;
11
+ function getTabbableEls(container) {
12
+ const treeWalker = document.createTreeWalker(container, NodeFilter.SHOW_ELEMENT, {
13
+ acceptNode: function (node) {
14
+ return node.tabIndex >= 0
15
+ ? NodeFilter.FILTER_ACCEPT
16
+ : NodeFilter.FILTER_SKIP;
17
+ },
18
+ });
19
+ const tabbable = [];
20
+ let currNode = null;
21
+ while ((currNode = treeWalker.nextNode())) {
22
+ {
23
+ tabbable.push(currNode);
24
+ }
25
+ }
26
+ return tabbable;
27
+ }
28
+ function isVisible(el) {
29
+ return new Promise((resolve) => {
30
+ const ob = new IntersectionObserver((entries) => {
31
+ resolve(entries[0].isIntersecting);
32
+ ob.disconnect();
33
+ });
34
+ ob.observe(el);
35
+ });
36
+ }
37
+ function isTabbable(el) {
38
+ return new Promise(async (resolve) => {
39
+ if (el.disabled) {
40
+ resolve(false);
41
+ return;
42
+ }
43
+ const visible = await isVisible(el);
44
+ if (!visible) {
45
+ resolve(false);
46
+ return;
47
+ }
48
+ resolve([...excludedEls].every((excludedEl) => !excludedEl.contains(el)));
49
+ });
50
+ }
51
+ async function getCurrentTabbable() {
52
+ const promiseArray = await Promise.all([...tabbableEls].map(async (el) => {
53
+ const isTababble = await isTabbable(el);
54
+ return isTababble ? el : false;
55
+ }));
56
+ return promiseArray.filter((item) => !!item);
57
+ }
58
+ async function advance() {
59
+ const currentTabbable = await getCurrentTabbable();
60
+ let next = currentTabbable.indexOf(root.activeElement) + 1;
61
+ if (next > currentTabbable.length - 1 || next < 0) {
62
+ next = 0;
63
+ }
64
+ currentTabbable[next]?.focus();
65
+ }
66
+ async function retreat() {
67
+ const currentTabbable = await getCurrentTabbable();
68
+ let next = currentTabbable.indexOf(root.activeElement) - 1;
69
+ if (next < 0) {
70
+ next = currentTabbable.length - 1;
71
+ }
72
+ currentTabbable[next]?.focus();
73
+ }
74
+ function handleMutation(records) {
75
+ const shouldUpdate = records.some((record) => {
76
+ if (record.type === 'attributes')
77
+ return true;
78
+ if ([...record.addedNodes, ...record.removedNodes].some((node) => getTabbableEls(node).length > 0)) {
79
+ return true;
80
+ }
81
+ return false;
82
+ });
83
+ if (shouldUpdate) {
84
+ updateTabbableEls({ include: [containerEl], merge: true });
85
+ }
86
+ }
87
+ function handleKeydown(evt) {
88
+ const keyList = ['Tab'];
89
+ if (keyList.includes(evt.code) &&
90
+ !evt.ctrlKey &&
91
+ !evt.altKey &&
92
+ !evt.metaKey) {
93
+ evt.preventDefault();
94
+ if (evt.code === 'Tab' && evt.shiftKey) {
95
+ retreat();
96
+ }
97
+ else {
98
+ advance();
99
+ }
100
+ }
101
+ }
102
+ function updateTabbableEls({ include = [], exclude = [], merge = false, }) {
103
+ if (merge) {
104
+ include.forEach((el) => {
105
+ excludedEls.delete(el);
106
+ getTabbableEls(el).forEach((el) => {
107
+ if (!tabbableEls.has(el)) {
108
+ tabbableEls.add(el);
109
+ }
110
+ });
111
+ });
112
+ exclude.forEach((el) => excludedEls.add(el));
113
+ }
114
+ else {
115
+ tabbableEls = new Set(include.flatMap((el) => getTabbableEls(el)));
116
+ excludedEls = new Set(exclude);
117
+ }
118
+ }
119
+ async function trapFocus(el, exclude = [], initialFocusIndex = 0) {
120
+ containerEl = el;
121
+ if (isShadowRoot(el)) {
122
+ root = el;
123
+ }
124
+ else {
125
+ root = document;
126
+ }
127
+ trapped = true;
128
+ updateTabbableEls({ include: [el], exclude });
129
+ document.addEventListener('keydown', handleKeydown);
130
+ mutationObserver.observe(el, {
131
+ subtree: true,
132
+ attributes: true,
133
+ attributeFilter: ['disabled'],
134
+ childList: true,
135
+ });
136
+ const currentTabbable = await getCurrentTabbable();
137
+ currentTabbable[initialFocusIndex]?.focus();
138
+ }
139
+ function releaseFocus(newFocusEl) {
140
+ if (!trapped)
141
+ return;
142
+ trapped = false;
143
+ newFocusEl = newFocusEl ?? document.body;
144
+ document.removeEventListener('keydown', handleKeydown);
145
+ mutationObserver.disconnect();
146
+ tabbableEls.clear();
147
+ excludedEls.clear();
148
+ containerEl = null;
149
+ if (newFocusEl)
150
+ newFocusEl.focus();
151
+ }
152
+ const isShadowRoot = (el) => el instanceof ShadowRoot;
153
+
154
+ class HurdyGurdy {
155
+ containerEl;
156
+ slides;
157
+ breadcrumbsContainerEl;
158
+ previousEl;
159
+ nextEl;
160
+ keyboardNav;
161
+ breadcrumbDiameter;
162
+ onSlideChange;
163
+ virtualize;
164
+ proximalSlidesToRender;
165
+ dynamicBreadCrumbsCutoff;
166
+ dragLimit;
167
+ transitionSpeed;
168
+ baseTransition;
169
+ momentumToTransition;
170
+ index;
171
+ _initialized;
172
+ _rootEl = document;
173
+ _innerEl;
174
+ _slideEls;
175
+ _breadcrumbsInnerEl;
176
+ _breadcrumbsCurrent;
177
+ _breadcrumbs;
178
+ _raf;
179
+ _focusRaf;
180
+ _st;
181
+ _transitionSt;
182
+ _isDragging;
183
+ _draggingDirection;
184
+ _dragStartPoint;
185
+ _prevDragPoint;
186
+ _positions;
187
+ _dragStartTranslation;
188
+ _currentPercentTranslation;
189
+ _progressToNextSlide;
190
+ _currentDeltaX;
191
+ _recentDeltas;
192
+ _resizeObserver;
193
+ _throttledDrag;
194
+ _throttledResize;
195
+ constructor({ slides, containerEl, breadcrumbsContainerEl, previousEl, nextEl, onSlideChange, breadcrumbDiameter = 7, dynamicBreadCrumbsCutoff = 10, keyboardNav = true, dragLimit = 0.5, virtualize = false, proximalSlidesToRender = 1, momentumToTransition = 5, transitionSpeed = 300, baseTransition = '', }) {
196
+ let ResizeObserver = window.ResizeObserver;
197
+ if ('ResizeObserver' in window === false) {
198
+ // @ts-ignore
199
+ ResizeObserver = window.BeholdResizeObserver;
200
+ }
201
+ this.slides = slides;
202
+ this.containerEl = containerEl;
203
+ this.breadcrumbsContainerEl = breadcrumbsContainerEl;
204
+ this.previousEl = previousEl;
205
+ this.nextEl = nextEl;
206
+ this.onSlideChange = onSlideChange;
207
+ this.breadcrumbDiameter = breadcrumbDiameter;
208
+ this.dynamicBreadCrumbsCutoff = dynamicBreadCrumbsCutoff;
209
+ this.keyboardNav = keyboardNav;
210
+ this.dragLimit = dragLimit;
211
+ this.virtualize = virtualize;
212
+ this.proximalSlidesToRender = proximalSlidesToRender;
213
+ this.transitionSpeed = transitionSpeed;
214
+ this.baseTransition = baseTransition;
215
+ this.momentumToTransition = momentumToTransition;
216
+ this.index = 0;
217
+ this._initialized = false;
218
+ this._innerEl = null;
219
+ this._slideEls = null;
220
+ this._breadcrumbs = null;
221
+ this._raf = null;
222
+ this._st = null;
223
+ this._transitionSt = null;
224
+ this._isDragging = false;
225
+ this._draggingDirection = null;
226
+ this._dragStartPoint = { x: 0, y: 0 };
227
+ this._prevDragPoint = { x: 0, y: 0 };
228
+ this._dragStartTranslation = 0;
229
+ this._currentPercentTranslation = 0;
230
+ this._progressToNextSlide = 0;
231
+ this._currentDeltaX = 0;
232
+ this._recentDeltas = [];
233
+ this._resizeObserver = new ResizeObserver((entries) => this._throttledResize(entries));
234
+ this.init = this.init.bind(this);
235
+ this.destroy = this.destroy.bind(this);
236
+ this._goTo = this._goTo.bind(this);
237
+ this._retreat = this._retreat.bind(this);
238
+ this._advance = this._advance.bind(this);
239
+ this._handlePrevClick = this._handlePrevClick.bind(this);
240
+ this._handleNextClick = this._handleNextClick.bind(this);
241
+ this._handleKeyDown = this._handleKeyDown.bind(this);
242
+ this._mouseDrag = this._mouseDrag.bind(this);
243
+ this._touchDrag = this._touchDrag.bind(this);
244
+ this._throttledDrag = throttle(this._drag, 10, this);
245
+ this._throttledResize = throttle(this._handleResize, 100, this);
246
+ this._startMouseDrag = this._startMouseDrag.bind(this);
247
+ this._startTouchDrag = this._startTouchDrag.bind(this);
248
+ this._startDrag = this._startDrag.bind(this);
249
+ this._endDrag = this._endDrag.bind(this);
250
+ this._updateBreadcrumbs = this._updateBreadcrumbs.bind(this);
251
+ this._updateBreadcrumbClasses = this._updateBreadcrumbClasses.bind(this);
252
+ this._addEventListeners = this._addEventListeners.bind(this);
253
+ this._removeEventListeners = this._removeEventListeners.bind(this);
254
+ }
255
+ _addEventListeners() {
256
+ this._innerEl.addEventListener('mousedown', this._startMouseDrag, {
257
+ passive: true,
258
+ });
259
+ this._innerEl.addEventListener('touchstart', this._startTouchDrag, {
260
+ passive: true,
261
+ });
262
+ document.body.addEventListener('mousemove', this._mouseDrag, {
263
+ passive: true,
264
+ });
265
+ document.body.addEventListener('mouseup', this._endDrag, { passive: true });
266
+ document.body.addEventListener('mouseleave', this._endDrag, {
267
+ passive: true,
268
+ });
269
+ document.body.addEventListener('touchmove', this._touchDrag, {
270
+ passive: true,
271
+ });
272
+ document.body.addEventListener('touchend', this._endDrag, { passive: true });
273
+ if (this.previousEl) {
274
+ this.previousEl.addEventListener('click', this._handlePrevClick, {
275
+ passive: true,
276
+ });
277
+ }
278
+ if (this.nextEl) {
279
+ this.nextEl.addEventListener('click', this._handleNextClick, {
280
+ passive: true,
281
+ });
282
+ }
283
+ if (this.keyboardNav) {
284
+ document.addEventListener('keydown', this._handleKeyDown);
285
+ }
286
+ }
287
+ _removeEventListeners() {
288
+ document.body.removeEventListener('mousemove', this._mouseDrag);
289
+ document.body.removeEventListener('mouseup', this._endDrag);
290
+ document.body.removeEventListener('mouseleave', this._endDrag);
291
+ document.body.removeEventListener('touchmove', this._touchDrag);
292
+ document.body.removeEventListener('touchend', this._endDrag);
293
+ if (this._innerEl) {
294
+ this._innerEl.removeEventListener('mousedown', this._startMouseDrag);
295
+ this._innerEl.removeEventListener('touchstart', this._startTouchDrag);
296
+ }
297
+ if (this.previousEl) {
298
+ this.previousEl.removeEventListener('click', this._handlePrevClick);
299
+ }
300
+ if (this.nextEl) {
301
+ this.nextEl.removeEventListener('click', this._handleNextClick);
302
+ }
303
+ if (this.keyboardNav) {
304
+ document.removeEventListener('keydown', this._handleKeyDown);
305
+ }
306
+ }
307
+ init(index = 0) {
308
+ if (this._initialized)
309
+ return;
310
+ this._initialized = true;
311
+ this._rootEl = getClosestShadowRootOrDocument(this.containerEl);
312
+ this._slideEls = this.slides.map((slide) => {
313
+ return createElement({
314
+ classes: 'hg-slide',
315
+ contents: slide,
316
+ });
317
+ });
318
+ this._breadcrumbs = this.slides.map((slide, i) => createElement({
319
+ classes: 'hg-breadcrumb',
320
+ listeners: { click: () => this._goTo({ index: i }) },
321
+ }));
322
+ this._breadcrumbsCurrent = createElement({
323
+ classes: 'hg-breadcrumbs-current',
324
+ });
325
+ this._breadcrumbsInnerEl = createElement({
326
+ classes: 'hg-breadcrumbs',
327
+ contents: [...this._breadcrumbs, this._breadcrumbsCurrent],
328
+ });
329
+ this._innerEl = createElement({
330
+ classes: 'hg-container',
331
+ contents: this._slideEls,
332
+ style: {
333
+ 'touch-action': 'pan-y',
334
+ },
335
+ });
336
+ this.containerEl.appendChild(this._innerEl);
337
+ if (this.breadcrumbsContainerEl) {
338
+ this.breadcrumbsContainerEl.style.setProperty('--breadCrumbDiameter', this.breadcrumbDiameter + 'px');
339
+ this.breadcrumbsContainerEl.appendChild(this._breadcrumbsInnerEl);
340
+ }
341
+ this._addEventListeners();
342
+ // Only one slide? Don't actually make a slideshow
343
+ if (this.slides.length < 2) {
344
+ this._breadcrumbsInnerEl.style.display = 'none';
345
+ this.previousEl.style.display = 'none';
346
+ this.nextEl.style.display = 'none';
347
+ }
348
+ this._resizeObserver?.observe(this.containerEl);
349
+ this._updateBreadcrumbs(this.index, this.index, false);
350
+ this._goTo({ index, animate: false, forceUpdate: true, isInitial: true });
351
+ }
352
+ destroy() {
353
+ if (!this._initialized)
354
+ return;
355
+ clearTimeout(this._st);
356
+ clearTimeout(this._transitionSt);
357
+ cancelAnimationFrame(this._raf);
358
+ cancelAnimationFrame(this._focusRaf);
359
+ this._resizeObserver.disconnect();
360
+ this._removeEventListeners();
361
+ this._breadcrumbs = null;
362
+ this._breadcrumbsCurrent = null;
363
+ this._breadcrumbsInnerEl.remove();
364
+ this._breadcrumbsInnerEl = null;
365
+ this._innerEl.remove();
366
+ this._innerEl = null;
367
+ this._rootEl = null;
368
+ this._slideEls = null;
369
+ this._initialized = false;
370
+ }
371
+ _handleResize(entries) {
372
+ if (!entries?.[0])
373
+ return;
374
+ this._positions = getElementPositions(this.containerEl, this._slideEls);
375
+ }
376
+ _updateBreadcrumbClasses(newIndex, animate = true) {
377
+ if (this._breadcrumbs.length >= this.dynamicBreadCrumbsCutoff &&
378
+ this.breadcrumbsContainerEl) {
379
+ setClasses(this._breadcrumbsInnerEl, {
380
+ 'no-transition': !animate,
381
+ });
382
+ requestAnimationFrame(() => {
383
+ this._breadcrumbsInnerEl.classList.remove('no-transition');
384
+ });
385
+ const translate = this._breadcrumbsInnerEl.offsetWidth / 2 -
386
+ this.breadcrumbDiameter / 2 -
387
+ this._breadcrumbs[newIndex].offsetLeft;
388
+ this._breadcrumbsInnerEl.style.transform = `translateX(${translate}px)`;
389
+ this._breadcrumbs.forEach((crumb, i) => {
390
+ setClasses(crumb, {
391
+ 'hg-breadcrumb--hidden': i <= newIndex - 5 || i >= newIndex + 5,
392
+ 'hg-breadcrumb--4': i === newIndex - 4 || i === newIndex + 4,
393
+ 'hg-breadcrumb--3': i === newIndex - 3 || i === newIndex + 3,
394
+ 'hg-breadcrumb--2': i === newIndex - 2 || i === newIndex + 2,
395
+ 'hg-breadcrumb--1': i === newIndex - 1 || i === newIndex + 1,
396
+ });
397
+ });
398
+ }
399
+ }
400
+ _updateBreadcrumbs(newIndex, oldIndex, animate) {
401
+ if (!this._breadcrumbs?.length)
402
+ return;
403
+ this._updateBreadcrumbClasses(newIndex, animate);
404
+ if (!this.breadcrumbsContainerEl)
405
+ return;
406
+ if (!animate ||
407
+ (this._breadcrumbs.length >= 10 && Math.abs(newIndex - oldIndex) > 1)) {
408
+ if (newIndex > oldIndex) {
409
+ this._breadcrumbsCurrent.style.left = '';
410
+ this._breadcrumbsCurrent.style.right = `${this._breadcrumbsInnerEl.offsetWidth -
411
+ (this._breadcrumbs[newIndex].offsetLeft + this.breadcrumbDiameter)}px`;
412
+ }
413
+ else {
414
+ this._breadcrumbsCurrent.style.right = '';
415
+ this._breadcrumbsCurrent.style.left =
416
+ this._breadcrumbs[newIndex].offsetLeft + 'px';
417
+ }
418
+ }
419
+ else {
420
+ if (newIndex < oldIndex) {
421
+ this._breadcrumbsCurrent.style.left = '';
422
+ this._breadcrumbsCurrent.style.right = `${this._breadcrumbsInnerEl.offsetWidth -
423
+ this._breadcrumbs[oldIndex]?.offsetLeft -
424
+ this.breadcrumbDiameter}px`;
425
+ }
426
+ else {
427
+ this._breadcrumbsCurrent.style.right = '';
428
+ this._breadcrumbsCurrent.style.left =
429
+ this._breadcrumbs[oldIndex]?.offsetLeft + 'px';
430
+ }
431
+ forceLayout();
432
+ this._raf = requestAnimationFrame(() => {
433
+ if (newIndex > oldIndex) {
434
+ this._breadcrumbsCurrent.style.width = `${this._breadcrumbs[newIndex]?.offsetLeft -
435
+ this._breadcrumbsCurrent.offsetLeft +
436
+ this.breadcrumbDiameter}px`;
437
+ }
438
+ else {
439
+ this._breadcrumbsCurrent.style.width = `${this._breadcrumbsCurrent.offsetLeft +
440
+ this._breadcrumbsCurrent.offsetWidth -
441
+ this._breadcrumbs[newIndex]?.offsetLeft}px`;
442
+ }
443
+ });
444
+ this._st = setTimeout(() => {
445
+ if (newIndex > oldIndex) {
446
+ this._breadcrumbsCurrent.style.left = '';
447
+ this._breadcrumbsCurrent.style.right = `${this._breadcrumbsInnerEl.offsetWidth -
448
+ (this._breadcrumbs[newIndex].offsetLeft + this.breadcrumbDiameter)}px`;
449
+ }
450
+ else {
451
+ this._breadcrumbsCurrent.style.right = '';
452
+ this._breadcrumbsCurrent.style.left =
453
+ this._breadcrumbs[newIndex].offsetLeft + 'px';
454
+ }
455
+ forceLayout();
456
+ this._raf = requestAnimationFrame(() => {
457
+ this._breadcrumbsCurrent.style.width = '';
458
+ });
459
+ }, 200);
460
+ }
461
+ }
462
+ _goTo({ index, animate = true, forceUpdate = false, easing = 'ease', isInitial = false, }) {
463
+ if (!this._slideEls?.[index])
464
+ return;
465
+ if (!this._initialized)
466
+ return;
467
+ cancelAnimationFrame(this._focusRaf);
468
+ const newIndex = index;
469
+ const oldIndex = this.index;
470
+ this.index = newIndex;
471
+ clearTimeout(this._transitionSt);
472
+ if (this.virtualize) {
473
+ this._slideEls.forEach((el, i) => {
474
+ const distance = Math.abs(this.index - i);
475
+ if (distance > this.proximalSlidesToRender && i !== oldIndex) {
476
+ if (el.hasChildNodes()) {
477
+ el.beholdReplaceChildren();
478
+ }
479
+ }
480
+ else if (!el.hasChildNodes()) {
481
+ el.beholdReplaceChildren(this.slides[i]);
482
+ }
483
+ });
484
+ }
485
+ if (window.matchMedia(`(prefers-reduced-motion)`).matches) {
486
+ animate = false;
487
+ }
488
+ this._isDragging = false;
489
+ this._progressToNextSlide = 0;
490
+ if (newIndex === oldIndex && !forceUpdate) {
491
+ this._breadcrumbsCurrent.style.width = '';
492
+ }
493
+ else {
494
+ cancelAnimationFrame(this._raf);
495
+ clearTimeout(this._st);
496
+ this._updateBreadcrumbs(newIndex, oldIndex, animate);
497
+ if (this.onSlideChange)
498
+ this.onSlideChange(newIndex, isInitial);
499
+ }
500
+ if (animate) {
501
+ this._innerEl.style.transition = `transform ${this.transitionSpeed}ms ${easing}`;
502
+ }
503
+ else {
504
+ this._innerEl.style.transition = this.baseTransition;
505
+ }
506
+ this._innerEl.style.transform = `translateX(${newIndex * -100}%)`;
507
+ this._currentPercentTranslation = newIndex * -100;
508
+ if (this.previousEl) {
509
+ if (newIndex < 1) {
510
+ if (this._rootEl.activeElement === this.previousEl) {
511
+ this._focusRaf = requestAnimationFrame(() => {
512
+ this.nextEl.focus();
513
+ });
514
+ }
515
+ this.previousEl.setAttribute('disabled', 'true');
516
+ }
517
+ else {
518
+ this.previousEl.removeAttribute('disabled');
519
+ }
520
+ }
521
+ if (this.nextEl) {
522
+ if (newIndex >= this._slideEls.length - 1) {
523
+ if (this._rootEl.activeElement === this.nextEl) {
524
+ this._focusRaf = requestAnimationFrame(() => {
525
+ this.previousEl.focus();
526
+ });
527
+ }
528
+ this.nextEl.setAttribute('disabled', 'true');
529
+ }
530
+ else {
531
+ this.nextEl.removeAttribute('disabled');
532
+ }
533
+ }
534
+ this._transitionSt = setTimeout(() => {
535
+ this._innerEl.style.transition = this.baseTransition;
536
+ }, this.transitionSpeed);
537
+ }
538
+ _handlePrevClick() {
539
+ this._retreat();
540
+ }
541
+ _handleNextClick() {
542
+ this._advance();
543
+ }
544
+ _retreat(easing = 'ease') {
545
+ if (typeof easing !== 'string')
546
+ easing = 'ease';
547
+ if (this.index < 1) {
548
+ this._goTo({ index: this.index });
549
+ }
550
+ else {
551
+ this._goTo({ index: this.index - 1, easing });
552
+ }
553
+ }
554
+ _advance(easing = 'ease') {
555
+ if (typeof easing !== 'string')
556
+ easing = 'ease';
557
+ if (this.index >= this._slideEls.length - 1) {
558
+ this._goTo({ index: this.index });
559
+ }
560
+ else {
561
+ this._goTo({ index: this.index + 1, easing });
562
+ }
563
+ }
564
+ _handleKeyDown(evt) {
565
+ if (evt.code === 'ArrowRight') {
566
+ evt.preventDefault();
567
+ this._advance();
568
+ }
569
+ if (evt.code === 'ArrowLeft') {
570
+ evt.preventDefault();
571
+ this._retreat();
572
+ }
573
+ }
574
+ _startMouseDrag(evt) {
575
+ evt.stopPropagation();
576
+ if (evt.button > 0)
577
+ return;
578
+ this._startDrag({ x: evt.clientX, y: evt.clientY });
579
+ }
580
+ _startTouchDrag(evt) {
581
+ evt.stopPropagation();
582
+ this._startDrag({
583
+ x: evt.touches.item(0).clientX,
584
+ y: evt.touches.item(0).clientY,
585
+ });
586
+ }
587
+ _startDrag(startPoint) {
588
+ if (this.slides.length < 2 || !this._initialized)
589
+ return;
590
+ this._isDragging = true;
591
+ clearTimeout(this._transitionSt);
592
+ cancelAnimationFrame(this._raf);
593
+ this._positions = getElementPositions(this.containerEl, this._slideEls);
594
+ this._dragStartTranslation = this._positions.leftDelta;
595
+ this._currentPercentTranslation =
596
+ (this._dragStartTranslation / this._positions.parent.width) * 100;
597
+ this._innerEl.style.transform = `translateX(${this._currentPercentTranslation}%)`;
598
+ this._innerEl.style.transition = this.baseTransition;
599
+ this._progressToNextSlide = 0;
600
+ this._breadcrumbsCurrent.style.transition = 'none';
601
+ this._dragStartPoint = startPoint;
602
+ this._prevDragPoint = startPoint;
603
+ this._currentDeltaX = 0;
604
+ this._recentDeltas = [];
605
+ }
606
+ _drag(currentPosition, isTouch = false) {
607
+ if (this.slides.length < 2 || !this._isDragging || !this._initialized) {
608
+ return;
609
+ }
610
+ const movementX = currentPosition.x - this._prevDragPoint.x;
611
+ this._positions = {
612
+ ...this._positions,
613
+ leftDelta: this._positions.leftDelta + movementX,
614
+ rightDelta: this._positions.rightDelta + movementX,
615
+ };
616
+ const dragLimitInPixels = this._positions.parent.width * this.dragLimit;
617
+ pushWithLimit(this._recentDeltas, movementX, 5);
618
+ this._prevDragPoint = currentPosition;
619
+ // Dragging past beginning or end
620
+ const isPastEdge = this._positions.leftDelta > 0 || this._positions.rightDelta < 0;
621
+ if (isPastEdge) {
622
+ const movementXWithResistance = applyResistance(movementX, this._currentDeltaX, this._positions.parent.width);
623
+ this._currentDeltaX = this._currentDeltaX + movementXWithResistance;
624
+ }
625
+ else {
626
+ this._currentDeltaX = this._currentDeltaX + movementX;
627
+ }
628
+ let deltaX = currentPosition.x - this._dragStartPoint.x;
629
+ let deltaY = currentPosition.y - this._dragStartPoint.y;
630
+ let slope = Math.abs(deltaY) / Math.abs(deltaX);
631
+ if (isTouch && slope > 0.85) {
632
+ this._endDrag();
633
+ return;
634
+ }
635
+ this._progressToNextSlide = Math.abs(deltaX / dragLimitInPixels);
636
+ if (movementX < 0) {
637
+ this._draggingDirection = 'left';
638
+ }
639
+ if (movementX > 0) {
640
+ this._draggingDirection = 'right';
641
+ }
642
+ const pixeltranslation = this._dragStartTranslation + this._currentDeltaX;
643
+ this._currentPercentTranslation =
644
+ (pixeltranslation / this._positions.parent.width) * 100;
645
+ if (this._currentDeltaX < 0) {
646
+ this._breadcrumbsCurrent.style.right = '';
647
+ this._breadcrumbsCurrent.style.left = `${this._breadcrumbs[this.index].offsetLeft}px`;
648
+ }
649
+ if (this._currentDeltaX > 0) {
650
+ this._breadcrumbsCurrent.style.left = '';
651
+ this._breadcrumbsCurrent.style.right = `${this._breadcrumbsInnerEl.offsetWidth -
652
+ (this._breadcrumbs[this.index].offsetLeft + this.breadcrumbDiameter)}px`;
653
+ }
654
+ if (isPastEdge) {
655
+ this._breadcrumbsCurrent.style.width = `${this.breadcrumbDiameter +
656
+ Math.abs((this.breadcrumbDiameter *
657
+ 4 *
658
+ (this._currentPercentTranslation + 100 * this.index)) /
659
+ 100)}px`;
660
+ }
661
+ else {
662
+ this._breadcrumbsCurrent.style.width = `${Math.min(this.breadcrumbDiameter * 2.75, this.breadcrumbDiameter +
663
+ Math.abs((this.breadcrumbDiameter *
664
+ 4 *
665
+ (this._currentPercentTranslation + 100 * this.index)) /
666
+ 100))}px`;
667
+ }
668
+ this._innerEl.style.transform = `translateX(${this._currentPercentTranslation}%)`;
669
+ this._innerEl.style.transition = this.baseTransition;
670
+ }
671
+ _mouseDrag(evt) {
672
+ this._throttledDrag({ x: evt.clientX, y: evt.clientY }, false);
673
+ }
674
+ _touchDrag(evt) {
675
+ this._throttledDrag({ x: evt.touches.item(0).clientX, y: evt.touches.item(0).clientY }, true);
676
+ }
677
+ _endDrag() {
678
+ this._isDragging = false;
679
+ this._breadcrumbsCurrent.style.transition = '';
680
+ this._innerEl.style.transition = this.baseTransition;
681
+ this._dragStartPoint = { x: 0, y: 0 };
682
+ this._prevDragPoint = { x: 0, y: 0 };
683
+ this._currentDeltaX = 0;
684
+ const momentum = getAbsArrayAverage(this._recentDeltas);
685
+ let action = null;
686
+ if (momentum > this.momentumToTransition ||
687
+ this._progressToNextSlide >= 1) {
688
+ if (this._currentPercentTranslation + 100 * this.index < 0 &&
689
+ this._draggingDirection === 'left') {
690
+ action = 'advance';
691
+ }
692
+ if (this._currentPercentTranslation + 100 * this.index > 0 &&
693
+ this._draggingDirection === 'right') {
694
+ action = 'retreat';
695
+ }
696
+ }
697
+ switch (action) {
698
+ case 'advance':
699
+ this._raf = requestAnimationFrame(() => this._advance('cubic-bezier(0.25, .25, 0.5, 1)'));
700
+ break;
701
+ case 'retreat':
702
+ this._raf = requestAnimationFrame(() => this._retreat('cubic-bezier(0.25, .25, 0.5, 1)'));
703
+ break;
704
+ default:
705
+ this._raf = requestAnimationFrame(() => this._goTo({ index: this.index }));
706
+ }
707
+ this._draggingDirection = null;
708
+ this._recentDeltas = [];
709
+ }
710
+ }
711
+ function getElementPositions(containerEl, slideEls) {
712
+ if (!containerEl || !slideEls?.length)
713
+ return;
714
+ const parentBox = containerEl.getBoundingClientRect();
715
+ const firstSlideBox = slideEls[0].getBoundingClientRect();
716
+ const lastSlideBox = slideEls[slideEls.length - 1].getBoundingClientRect();
717
+ return {
718
+ parent: parentBox,
719
+ firstSlide: firstSlideBox,
720
+ lastSlide: lastSlideBox,
721
+ leftDelta: firstSlideBox.left - parentBox.left,
722
+ rightDelta: lastSlideBox.right - parentBox.right,
723
+ };
724
+ }
725
+ function applyResistance(delta, total, limit, slope = 0.125) {
726
+ const resistance = 1 - (Math.abs(total) / Math.abs(limit)) ** slope;
727
+ return delta * resistance;
728
+ }
729
+ function getAbsArrayAverage(arr) {
730
+ return Math.abs(arr.reduce((acc, curr) => acc + curr, 0) / arr.length);
731
+ }
732
+
733
+ class PopoverScroller {
734
+ slides;
735
+ containerEl;
736
+ onSlideChange;
737
+ onRequestClose;
738
+ _initialized;
739
+ _currentSlide;
740
+ _scrollContainerEl;
741
+ _innerEl;
742
+ _throttledScroll;
743
+ _goToRaf;
744
+ constructor({ slides, containerEl, onSlideChange, onRequestClose = null }) {
745
+ this.slides = slides;
746
+ this.containerEl = containerEl;
747
+ this.onSlideChange = onSlideChange;
748
+ this.onRequestClose = onRequestClose;
749
+ this.init = this.init.bind(this);
750
+ this.destroy = this.destroy.bind(this);
751
+ this._initialized = false;
752
+ this._currentSlide = null;
753
+ this._scrollContainerEl = null;
754
+ this._innerEl = null;
755
+ this._onBackGroundClick = this._onBackGroundClick.bind(this);
756
+ this._throttledScroll = throttle(this._handleScroll, 200, this);
757
+ }
758
+ init(index = 0) {
759
+ if (this._initialized)
760
+ return;
761
+ this._initialized = true;
762
+ this._innerEl = createElement({
763
+ classes: prefixedClass('inner'),
764
+ contents: this.slides,
765
+ });
766
+ this._scrollContainerEl = createElement({
767
+ classes: prefixedClass('container'),
768
+ contents: this._innerEl,
769
+ });
770
+ this.containerEl.appendChild(this._scrollContainerEl);
771
+ this._scrollContainerEl.addEventListener('click', this._onBackGroundClick);
772
+ this._scrollContainerEl.addEventListener('scroll', this._throttledScroll, {
773
+ passive: true,
774
+ });
775
+ this._goTo({ index, animate: false });
776
+ }
777
+ destroy() {
778
+ if (!this._initialized)
779
+ return;
780
+ cancelAnimationFrame(this._goToRaf);
781
+ this._initialized = false;
782
+ this._scrollContainerEl.removeEventListener('click', this._onBackGroundClick);
783
+ this._scrollContainerEl.removeEventListener('scroll', this._throttledScroll);
784
+ this._scrollContainerEl.remove();
785
+ this._scrollContainerEl = null;
786
+ this._innerEl = null;
787
+ }
788
+ _handleScroll() {
789
+ getMostVisible(this.slides).then((mostVisible) => {
790
+ if (this._currentSlide !== mostVisible) {
791
+ this._currentSlide = mostVisible;
792
+ if (this.onSlideChange)
793
+ this.onSlideChange(this._currentSlide);
794
+ }
795
+ });
796
+ }
797
+ _onBackGroundClick(evt) {
798
+ if (evt.target === this._scrollContainerEl && this.onRequestClose) {
799
+ this.onRequestClose();
800
+ }
801
+ }
802
+ _goTo({ index, animate = true }) {
803
+ cancelAnimationFrame(this._goToRaf);
804
+ if (!this.slides?.[index])
805
+ return;
806
+ this._currentSlide = index;
807
+ if (this.onSlideChange)
808
+ this.onSlideChange(this._currentSlide);
809
+ this._goToRaf = requestAnimationFrame(() => {
810
+ const slideTop = this.slides[index].offsetTop;
811
+ this._scrollContainerEl?.scrollTo({
812
+ top: slideTop - 10,
813
+ behavior: animate ? 'smooth' : 'instant',
814
+ });
815
+ });
816
+ }
817
+ }
818
+ function prefixedClass(className) {
819
+ return 'behold-ps-' + className;
820
+ }
821
+
822
+ var mutedIcon = "<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\t viewBox=\"0 0 20 20\" enable-background=\"new 0 0 20 20\" xml:space=\"preserve\">\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" fill=\"#FFFFFF\" d=\"M4.4,7.3C4.2,7.3,4,7.5,4,7.7v4.6c0,0.2,0.2,0.4,0.4,0.4h2.2\n\tl3.2,3.2c0.2,0.2,0.6,0.1,0.6-0.2v-2.4c0-0.1-0.1-0.2-0.1-0.3L4.8,7.4C4.7,7.4,4.6,7.3,4.5,7.3C4.5,7.3,4.4,7.3,4.4,7.3z M16.1,15.2\n\tl-1.4-1.4c0.5-0.7,1.3-1.9,1.3-3.8c0-2.8-1.8-4.3-1.8-4.3c-0.1-0.2-0.4-0.2-0.6,0L13.3,6c-0.1,0.2-0.1,0.4,0,0.6\n\tc0,0,1.4,1.2,1.4,3.4c0,1.4-0.5,2.3-0.9,2.9L12.9,12c0.3-0.4,0.6-1.1,0.6-2c0-1.7-1-2.6-1-2.6c-0.1-0.2-0.4-0.2-0.6,0l-0.4,0.3\n\tc-0.1,0.2-0.1,0.4,0,0.6c0,0,0.7,0.5,0.7,1.7c0,0.4-0.1,0.8-0.2,1.1l-1.6-1.6V4.3c0-0.3-0.4-0.5-0.6-0.2L7.4,6.5L4.8,3.9\n\tc-0.1-0.1-0.4-0.1-0.5,0L4,4.3C3.8,4.4,3.8,4.7,4,4.8l1,1.1l6.7,6.7l3.5,3.5c0.1,0.1,0.4,0.1,0.5,0l0.4-0.4\n\tC16.2,15.6,16.2,15.3,16.1,15.2z\"/>\n</svg>";
823
+
824
+ var unmutedIcon = "<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\t viewBox=\"0 0 20 20\" enable-background=\"new 0 0 20 20\" xml:space=\"preserve\">\n<path fill=\"#FFFFFF\" d=\"M12.5,7.3c-0.3-0.4-0.8-0.4-1.1-0.2C11,7.4,11,7.9,11.2,8.3l0,0c0.4,0.5,0.6,1.1,0.6,1.7\n\tc0,0.6-0.2,1.2-0.6,1.7c-0.3,0.4-0.2,0.9,0.1,1.1c0.4,0.3,0.9,0.2,1.1-0.1c0,0,0,0,0,0c0.6-0.8,0.9-1.7,0.9-2.7\n\tC13.4,9,13.1,8.1,12.5,7.3z M14.6,6c-0.3-0.4-0.8-0.4-1.1-0.1C13.1,6.2,13,6.7,13.3,7c0,0,0,0,0,0c0.7,0.8,1.1,1.9,1.1,3\n\tc0,1.1-0.4,2.1-1.1,3c-0.3,0.4-0.2,0.9,0.1,1.1c0.3,0.3,0.8,0.2,1.1-0.1c0.9-1.1,1.4-2.5,1.4-4C16,8.5,15.5,7.1,14.6,6z M9.7,4\n\tC9.5,4,9.2,4,9.1,4.1L6.3,6.7H4.5C4.2,6.7,4,7,4,7.3v5.5c0,0.3,0.2,0.5,0.5,0.5h1.8l2.7,2.6l0,0c0.2,0.2,0.6,0.2,0.8,0\n\tc0.1-0.1,0.2-0.3,0.2-0.4l0-10.8C10,4.3,9.9,4.1,9.7,4z\"/>\n</svg>";
825
+
826
+ /**
827
+ * @description
828
+ * Required props: post
829
+ */
830
+ class PopoverSlideVideo extends BaseElement {
831
+ label = 'PopoverSlideVideo';
832
+ // Internal
833
+ _videoEl;
834
+ _imageEl;
835
+ _soundControlEl;
836
+ // Provided
837
+ post;
838
+ constructor() {
839
+ super();
840
+ // Register child components
841
+ Video.register();
842
+ Image.register();
843
+ this._onLoad = this._onLoad.bind(this);
844
+ this._onPlay = this._onPlay.bind(this);
845
+ this._onPause = this._onPause.bind(this);
846
+ this._togglePlayback = this._togglePlayback.bind(this);
847
+ this._toggleSound = this._toggleSound.bind(this);
848
+ this.play = this.play.bind(this);
849
+ this.pause = this.pause.bind(this);
850
+ this.showSoundControl = this.showSoundControl.bind(this);
851
+ this.hideSoundControl = this.hideSoundControl.bind(this);
852
+ this.preload = this.preload.bind(this);
853
+ this.onLocalStateChange(this._handleLocalStateChange, { isPlaying: false });
854
+ this.onGlobalStateChange(this._handleGlobalStateChange);
855
+ // Connect
856
+ this.onConnect(() => {
857
+ if (this.post.mediaUrl) {
858
+ this._videoEl = createElement({
859
+ type: 'behold-video',
860
+ classes: 'video',
861
+ props: {
862
+ mediaUrl: this.post.mediaUrl,
863
+ sizes: this.post.sizes,
864
+ renderPlaceholder: true,
865
+ },
866
+ listeners: {
867
+ click: this._togglePlayback,
868
+ load: this._onLoad,
869
+ play: this._onPlay,
870
+ pause: this._onPause,
871
+ },
872
+ });
873
+ this._soundControlEl = createElement({
874
+ type: 'button',
875
+ classes: 'video-mute',
876
+ contents: this.globalState.isMuted ? mutedIcon : unmutedIcon,
877
+ listeners: {
878
+ click: this._toggleSound,
879
+ },
880
+ attributes: {
881
+ 'aria-label': this.globalState.isMuted ? 'unmute' : 'mute',
882
+ },
883
+ });
884
+ if (this.globalState.isMuted) {
885
+ this._videoEl.mute();
886
+ }
887
+ else {
888
+ this._videoEl.unmute();
889
+ }
890
+ this.classList.add('video-container', 'video-container--paused');
891
+ this.beholdReplaceChildren(this._videoEl, this._soundControlEl);
892
+ }
893
+ else {
894
+ this._imageEl = createElement({
895
+ type: 'behold-image',
896
+ props: {
897
+ sizes: this.post.sizes,
898
+ mediaUrl: this.post.thumbnailUrl,
899
+ aspectRatio: this.post.sizes.full.width / this.post.sizes.full.height,
900
+ },
901
+ listeners: {
902
+ load: this._onLoad,
903
+ },
904
+ });
905
+ this.beholdReplaceChildren(this._imageEl);
906
+ }
907
+ });
908
+ }
909
+ _handleLocalStateChange({ changedProps, newState }) {
910
+ if (changedProps.includes('isPlaying')) {
911
+ if (newState.isPlaying && !this._videoEl.isPlaying) {
912
+ this._videoEl.play();
913
+ }
914
+ if (!newState.isPlaying && this._videoEl.isPlaying) {
915
+ this._videoEl.pause();
916
+ }
917
+ }
918
+ }
919
+ _handleGlobalStateChange({ changedProps, newState }) {
920
+ if (changedProps.includes('isMuted')) {
921
+ if (this._videoEl && this._soundControlEl) {
922
+ if (newState.isMuted) {
923
+ this._videoEl.mute();
924
+ this._soundControlEl.innerHTML = mutedIcon;
925
+ }
926
+ else {
927
+ this._videoEl.unmute();
928
+ this._soundControlEl.innerHTML = unmutedIcon;
929
+ }
930
+ }
931
+ }
932
+ }
933
+ _onLoad() {
934
+ this.dispatchEvent(new Event('load'));
935
+ this.classList.add('is-loaded');
936
+ }
937
+ _onPlay() {
938
+ this.classList.remove('video-container--paused');
939
+ }
940
+ _onPause() {
941
+ this.classList.add('video-container--paused');
942
+ }
943
+ _togglePlayback() {
944
+ if (!this._videoEl)
945
+ return;
946
+ if (this._videoEl.isPlaying) {
947
+ this.pause();
948
+ }
949
+ else {
950
+ this.play();
951
+ }
952
+ }
953
+ _toggleSound() {
954
+ if (!this._videoEl)
955
+ return;
956
+ if (this._videoEl.muted) {
957
+ this.updateGlobalState({ isMuted: false });
958
+ }
959
+ else {
960
+ this.updateGlobalState({ isMuted: true });
961
+ }
962
+ }
963
+ play() {
964
+ this.updateLocalState({ isPlaying: true });
965
+ this.showSoundControl();
966
+ }
967
+ pause() {
968
+ this.updateLocalState({ isPlaying: false });
969
+ }
970
+ showSoundControl() {
971
+ if (!this.isConnected || !this._soundControlEl)
972
+ return;
973
+ this._soundControlEl.classList.add('video-mute--visible');
974
+ }
975
+ hideSoundControl() {
976
+ if (!this.isConnected || !this._soundControlEl)
977
+ return;
978
+ this._soundControlEl.classList.remove('video-mute--visible');
979
+ }
980
+ /**
981
+ * Preload
982
+ */
983
+ preload() {
984
+ this._videoEl?.preload();
985
+ }
986
+ /*
987
+ * Register
988
+ */
989
+ static register(name = 'behold-popover-slide-video') {
990
+ if (!customElements.get(name)) {
991
+ customElements.define(name, PopoverSlideVideo);
992
+ }
993
+ return name;
994
+ }
995
+ }
996
+
997
+ /**
998
+ * @description
999
+ * Required props: 'post'
1000
+ */
1001
+ class PopoverSlideAlbum extends BaseElement {
1002
+ label = 'PopoverSlideAlbum';
1003
+ // Internal
1004
+ _containerEl;
1005
+ _spaceholderEl;
1006
+ _childEls;
1007
+ _previousEl;
1008
+ _nextEl;
1009
+ _breadcrumbsEl;
1010
+ _childCarousel;
1011
+ currentSlideIndex = 0;
1012
+ // Provided
1013
+ post;
1014
+ constructor() {
1015
+ super();
1016
+ // Listen to Prop changes
1017
+ this.onPropChange(() => { }, ['post']);
1018
+ // Register child components
1019
+ Image.register();
1020
+ PopoverSlideVideo.register();
1021
+ // Bind event handlers
1022
+ this._handleSlideChange = this._handleSlideChange.bind(this);
1023
+ this._handleIntersection = this._handleIntersection.bind(this);
1024
+ this.preload = this.preload.bind(this);
1025
+ // Connect
1026
+ this.onConnect(() => {
1027
+ this._childEls = this._buildSlideEls();
1028
+ const spaceholderSource = this.post.sizes?.full?.height
1029
+ ? `data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' x='0px' y='0px' width='${this.post.sizes?.full?.width}' height='${this.post.sizes?.full?.height}'%3E%3C/svg%3E%0A`
1030
+ : this.post.children?.[0]?.sizes?.full.mediaUrl ||
1031
+ this.post.children?.[0]?.thumbnailUrl ||
1032
+ null;
1033
+ if (this.post.mediaUrlIsVideo && !spaceholderSource) {
1034
+ this._spaceholderEl = createElement({
1035
+ type: 'video',
1036
+ classes: 'slide__carousel-spaceholder',
1037
+ attributes: {
1038
+ src: this.post.mediaUrl,
1039
+ height: this.post.sizes?.full?.height,
1040
+ width: this.post.sizes?.full?.width,
1041
+ },
1042
+ props: {
1043
+ muted: true,
1044
+ },
1045
+ });
1046
+ }
1047
+ else {
1048
+ this._spaceholderEl = createElement({
1049
+ type: 'img',
1050
+ classes: 'slide__carousel-spaceholder',
1051
+ attributes: {
1052
+ src: spaceholderSource,
1053
+ height: this.post.sizes?.full?.height,
1054
+ width: this.post.sizes?.full?.width,
1055
+ },
1056
+ });
1057
+ }
1058
+ this._previousEl = createElement({
1059
+ type: 'button',
1060
+ classes: 'slide__carousel-previous',
1061
+ attributes: { 'aria-label': 'Previous album slide' },
1062
+ contents: caretLeftIcon,
1063
+ });
1064
+ this._nextEl = createElement({
1065
+ type: 'button',
1066
+ classes: 'slide__carousel-next',
1067
+ attributes: { 'aria-label': 'Next album slide' },
1068
+ contents: caretRightIcon,
1069
+ });
1070
+ this._breadcrumbsEl = createElement({
1071
+ classes: 'slide__carousel-breadcrumbs',
1072
+ });
1073
+ this._containerEl = createElement({
1074
+ classes: 'slide__carousel',
1075
+ contents: [
1076
+ ...this._childEls,
1077
+ this._previousEl,
1078
+ this._nextEl,
1079
+ this._breadcrumbsEl,
1080
+ ],
1081
+ });
1082
+ this.replaceChildren(this._spaceholderEl, this._containerEl);
1083
+ this._childCarousel = new HurdyGurdy({
1084
+ slides: this._childEls,
1085
+ containerEl: this._containerEl,
1086
+ keyboardNav: false,
1087
+ breadcrumbsContainerEl: this._breadcrumbsEl,
1088
+ dynamicBreadCrumbsCutoff: 7,
1089
+ previousEl: this._previousEl,
1090
+ nextEl: this._nextEl,
1091
+ onSlideChange: this._handleSlideChange,
1092
+ virtualize: true,
1093
+ proximalSlidesToRender: 2,
1094
+ dragLimit: 0.6,
1095
+ });
1096
+ this.onIntersection(this, this._handleIntersection);
1097
+ });
1098
+ this.onDisconnect(() => {
1099
+ this._childCarousel.destroy();
1100
+ this._childCarousel = null;
1101
+ });
1102
+ }
1103
+ /**
1104
+ * Update tabbable els
1105
+ */
1106
+ _updateTabbable() {
1107
+ updateTabbableEls({
1108
+ include: [this._childEls[this.currentSlideIndex]],
1109
+ exclude: this._childEls.filter((c, i) => i !== this.currentSlideIndex),
1110
+ merge: true,
1111
+ });
1112
+ }
1113
+ /**
1114
+ * On intersection
1115
+ */
1116
+ _handleIntersection(entry) {
1117
+ if (entry.isIntersecting) {
1118
+ this._childCarousel.init(0);
1119
+ }
1120
+ }
1121
+ /**
1122
+ * On slide change
1123
+ */
1124
+ _handleSlideChange(newIndex, isInitial = false) {
1125
+ if (newIndex !== this.currentSlideIndex &&
1126
+ this.globalState.keyboardNavEnabled) {
1127
+ announceToScreenReader(`Slide ${newIndex + 1} of ${this._childEls.length} in Album`);
1128
+ }
1129
+ this.currentSlideIndex = newIndex;
1130
+ this._childEls.forEach((child, i) => {
1131
+ if (isVideoSlide(child)) {
1132
+ if (i === newIndex) {
1133
+ child.play();
1134
+ }
1135
+ else {
1136
+ child.hideSoundControl();
1137
+ child.pause();
1138
+ }
1139
+ }
1140
+ });
1141
+ const prev = this._childEls[newIndex - 1];
1142
+ const next = this._childEls[newIndex + 1];
1143
+ if (prev)
1144
+ prev.preload();
1145
+ if (next)
1146
+ next.preload();
1147
+ this._updateTabbable();
1148
+ if (!isInitial) {
1149
+ this._setBackgroundColor(newIndex);
1150
+ }
1151
+ }
1152
+ /**
1153
+ * Set background color
1154
+ */
1155
+ _setBackgroundColor(index) {
1156
+ const hslArray = RGBStringToHSLArray(this.post.children[index].colorPalette?.dominant || '100,100,100').map((val) => Math.round(val));
1157
+ this.style.backgroundColor = `hsl(${hslArray[0]} ${Math.min(hslArray[1], 35)}% ${Math.min(hslArray[2], 13)}%)`;
1158
+ const ldrColorHSLArray = RGBStringToHSLArray(this.post.children[index].colorPalette?.dominant || '255,255,255').map((val) => Math.round(val));
1159
+ const ldrColorString = `hsl(${ldrColorHSLArray[0]} ${ldrColorHSLArray[1]}% ${Math.max(ldrColorHSLArray[2], 50)}%)`;
1160
+ this.style.setProperty('--uib-color', ldrColorString);
1161
+ this.updateGlobalState({
1162
+ popoverOverlayHslArray: hslArray,
1163
+ });
1164
+ }
1165
+ /**
1166
+ * Build slide els
1167
+ */
1168
+ _buildSlideEls() {
1169
+ return this.post.children.map((child) => {
1170
+ let mediaEl = null;
1171
+ switch (child.mediaType) {
1172
+ case 'IMAGE':
1173
+ mediaEl = createElement({
1174
+ type: 'behold-image',
1175
+ classes: 'slide__carousel-slide',
1176
+ props: {
1177
+ sizes: child.sizes,
1178
+ mediaUrl: child.mediaUrl,
1179
+ showLoader: true,
1180
+ aspectRatio: child.sizes.full.width / child.sizes.full.height,
1181
+ },
1182
+ });
1183
+ break;
1184
+ case 'VIDEO':
1185
+ mediaEl = createElement({
1186
+ type: 'behold-popover-slide-video',
1187
+ classes: 'slide__carousel-slide',
1188
+ props: {
1189
+ post: child,
1190
+ },
1191
+ });
1192
+ break;
1193
+ }
1194
+ return mediaEl;
1195
+ });
1196
+ }
1197
+ /**
1198
+ * Play
1199
+ */
1200
+ play() {
1201
+ const currentChild = this._childEls[this.currentSlideIndex];
1202
+ if (isVideoSlide(currentChild)) {
1203
+ currentChild.play();
1204
+ }
1205
+ }
1206
+ /**
1207
+ * Pause
1208
+ */
1209
+ pause() {
1210
+ this._childEls.filter(isVideoSlide).forEach((child) => {
1211
+ child.hideSoundControl();
1212
+ child.pause();
1213
+ });
1214
+ }
1215
+ /**
1216
+ * Preload media
1217
+ */
1218
+ preload() {
1219
+ this._childEls?.[0]?.preload();
1220
+ }
1221
+ /*
1222
+ * Register
1223
+ */
1224
+ static register(name = 'behold-popover-slide-album') {
1225
+ if (!customElements.get(name)) {
1226
+ customElements.define(name, PopoverSlideAlbum);
1227
+ }
1228
+ return name;
1229
+ }
1230
+ }
1231
+ const isVideoSlide = (slide) => slide.tagName === 'BEHOLD-POPOVER-SLIDE-VIDEO';
1232
+
1233
+ var hashIcon = "<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\t viewBox=\"0 0 16 16\" enable-background=\"new 0 0 16 16\" xml:space=\"preserve\">\n<g>\n\t<path fill=\"#262626\" d=\"M13.8,5.9H3.2c-0.4,0-0.7-0.3-0.7-0.7s0.3-0.7,0.7-0.7h10.6c0.4,0,0.7,0.3,0.7,0.7S14.1,5.9,13.8,5.9z\"/>\n</g>\n<g>\n\t<path fill=\"#262626\" d=\"M12.8,10.8H2.2c-0.4,0-0.7-0.3-0.7-0.7s0.3-0.7,0.7-0.7h10.6c0.4,0,0.7,0.3,0.7,0.7S13.2,10.8,12.8,10.8z\"\n\t\t/>\n</g>\n<g>\n\t<path fill=\"#262626\" d=\"M8.9,15.3c0,0-0.1,0-0.1,0c-0.4-0.1-0.6-0.4-0.5-0.8l2.4-13.3c0.1-0.4,0.4-0.6,0.8-0.5\n\t\tc0.4,0.1,0.6,0.4,0.5,0.8L9.6,14.8C9.5,15.1,9.2,15.3,8.9,15.3z\"/>\n</g>\n<g>\n\t<path fill=\"#262626\" d=\"M4.7,15.3c0,0-0.1,0-0.1,0c-0.4-0.1-0.6-0.4-0.5-0.8L6.4,1.2c0.1-0.4,0.4-0.6,0.8-0.5\n\t\tc0.4,0.1,0.6,0.4,0.5,0.8L5.3,14.8C5.3,15.1,5,15.3,4.7,15.3z\"/>\n</g>\n</svg>";
1234
+
1235
+ var externalLinkIcon = "<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\t viewBox=\"0 0 20 20\" enable-background=\"new 0 0 20 20\" xml:space=\"preserve\">\n<g>\n\t<path d=\"M16,19.8H4c-2.1,0-3.8-1.7-3.8-3.8V4c0-2.1,1.7-3.8,3.8-3.8h12c2.1,0,3.8,1.7,3.8,3.8v12C19.8,18.1,18.1,19.8,16,19.8z\n\t\t M4,1.8c-1.2,0-2.2,1-2.2,2.2v12c0,1.2,1,2.2,2.2,2.2h12c1.2,0,2.2-1,2.2-2.2V4c0-1.2-1-2.2-2.2-2.2H4z\"/>\n</g>\n<path d=\"M14.4,5.6v7.5h-1.5V8.2l-6,6l-1.1-1.1l6-6H6.9V5.6H14.4z\"/>\n</svg>";
1236
+
1237
+ /**
1238
+ * @description
1239
+ * Required props: 'post', 'feedMetadata'
1240
+ */
1241
+ class PopoverGallerySlide extends BaseElement {
1242
+ label = 'PopoverGallerySlide';
1243
+ // Internal
1244
+ _innerEl;
1245
+ _avatarImageEl;
1246
+ _headerText;
1247
+ _avatarEl;
1248
+ _headerEl;
1249
+ _captionEl;
1250
+ _footerLinkEl;
1251
+ _footerEl;
1252
+ _textEl;
1253
+ _mediaEl;
1254
+ _moreEl;
1255
+ // Provided
1256
+ post;
1257
+ feedMetadata;
1258
+ constructor() {
1259
+ super();
1260
+ // Define which props will trigger _handlePropChange
1261
+ this.onPropChange(this._handlePropChange, ['post', 'feedMetadata']);
1262
+ // Register child components
1263
+ Image.register();
1264
+ PopoverSlideVideo.register();
1265
+ PopoverSlideAlbum.register();
1266
+ // Bind event listeners
1267
+ this.expandCaption = this.expandCaption.bind(this);
1268
+ this.preload = this.preload.bind(this);
1269
+ // Connect
1270
+ this.onConnect(() => {
1271
+ this.render();
1272
+ });
1273
+ }
1274
+ /**
1275
+ * Render contents
1276
+ */
1277
+ render() {
1278
+ this.classList.remove('is-loaded');
1279
+ if (!this.post)
1280
+ return;
1281
+ const hslArray = RGBStringToHSLArray(this.post.colorPalette?.dominant || '100,100,100').map((val) => Math.round(val));
1282
+ const bgColorString = `hsl(${hslArray[0]} ${Math.min(hslArray[1], 35)}% ${Math.min(hslArray[2], 13)}%)`;
1283
+ const ldrColorHSLArray = RGBStringToHSLArray(this.post.colorPalette?.dominant || '255,255,255').map((val) => Math.round(val));
1284
+ const ldrColorString = `hsl(${ldrColorHSLArray[0]} ${ldrColorHSLArray[1]}% ${Math.max(ldrColorHSLArray[2], 50)}%)`;
1285
+ this.style.setProperty('--uib-color', ldrColorString);
1286
+ switch (this.post?.mediaType) {
1287
+ case 'VIDEO':
1288
+ this._mediaEl = createElement({
1289
+ type: 'behold-popover-slide-video',
1290
+ classes: 'slide__media',
1291
+ style: {
1292
+ backgroundColor: bgColorString,
1293
+ },
1294
+ props: {
1295
+ post: this.post,
1296
+ },
1297
+ });
1298
+ break;
1299
+ case 'CAROUSEL_ALBUM':
1300
+ this._mediaEl = createElement({
1301
+ type: 'behold-popover-slide-album',
1302
+ classes: 'slide__media',
1303
+ style: {
1304
+ backgroundColor: bgColorString,
1305
+ },
1306
+ props: {
1307
+ post: this.post,
1308
+ aspectRatio: this.post.sizes.full.width / this.post.sizes.full.height,
1309
+ },
1310
+ });
1311
+ break;
1312
+ case 'IMAGE':
1313
+ default:
1314
+ this._mediaEl = createElement({
1315
+ type: 'behold-image',
1316
+ classes: 'slide__media',
1317
+ style: {
1318
+ backgroundColor: bgColorString,
1319
+ },
1320
+ props: {
1321
+ sizes: this.post.sizes,
1322
+ mediaUrl: this.post.mediaUrl,
1323
+ showLoader: true,
1324
+ aspectRatio: this.post.sizes.full.width / this.post.sizes.full.height,
1325
+ },
1326
+ });
1327
+ }
1328
+ this._avatarImageEl = !this.feedMetadata?.profilePictureUrl
1329
+ ? null
1330
+ : createElement({
1331
+ type: 'img',
1332
+ attributes: { src: this.feedMetadata.profilePictureUrl },
1333
+ });
1334
+ this._headerText = '@' + this.feedMetadata.username;
1335
+ if (this.feedMetadata.hashtags) {
1336
+ this._avatarImageEl = hashIcon;
1337
+ this._headerText = this.feedMetadata.hashtags.join(', ');
1338
+ }
1339
+ this._avatarEl = this._avatarImageEl
1340
+ ? createElement({
1341
+ classes: 'slide__avatar',
1342
+ contents: this._avatarImageEl,
1343
+ attributes: {
1344
+ 'aria-label': this.feedMetadata.hashtags ? 'hashtags' : 'username',
1345
+ },
1346
+ })
1347
+ : null;
1348
+ this._headerEl = createElement({
1349
+ classes: 'slide__header',
1350
+ contents: [this._avatarEl, this._headerText],
1351
+ });
1352
+ this._captionEl = this.post?.caption?.trim()?.length
1353
+ ? createElement({
1354
+ classes: 'slide__caption',
1355
+ contents: this.post.caption,
1356
+ })
1357
+ : null;
1358
+ this._footerLinkEl = this.post.permalink
1359
+ ? createElement({
1360
+ type: 'a',
1361
+ attributes: {
1362
+ href: this.post.permalink,
1363
+ target: '_blank',
1364
+ },
1365
+ classes: 'slide__footer-link',
1366
+ contents: ['Go to post', externalLinkIcon],
1367
+ })
1368
+ : '';
1369
+ this._footerEl = createElement({
1370
+ classes: 'slide__footer',
1371
+ contents: [this._footerLinkEl],
1372
+ });
1373
+ this._textEl = createElement({
1374
+ classes: 'slide__text',
1375
+ contents: [this._headerEl, this._captionEl, this._footerEl],
1376
+ });
1377
+ this._innerEl = createElement({
1378
+ classes: 'slide__inner',
1379
+ contents: [this._mediaEl, this._textEl],
1380
+ });
1381
+ this._moreEl = createElement({
1382
+ type: 'button',
1383
+ classes: 'slide__more',
1384
+ contents: '… more',
1385
+ listeners: { click: this.expandCaption },
1386
+ });
1387
+ this.beholdReplaceChildren(this._innerEl);
1388
+ forceLayout();
1389
+ this.to(() => {
1390
+ this.classList.add('is-loaded');
1391
+ }, 10, 'onConnect');
1392
+ }
1393
+ /*
1394
+ * Handle prop change
1395
+ */
1396
+ _handlePropChange({ changedProp, newValue }) {
1397
+ switch (changedProp) {
1398
+ case 'feedMetadata':
1399
+ if (!this.isConnected)
1400
+ return;
1401
+ this._headerText = '@' + newValue.username;
1402
+ if (newValue.hashtags?.length) {
1403
+ this._avatarImageEl = hashIcon;
1404
+ this._headerText = newValue.hashtags.join(', ');
1405
+ }
1406
+ else {
1407
+ this._avatarImageEl = !newValue?.profilePictureUrl
1408
+ ? null
1409
+ : createElement({
1410
+ type: 'img',
1411
+ attributes: { src: newValue.profilePictureUrl },
1412
+ });
1413
+ }
1414
+ this._avatarEl = this._avatarImageEl
1415
+ ? createElement({
1416
+ classes: 'slide__avatar',
1417
+ contents: this._avatarImageEl,
1418
+ attributes: {
1419
+ 'aria-label': this.feedMetadata.hashtags
1420
+ ? 'hashtags'
1421
+ : 'username',
1422
+ },
1423
+ })
1424
+ : null;
1425
+ this._headerEl = createElement({
1426
+ classes: 'slide__header',
1427
+ contents: [this._avatarEl, this._headerText],
1428
+ });
1429
+ break;
1430
+ case 'post':
1431
+ if (!this._mediaEl) {
1432
+ this.render();
1433
+ }
1434
+ if (newValue?.mediaType === 'IMAGE') {
1435
+ Object.assign(this._mediaEl, {
1436
+ sizes: this.post.sizes,
1437
+ mediaUrl: this.post.mediaUrl,
1438
+ showLoader: true,
1439
+ });
1440
+ }
1441
+ else {
1442
+ if (!isImage(this._mediaEl)) {
1443
+ this._mediaEl.post = newValue;
1444
+ }
1445
+ }
1446
+ break;
1447
+ }
1448
+ }
1449
+ /**
1450
+ * Activate
1451
+ */
1452
+ activate() {
1453
+ if ('VIDEO,CAROUSEL_ALBUM'.includes(this.post.mediaType) && this._mediaEl) {
1454
+ const videoEl = this._mediaEl;
1455
+ videoEl.play();
1456
+ }
1457
+ }
1458
+ /**
1459
+ * Deactivate
1460
+ */
1461
+ deactivate() {
1462
+ if (this.post.mediaType === 'VIDEO' && this._mediaEl) {
1463
+ const el = this._mediaEl;
1464
+ el.pause();
1465
+ }
1466
+ if (this.post.mediaType === 'CAROUSEL_ALBUM' && this._mediaEl) {
1467
+ const el = this._mediaEl;
1468
+ el.pause();
1469
+ }
1470
+ }
1471
+ /**
1472
+ * Preload media
1473
+ */
1474
+ preload() {
1475
+ this._mediaEl?.preload();
1476
+ }
1477
+ /**
1478
+ * Get background color
1479
+ */
1480
+ getBackgroundColor() {
1481
+ let colorSource = this.post;
1482
+ if (this.post?.mediaType === 'CAROUSEL_ALBUM') {
1483
+ const albumEl = this._mediaEl;
1484
+ colorSource = this.post?.children?.[albumEl?.currentSlideIndex ?? 0];
1485
+ }
1486
+ const hslArray = RGBStringToHSLArray(colorSource?.colorPalette?.dominant || '100,100,100').map((val) => Math.round(val));
1487
+ return hslArray;
1488
+ }
1489
+ /**
1490
+ * Expand post caption
1491
+ */
1492
+ expandCaption() {
1493
+ if (!this._captionEl)
1494
+ return;
1495
+ this._captionEl.style.transition = '';
1496
+ this._captionEl.style.height = this._captionEl.offsetHeight + 'px';
1497
+ this._captionEl.innerHTML = this.post?.caption || '';
1498
+ forceLayout();
1499
+ this.raf(() => {
1500
+ this._captionEl.style.transition = 'height .3s ease';
1501
+ this._captionEl.style.height = this._captionEl.scrollHeight + 'px';
1502
+ this.to(() => {
1503
+ this._captionEl.style.transition = '';
1504
+ this._captionEl.style.height = '';
1505
+ }, 300, 'expandCaption');
1506
+ }, 'expandCaption');
1507
+ }
1508
+ /**
1509
+ * Collapse post caption
1510
+ */
1511
+ collapseCaption() {
1512
+ if (!this._captionEl)
1513
+ return;
1514
+ const truncatedCaption = getTruncatedText({
1515
+ text: this.post.caption,
1516
+ maxChars: 120,
1517
+ maxLines: 4,
1518
+ });
1519
+ this._captionEl.innerHTML = truncatedCaption;
1520
+ if (truncatedCaption?.length < this.post?.caption?.length) {
1521
+ this._captionEl.appendChild(this._moreEl);
1522
+ }
1523
+ }
1524
+ /*
1525
+ * Register
1526
+ */
1527
+ static register(name = 'behold-popover-gallery-slide') {
1528
+ if (!customElements.get(name)) {
1529
+ customElements.define(name, PopoverGallerySlide);
1530
+ }
1531
+ return name;
1532
+ }
1533
+ }
1534
+ /*
1535
+ * Types
1536
+ */
1537
+ const isImage = (el) => el.tagName === 'BEHOLD-IMAGE';
1538
+
1539
+ var xIcon = "<svg version=\"1.1\" id=\"Layer_1\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" x=\"0px\" y=\"0px\"\n\t viewBox=\"0 0 20 20\" enable-background=\"new 0 0 20 20\" xml:space=\"preserve\">\n<path fill-rule=\"evenodd\" clip-rule=\"evenodd\" fill=\"#081B10\" d=\"M11.6,10.1l5.5-5.7c0.5-0.5,0.5-1.1,0-1.6c-0.5-0.5-1.1-0.5-1.6,0\n\tl-5.5,5.6L4.4,2.8C4,2.4,3.3,2.4,2.8,2.8S2.4,4,2.8,4.4L8.4,10l-5.5,5.6c-0.5,0.5-0.5,1.1,0,1.6c0.5,0.5,1.1,0.5,1.6,0l5.5-5.6\n\tl5.5,5.6c0.5,0.5,1.1,0.5,1.6,0c0.5-0.5,0.5-1.1,0-1.6C17,15.6,11.6,10.1,11.6,10.1z\"/>\n</svg>";
1540
+
1541
+ var css_248z$2 = ":host{--icon-play:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 35 35' xml:space='preserve'%3E%3Cpath fill='%23FFF' d='M28.4 14.9 9.5 4.2C7.5 3.1 5 4.6 5 6.8v21.3c0 2.3 2.5 3.7 4.5 2.6l19-10.7c2-1 2-4-.1-5.1z'/%3E%3C/svg%3E\");--icon-gallery:url(\"data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 35 35' xml:space='preserve'%3E%3Cpath fill='%23FFF' d='M27.3 22.7v-17c0-2.6-2.1-4.7-4.7-4.7H5.7C3.1 1 1 3.1 1 5.7v17c0 2.6 2.1 4.7 4.7 4.7h17c2.5-.1 4.6-2.2 4.6-4.7zm4-13.4v14.6c0 4.1-3.4 7.4-7.4 7.4H9.2c-.5 0-.8.6-.5 1 .9 1 2.2 1.6 3.7 1.6h12.1c5.2 0 9.3-4.2 9.3-9.3V12.5c0-1.5-.6-2.8-1.6-3.7-.3-.4-.9 0-.9.5z'/%3E%3C/svg%3E\");--bottomPadding:60px;--height:min(calc(100vh - 120px - var(--bottomPadding)),1400px);--width:calc(100vw - 120px);--text-width:400px;--text-color:#262626;--text-background:#fff;--text-size:15px;--border-color:#ededed;--ease-out-back:cubic-bezier(0.085,1.735,0.285,0.995);align-items:center;box-sizing:border-box;height:100vh;justify-content:flex-start;left:0;overflow:hidden;pointer-events:none;position:fixed;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%;z-index:99999}:host *{box-sizing:border-box}@media (max-width:1200px){:host{--text-width:300px;--text-size:13px}}:host(.is-scroller){--text-width:100%;--height:auto;--width:calc(100vw - 40px)}@media (prefers-color-scheme:dark){:host(.theme--auto){--text-color:#f2f2f2;--text-background:#1a1a1a;--border-color:#292929}}:host(.theme--dark){--text-color:#f2f2f2;--text-background:#1a1a1a;--border-color:#292929}:host(.is-visible){pointer-events:all}.overlay{background-color:rgba(0,0,0,.6);display:block;height:100%;left:0;opacity:0;pointer-events:none;position:absolute;top:0;transition:all .3s ease;width:100%;will-change:opacity,background-color}@media (min-width:901px){.overlay{-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}}:host(.is-visible) .overlay{opacity:1;pointer-events:all}.inner{display:flex;height:calc(100% - var(--bottomPadding));justify-content:center;pointer-events:none;position:relative;width:100%;z-index:1}:host(.is-scroller) .inner{height:100%}behold-popover-gallery-slide{align-items:center;display:flex;flex-grow:0;flex-shrink:0;height:calc(100% - var(--bottomPadding));justify-content:center;margin:0;opacity:0;padding:0;pointer-events:none;transform:scale(.99);transition:transform .2s ease-out,opacity .2s ease-out;width:100%}@media (min-width:901px){behold-popover-gallery-slide:active{cursor:grabbing}}@media (prefers-reduced-motion){behold-popover-gallery-slide{transform:none;transition:none}}:host(.is-visible) behold-popover-gallery-slide.is-loaded{opacity:1;transform:none}:host(.is-scroller) behold-popover-gallery-slide{height:auto;margin-top:10px}.slide__inner{align-items:center;background-color:var(--text-background);display:flex;justify-content:center;max-height:var(--height);max-width:var(--width);overflow:hidden;pointer-events:all;position:relative}:host(.is-scroller) .slide__inner{border-radius:4px;flex-direction:column}.slide__media{align-items:center;display:flex;flex-shrink:1;height:var(--height);justify-content:center;max-height:var(--height);overflow:hidden;position:relative;transition:background-color .3s ease;z-index:1}behold-image img,behold-image video,behold-video img,behold-video video{height:auto;max-height:100%;-o-object-fit:contain;object-fit:contain;-o-object-position:center center;object-position:center center;opacity:0;position:relative;width:auto;z-index:1}.behold-ps-container behold-image img,.behold-ps-container behold-image video,.behold-ps-container behold-video img,.behold-ps-container behold-video video{max-width:100%}behold-image{min-height:10px;min-width:10px;pointer-events:none;position:relative}@supports (aspect-ratio:1/1){behold-image img{min-height:100%;min-width:100%}}behold-image.is-loaded img{opacity:1;transition:opacity .4s ease}.slide__carousel{height:100%;left:0;position:absolute;top:0;width:100%}.slide__carousel:before{background:linear-gradient(0deg,rgba(0,0,0,.4),transparent);bottom:0;height:60px;left:0;width:100%;z-index:1}.slide__carousel:after,.slide__carousel:before{content:\"\";pointer-events:none;position:absolute;transform:translateZ(0)}.slide__carousel:after{background:var(--icon-gallery);height:20px;left:20px;opacity:.75;top:20px;width:20px;z-index:2}:host(.is-scroller) .slide__carousel:after{left:auto;right:15px;top:15px}img.slide__carousel-spaceholder,video.slide__carousel-spaceholder{height:auto;max-height:100%;opacity:0;pointer-events:none;visibility:hidden;width:auto}.behold-ps-container img.slide__carousel-spaceholder,.behold-ps-container video.slide__carousel-spaceholder{max-width:100%}.slide__carousel-breadcrumbs{bottom:30px;height:10px;left:50%;position:absolute;transform:translateX(-50%);z-index:2}:host(.is-scroller) .slide__carousel-breadcrumbs{bottom:10px}.slide__carousel-next,.slide__carousel-previous{align-items:center;background-color:hsla(0,0%,100%,.95);border:none;border-radius:50%;box-shadow:0 0 10px rgba(0,0,0,.2);display:flex;height:30px;justify-content:center;opacity:.75;outline:none;position:absolute;top:50%;touch-action:manipulation;transform:translateY(-50%) translateZ(0);transition:opacity .3s ease;width:30px;z-index:2}:host(.keyboard-nav) .slide__carousel-next:focus,:host(.keyboard-nav) .slide__carousel-previous:focus{background-color:#000;box-shadow:0 0 10px rgba(0,0,0,.2),0 0 0 2px #4169e1,0 0 0 3px #fff;opacity:1}:host(.keyboard-nav) .slide__carousel-next:focus svg path,:host(.keyboard-nav) .slide__carousel-previous:focus svg path{fill:#fff}.slide__carousel-next:not(:disabled),.slide__carousel-previous:not(:disabled){cursor:pointer}.slide__carousel-next:not(:disabled):hover,.slide__carousel-previous:not(:disabled):hover{opacity:1}.slide__carousel-next:disabled,.slide__carousel-previous:disabled{opacity:.25}.slide__carousel-next:before,.slide__carousel-previous:before{content:\"\";height:60px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:60px}.slide__carousel-next svg,.slide__carousel-previous svg{height:12px;position:absolute;width:12px}.slide__carousel-next svg path,.slide__carousel-previous svg path{fill:#000}:host(.is-scroller) .slide__carousel-next,:host(.is-scroller) .slide__carousel-previous{background-color:transparent;box-shadow:none;height:20px;width:20px}:host(.is-scroller) .slide__carousel-next svg path,:host(.is-scroller) .slide__carousel-previous svg path{fill:#fff}.slide__carousel-previous{left:20px}.slide__carousel-previous svg{transform:translateX(-1px)}:host(.is-scroller) .slide__carousel-previous{left:10px}.slide__carousel-next{right:20px}.slide__carousel-next svg{transform:translateX(1px)}:host(.is-scroller) .slide__carousel-next{right:10px}.slide__carousel-slide{cursor:grab;display:flex;height:var(--height);overflow:hidden;width:auto}.slide__carousel-slide:active{cursor:grabbing}.slide__carousel-slide-media{height:auto;max-height:100%;max-width:100%;-o-object-fit:contain;object-fit:contain;pointer-events:none;width:auto}.video-container{align-items:center;cursor:pointer;display:flex;height:var(--height);justify-content:center;overflow:hidden;position:relative;width:100%}.video-container:after{background:var(--icon-play);content:\"\";filter:drop-shadow(1px 1px 1px rgba(0,0,0,.1));height:80px;left:calc(50% - 40px);opacity:0;pointer-events:none;position:absolute;top:calc(50% - 40px);transform:scale(.5);transition:all .15s ease;width:80px;z-index:2}.video-container.video-container--paused:after{opacity:.8;transform:none;transition:opacity .2s ease,transform .3s var(--ease-out-back)}.video-container:active{cursor:grabbing}behold-video{align-items:center;display:flex;height:100%;width:100%}behold-video.is-loaded video{opacity:1;transition:opacity .4s ease}.video-mute{align-items:center;background:transparent;border:none;bottom:0;cursor:pointer;display:flex;height:60px;justify-content:center;margin:0;opacity:0;outline:none;padding:0;position:absolute;right:0;transform:translateZ(0);transition:opacity .1s ease;width:60px;z-index:2}.video-mute.video-mute--visible{opacity:1;transition:opacity .2s ease .2s}.video-mute:before{background-color:rgba(0,0,0,.5);border-radius:50%;content:\"\";height:28px;left:calc(50% - 14px);position:absolute;top:calc(50% - 14px);width:28px}:host(.keyboard-nav) .video-mute:focus:before{background-color:#000;box-shadow:0 0 10px rgba(0,0,0,.2),0 0 0 2px #4169e1,0 0 0 4px #fff}.video-mute svg{height:20px;left:calc(50% - 10px);position:absolute;top:calc(50% - 10px);width:20px}.slide__text{align-items:stretch;box-shadow:-1px 0 0 var(--border-color);color:var(--text-color);display:flex;flex-direction:column;flex-shrink:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;font-size:var(--text-size);height:var(--height);justify-content:flex-start;pointer-events:none;position:relative;transform:translateZ(0);width:var(--text-width);z-index:1}.slide__header{align-items:center;border-bottom:1px solid var(--border-color);display:flex;font-weight:600;line-height:1.25;padding:30px}@media (prefers-color-scheme:dark){.theme--auto .slide__header{border-color:#292929}}.slide__header.theme--dark{border-color:#292929}@media (max-width:1200px){.slide__header{padding:20px}}.slide__avatar{align-items:center;border-radius:50%;display:flex;flex-shrink:0;height:42px;justify-content:center;margin-right:10px;overflow:hidden;position:relative;width:42px}.slide__avatar:before{background:radial-gradient(circle farthest-corner at 32% 106%,#ffe17d 0,#ffcd69 10%,#fa9137 28%,#eb4141 42%,transparent 82%),linear-gradient(135deg,#c33cbe 12%,#c33cbe 58%);height:100%;left:0;top:0;width:100%}.slide__avatar:after,.slide__avatar:before{border-radius:50%;content:\"\";position:absolute}.slide__avatar:after{background-color:var(--text-background);height:calc(100% - 4px);left:2px;top:2px;width:calc(100% - 4px)}@media (prefers-color-scheme:dark){.theme--auto .slide__avatar{background-color:#333}}.slide__avatar.theme--dark{background-color:#333}.slide__avatar img{border-radius:50%;height:calc(100% - 8px);position:relative;width:calc(100% - 8px);z-index:1}.slide__avatar svg{height:15px;position:relative;width:15px;z-index:1}.slide__avatar svg path{fill:var(--text-color)}:host(.is-scroller) .slide__avatar{height:32px;width:32px}:host(.is-scroller) .slide__avatar svg{height:12px;width:12px}.slide__caption{line-height:1.5;overflow:auto;padding:30px;scrollbar-width:none;white-space:pre-wrap;word-break:break-word}:host(.is-visible) .slide__caption{pointer-events:all}.slide__caption::-webkit-scrollbar{width:0!important}:host(.is-scroller) .slide__caption{overflow:hidden}.slide__more{background:transparent;border:none;color:var(--text-color);cursor:pointer;margin:0;opacity:.75;padding:0}.slide__more:hover{opacity:1;text-decoration:underline}.slide__footer{border-top:1px solid var(--border-color);margin-top:auto}:host(.is-visible) .slide__footer{pointer-events:all}.slide__footer-link{align-items:center;color:var(--text-color);cursor:pointer;display:flex;font-size:.9333em;font-weight:600;padding:30px;text-decoration:none;transition:background .3s ease}:host(.keyboard-nav) .slide__footer-link:focus{background-color:var(--border-color);border:none;box-shadow:inset 0 0 0 1px #fff,inset 0 0 0 3px #4169e1;outline:none;transition:background .1s ease}.slide__footer-link:hover{background-color:var(--border-color)}.slide__footer-link svg{height:17px;margin-left:auto;width:17px}.slide__footer-link svg path{fill:var(--text-color)}@media (max-width:1200px){.slide__footer-link{padding:20px}}.breadcrumbs{align-items:center;bottom:calc(var(--bottomPadding)/2 + 30px - (var(--breadCrumbDiameter) + 10px)/2);display:flex;gap:calc(var(--breadCrumbDiameter)*.75);height:calc(var(--breadCrumbDiameter) + 10px);justify-content:center;left:50%;opacity:0;position:absolute;transform:translateX(-50%);width:auto;z-index:2}:host(.is-visible) .breadcrumbs{opacity:1}.breadcrumbs-current,.breadcrumbs-current:empty{background-color:#fff;border-radius:calc(var(--breadCrumbDiameter)/2);display:block;height:var(--breadCrumbDiameter);position:absolute;top:5px;transition:width .3s ease;width:var(--breadCrumbDiameter);will-change:left,right,width}.breadcrumb,.breadcrumb:empty{background-color:hsla(0,0%,100%,.4);border-radius:50%;cursor:pointer;display:block;height:7px;transition:all .3s ease;width:7px}.breadcrumb:empty:hover,.breadcrumb:hover{background-color:#fff}.close{align-items:center;background:none;border:none;cursor:pointer;display:flex;height:30px;justify-content:center;margin:0;opacity:0;padding:0;position:absolute;right:15px;top:15px;width:30px;z-index:2}:host(.is-visible) .close{opacity:.75;transition:opacity .3s ease}:host(.is-visible) .close:hover{opacity:1}:host(.keyboard-nav) .close:focus{box-shadow:0 0 0 2px #4169e1,0 0 0 3px #fff;opacity:1}.close:focus{border:none;outline:none}.close:before{content:\"\";height:60px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:60px}.close svg{height:20px;width:20px}.close svg path{fill:#fff}:host(.is-scroller) .close{background-color:hsla(0,0%,97%,.85);border-radius:50%;opacity:1;right:5px;top:5px}:host(.is-scroller) .close svg{height:14px;width:14px}:host(.is-scroller) .close svg path{fill:#000}.next,.previous{align-items:center;background:none;border:none;cursor:pointer;display:flex;height:60px;justify-content:center;margin:0;opacity:0;padding:0;position:absolute;top:calc(50% - var(--bottomPadding)/2);touch-action:manipulation;transform:translateY(-50%);width:60px;z-index:2}:host(.is-visible) .next,:host(.is-visible) .previous{opacity:.75;transition:opacity .3s ease}:host(.is-visible) .next:focus,:host(.is-visible) .previous:focus{border:none;outline:none}:host(.is-visible) .next:hover,:host(.is-visible) .previous:hover{opacity:1}:host(.is-visible) .next:disabled,:host(.is-visible) .previous:disabled{cursor:default;opacity:.15}:host(.is-visible) .next:disabled:hover,:host(.is-visible) .previous:disabled:hover{opacity:.15}:host(.keyboard-nav) .next:focus,:host(.keyboard-nav) .previous:focus{box-shadow:0 0 0 2px #4169e1,0 0 0 3px #fff;opacity:1}.next svg,.previous svg{height:16px;width:16px}.next svg path,.previous svg path{fill:#fff}.previous{left:0}.next{right:0}.ldr{--uib-size:50px;--uib-speed:1s;--uib-stroke:2px;--uib-bg-opacity:0.1;align-items:center;border-radius:calc(var(--uib-stroke)/2);contain:strict;display:none;height:var(--uib-stroke);justify-content:center;left:calc(50% - var(--uib-size)/2);overflow:hidden;position:absolute;top:calc(50% - var(--uib-stroke)/2);transform:translateZ(0);width:var(--uib-size)}.ldr.ldr--visible{display:flex}behold-image.is-loaded .ldr{display:none}.ldr:before{left:0;opacity:var(--uib-bg-opacity);position:absolute;top:0}.ldr:after,.ldr:before{background-color:var(--uib-color);content:\"\";height:100%;transition:background-color .3s ease;width:100%}.ldr:after{animation:wobble var(--uib-speed) ease-in-out infinite;border-radius:calc(var(--uib-stroke)/2);transform:translateX(-95%)}@keyframes wobble{0%,to{transform:translateX(-95%)}50%{transform:translateX(95%)}}";
1542
+ var styles = css_248z$2;
1543
+
1544
+ var css_248z$1 = ".hg-container{align-items:flex-start;backface-visibility:hidden;contain:layout style;justify-content:flex-start;-webkit-user-select:none;-moz-user-select:none;user-select:none;will-change:transform}.hg-container,.hg-slide{display:flex;height:100%;width:100%}.hg-slide{contain:strict;flex-grow:0;flex-shrink:0}.hg-breadcrumbs,.hg-slide{align-items:center;justify-content:center}.hg-breadcrumbs{--ease:cubic-bezier(0.215,0.61,0.355,1);display:flex;gap:calc(var(--breadCrumbDiameter)*.75);height:calc(var(--breadCrumbDiameter) + 10px);pointer-events:all;position:relative;transition:transform .4s var(--ease);width:auto;will-change:transform}.hg-breadcrumbs.no-transition{transition:none}@media (prefers-reduced-motion){.hg-breadcrumbs{transition:none}}.hg-breadcrumbs-current,.hg-breadcrumbs-current:empty{background-color:#fff;border-radius:calc(var(--breadCrumbDiameter)/2);display:block;height:var(--breadCrumbDiameter);position:absolute;top:5px;transition:width .3s var(--ease);width:var(--breadCrumbDiameter);will-change:left,right,width}.hg-breadcrumb,.hg-breadcrumb:empty{cursor:pointer;display:block;flex-shrink:0;height:var(--breadCrumbDiameter);position:relative;width:var(--breadCrumbDiameter)}.hg-breadcrumb:before,.hg-breadcrumb:empty:before{content:\"\";height:60px;left:50%;position:absolute;top:50%;transform:translate(-50%,-50%);width:calc(var(--breadCrumbDiameter)*1.75)}.hg-breadcrumb:after,.hg-breadcrumb:empty:after{background-color:hsla(0,0%,100%,.4);border-radius:50%;content:\"\";height:100%;left:0;position:absolute;top:0;transition:all .3s var(--ease);width:100%}.no-transition .hg-breadcrumb:after,.no-transition .hg-breadcrumb:empty:after{transition:none}@media (prefers-reduced-motion){.hg-breadcrumb:after,.hg-breadcrumb:empty:after{transition:none}}.hg-breadcrumb.hg-breadcrumb--1:after,.hg-breadcrumb:empty.hg-breadcrumb--1:after{transform:scale(.85)}.hg-breadcrumb.hg-breadcrumb--2:after,.hg-breadcrumb:empty.hg-breadcrumb--2:after{opacity:.75;transform:scale(.7)}.hg-breadcrumb.hg-breadcrumb--3:after,.hg-breadcrumb:empty.hg-breadcrumb--3:after{opacity:.5;transform:scale(.55)}.hg-breadcrumb.hg-breadcrumb--4:after,.hg-breadcrumb:empty.hg-breadcrumb--4:after{opacity:.25;transform:scale(.4)}.hg-breadcrumb.hg-breadcrumb--hidden,.hg-breadcrumb:empty.hg-breadcrumb--hidden{pointer-events:none}.hg-breadcrumb.hg-breadcrumb--hidden:after,.hg-breadcrumb:empty.hg-breadcrumb--hidden:after{opacity:0;transform:scale(0)}.hg-breadcrumb:empty:hover:after,.hg-breadcrumb:hover:after{background-color:#fff;opacity:1;transform:none}";
1545
+ var hgStyles = css_248z$1;
1546
+
1547
+ var css_248z = ".behold-ps-container{display:flex;height:100vh;justify-content:center;overflow:auto;pointer-events:all;scrollbar-width:none;width:100%}.behold-ps-container::-webkit-scrollbar{width:0!important}.behold-ps-inner{max-width:400px}.behold-ps-inner:before{height:10px}.behold-ps-inner:after,.behold-ps-inner:before{content:\"\";display:block;pointer-events:none;width:100%}.behold-ps-inner:after{height:90px}";
1548
+ var psStyles = css_248z;
1549
+
1550
+ /**
1551
+ * @description
1552
+ * Required props: 'posts', 'widgetSettings', 'feedMetadata'
1553
+ */
1554
+ class PopoverGallery extends BaseElement {
1555
+ label = 'PopoverGallery';
1556
+ // Provided
1557
+ posts;
1558
+ widgetSettings;
1559
+ feedMetadata;
1560
+ closeFocusEl = document.body;
1561
+ onSlideChange;
1562
+ // Internal
1563
+ _isOpen;
1564
+ _verticalScrollBreakpoint = 900;
1565
+ _shadow;
1566
+ _fragment;
1567
+ _styleEl;
1568
+ _overlayEl;
1569
+ _previousEl;
1570
+ _nextEl;
1571
+ _closeEl;
1572
+ _breadcrumbContainer;
1573
+ _innerEl;
1574
+ _postEls;
1575
+ _hurdyGurdy;
1576
+ _popoverScroller;
1577
+ _currentPostIndex = 0;
1578
+ _startingDocumentOverflow = '';
1579
+ _startingDocumentRightPadding = '';
1580
+ constructor() {
1581
+ super();
1582
+ this._shadow = this.attachShadow({ mode: 'open' });
1583
+ this._isOpen = false;
1584
+ // Listen to prop changes
1585
+ this.onPropChange(this._handlePropChange, [
1586
+ 'posts',
1587
+ 'widgetSettings',
1588
+ 'feedMetadata',
1589
+ ]);
1590
+ // Register child components
1591
+ PopoverGallerySlide.register();
1592
+ // Bind handlers
1593
+ this._handleSlideChange = this._handleSlideChange.bind(this);
1594
+ this._close = this._close.bind(this);
1595
+ this._handleKeydown = this._handleKeydown.bind(this);
1596
+ // On global state change
1597
+ this.onGlobalStateChange(this._handleGlobalStateChange);
1598
+ // connected
1599
+ this.onConnect(() => {
1600
+ setClasses(this, {
1601
+ 'theme--light': this.widgetSettings.popupColorTheme === 'light',
1602
+ 'theme--dark': this.widgetSettings.popupColorTheme === 'dark',
1603
+ 'theme--auto': this.widgetSettings.popupColorTheme === 'auto',
1604
+ });
1605
+ setClasses(this, {
1606
+ 'keyboard-nav': this.globalState.keyboardNavEnabled,
1607
+ });
1608
+ this._overlayEl = createElement({
1609
+ classes: 'overlay',
1610
+ listeners: { click: this._close },
1611
+ });
1612
+ this._previousEl = createElement({
1613
+ type: 'button',
1614
+ classes: 'previous',
1615
+ attributes: { 'aria-label': 'Previous post' },
1616
+ contents: caretLeftIcon,
1617
+ });
1618
+ this._nextEl = createElement({
1619
+ type: 'button',
1620
+ classes: 'next',
1621
+ attributes: { 'aria-label': 'Next post' },
1622
+ contents: caretRightIcon,
1623
+ });
1624
+ this._closeEl = createElement({
1625
+ type: 'button',
1626
+ classes: 'close',
1627
+ contents: xIcon,
1628
+ attributes: { 'aria-label': 'Close' },
1629
+ listeners: {
1630
+ click: (evt) => {
1631
+ evt.preventDefault();
1632
+ this._close();
1633
+ },
1634
+ },
1635
+ });
1636
+ this._breadcrumbContainer = createElement({
1637
+ classes: 'breadcrumbs',
1638
+ });
1639
+ this._postEls = this.posts.map((post) => {
1640
+ const el = document.createElement('behold-popover-gallery-slide');
1641
+ el.post = post;
1642
+ el.feedMetadata = this.feedMetadata;
1643
+ return el;
1644
+ });
1645
+ this._innerEl = createElement({
1646
+ classes: 'inner',
1647
+ contents: this._postEls,
1648
+ });
1649
+ this._fragment = document.createDocumentFragment();
1650
+ this._fragment.beholdReplaceChildren(this._overlayEl, this._innerEl, this._breadcrumbContainer, this._previousEl, this._nextEl, this._closeEl);
1651
+ this._styleEl = createElement({
1652
+ type: 'style',
1653
+ contents: [styles.toString(), hgStyles.toString(), psStyles.toString()],
1654
+ });
1655
+ this._hurdyGurdy = new HurdyGurdy({
1656
+ slides: this._postEls,
1657
+ containerEl: this._innerEl,
1658
+ breadcrumbsContainerEl: this._breadcrumbContainer,
1659
+ previousEl: this._previousEl,
1660
+ nextEl: this._nextEl,
1661
+ onSlideChange: this._handleSlideChange,
1662
+ breadcrumbDiameter: this._postEls.length > 9 ? 9 : 8,
1663
+ virtualize: true,
1664
+ dragLimit: 0.4,
1665
+ });
1666
+ this._popoverScroller = new PopoverScroller({
1667
+ slides: this._postEls,
1668
+ containerEl: this._innerEl,
1669
+ onSlideChange: this._handleSlideChange,
1670
+ onRequestClose: () => {
1671
+ this._close();
1672
+ },
1673
+ });
1674
+ this.onResize(this, this, this._handleResize);
1675
+ });
1676
+ this.onDisconnect(() => {
1677
+ document.removeEventListener('keydown', this._handleKeydown);
1678
+ releaseFocus(this.closeFocusEl);
1679
+ this._hurdyGurdy.destroy();
1680
+ this._popoverScroller.destroy();
1681
+ this._hurdyGurdy = null;
1682
+ this._popoverScroller = null;
1683
+ document.body.style.overflow = this._startingDocumentOverflow;
1684
+ document.documentElement.style.paddingRight =
1685
+ this._startingDocumentRightPadding;
1686
+ });
1687
+ }
1688
+ /**
1689
+ * Handle prop change
1690
+ */
1691
+ _handlePropChange({ changedProp, oldValue, newValue }) {
1692
+ switch (changedProp) {
1693
+ case 'posts':
1694
+ if (newValue && this._innerEl) {
1695
+ this.cancelRaf('updatePosts');
1696
+ this._postEls = newValue.map((post) => {
1697
+ const el = document.createElement('behold-popover-gallery-slide');
1698
+ el.post = post;
1699
+ el.feedMetadata = this.feedMetadata;
1700
+ return el;
1701
+ });
1702
+ this._innerEl.beholdReplaceChildren(...this._postEls);
1703
+ this._currentPostIndex = Math.min(this._currentPostIndex, this._postEls.length - 1);
1704
+ if (this._isOpen) {
1705
+ this._render();
1706
+ forceLayout();
1707
+ this.raf(() => {
1708
+ this._checkSize(this.offsetWidth);
1709
+ }, 'updatePosts');
1710
+ }
1711
+ }
1712
+ case 'widgetSettings':
1713
+ if (hasChanges(oldValue, newValue, 'popupColorTheme')) {
1714
+ setClasses(this, {
1715
+ 'theme--light': this.widgetSettings.popupColorTheme === 'light',
1716
+ 'theme--dark': this.widgetSettings.popupColorTheme === 'dark',
1717
+ 'theme--auto': this.widgetSettings.popupColorTheme === 'auto',
1718
+ });
1719
+ }
1720
+ break;
1721
+ case 'feedMetadata':
1722
+ if (this._postEls) {
1723
+ this._postEls.map((el) => {
1724
+ el.feedMetadata = newValue;
1725
+ });
1726
+ }
1727
+ break;
1728
+ }
1729
+ }
1730
+ /**
1731
+ * Handle state change
1732
+ */
1733
+ _handleGlobalStateChange({ changedProps, newState }) {
1734
+ if (changedProps.includes('keyboardNavEnabled')) {
1735
+ setClasses(this, {
1736
+ 'keyboard-nav': this.globalState.keyboardNavEnabled,
1737
+ });
1738
+ }
1739
+ if (changedProps.includes('popoverOverlayHslArray') ||
1740
+ changedProps.includes('popoverOverlayOpacity')) {
1741
+ const hslArray = newState.popoverOverlayHslArray;
1742
+ const opacity = newState.popoverOverlayOpacity;
1743
+ this.raf(() => {
1744
+ this._overlayEl.style.backgroundColor = `hsl(${hslArray[0]} ${Math.min(hslArray[1], 50)}% ${Math.min(hslArray[2], 15)}% / ${opacity})`;
1745
+ }, 'overlayColor');
1746
+ }
1747
+ }
1748
+ /**
1749
+ * Handle keydown
1750
+ */
1751
+ _handleKeydown(evt) {
1752
+ if (evt.code === 'Escape') {
1753
+ evt.preventDefault();
1754
+ this._close();
1755
+ }
1756
+ }
1757
+ /**
1758
+ * Open
1759
+ */
1760
+ open(index, closeFocusEl) {
1761
+ if (this._isOpen)
1762
+ return;
1763
+ this._isOpen = true;
1764
+ this._currentPostIndex = index;
1765
+ this.cancelRaf('open');
1766
+ this.closeFocusEl = closeFocusEl;
1767
+ this._startingDocumentOverflow = document.body.style.overflow;
1768
+ const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth;
1769
+ this._startingDocumentRightPadding =
1770
+ document.documentElement.style.paddingRight;
1771
+ const computedRightPadding = parseInt(getComputedStyle(document.documentElement).paddingRight.replace('px', ''));
1772
+ document.documentElement.style.paddingRight = `${computedRightPadding + scrollbarWidth}px`;
1773
+ this.style.paddingRight = `${scrollbarWidth}px`;
1774
+ document.body.style.overflow = 'hidden';
1775
+ this._render();
1776
+ forceLayout();
1777
+ this.raf(() => {
1778
+ this.classList.add('is-visible');
1779
+ trapFocus(this._shadow, this._postEls?.filter((el, i) => i !== index), 1);
1780
+ this._checkSize(this.offsetWidth);
1781
+ document.addEventListener('keydown', this._handleKeydown);
1782
+ }, 'open');
1783
+ }
1784
+ /**
1785
+ * Close
1786
+ */
1787
+ _close() {
1788
+ if (!this._isOpen)
1789
+ return;
1790
+ this._isOpen = false;
1791
+ this.cancelTo('close');
1792
+ this.classList.remove('is-visible');
1793
+ this.to(this.remove.bind(this), 300, 'close');
1794
+ releaseFocus(this.closeFocusEl);
1795
+ document.removeEventListener('keydown', this._handleKeydown);
1796
+ document.body.style.overflow = this._startingDocumentOverflow;
1797
+ document.documentElement.style.paddingRight =
1798
+ this._startingDocumentRightPadding;
1799
+ this.style.paddingRight = '';
1800
+ }
1801
+ /**
1802
+ * Handle slide change
1803
+ */
1804
+ _handleSlideChange(newIndex) {
1805
+ this._currentPostIndex = newIndex;
1806
+ let mediaType = 'image';
1807
+ switch (this.posts[newIndex]?.mediaType) {
1808
+ case 'VIDEO':
1809
+ mediaType = this.posts[newIndex].isReel ? 'reel' : 'video';
1810
+ break;
1811
+ case 'CAROUSEL_ALBUM':
1812
+ mediaType = 'album';
1813
+ break;
1814
+ case 'IMAGE':
1815
+ default:
1816
+ mediaType = 'image';
1817
+ }
1818
+ if (this.globalState.keyboardNavEnabled) {
1819
+ announceToScreenReader(`${mediaType}, post ${newIndex + 1} of ${this._postEls.length} in gallery`);
1820
+ }
1821
+ updateTabbableEls({
1822
+ include: [this._shadow],
1823
+ exclude: this._postEls.filter((el, i) => i !== newIndex),
1824
+ merge: false,
1825
+ });
1826
+ if (this.onSlideChange) {
1827
+ this.onSlideChange(newIndex);
1828
+ }
1829
+ this._postEls.forEach((slide, i) => {
1830
+ if (i === newIndex) {
1831
+ slide.activate();
1832
+ }
1833
+ else {
1834
+ slide.deactivate();
1835
+ }
1836
+ });
1837
+ const prevPostEl = this._postEls[newIndex - 1] ?? null;
1838
+ const nextPostEl = this._postEls[newIndex + 1] ?? null;
1839
+ if (prevPostEl) {
1840
+ this.raf(() => prevPostEl.preload(), 'preloadPrev');
1841
+ }
1842
+ if (nextPostEl) {
1843
+ this.raf(() => nextPostEl.preload(), 'preloadNext');
1844
+ }
1845
+ const hslArray = this._postEls?.[newIndex]
1846
+ ? this._postEls[newIndex].getBackgroundColor()
1847
+ : null;
1848
+ if (hslArray) {
1849
+ this.updateGlobalState({
1850
+ popoverOverlayHslArray: hslArray,
1851
+ });
1852
+ }
1853
+ }
1854
+ /**
1855
+ * Check size and update as needed
1856
+ */
1857
+ _checkSize(containerWidth) {
1858
+ if (containerWidth > this._verticalScrollBreakpoint) {
1859
+ this.classList.remove('is-scroller');
1860
+ this._previousEl.style.display = '';
1861
+ this._nextEl.style.display = '';
1862
+ this._popoverScroller.destroy();
1863
+ this._hurdyGurdy.init(this._currentPostIndex);
1864
+ this._postEls.forEach((slide) => slide.expandCaption());
1865
+ this.updateGlobalState({
1866
+ popoverOverlayOpacity: 0.85,
1867
+ });
1868
+ }
1869
+ else {
1870
+ this.classList.add('is-scroller');
1871
+ this._hurdyGurdy.destroy();
1872
+ this._popoverScroller.init(this._currentPostIndex);
1873
+ this._postEls.forEach((slide) => slide.collapseCaption());
1874
+ this._previousEl.disabled = false;
1875
+ this._previousEl.style.display = 'none';
1876
+ this._nextEl.disabled = false;
1877
+ this._nextEl.style.display = 'none';
1878
+ this.updateGlobalState({
1879
+ popoverOverlayOpacity: 0.9,
1880
+ });
1881
+ }
1882
+ }
1883
+ _handleResize(entry) {
1884
+ const containerWidth = entry?.borderBoxSize?.[0]?.inlineSize || entry?.contentRect?.width || 0;
1885
+ this._checkSize(containerWidth);
1886
+ }
1887
+ /*
1888
+ * Render
1889
+ */
1890
+ _render() {
1891
+ document.body.append(this);
1892
+ this._shadow.beholdReplaceChildren(this._fragment, this._styleEl);
1893
+ }
1894
+ /*
1895
+ * Register
1896
+ */
1897
+ static register(name = 'behold-popover-gallery') {
1898
+ if (!customElements.get(name)) {
1899
+ customElements.define(name, PopoverGallery);
1900
+ }
1901
+ return name;
1902
+ }
1903
+ }
1904
+
1905
+ export { PopoverGallery as default };