@asante-org/atlascopco-vt-litesitegenerator 3.8.14 → 3.8.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +568 -315
- package/dist/index.esm.js.map +1 -1
- package/dist/index.esm.scss +694 -132
- package/dist/index.js +567 -314
- package/dist/index.js.map +1 -1
- package/dist/index.scss +694 -132
- package/dist/src/components/lsg/LsgCarousel/LsgCarousel.d.ts +40 -12
- package/dist/src/components/lsg/LsgCarousel/LsgCarousel.stories.d.ts +20 -3
- package/dist/src/components/lsg/LsgCarousel/LsgCarouselController.d.ts +57 -1
- package/dist/src/components/lsg/LsgCarousel/bootLsgCarousel.d.ts +2 -9
- package/dist/src/components/lsg/LsgCarousel/index.d.ts +2 -2
- package/dist/themes/theme-1.css +371 -469
- package/dist/themes/theme-1.css.map +1 -1
- package/dist/themes/theme-1.js +270 -51
- package/dist/themes/theme-1.js.map +1 -1
- package/dist/themes/theme-2.css +550 -187
- package/dist/themes/theme-2.css.map +1 -1
- package/dist/themes/theme-2.js +270 -51
- package/dist/themes/theme-2.js.map +1 -1
- package/dist/themes/theme-3.css +566 -66
- package/dist/themes/theme-3.css.map +1 -1
- package/dist/themes/theme-3.js +270 -51
- package/dist/themes/theme-3.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useId, useState, useRef, useEffect, useCallback,
|
|
1
|
+
import React, { useId, useState, useRef, useMemo, useEffect, useCallback, forwardRef, useImperativeHandle } from 'react';
|
|
2
2
|
|
|
3
3
|
function _extends() {
|
|
4
4
|
return _extends = Object.assign ? Object.assign.bind() : function (n) {
|
|
@@ -2260,8 +2260,247 @@ function EmblaCarousel(root, userOptions, userPlugins) {
|
|
|
2260
2260
|
}
|
|
2261
2261
|
EmblaCarousel.globalOptions = undefined;
|
|
2262
2262
|
|
|
2263
|
+
function clampNumber(number, min, max) {
|
|
2264
|
+
return Math.min(Math.max(number, min), max);
|
|
2265
|
+
}
|
|
2266
|
+
function isNumber(value) {
|
|
2267
|
+
return typeof value === 'number' && !isNaN(value);
|
|
2268
|
+
}
|
|
2269
|
+
function Fade(userOptions = {}) {
|
|
2270
|
+
const fullOpacity = 1;
|
|
2271
|
+
const noOpacity = 0;
|
|
2272
|
+
const fadeFriction = 0.68;
|
|
2273
|
+
let emblaApi;
|
|
2274
|
+
let opacities = [];
|
|
2275
|
+
let fadeToNextDistance;
|
|
2276
|
+
let distanceFromPointerDown = 0;
|
|
2277
|
+
let fadeVelocity = 0;
|
|
2278
|
+
let progress = 0;
|
|
2279
|
+
let shouldFadePair = false;
|
|
2280
|
+
let defaultSettledBehaviour;
|
|
2281
|
+
let defaultProgressBehaviour;
|
|
2282
|
+
function init(emblaApiInstance) {
|
|
2283
|
+
emblaApi = emblaApiInstance;
|
|
2284
|
+
const selectedSnap = emblaApi.selectedScrollSnap();
|
|
2285
|
+
const {
|
|
2286
|
+
scrollBody,
|
|
2287
|
+
containerRect,
|
|
2288
|
+
axis
|
|
2289
|
+
} = emblaApi.internalEngine();
|
|
2290
|
+
const containerSize = axis.measureSize(containerRect);
|
|
2291
|
+
fadeToNextDistance = clampNumber(containerSize * 0.75, 200, 500);
|
|
2292
|
+
shouldFadePair = false;
|
|
2293
|
+
opacities = emblaApi.scrollSnapList().map((_, index) => index === selectedSnap ? fullOpacity : noOpacity);
|
|
2294
|
+
defaultSettledBehaviour = scrollBody.settled;
|
|
2295
|
+
defaultProgressBehaviour = emblaApi.scrollProgress;
|
|
2296
|
+
scrollBody.settled = settled;
|
|
2297
|
+
emblaApi.scrollProgress = scrollProgress;
|
|
2298
|
+
emblaApi.on('select', select).on('slideFocus', fadeToSelectedSnapInstantly).on('pointerDown', pointerDown).on('pointerUp', pointerUp);
|
|
2299
|
+
disableScroll();
|
|
2300
|
+
fadeToSelectedSnapInstantly();
|
|
2301
|
+
}
|
|
2302
|
+
function destroy() {
|
|
2303
|
+
const {
|
|
2304
|
+
scrollBody
|
|
2305
|
+
} = emblaApi.internalEngine();
|
|
2306
|
+
scrollBody.settled = defaultSettledBehaviour;
|
|
2307
|
+
emblaApi.scrollProgress = defaultProgressBehaviour;
|
|
2308
|
+
emblaApi.off('select', select).off('slideFocus', fadeToSelectedSnapInstantly).off('pointerDown', pointerDown).off('pointerUp', pointerUp);
|
|
2309
|
+
emblaApi.slideNodes().forEach(slideNode => {
|
|
2310
|
+
const slideStyle = slideNode.style;
|
|
2311
|
+
slideStyle.opacity = '';
|
|
2312
|
+
slideStyle.transform = '';
|
|
2313
|
+
slideStyle.pointerEvents = '';
|
|
2314
|
+
if (!slideNode.getAttribute('style')) slideNode.removeAttribute('style');
|
|
2315
|
+
});
|
|
2316
|
+
}
|
|
2317
|
+
function fadeToSelectedSnapInstantly() {
|
|
2318
|
+
const selectedSnap = emblaApi.selectedScrollSnap();
|
|
2319
|
+
setOpacities(selectedSnap, fullOpacity);
|
|
2320
|
+
}
|
|
2321
|
+
function pointerUp() {
|
|
2322
|
+
shouldFadePair = false;
|
|
2323
|
+
}
|
|
2324
|
+
function pointerDown() {
|
|
2325
|
+
shouldFadePair = false;
|
|
2326
|
+
distanceFromPointerDown = 0;
|
|
2327
|
+
fadeVelocity = 0;
|
|
2328
|
+
}
|
|
2329
|
+
function select() {
|
|
2330
|
+
const duration = emblaApi.internalEngine().scrollBody.duration();
|
|
2331
|
+
fadeVelocity = duration ? 0 : fullOpacity;
|
|
2332
|
+
shouldFadePair = true;
|
|
2333
|
+
if (!duration) fadeToSelectedSnapInstantly();
|
|
2334
|
+
}
|
|
2335
|
+
function getSlideTransform(position) {
|
|
2336
|
+
const {
|
|
2337
|
+
axis
|
|
2338
|
+
} = emblaApi.internalEngine();
|
|
2339
|
+
const translateAxis = axis.scroll.toUpperCase();
|
|
2340
|
+
return `translate${translateAxis}(${axis.direction(position)}px)`;
|
|
2341
|
+
}
|
|
2342
|
+
function disableScroll() {
|
|
2343
|
+
const {
|
|
2344
|
+
translate,
|
|
2345
|
+
slideLooper
|
|
2346
|
+
} = emblaApi.internalEngine();
|
|
2347
|
+
translate.clear();
|
|
2348
|
+
translate.toggleActive(false);
|
|
2349
|
+
slideLooper.loopPoints.forEach(({
|
|
2350
|
+
translate
|
|
2351
|
+
}) => {
|
|
2352
|
+
translate.clear();
|
|
2353
|
+
translate.toggleActive(false);
|
|
2354
|
+
});
|
|
2355
|
+
}
|
|
2356
|
+
function lockExcessiveScroll(fadeIndex) {
|
|
2357
|
+
const {
|
|
2358
|
+
scrollSnaps,
|
|
2359
|
+
location,
|
|
2360
|
+
target
|
|
2361
|
+
} = emblaApi.internalEngine();
|
|
2362
|
+
if (!isNumber(fadeIndex) || opacities[fadeIndex] < 0.5) return;
|
|
2363
|
+
location.set(scrollSnaps[fadeIndex]);
|
|
2364
|
+
target.set(location);
|
|
2365
|
+
}
|
|
2366
|
+
function setOpacities(fadeIndex, velocity) {
|
|
2367
|
+
const scrollSnaps = emblaApi.scrollSnapList();
|
|
2368
|
+
scrollSnaps.forEach((_, indexA) => {
|
|
2369
|
+
const absVelocity = Math.abs(velocity);
|
|
2370
|
+
const currentOpacity = opacities[indexA];
|
|
2371
|
+
const isFadeIndex = indexA === fadeIndex;
|
|
2372
|
+
const nextOpacity = isFadeIndex ? currentOpacity + absVelocity : currentOpacity - absVelocity;
|
|
2373
|
+
const clampedOpacity = clampNumber(nextOpacity, noOpacity, fullOpacity);
|
|
2374
|
+
opacities[indexA] = clampedOpacity;
|
|
2375
|
+
const fadePair = isFadeIndex && shouldFadePair;
|
|
2376
|
+
const indexB = emblaApi.previousScrollSnap();
|
|
2377
|
+
if (fadePair) opacities[indexB] = 1 - clampedOpacity;
|
|
2378
|
+
if (isFadeIndex) setProgress(fadeIndex, clampedOpacity);
|
|
2379
|
+
setOpacity(indexA);
|
|
2380
|
+
});
|
|
2381
|
+
}
|
|
2382
|
+
function setOpacity(index) {
|
|
2383
|
+
const slidesInSnap = emblaApi.internalEngine().slideRegistry[index];
|
|
2384
|
+
const {
|
|
2385
|
+
scrollSnaps,
|
|
2386
|
+
containerRect
|
|
2387
|
+
} = emblaApi.internalEngine();
|
|
2388
|
+
const opacity = opacities[index];
|
|
2389
|
+
slidesInSnap.forEach(slideIndex => {
|
|
2390
|
+
const slideStyle = emblaApi.slideNodes()[slideIndex].style;
|
|
2391
|
+
const roundedOpacity = parseFloat(opacity.toFixed(2));
|
|
2392
|
+
const hasOpacity = roundedOpacity > noOpacity;
|
|
2393
|
+
const position = hasOpacity ? scrollSnaps[index] : containerRect.width + 2;
|
|
2394
|
+
const transform = getSlideTransform(position);
|
|
2395
|
+
if (hasOpacity) slideStyle.transform = transform;
|
|
2396
|
+
slideStyle.opacity = roundedOpacity.toString();
|
|
2397
|
+
slideStyle.pointerEvents = opacity > 0.5 ? 'auto' : 'none';
|
|
2398
|
+
if (!hasOpacity) slideStyle.transform = transform;
|
|
2399
|
+
});
|
|
2400
|
+
}
|
|
2401
|
+
function setProgress(fadeIndex, opacity) {
|
|
2402
|
+
const {
|
|
2403
|
+
index,
|
|
2404
|
+
dragHandler,
|
|
2405
|
+
scrollSnaps
|
|
2406
|
+
} = emblaApi.internalEngine();
|
|
2407
|
+
const pointerDown = dragHandler.pointerDown();
|
|
2408
|
+
const snapFraction = 1 / (scrollSnaps.length - 1);
|
|
2409
|
+
let indexA = fadeIndex;
|
|
2410
|
+
let indexB = pointerDown ? emblaApi.selectedScrollSnap() : emblaApi.previousScrollSnap();
|
|
2411
|
+
if (pointerDown && indexA === indexB) {
|
|
2412
|
+
const reverseSign = Math.sign(distanceFromPointerDown) * -1;
|
|
2413
|
+
indexA = indexB;
|
|
2414
|
+
indexB = index.clone().set(indexB).add(reverseSign).get();
|
|
2415
|
+
}
|
|
2416
|
+
const currentPosition = indexB * snapFraction;
|
|
2417
|
+
const diffPosition = (indexA - indexB) * snapFraction;
|
|
2418
|
+
progress = currentPosition + diffPosition * opacity;
|
|
2419
|
+
}
|
|
2420
|
+
function getFadeIndex() {
|
|
2421
|
+
const {
|
|
2422
|
+
dragHandler,
|
|
2423
|
+
index,
|
|
2424
|
+
scrollBody
|
|
2425
|
+
} = emblaApi.internalEngine();
|
|
2426
|
+
const selectedSnap = emblaApi.selectedScrollSnap();
|
|
2427
|
+
if (!dragHandler.pointerDown()) return selectedSnap;
|
|
2428
|
+
const directionSign = Math.sign(scrollBody.velocity());
|
|
2429
|
+
const distanceSign = Math.sign(distanceFromPointerDown);
|
|
2430
|
+
const nextSnap = index.clone().set(selectedSnap).add(directionSign * -1).get();
|
|
2431
|
+
if (!directionSign || !distanceSign) return null;
|
|
2432
|
+
return distanceSign === directionSign ? nextSnap : selectedSnap;
|
|
2433
|
+
}
|
|
2434
|
+
function fade(emblaApi) {
|
|
2435
|
+
const {
|
|
2436
|
+
dragHandler,
|
|
2437
|
+
scrollBody
|
|
2438
|
+
} = emblaApi.internalEngine();
|
|
2439
|
+
const pointerDown = dragHandler.pointerDown();
|
|
2440
|
+
const velocity = scrollBody.velocity();
|
|
2441
|
+
const duration = scrollBody.duration();
|
|
2442
|
+
const fadeIndex = getFadeIndex();
|
|
2443
|
+
const noFadeIndex = !isNumber(fadeIndex);
|
|
2444
|
+
if (pointerDown) {
|
|
2445
|
+
if (!velocity) return;
|
|
2446
|
+
distanceFromPointerDown += velocity;
|
|
2447
|
+
fadeVelocity = Math.abs(velocity / fadeToNextDistance);
|
|
2448
|
+
lockExcessiveScroll(fadeIndex);
|
|
2449
|
+
}
|
|
2450
|
+
if (!pointerDown) {
|
|
2451
|
+
if (!duration || noFadeIndex) return;
|
|
2452
|
+
fadeVelocity += (fullOpacity - opacities[fadeIndex]) / duration;
|
|
2453
|
+
fadeVelocity *= fadeFriction;
|
|
2454
|
+
}
|
|
2455
|
+
if (noFadeIndex) return;
|
|
2456
|
+
setOpacities(fadeIndex, fadeVelocity);
|
|
2457
|
+
}
|
|
2458
|
+
function settled() {
|
|
2459
|
+
const {
|
|
2460
|
+
target,
|
|
2461
|
+
location
|
|
2462
|
+
} = emblaApi.internalEngine();
|
|
2463
|
+
const diffToTarget = target.get() - location.get();
|
|
2464
|
+
const notReachedTarget = Math.abs(diffToTarget) >= 1;
|
|
2465
|
+
const fadeIndex = getFadeIndex();
|
|
2466
|
+
const noFadeIndex = !isNumber(fadeIndex);
|
|
2467
|
+
fade(emblaApi);
|
|
2468
|
+
if (noFadeIndex || notReachedTarget) return false;
|
|
2469
|
+
return opacities[fadeIndex] > 0.999;
|
|
2470
|
+
}
|
|
2471
|
+
function scrollProgress() {
|
|
2472
|
+
return progress;
|
|
2473
|
+
}
|
|
2474
|
+
const self = {
|
|
2475
|
+
name: 'fade',
|
|
2476
|
+
options: userOptions,
|
|
2477
|
+
init,
|
|
2478
|
+
destroy
|
|
2479
|
+
};
|
|
2480
|
+
return self;
|
|
2481
|
+
}
|
|
2482
|
+
Fade.globalOptions = undefined;
|
|
2483
|
+
|
|
2484
|
+
var alignForLayout = function (layout) {
|
|
2485
|
+
return layout === "full-width" ? "center" : "start";
|
|
2486
|
+
};
|
|
2487
|
+
var MOBILE_MEDIA_QUERY$1 = "(max-width: 767px)";
|
|
2488
|
+
/** Slide state classes. CSS uses them to size the full-width focus mode. */
|
|
2489
|
+
var SLIDE_ACTIVE = "lsg-carousel__slide--active";
|
|
2490
|
+
var SLIDE_PREV = "lsg-carousel__slide--prev";
|
|
2491
|
+
var SLIDE_NEXT = "lsg-carousel__slide--next";
|
|
2492
|
+
/** Media track slides. Also the dot/aria-label source of truth. */
|
|
2493
|
+
var MEDIA_ITEM_SELECTOR = "[data-lsg-carousel-item]";
|
|
2494
|
+
/** Text track slides, one per media slide. */
|
|
2495
|
+
var CONTENT_ITEM_SELECTOR = "[data-lsg-carousel-content-item]";
|
|
2496
|
+
var directChildren = function (container, selector) {
|
|
2497
|
+
return container ? Array.from(container.children).filter(function (el) {
|
|
2498
|
+
return el instanceof HTMLElement && el.matches(selector);
|
|
2499
|
+
}) : [];
|
|
2500
|
+
};
|
|
2263
2501
|
var LsgCarouselController = /** @class */function () {
|
|
2264
2502
|
function LsgCarouselController(viewport, elements, options) {
|
|
2503
|
+
var _a;
|
|
2265
2504
|
if (elements === void 0) {
|
|
2266
2505
|
elements = {};
|
|
2267
2506
|
}
|
|
@@ -2269,8 +2508,10 @@ var LsgCarouselController = /** @class */function () {
|
|
|
2269
2508
|
options = {};
|
|
2270
2509
|
}
|
|
2271
2510
|
var _this = this;
|
|
2272
|
-
var
|
|
2273
|
-
this.
|
|
2511
|
+
var _b, _c, _d, _e, _f, _g, _h, _j;
|
|
2512
|
+
this.media = null;
|
|
2513
|
+
this.content = null;
|
|
2514
|
+
this.syncing = false;
|
|
2274
2515
|
/**
|
|
2275
2516
|
* Embla automatically falls back to non-looping mode when there is not enough
|
|
2276
2517
|
* slide content to create a safe loop (most noticeable with two-up layouts and
|
|
@@ -2278,82 +2519,271 @@ var LsgCarouselController = /** @class */function () {
|
|
|
2278
2519
|
* when there is no native previous snap, jump to the final authored snap.
|
|
2279
2520
|
*/
|
|
2280
2521
|
this.scrollPrev = function () {
|
|
2281
|
-
if (!_this.
|
|
2282
|
-
if (_this.
|
|
2283
|
-
_this.
|
|
2522
|
+
if (!_this.media) return;
|
|
2523
|
+
if (_this.media.canScrollPrev()) {
|
|
2524
|
+
_this.media.scrollPrev();
|
|
2284
2525
|
return;
|
|
2285
2526
|
}
|
|
2286
|
-
var lastSnap = _this.
|
|
2287
|
-
if (lastSnap >= 0) _this.
|
|
2527
|
+
var lastSnap = _this.media.scrollSnapList().length - 1;
|
|
2528
|
+
if (lastSnap >= 0) _this.media.scrollTo(lastSnap);
|
|
2288
2529
|
};
|
|
2289
2530
|
/** See `scrollPrev` for why the explicit wrap fallback is required. */
|
|
2290
2531
|
this.scrollNext = function () {
|
|
2291
|
-
if (!_this.
|
|
2292
|
-
if (_this.
|
|
2293
|
-
_this.
|
|
2532
|
+
if (!_this.media) return;
|
|
2533
|
+
if (_this.media.canScrollNext()) {
|
|
2534
|
+
_this.media.scrollNext();
|
|
2294
2535
|
return;
|
|
2295
2536
|
}
|
|
2296
|
-
if (_this.
|
|
2537
|
+
if (_this.media.scrollSnapList().length > 0) _this.media.scrollTo(0);
|
|
2297
2538
|
};
|
|
2539
|
+
/**
|
|
2540
|
+
* The text track never initiates navigation, but it owns its own resize and
|
|
2541
|
+
* mutation observers. If one instance re-measures without the other, this pulls
|
|
2542
|
+
* the media track back onto the text track's index rather than letting them drift.
|
|
2543
|
+
*/
|
|
2544
|
+
this.handleContentSelect = function () {
|
|
2545
|
+
if (!_this.media || !_this.content || _this.syncing) return;
|
|
2546
|
+
var target = _this.content.selectedScrollSnap();
|
|
2547
|
+
if (_this.media.selectedScrollSnap() === target) return;
|
|
2548
|
+
_this.syncing = true;
|
|
2549
|
+
try {
|
|
2550
|
+
_this.media.scrollTo(target, true);
|
|
2551
|
+
} finally {
|
|
2552
|
+
_this.syncing = false;
|
|
2553
|
+
}
|
|
2554
|
+
};
|
|
2555
|
+
/** Reader-initiated navigation: repaint state, then crossfade the text. */
|
|
2556
|
+
this.handleMediaSelect = function () {
|
|
2557
|
+
_this.syncSelectedState();
|
|
2558
|
+
_this.pushToContent();
|
|
2559
|
+
};
|
|
2560
|
+
/**
|
|
2561
|
+
* Re-measure events (breakpoint flip, resize, authored items added/removed).
|
|
2562
|
+
* The text is realigned with a hard cut because nothing moved for the reader.
|
|
2563
|
+
*/
|
|
2564
|
+
this.handleResync = function () {
|
|
2565
|
+
_this.syncSelectedState();
|
|
2566
|
+
_this.pushToContent(true);
|
|
2567
|
+
};
|
|
2568
|
+
/** Repaints dot/arrow/a11y state from the media index. Never navigates. */
|
|
2298
2569
|
this.syncSelectedState = function () {
|
|
2299
|
-
var _a, _b;
|
|
2300
|
-
var selected = (_b = (_a = _this.
|
|
2570
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2571
|
+
var selected = (_b = (_a = _this.media) === null || _a === void 0 ? void 0 : _a.selectedScrollSnap()) !== null && _b !== void 0 ? _b : 0;
|
|
2572
|
+
var snapCount = (_d = (_c = _this.media) === null || _c === void 0 ? void 0 : _c.scrollSnapList().length) !== null && _d !== void 0 ? _d : 0;
|
|
2301
2573
|
_this.paginationBtns.forEach(function (button, index) {
|
|
2302
2574
|
var active = index === selected;
|
|
2303
2575
|
button.classList.toggle("lsg-carousel__dot--active", active);
|
|
2304
2576
|
button.setAttribute("aria-current", active ? "true" : "false");
|
|
2305
2577
|
});
|
|
2578
|
+
// Cosmetic only. Looping plus the cyclic wrap above mean both arrows always
|
|
2579
|
+
// act, so `disabled`/`aria-disabled` would misreport them to assistive tech.
|
|
2580
|
+
// Themes use these classes to mute the leading/trailing half of the pill.
|
|
2581
|
+
(_e = _this.els.prevBtn) === null || _e === void 0 ? void 0 : _e.classList.toggle("lsg-carousel__arrow--at-start", selected === 0);
|
|
2582
|
+
(_f = _this.els.nextBtn) === null || _f === void 0 ? void 0 : _f.classList.toggle("lsg-carousel__arrow--at-end", snapCount > 0 && selected === snapCount - 1);
|
|
2583
|
+
// Which slide is in focus, and which neighbour sits on each side of it. The
|
|
2584
|
+
// neighbours only wrap when Embla is really looping: with too few slides it
|
|
2585
|
+
// falls back to a plain track (see scrollPrev), where slide 0 has nothing
|
|
2586
|
+
// to its left. `options` is the effective set, after that fallback.
|
|
2587
|
+
var count = _this.mediaSlides.length;
|
|
2588
|
+
var looping = (_h = (_g = _this.media) === null || _g === void 0 ? void 0 : _g.internalEngine().options.loop) !== null && _h !== void 0 ? _h : false;
|
|
2589
|
+
var prev = looping ? (selected - 1 + count) % count : selected - 1;
|
|
2590
|
+
var next = looping ? (selected + 1) % count : selected + 1;
|
|
2591
|
+
_this.mediaSlides.forEach(function (slide, index) {
|
|
2592
|
+
slide.classList.toggle(SLIDE_ACTIVE, index === selected);
|
|
2593
|
+
slide.classList.toggle(SLIDE_PREV, index === prev);
|
|
2594
|
+
slide.classList.toggle(SLIDE_NEXT, index === next);
|
|
2595
|
+
});
|
|
2596
|
+
// The fade plugin only sets opacity and pointer-events, so without this every
|
|
2597
|
+
// faded-out text block keeps its heading in the accessibility tree and its CTA
|
|
2598
|
+
// in the tab order - N copies of the same landmark for a sighted-equivalent
|
|
2599
|
+
// view of one.
|
|
2600
|
+
_this.contentSlides.forEach(function (slide, index) {
|
|
2601
|
+
var active = index === selected;
|
|
2602
|
+
slide.toggleAttribute("inert", !active);
|
|
2603
|
+
if (active) slide.removeAttribute("aria-hidden");else slide.setAttribute("aria-hidden", "true");
|
|
2604
|
+
});
|
|
2306
2605
|
};
|
|
2307
2606
|
this.els = elements;
|
|
2607
|
+
this.mediaViewport = viewport;
|
|
2308
2608
|
this.paginationBtns = elements.paginationBtns ? Array.from(elements.paginationBtns) : [];
|
|
2309
|
-
|
|
2310
|
-
|
|
2609
|
+
var mediaTrack = viewport.firstElementChild;
|
|
2610
|
+
var mediaSlides = directChildren(mediaTrack, MEDIA_ITEM_SELECTOR);
|
|
2611
|
+
this.mediaSlides = mediaSlides;
|
|
2612
|
+
var align = (_b = options.align) !== null && _b !== void 0 ? _b : "start";
|
|
2613
|
+
// Embla resolves `container` as `root.children[0]` and `slides` as its
|
|
2614
|
+
// element children. Passing both explicitly instead makes the instance
|
|
2615
|
+
// immune to AEM injecting its own nodes (e.g. the edit-mode
|
|
2616
|
+
// `div.new.section.aem-Grid-newComponent` drop target) into the track.
|
|
2617
|
+
this.media = EmblaCarousel(viewport, {
|
|
2618
|
+
// `center` loops natively from three items as long as a slide is at least
|
|
2619
|
+
// half the viewport wide: Embla's canLoop() needs the OTHER slides to
|
|
2620
|
+
// cover the viewport. LsgCarousel.scss sizes the full-width slides to
|
|
2621
|
+
// --lsg-carousel-center-basis (50%) for exactly this reason.
|
|
2622
|
+
align: align,
|
|
2311
2623
|
// Every authored media item owns a pagination dot. `trimSnaps` can remove
|
|
2312
2624
|
// the final snap when two-up/peek layouts do not have enough overflow,
|
|
2313
2625
|
// leaving the last authored item only partially reachable. Keep all snaps
|
|
2314
2626
|
// so dot/item indexes stay 1:1 for 2, 3, 4, ... media items.
|
|
2627
|
+
//
|
|
2628
|
+
// This is ALSO load-bearing for the text/media sync: `containSnaps` is
|
|
2629
|
+
// `!loop && !!containScroll`, so with this `false` the snap list is
|
|
2630
|
+
// always `snapsAligned` - one snap per slide, whatever the slide's
|
|
2631
|
+
// flex-basis. That is the only reason a 380px peek track and a 100%-wide
|
|
2632
|
+
// crossfade track can share one index. Reverting this to `trimSnaps`
|
|
2633
|
+
// drops trailing snaps on the media track alone and desyncs the tail.
|
|
2315
2634
|
containScroll: false,
|
|
2316
|
-
direction: (
|
|
2317
|
-
loop: (
|
|
2635
|
+
direction: (_c = options.direction) !== null && _c !== void 0 ? _c : "ltr",
|
|
2636
|
+
loop: (_d = options.loop) !== null && _d !== void 0 ? _d : true,
|
|
2318
2637
|
skipSnaps: false,
|
|
2319
|
-
slidesToScroll: 1
|
|
2638
|
+
slidesToScroll: 1,
|
|
2639
|
+
container: mediaTrack !== null && mediaTrack !== void 0 ? mediaTrack : undefined,
|
|
2640
|
+
slides: mediaSlides.length ? mediaSlides : undefined,
|
|
2641
|
+
// All layouts collapse to the same mobile stack, which is never
|
|
2642
|
+
// mirrored and never centred. Embla restores the selected index when a
|
|
2643
|
+
// breakpoint re-activates, so the flip is not visible to the reader.
|
|
2644
|
+
breakpoints: (_a = {}, _a[MOBILE_MEDIA_QUERY$1] = {
|
|
2645
|
+
direction: "ltr",
|
|
2646
|
+
align: "start"
|
|
2647
|
+
}, _a)
|
|
2320
2648
|
});
|
|
2649
|
+
var contentViewport = (_e = elements.contentViewport) !== null && _e !== void 0 ? _e : null;
|
|
2650
|
+
var contentTrack = contentViewport === null || contentViewport === void 0 ? void 0 : contentViewport.firstElementChild;
|
|
2651
|
+
this.contentSlides = directChildren(contentTrack, CONTENT_ITEM_SELECTOR);
|
|
2652
|
+
// Unequal counts are the one remaining way the two tracks can desync, and a
|
|
2653
|
+
// text block silently paired with the wrong image is worse than no text
|
|
2654
|
+
// animation at all. Degrade to media-only rather than risk it.
|
|
2655
|
+
var countsMatch = mediaSlides.length > 0 && this.contentSlides.length === mediaSlides.length;
|
|
2656
|
+
if (contentViewport && contentTrack && countsMatch) {
|
|
2657
|
+
this.content = EmblaCarousel(contentViewport, {
|
|
2658
|
+
align: "start",
|
|
2659
|
+
// Must match the media track's snap arithmetic - see above.
|
|
2660
|
+
containScroll: false,
|
|
2661
|
+
// The text crossfades in place, so there is nothing to mirror.
|
|
2662
|
+
direction: "ltr",
|
|
2663
|
+
// Inert on a fade instance: the plugin calls `disableScroll()`, which
|
|
2664
|
+
// deactivates the translate and every loop point. Set for config
|
|
2665
|
+
// symmetry with the media track, not for behaviour.
|
|
2666
|
+
loop: (_f = options.loop) !== null && _f !== void 0 ? _f : true,
|
|
2667
|
+
skipSnaps: false,
|
|
2668
|
+
slidesToScroll: 1,
|
|
2669
|
+
// The reader drags the media, never the text. Without this the text
|
|
2670
|
+
// track would fight the media track for the same pointer.
|
|
2671
|
+
watchDrag: false,
|
|
2672
|
+
container: contentTrack,
|
|
2673
|
+
slides: this.contentSlides
|
|
2674
|
+
}, [Fade()]);
|
|
2675
|
+
}
|
|
2321
2676
|
this.paginationHandlers = this.paginationBtns.map(function (_, index) {
|
|
2322
2677
|
return function () {
|
|
2323
2678
|
var _a;
|
|
2324
|
-
(_a = _this.
|
|
2679
|
+
(_a = _this.media) === null || _a === void 0 ? void 0 : _a.scrollTo(index);
|
|
2325
2680
|
};
|
|
2326
2681
|
});
|
|
2327
|
-
|
|
2328
|
-
|
|
2682
|
+
// Focus mode: clicking a peeking neighbour centres it instead of reaching the
|
|
2683
|
+
// media inside, so a half-hidden video cannot start playing off-centre.
|
|
2684
|
+
// Capture phase, and Embla's own capture listener on the viewport runs first
|
|
2685
|
+
// and swallows the click that ends a drag, so only real clicks get here.
|
|
2686
|
+
this.slideClickHandlers = align === "center" ? mediaSlides.map(function (_, index) {
|
|
2687
|
+
return function (event) {
|
|
2688
|
+
if (!_this.media || _this.media.selectedScrollSnap() === index) return;
|
|
2689
|
+
event.preventDefault();
|
|
2690
|
+
event.stopPropagation();
|
|
2691
|
+
_this.media.scrollTo(index);
|
|
2692
|
+
};
|
|
2693
|
+
}) : [];
|
|
2694
|
+
(_g = this.els.prevBtn) === null || _g === void 0 ? void 0 : _g.addEventListener("click", this.scrollPrev);
|
|
2695
|
+
(_h = this.els.nextBtn) === null || _h === void 0 ? void 0 : _h.addEventListener("click", this.scrollNext);
|
|
2329
2696
|
this.paginationBtns.forEach(function (button, index) {
|
|
2330
2697
|
button.addEventListener("click", _this.paginationHandlers[index]);
|
|
2331
2698
|
});
|
|
2332
|
-
this.
|
|
2333
|
-
|
|
2334
|
-
|
|
2699
|
+
this.slideClickHandlers.forEach(function (handler, index) {
|
|
2700
|
+
mediaSlides[index].addEventListener("click", handler, true);
|
|
2701
|
+
});
|
|
2702
|
+
this.media.on("select", this.handleMediaSelect);
|
|
2703
|
+
this.media.on("reInit", this.handleResync);
|
|
2704
|
+
this.media.on("slidesChanged", this.handleResync);
|
|
2705
|
+
(_j = this.content) === null || _j === void 0 ? void 0 : _j.on("select", this.handleContentSelect);
|
|
2706
|
+
// Initial alignment is a hard cut - there is nothing to crossfade from.
|
|
2707
|
+
this.handleResync();
|
|
2335
2708
|
}
|
|
2709
|
+
/**
|
|
2710
|
+
* Drive the text track from the media index.
|
|
2711
|
+
*
|
|
2712
|
+
* `jump` skips the crossfade (Embla sets duration 0, and the fade plugin then
|
|
2713
|
+
* snaps opacity instantly). Use it only for re-measure events, never for
|
|
2714
|
+
* reader-initiated navigation, or the text hard-cuts instead of fading.
|
|
2715
|
+
*/
|
|
2716
|
+
LsgCarouselController.prototype.pushToContent = function (jump) {
|
|
2717
|
+
if (jump === void 0) {
|
|
2718
|
+
jump = false;
|
|
2719
|
+
}
|
|
2720
|
+
if (!this.media || !this.content || this.syncing) return;
|
|
2721
|
+
var target = this.media.selectedScrollSnap();
|
|
2722
|
+
if (this.content.selectedScrollSnap() === target) return;
|
|
2723
|
+
this.syncing = true;
|
|
2724
|
+
try {
|
|
2725
|
+
this.content.scrollTo(target, jump);
|
|
2726
|
+
} finally {
|
|
2727
|
+
this.syncing = false;
|
|
2728
|
+
}
|
|
2729
|
+
};
|
|
2336
2730
|
Object.defineProperty(LsgCarouselController.prototype, "emblaApi", {
|
|
2337
2731
|
get: function () {
|
|
2338
|
-
return this.
|
|
2732
|
+
return this.media;
|
|
2733
|
+
},
|
|
2734
|
+
enumerable: false,
|
|
2735
|
+
configurable: true
|
|
2736
|
+
});
|
|
2737
|
+
Object.defineProperty(LsgCarouselController.prototype, "contentApi", {
|
|
2738
|
+
/** Text track handle. Exposed for the index-parity checks in the test plan. */
|
|
2739
|
+
get: function () {
|
|
2740
|
+
return this.content;
|
|
2339
2741
|
},
|
|
2340
2742
|
enumerable: false,
|
|
2341
2743
|
configurable: true
|
|
2342
2744
|
});
|
|
2343
2745
|
LsgCarouselController.prototype.destroy = function () {
|
|
2344
2746
|
var _this = this;
|
|
2345
|
-
var _a, _b;
|
|
2747
|
+
var _a, _b, _c, _d;
|
|
2346
2748
|
(_a = this.els.prevBtn) === null || _a === void 0 ? void 0 : _a.removeEventListener("click", this.scrollPrev);
|
|
2347
2749
|
(_b = this.els.nextBtn) === null || _b === void 0 ? void 0 : _b.removeEventListener("click", this.scrollNext);
|
|
2348
2750
|
this.paginationBtns.forEach(function (button, index) {
|
|
2349
2751
|
button.removeEventListener("click", _this.paginationHandlers[index]);
|
|
2350
2752
|
});
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2753
|
+
this.slideClickHandlers.forEach(function (handler, index) {
|
|
2754
|
+
_this.mediaSlides[index].removeEventListener("click", handler, true);
|
|
2755
|
+
});
|
|
2756
|
+
// Content first: its plugin restores the inline opacity/transform it wrote,
|
|
2757
|
+
// and it reads `internalEngine()` while doing so.
|
|
2758
|
+
if (this.content) {
|
|
2759
|
+
this.content.off("select", this.handleContentSelect);
|
|
2760
|
+
this.content.destroy();
|
|
2761
|
+
this.content = null;
|
|
2762
|
+
}
|
|
2763
|
+
if (this.media) {
|
|
2764
|
+
this.media.off("select", this.handleMediaSelect);
|
|
2765
|
+
this.media.off("reInit", this.handleResync);
|
|
2766
|
+
this.media.off("slidesChanged", this.handleResync);
|
|
2767
|
+
this.media.destroy();
|
|
2768
|
+
this.media = null;
|
|
2356
2769
|
}
|
|
2770
|
+
// Embla restores what Embla wrote. Everything below is ours, and leaving it
|
|
2771
|
+
// behind would make server-rendered markup re-initialise into a stale state.
|
|
2772
|
+
this.paginationBtns.forEach(function (button) {
|
|
2773
|
+
button.classList.remove("lsg-carousel__dot--active");
|
|
2774
|
+
button.removeAttribute("aria-current");
|
|
2775
|
+
});
|
|
2776
|
+
(_c = this.els.prevBtn) === null || _c === void 0 ? void 0 : _c.classList.remove("lsg-carousel__arrow--at-start");
|
|
2777
|
+
(_d = this.els.nextBtn) === null || _d === void 0 ? void 0 : _d.classList.remove("lsg-carousel__arrow--at-end");
|
|
2778
|
+
// SLIDE_ACTIVE stays off too: the server/React markup puts it on slide 0,
|
|
2779
|
+
// so re-initialising adds it back there.
|
|
2780
|
+
this.mediaSlides.forEach(function (slide) {
|
|
2781
|
+
slide.classList.remove(SLIDE_ACTIVE, SLIDE_PREV, SLIDE_NEXT);
|
|
2782
|
+
});
|
|
2783
|
+
this.contentSlides.forEach(function (slide) {
|
|
2784
|
+
slide.removeAttribute("inert");
|
|
2785
|
+
slide.removeAttribute("aria-hidden");
|
|
2786
|
+
});
|
|
2357
2787
|
};
|
|
2358
2788
|
return LsgCarouselController;
|
|
2359
2789
|
}();
|
|
@@ -2365,24 +2795,28 @@ var mediaTypeFor = function (item) {
|
|
|
2365
2795
|
var directionForLayout = function (layout) {
|
|
2366
2796
|
return layout === "media-left" ? "rtl" : "ltr";
|
|
2367
2797
|
};
|
|
2798
|
+
var hasText = function (item) {
|
|
2799
|
+
return Boolean(item.preTitle || item.heading || item.body || item.cta);
|
|
2800
|
+
};
|
|
2368
2801
|
var LsgCarousel = function (_a) {
|
|
2369
|
-
var _b
|
|
2370
|
-
|
|
2802
|
+
var _b = _a.items,
|
|
2803
|
+
items = _b === void 0 ? [] : _b,
|
|
2804
|
+
_c = _a.layout,
|
|
2805
|
+
layout = _c === void 0 ? "media-right" : _c,
|
|
2806
|
+
background = _a.background,
|
|
2807
|
+
accent = _a.accent,
|
|
2808
|
+
_d = _a.headingTag,
|
|
2809
|
+
headingTag = _d === void 0 ? "h2" : _d,
|
|
2810
|
+
_e = _a.ariaLabel,
|
|
2811
|
+
ariaLabel = _e === void 0 ? "Media carousel" : _e,
|
|
2812
|
+
_f = _a.className,
|
|
2813
|
+
className = _f === void 0 ? "" : _f,
|
|
2814
|
+
heading = _a.heading,
|
|
2371
2815
|
preTitle = _a.preTitle,
|
|
2372
2816
|
body = _a.body,
|
|
2373
|
-
cta = _a.cta
|
|
2374
|
-
_c = _a.items,
|
|
2375
|
-
items = _c === void 0 ? [] : _c,
|
|
2376
|
-
_d = _a.layout,
|
|
2377
|
-
layout = _d === void 0 ? "media-right" : _d,
|
|
2378
|
-
_e = _a.headingTag,
|
|
2379
|
-
headingTag = _e === void 0 ? "h2" : _e,
|
|
2380
|
-
_f = _a.ariaLabel,
|
|
2381
|
-
ariaLabel = _f === void 0 ? "Media carousel" : _f,
|
|
2382
|
-
_g = _a.className,
|
|
2383
|
-
className = _g === void 0 ? "" : _g;
|
|
2384
|
-
var rootRef = useRef(null);
|
|
2817
|
+
cta = _a.cta;
|
|
2385
2818
|
var viewportRef = useRef(null);
|
|
2819
|
+
var contentViewportRef = useRef(null);
|
|
2386
2820
|
var prevBtnRef = useRef(null);
|
|
2387
2821
|
var nextBtnRef = useRef(null);
|
|
2388
2822
|
var dotsRef = useRef(null);
|
|
@@ -2390,71 +2824,109 @@ var LsgCarousel = function (_a) {
|
|
|
2390
2824
|
var HeadingTag = headingTag;
|
|
2391
2825
|
var isCarousel = items.length > 1;
|
|
2392
2826
|
var carouselDirection = directionForLayout(layout);
|
|
2827
|
+
var carouselAlign = alignForLayout(layout);
|
|
2828
|
+
// Legacy single-content-block callers passed the text alongside `items`. Fold
|
|
2829
|
+
// it onto the first item so their carousel still renders its copy.
|
|
2830
|
+
var resolvedItems = useMemo(function () {
|
|
2831
|
+
var legacy = {
|
|
2832
|
+
preTitle: preTitle,
|
|
2833
|
+
heading: heading,
|
|
2834
|
+
body: body,
|
|
2835
|
+
cta: cta
|
|
2836
|
+
};
|
|
2837
|
+
var hasLegacy = Boolean(legacy.preTitle || legacy.heading || legacy.body || legacy.cta);
|
|
2838
|
+
if (!hasLegacy || !items.length || hasText(items[0])) return items;
|
|
2839
|
+
return items.map(function (item, index) {
|
|
2840
|
+
return index === 0 ? __assign(__assign({}, legacy), item) : item;
|
|
2841
|
+
});
|
|
2842
|
+
}, [items, preTitle, heading, body, cta]);
|
|
2393
2843
|
useEffect(function () {
|
|
2394
2844
|
var _a, _b;
|
|
2395
2845
|
if (!viewportRef.current || !isCarousel) return;
|
|
2396
2846
|
controllerRef.current = new LsgCarouselController(viewportRef.current, {
|
|
2397
2847
|
prevBtn: prevBtnRef.current,
|
|
2398
2848
|
nextBtn: nextBtnRef.current,
|
|
2399
|
-
paginationBtns: (_b = (_a = dotsRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll("[data-lsg-carousel-dot]")) !== null && _b !== void 0 ? _b : []
|
|
2849
|
+
paginationBtns: (_b = (_a = dotsRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll("[data-lsg-carousel-dot]")) !== null && _b !== void 0 ? _b : [],
|
|
2850
|
+
contentViewport: contentViewportRef.current
|
|
2400
2851
|
}, {
|
|
2401
2852
|
loop: true,
|
|
2402
|
-
direction: carouselDirection
|
|
2853
|
+
direction: carouselDirection,
|
|
2854
|
+
align: carouselAlign
|
|
2403
2855
|
});
|
|
2404
2856
|
return function () {
|
|
2405
2857
|
var _a;
|
|
2406
2858
|
(_a = controllerRef.current) === null || _a === void 0 ? void 0 : _a.destroy();
|
|
2407
2859
|
controllerRef.current = null;
|
|
2408
2860
|
};
|
|
2409
|
-
}, [carouselDirection, isCarousel,
|
|
2410
|
-
var rootClasses = ["lsg-carousel", "lsg-carousel--".concat(layout),
|
|
2861
|
+
}, [carouselAlign, carouselDirection, isCarousel, resolvedItems.length]);
|
|
2862
|
+
var rootClasses = ["lsg-carousel", "lsg-carousel--".concat(layout),
|
|
2863
|
+
// In AEM this class arrives on the decoration div instead; the SCSS only
|
|
2864
|
+
// sets inherited custom properties, so either position works.
|
|
2865
|
+
background ? "lsg-carousel--bg-".concat(background) : "", accent ? "lsg-carousel--accent-".concat(accent) : "", className].filter(Boolean).join(" ");
|
|
2866
|
+
var keyFor = function (item, index) {
|
|
2867
|
+
var _a, _b, _c;
|
|
2868
|
+
return (_a = item.id) !== null && _a !== void 0 ? _a : "".concat(mediaTypeFor(item), "-").concat((_c = (_b = item.imageUrl) !== null && _b !== void 0 ? _b : item.videoUrl) !== null && _c !== void 0 ? _c : index, "-").concat(index);
|
|
2869
|
+
};
|
|
2411
2870
|
return /*#__PURE__*/React.createElement("section", {
|
|
2412
|
-
ref: rootRef,
|
|
2413
2871
|
className: rootClasses,
|
|
2414
2872
|
"data-lsg-is": "carousel",
|
|
2415
2873
|
"data-lsg-carousel-layout": layout,
|
|
2416
2874
|
"data-lsg-carousel-direction": carouselDirection,
|
|
2417
|
-
"data-lsg-carousel-count":
|
|
2875
|
+
"data-lsg-carousel-count": resolvedItems.length,
|
|
2418
2876
|
"aria-label": ariaLabel
|
|
2419
2877
|
}, /*#__PURE__*/React.createElement("div", {
|
|
2420
2878
|
className: "lsg-carousel__shell"
|
|
2421
2879
|
}, /*#__PURE__*/React.createElement("div", {
|
|
2422
|
-
className: "lsg-carousel__content"
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
}, /*#__PURE__*/React.createElement("
|
|
2426
|
-
className: "lsg-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2880
|
+
className: "lsg-carousel__content",
|
|
2881
|
+
ref: contentViewportRef,
|
|
2882
|
+
"data-lsg-carousel-content-viewport": true
|
|
2883
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
2884
|
+
className: "lsg-carousel__content-track"
|
|
2885
|
+
}, resolvedItems.map(function (item, index) {
|
|
2886
|
+
var _a;
|
|
2887
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
2888
|
+
key: keyFor(item, index),
|
|
2889
|
+
className: "lsg-carousel__content-slide",
|
|
2890
|
+
"data-lsg-carousel-content-item": true
|
|
2891
|
+
}, item.preTitle && /*#__PURE__*/React.createElement("div", {
|
|
2892
|
+
className: "lsg-carousel__pre-title"
|
|
2893
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
2894
|
+
className: "lsg-carousel__pre-title-marker",
|
|
2895
|
+
"aria-hidden": "true"
|
|
2896
|
+
}), /*#__PURE__*/React.createElement("span", null, item.preTitle)), item.heading && /*#__PURE__*/React.createElement(HeadingTag, {
|
|
2897
|
+
className: "lsg-carousel__heading"
|
|
2898
|
+
}, item.heading), item.body && /*#__PURE__*/React.createElement("p", {
|
|
2899
|
+
className: "lsg-carousel__body"
|
|
2900
|
+
}, item.body), item.cta && /*#__PURE__*/React.createElement("div", {
|
|
2901
|
+
className: "lsg-carousel__actions"
|
|
2902
|
+
}, /*#__PURE__*/React.createElement(LsgButton, {
|
|
2903
|
+
className: "lsg-carousel__cta",
|
|
2904
|
+
href: item.cta.href,
|
|
2905
|
+
external: item.cta.external,
|
|
2906
|
+
variant: (_a = item.cta.variant) !== null && _a !== void 0 ? _a : "primary",
|
|
2907
|
+
onClick: item.cta.onClick
|
|
2908
|
+
}, item.cta.label)));
|
|
2909
|
+
}))), /*#__PURE__*/React.createElement("div", {
|
|
2441
2910
|
className: "lsg-carousel__media-column"
|
|
2442
2911
|
}, /*#__PURE__*/React.createElement("div", {
|
|
2443
2912
|
className: "lsg-carousel__viewport",
|
|
2444
2913
|
ref: viewportRef,
|
|
2445
|
-
dir: carouselDirection
|
|
2914
|
+
dir: carouselDirection,
|
|
2915
|
+
"data-lsg-carousel-media-viewport": true
|
|
2446
2916
|
}, /*#__PURE__*/React.createElement("div", {
|
|
2447
2917
|
className: "lsg-carousel__track",
|
|
2448
2918
|
role: "list"
|
|
2449
|
-
},
|
|
2450
|
-
var _a, _b, _c, _d
|
|
2919
|
+
}, resolvedItems.map(function (item, index) {
|
|
2920
|
+
var _a, _b, _c, _d;
|
|
2451
2921
|
var type = mediaTypeFor(item);
|
|
2452
|
-
var key = (_a = item.id) !== null && _a !== void 0 ? _a : "".concat(type, "-").concat((_c = (_b = item.imageUrl) !== null && _b !== void 0 ? _b : item.videoUrl) !== null && _c !== void 0 ? _c : index, "-").concat(index);
|
|
2453
2922
|
return /*#__PURE__*/React.createElement("article", {
|
|
2454
|
-
key:
|
|
2455
|
-
|
|
2923
|
+
key: keyFor(item, index)
|
|
2924
|
+
// Slide 0 starts active, as the first dot does, so the
|
|
2925
|
+
// full-width focus mode is not all-shrunk before JS runs.
|
|
2926
|
+
,
|
|
2927
|
+
className: "lsg-carousel__slide".concat(index === 0 ? " lsg-carousel__slide--active" : ""),
|
|
2456
2928
|
role: "listitem",
|
|
2457
|
-
"aria-label": "Slide ".concat(index + 1, " of ").concat(
|
|
2929
|
+
"aria-label": "Slide ".concat(index + 1, " of ").concat(resolvedItems.length),
|
|
2458
2930
|
"data-lsg-carousel-item": true
|
|
2459
2931
|
}, /*#__PURE__*/React.createElement("div", {
|
|
2460
2932
|
className: "lsg-carousel__media"
|
|
@@ -2462,10 +2934,10 @@ var LsgCarousel = function (_a) {
|
|
|
2462
2934
|
videoUrl: item.videoUrl,
|
|
2463
2935
|
imageUrl: item.videoPoster,
|
|
2464
2936
|
imageAlt: item.imageAlt,
|
|
2465
|
-
controls: (
|
|
2466
|
-
autoplay: (
|
|
2467
|
-
muted: (
|
|
2468
|
-
loop: (
|
|
2937
|
+
controls: (_a = item.videoControls) !== null && _a !== void 0 ? _a : true,
|
|
2938
|
+
autoplay: (_b = item.videoAutoPlay) !== null && _b !== void 0 ? _b : false,
|
|
2939
|
+
muted: (_c = item.videoMuted) !== null && _c !== void 0 ? _c : true,
|
|
2940
|
+
loop: (_d = item.videoLoop) !== null && _d !== void 0 ? _d : false,
|
|
2469
2941
|
displayMode: "content",
|
|
2470
2942
|
showTags: false,
|
|
2471
2943
|
className: "lsg-carousel__video-component"
|
|
@@ -2480,8 +2952,10 @@ var LsgCarousel = function (_a) {
|
|
|
2480
2952
|
className: "lsg-carousel__media-label"
|
|
2481
2953
|
}, item.label)));
|
|
2482
2954
|
}))), isCarousel && /*#__PURE__*/React.createElement("div", {
|
|
2483
|
-
className: "lsg-
|
|
2955
|
+
className: "lsg-carousel__controls",
|
|
2484
2956
|
"aria-label": "Carousel navigation"
|
|
2957
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
2958
|
+
className: "lsg-carousel__nav"
|
|
2485
2959
|
}, /*#__PURE__*/React.createElement("button", {
|
|
2486
2960
|
ref: prevBtnRef,
|
|
2487
2961
|
className: "lsg-carousel__arrow lsg-carousel__arrow--prev",
|
|
@@ -2491,10 +2965,19 @@ var LsgCarousel = function (_a) {
|
|
|
2491
2965
|
}, /*#__PURE__*/React.createElement("span", {
|
|
2492
2966
|
className: "lsg-carousel__arrow-icon",
|
|
2493
2967
|
"aria-hidden": "true"
|
|
2494
|
-
})), /*#__PURE__*/React.createElement("
|
|
2968
|
+
})), /*#__PURE__*/React.createElement("button", {
|
|
2969
|
+
ref: nextBtnRef,
|
|
2970
|
+
className: "lsg-carousel__arrow lsg-carousel__arrow--next",
|
|
2971
|
+
type: "button",
|
|
2972
|
+
"aria-label": "Next slide",
|
|
2973
|
+
"data-lsg-carousel-next": true
|
|
2974
|
+
}, /*#__PURE__*/React.createElement("span", {
|
|
2975
|
+
className: "lsg-carousel__arrow-icon",
|
|
2976
|
+
"aria-hidden": "true"
|
|
2977
|
+
}))), /*#__PURE__*/React.createElement("div", {
|
|
2495
2978
|
className: "lsg-carousel__pagination",
|
|
2496
2979
|
ref: dotsRef
|
|
2497
|
-
},
|
|
2980
|
+
}, resolvedItems.map(function (item, index) {
|
|
2498
2981
|
var _a;
|
|
2499
2982
|
return /*#__PURE__*/React.createElement("button", {
|
|
2500
2983
|
key: (_a = item.id) !== null && _a !== void 0 ? _a : "dot-".concat(index),
|
|
@@ -2504,15 +2987,6 @@ var LsgCarousel = function (_a) {
|
|
|
2504
2987
|
"aria-current": index === 0 ? "true" : "false",
|
|
2505
2988
|
"data-lsg-carousel-dot": true
|
|
2506
2989
|
});
|
|
2507
|
-
})), /*#__PURE__*/React.createElement("button", {
|
|
2508
|
-
ref: nextBtnRef,
|
|
2509
|
-
className: "lsg-carousel__arrow lsg-carousel__arrow--next",
|
|
2510
|
-
type: "button",
|
|
2511
|
-
"aria-label": "Next slide",
|
|
2512
|
-
"data-lsg-carousel-next": true
|
|
2513
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
2514
|
-
className: "lsg-carousel__arrow-icon",
|
|
2515
|
-
"aria-hidden": "true"
|
|
2516
2990
|
}))))));
|
|
2517
2991
|
};
|
|
2518
2992
|
|
|
@@ -4225,227 +4699,6 @@ var LsgFooter = function (_a) {
|
|
|
4225
4699
|
}))))), bottomTopBar, bottomBar);
|
|
4226
4700
|
};
|
|
4227
4701
|
|
|
4228
|
-
function clampNumber(number, min, max) {
|
|
4229
|
-
return Math.min(Math.max(number, min), max);
|
|
4230
|
-
}
|
|
4231
|
-
function isNumber(value) {
|
|
4232
|
-
return typeof value === 'number' && !isNaN(value);
|
|
4233
|
-
}
|
|
4234
|
-
function Fade(userOptions = {}) {
|
|
4235
|
-
const fullOpacity = 1;
|
|
4236
|
-
const noOpacity = 0;
|
|
4237
|
-
const fadeFriction = 0.68;
|
|
4238
|
-
let emblaApi;
|
|
4239
|
-
let opacities = [];
|
|
4240
|
-
let fadeToNextDistance;
|
|
4241
|
-
let distanceFromPointerDown = 0;
|
|
4242
|
-
let fadeVelocity = 0;
|
|
4243
|
-
let progress = 0;
|
|
4244
|
-
let shouldFadePair = false;
|
|
4245
|
-
let defaultSettledBehaviour;
|
|
4246
|
-
let defaultProgressBehaviour;
|
|
4247
|
-
function init(emblaApiInstance) {
|
|
4248
|
-
emblaApi = emblaApiInstance;
|
|
4249
|
-
const selectedSnap = emblaApi.selectedScrollSnap();
|
|
4250
|
-
const {
|
|
4251
|
-
scrollBody,
|
|
4252
|
-
containerRect,
|
|
4253
|
-
axis
|
|
4254
|
-
} = emblaApi.internalEngine();
|
|
4255
|
-
const containerSize = axis.measureSize(containerRect);
|
|
4256
|
-
fadeToNextDistance = clampNumber(containerSize * 0.75, 200, 500);
|
|
4257
|
-
shouldFadePair = false;
|
|
4258
|
-
opacities = emblaApi.scrollSnapList().map((_, index) => index === selectedSnap ? fullOpacity : noOpacity);
|
|
4259
|
-
defaultSettledBehaviour = scrollBody.settled;
|
|
4260
|
-
defaultProgressBehaviour = emblaApi.scrollProgress;
|
|
4261
|
-
scrollBody.settled = settled;
|
|
4262
|
-
emblaApi.scrollProgress = scrollProgress;
|
|
4263
|
-
emblaApi.on('select', select).on('slideFocus', fadeToSelectedSnapInstantly).on('pointerDown', pointerDown).on('pointerUp', pointerUp);
|
|
4264
|
-
disableScroll();
|
|
4265
|
-
fadeToSelectedSnapInstantly();
|
|
4266
|
-
}
|
|
4267
|
-
function destroy() {
|
|
4268
|
-
const {
|
|
4269
|
-
scrollBody
|
|
4270
|
-
} = emblaApi.internalEngine();
|
|
4271
|
-
scrollBody.settled = defaultSettledBehaviour;
|
|
4272
|
-
emblaApi.scrollProgress = defaultProgressBehaviour;
|
|
4273
|
-
emblaApi.off('select', select).off('slideFocus', fadeToSelectedSnapInstantly).off('pointerDown', pointerDown).off('pointerUp', pointerUp);
|
|
4274
|
-
emblaApi.slideNodes().forEach(slideNode => {
|
|
4275
|
-
const slideStyle = slideNode.style;
|
|
4276
|
-
slideStyle.opacity = '';
|
|
4277
|
-
slideStyle.transform = '';
|
|
4278
|
-
slideStyle.pointerEvents = '';
|
|
4279
|
-
if (!slideNode.getAttribute('style')) slideNode.removeAttribute('style');
|
|
4280
|
-
});
|
|
4281
|
-
}
|
|
4282
|
-
function fadeToSelectedSnapInstantly() {
|
|
4283
|
-
const selectedSnap = emblaApi.selectedScrollSnap();
|
|
4284
|
-
setOpacities(selectedSnap, fullOpacity);
|
|
4285
|
-
}
|
|
4286
|
-
function pointerUp() {
|
|
4287
|
-
shouldFadePair = false;
|
|
4288
|
-
}
|
|
4289
|
-
function pointerDown() {
|
|
4290
|
-
shouldFadePair = false;
|
|
4291
|
-
distanceFromPointerDown = 0;
|
|
4292
|
-
fadeVelocity = 0;
|
|
4293
|
-
}
|
|
4294
|
-
function select() {
|
|
4295
|
-
const duration = emblaApi.internalEngine().scrollBody.duration();
|
|
4296
|
-
fadeVelocity = duration ? 0 : fullOpacity;
|
|
4297
|
-
shouldFadePair = true;
|
|
4298
|
-
if (!duration) fadeToSelectedSnapInstantly();
|
|
4299
|
-
}
|
|
4300
|
-
function getSlideTransform(position) {
|
|
4301
|
-
const {
|
|
4302
|
-
axis
|
|
4303
|
-
} = emblaApi.internalEngine();
|
|
4304
|
-
const translateAxis = axis.scroll.toUpperCase();
|
|
4305
|
-
return `translate${translateAxis}(${axis.direction(position)}px)`;
|
|
4306
|
-
}
|
|
4307
|
-
function disableScroll() {
|
|
4308
|
-
const {
|
|
4309
|
-
translate,
|
|
4310
|
-
slideLooper
|
|
4311
|
-
} = emblaApi.internalEngine();
|
|
4312
|
-
translate.clear();
|
|
4313
|
-
translate.toggleActive(false);
|
|
4314
|
-
slideLooper.loopPoints.forEach(({
|
|
4315
|
-
translate
|
|
4316
|
-
}) => {
|
|
4317
|
-
translate.clear();
|
|
4318
|
-
translate.toggleActive(false);
|
|
4319
|
-
});
|
|
4320
|
-
}
|
|
4321
|
-
function lockExcessiveScroll(fadeIndex) {
|
|
4322
|
-
const {
|
|
4323
|
-
scrollSnaps,
|
|
4324
|
-
location,
|
|
4325
|
-
target
|
|
4326
|
-
} = emblaApi.internalEngine();
|
|
4327
|
-
if (!isNumber(fadeIndex) || opacities[fadeIndex] < 0.5) return;
|
|
4328
|
-
location.set(scrollSnaps[fadeIndex]);
|
|
4329
|
-
target.set(location);
|
|
4330
|
-
}
|
|
4331
|
-
function setOpacities(fadeIndex, velocity) {
|
|
4332
|
-
const scrollSnaps = emblaApi.scrollSnapList();
|
|
4333
|
-
scrollSnaps.forEach((_, indexA) => {
|
|
4334
|
-
const absVelocity = Math.abs(velocity);
|
|
4335
|
-
const currentOpacity = opacities[indexA];
|
|
4336
|
-
const isFadeIndex = indexA === fadeIndex;
|
|
4337
|
-
const nextOpacity = isFadeIndex ? currentOpacity + absVelocity : currentOpacity - absVelocity;
|
|
4338
|
-
const clampedOpacity = clampNumber(nextOpacity, noOpacity, fullOpacity);
|
|
4339
|
-
opacities[indexA] = clampedOpacity;
|
|
4340
|
-
const fadePair = isFadeIndex && shouldFadePair;
|
|
4341
|
-
const indexB = emblaApi.previousScrollSnap();
|
|
4342
|
-
if (fadePair) opacities[indexB] = 1 - clampedOpacity;
|
|
4343
|
-
if (isFadeIndex) setProgress(fadeIndex, clampedOpacity);
|
|
4344
|
-
setOpacity(indexA);
|
|
4345
|
-
});
|
|
4346
|
-
}
|
|
4347
|
-
function setOpacity(index) {
|
|
4348
|
-
const slidesInSnap = emblaApi.internalEngine().slideRegistry[index];
|
|
4349
|
-
const {
|
|
4350
|
-
scrollSnaps,
|
|
4351
|
-
containerRect
|
|
4352
|
-
} = emblaApi.internalEngine();
|
|
4353
|
-
const opacity = opacities[index];
|
|
4354
|
-
slidesInSnap.forEach(slideIndex => {
|
|
4355
|
-
const slideStyle = emblaApi.slideNodes()[slideIndex].style;
|
|
4356
|
-
const roundedOpacity = parseFloat(opacity.toFixed(2));
|
|
4357
|
-
const hasOpacity = roundedOpacity > noOpacity;
|
|
4358
|
-
const position = hasOpacity ? scrollSnaps[index] : containerRect.width + 2;
|
|
4359
|
-
const transform = getSlideTransform(position);
|
|
4360
|
-
if (hasOpacity) slideStyle.transform = transform;
|
|
4361
|
-
slideStyle.opacity = roundedOpacity.toString();
|
|
4362
|
-
slideStyle.pointerEvents = opacity > 0.5 ? 'auto' : 'none';
|
|
4363
|
-
if (!hasOpacity) slideStyle.transform = transform;
|
|
4364
|
-
});
|
|
4365
|
-
}
|
|
4366
|
-
function setProgress(fadeIndex, opacity) {
|
|
4367
|
-
const {
|
|
4368
|
-
index,
|
|
4369
|
-
dragHandler,
|
|
4370
|
-
scrollSnaps
|
|
4371
|
-
} = emblaApi.internalEngine();
|
|
4372
|
-
const pointerDown = dragHandler.pointerDown();
|
|
4373
|
-
const snapFraction = 1 / (scrollSnaps.length - 1);
|
|
4374
|
-
let indexA = fadeIndex;
|
|
4375
|
-
let indexB = pointerDown ? emblaApi.selectedScrollSnap() : emblaApi.previousScrollSnap();
|
|
4376
|
-
if (pointerDown && indexA === indexB) {
|
|
4377
|
-
const reverseSign = Math.sign(distanceFromPointerDown) * -1;
|
|
4378
|
-
indexA = indexB;
|
|
4379
|
-
indexB = index.clone().set(indexB).add(reverseSign).get();
|
|
4380
|
-
}
|
|
4381
|
-
const currentPosition = indexB * snapFraction;
|
|
4382
|
-
const diffPosition = (indexA - indexB) * snapFraction;
|
|
4383
|
-
progress = currentPosition + diffPosition * opacity;
|
|
4384
|
-
}
|
|
4385
|
-
function getFadeIndex() {
|
|
4386
|
-
const {
|
|
4387
|
-
dragHandler,
|
|
4388
|
-
index,
|
|
4389
|
-
scrollBody
|
|
4390
|
-
} = emblaApi.internalEngine();
|
|
4391
|
-
const selectedSnap = emblaApi.selectedScrollSnap();
|
|
4392
|
-
if (!dragHandler.pointerDown()) return selectedSnap;
|
|
4393
|
-
const directionSign = Math.sign(scrollBody.velocity());
|
|
4394
|
-
const distanceSign = Math.sign(distanceFromPointerDown);
|
|
4395
|
-
const nextSnap = index.clone().set(selectedSnap).add(directionSign * -1).get();
|
|
4396
|
-
if (!directionSign || !distanceSign) return null;
|
|
4397
|
-
return distanceSign === directionSign ? nextSnap : selectedSnap;
|
|
4398
|
-
}
|
|
4399
|
-
function fade(emblaApi) {
|
|
4400
|
-
const {
|
|
4401
|
-
dragHandler,
|
|
4402
|
-
scrollBody
|
|
4403
|
-
} = emblaApi.internalEngine();
|
|
4404
|
-
const pointerDown = dragHandler.pointerDown();
|
|
4405
|
-
const velocity = scrollBody.velocity();
|
|
4406
|
-
const duration = scrollBody.duration();
|
|
4407
|
-
const fadeIndex = getFadeIndex();
|
|
4408
|
-
const noFadeIndex = !isNumber(fadeIndex);
|
|
4409
|
-
if (pointerDown) {
|
|
4410
|
-
if (!velocity) return;
|
|
4411
|
-
distanceFromPointerDown += velocity;
|
|
4412
|
-
fadeVelocity = Math.abs(velocity / fadeToNextDistance);
|
|
4413
|
-
lockExcessiveScroll(fadeIndex);
|
|
4414
|
-
}
|
|
4415
|
-
if (!pointerDown) {
|
|
4416
|
-
if (!duration || noFadeIndex) return;
|
|
4417
|
-
fadeVelocity += (fullOpacity - opacities[fadeIndex]) / duration;
|
|
4418
|
-
fadeVelocity *= fadeFriction;
|
|
4419
|
-
}
|
|
4420
|
-
if (noFadeIndex) return;
|
|
4421
|
-
setOpacities(fadeIndex, fadeVelocity);
|
|
4422
|
-
}
|
|
4423
|
-
function settled() {
|
|
4424
|
-
const {
|
|
4425
|
-
target,
|
|
4426
|
-
location
|
|
4427
|
-
} = emblaApi.internalEngine();
|
|
4428
|
-
const diffToTarget = target.get() - location.get();
|
|
4429
|
-
const notReachedTarget = Math.abs(diffToTarget) >= 1;
|
|
4430
|
-
const fadeIndex = getFadeIndex();
|
|
4431
|
-
const noFadeIndex = !isNumber(fadeIndex);
|
|
4432
|
-
fade(emblaApi);
|
|
4433
|
-
if (noFadeIndex || notReachedTarget) return false;
|
|
4434
|
-
return opacities[fadeIndex] > 0.999;
|
|
4435
|
-
}
|
|
4436
|
-
function scrollProgress() {
|
|
4437
|
-
return progress;
|
|
4438
|
-
}
|
|
4439
|
-
const self = {
|
|
4440
|
-
name: 'fade',
|
|
4441
|
-
options: userOptions,
|
|
4442
|
-
init,
|
|
4443
|
-
destroy
|
|
4444
|
-
};
|
|
4445
|
-
return self;
|
|
4446
|
-
}
|
|
4447
|
-
Fade.globalOptions = undefined;
|
|
4448
|
-
|
|
4449
4702
|
var LsgHeroController = /** @class */function () {
|
|
4450
4703
|
function LsgHeroController(viewport, elements, options) {
|
|
4451
4704
|
if (elements === void 0) {
|