@brandonsoccer22/gsap-editorial-carousel 0.1.3 → 0.1.4

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/README.md CHANGED
@@ -153,17 +153,22 @@ registerAnimation("split-lines-exit", splitLinesExit);
153
153
 
154
154
  createCarousel("[data-carousel]", {
155
155
  gsap,
156
- transition: { overlap: 0.05 }
156
+ transition: { overlap: 0.05, exitOverlap: 0.05 }
157
157
  });
158
158
  ```
159
159
 
160
+ `transition.exitOverlap` controls how much the enter timeline overlaps the exit timeline; defaults to `transition.overlap`.
161
+
160
162
  ## Data attributes reference
161
163
  - `data-seq="1"` sequence group (integer, default 1)
162
164
  - `data-exit-seq="1"` exit sequence group (integer, defaults to `data-seq`)
163
165
  - `data-dur="0.6"` duration in seconds (default from options)
164
166
  - `data-delay="0"` delay in seconds (default 0)
167
+ - `data-exit-dur="0.6"` exit duration in seconds (defaults to `data-dur`)
168
+ - `data-exit-delay="0"` exit delay in seconds (defaults to `data-delay`)
165
169
  - `data-at="-=0.4"` position offset in seconds for this element within its sequence; supports `+=`/`-=` or a plain number
166
170
  - `data-ease="power2.out"` GSAP ease string
171
+ - `data-exit-ease="power2.out"` exit ease string (defaults to `data-ease`)
167
172
  - `data-exit="fade-in"` explicit exit animation name
168
173
 
169
174
  ## Reduced motion
package/dist/index.cjs CHANGED
@@ -57,6 +57,11 @@ function setSlidesState(slides, activeIndex, activeClass) {
57
57
  slides.forEach((slide, index) => {
58
58
  const isActive = index === activeIndex;
59
59
  slide.setAttribute("aria-hidden", isActive ? "false" : "true");
60
+ if (isActive) {
61
+ slide.removeAttribute("inert");
62
+ } else {
63
+ slide.setAttribute("inert", "");
64
+ }
60
65
  toggleClass(slide, activeClass, isActive);
61
66
  });
62
67
  }
@@ -141,6 +146,7 @@ function ensureDefaultAnimationsRegistered() {
141
146
  },
142
147
  opts.at
143
148
  );
149
+ tl.set(el, { autoAlpha: 0 }, ">");
144
150
  };
145
151
  const fadeUp = ({ el, gsap: gsap3, opts, tl }) => {
146
152
  tl.fromTo(
@@ -168,6 +174,35 @@ function ensureDefaultAnimationsRegistered() {
168
174
  },
169
175
  opts.at
170
176
  );
177
+ tl.set(el, { autoAlpha: 0 }, ">");
178
+ };
179
+ const fadeDown = ({ el, gsap: gsap3, opts, tl }) => {
180
+ tl.fromTo(
181
+ el,
182
+ { autoAlpha: 0, y: -24 },
183
+ {
184
+ autoAlpha: 1,
185
+ y: 0,
186
+ duration: opts.dur,
187
+ delay: opts.delay,
188
+ ease: opts.ease
189
+ },
190
+ opts.at
191
+ );
192
+ };
193
+ fadeDown.reverse = ({ el, gsap: gsap3, opts, tl }) => {
194
+ tl.to(
195
+ el,
196
+ {
197
+ autoAlpha: 0,
198
+ y: 12,
199
+ duration: opts.dur,
200
+ delay: opts.delay,
201
+ ease: opts.ease
202
+ },
203
+ opts.at
204
+ );
205
+ tl.set(el, { autoAlpha: 0 }, ">");
171
206
  };
172
207
  const slideIn = ({ el, gsap: gsap3, opts, tl }) => {
173
208
  tl.fromTo(
@@ -195,16 +230,303 @@ function ensureDefaultAnimationsRegistered() {
195
230
  },
196
231
  opts.at
197
232
  );
233
+ tl.set(el, { autoAlpha: 0 }, ">");
234
+ };
235
+ const fadeOut = ({ el, gsap: gsap3, opts, tl }) => {
236
+ tl.to(
237
+ el,
238
+ {
239
+ autoAlpha: 0,
240
+ duration: opts.dur,
241
+ delay: opts.delay,
242
+ ease: opts.ease
243
+ },
244
+ opts.at
245
+ );
246
+ tl.set(el, { autoAlpha: 0 }, ">");
247
+ };
248
+ fadeOut.reverse = ({ el, gsap: gsap3, opts, tl }) => {
249
+ tl.to(
250
+ el,
251
+ {
252
+ autoAlpha: 1,
253
+ duration: opts.dur,
254
+ delay: opts.delay,
255
+ ease: opts.ease
256
+ },
257
+ opts.at
258
+ );
259
+ };
260
+ const slideOut = ({ el, gsap: gsap3, opts, tl }) => {
261
+ tl.to(
262
+ el,
263
+ {
264
+ autoAlpha: 0,
265
+ x: opts.direction * -24,
266
+ duration: opts.dur,
267
+ delay: opts.delay,
268
+ ease: opts.ease
269
+ },
270
+ opts.at
271
+ );
272
+ tl.set(el, { autoAlpha: 0 }, ">");
273
+ };
274
+ slideOut.reverse = ({ el, gsap: gsap3, opts, tl }) => {
275
+ tl.to(
276
+ el,
277
+ {
278
+ autoAlpha: 1,
279
+ x: 0,
280
+ duration: opts.dur,
281
+ delay: opts.delay,
282
+ ease: opts.ease
283
+ },
284
+ opts.at
285
+ );
198
286
  };
199
287
  registerAnimations({
200
288
  "fade-in": fadeIn,
289
+ "fade-down": fadeDown,
290
+ "fade-down-in": fadeDownIn,
291
+ "fade-down-out": fadeDownOut,
292
+ "fade-out": fadeOut,
201
293
  "fade-up": fadeUp,
202
- "slide-in": slideIn
294
+ "fade-up-in": fadeUpIn,
295
+ "fade-up-out": fadeUpOut,
296
+ "fade-start-in": fadeStartIn,
297
+ "fade-start-out": fadeStartOut,
298
+ "fade-end-in": fadeEndIn,
299
+ "fade-end-out": fadeEndOut,
300
+ "slide-in": slideIn,
301
+ "slide-out": slideOut
203
302
  });
204
303
  }
304
+ var fadeUpIn = ({ el, gsap: gsap3, opts, tl }) => {
305
+ tl.fromTo(
306
+ el,
307
+ { autoAlpha: 0, y: 24 },
308
+ {
309
+ autoAlpha: 1,
310
+ y: 0,
311
+ duration: opts.dur,
312
+ delay: opts.delay,
313
+ ease: opts.ease
314
+ },
315
+ opts.at
316
+ );
317
+ };
318
+ fadeUpIn.reverse = ({ el, gsap: gsap3, opts, tl }) => {
319
+ tl.to(
320
+ el,
321
+ {
322
+ autoAlpha: 0,
323
+ y: -12,
324
+ duration: opts.dur,
325
+ delay: opts.delay,
326
+ ease: opts.ease
327
+ },
328
+ opts.at
329
+ );
330
+ tl.set(el, { autoAlpha: 0 }, ">");
331
+ };
332
+ var fadeUpOut = ({ el, gsap: gsap3, opts, tl }) => {
333
+ tl.to(
334
+ el,
335
+ {
336
+ autoAlpha: 0,
337
+ y: -12,
338
+ duration: opts.dur,
339
+ delay: opts.delay,
340
+ ease: opts.ease
341
+ },
342
+ opts.at
343
+ );
344
+ tl.set(el, { autoAlpha: 0 }, ">");
345
+ };
346
+ fadeUpOut.reverse = ({ el, gsap: gsap3, opts, tl }) => {
347
+ tl.fromTo(
348
+ el,
349
+ { autoAlpha: 0, y: 24 },
350
+ {
351
+ autoAlpha: 1,
352
+ y: 0,
353
+ duration: opts.dur,
354
+ delay: opts.delay,
355
+ ease: opts.ease
356
+ },
357
+ opts.at
358
+ );
359
+ };
360
+ var fadeDownIn = ({ el, gsap: gsap3, opts, tl }) => {
361
+ tl.fromTo(
362
+ el,
363
+ { autoAlpha: 0, y: -24 },
364
+ {
365
+ autoAlpha: 1,
366
+ y: 0,
367
+ duration: opts.dur,
368
+ delay: opts.delay,
369
+ ease: opts.ease
370
+ },
371
+ opts.at
372
+ );
373
+ };
374
+ fadeDownIn.reverse = ({ el, gsap: gsap3, opts, tl }) => {
375
+ tl.to(
376
+ el,
377
+ {
378
+ autoAlpha: 0,
379
+ y: 12,
380
+ duration: opts.dur,
381
+ delay: opts.delay,
382
+ ease: opts.ease
383
+ },
384
+ opts.at
385
+ );
386
+ tl.set(el, { autoAlpha: 0 }, ">");
387
+ };
388
+ var fadeDownOut = ({ el, gsap: gsap3, opts, tl }) => {
389
+ tl.to(
390
+ el,
391
+ {
392
+ autoAlpha: 0,
393
+ y: 12,
394
+ duration: opts.dur,
395
+ delay: opts.delay,
396
+ ease: opts.ease
397
+ },
398
+ opts.at
399
+ );
400
+ tl.set(el, { autoAlpha: 0 }, ">");
401
+ };
402
+ fadeDownOut.reverse = ({ el, gsap: gsap3, opts, tl }) => {
403
+ tl.fromTo(
404
+ el,
405
+ { autoAlpha: 0, y: -24 },
406
+ {
407
+ autoAlpha: 1,
408
+ y: 0,
409
+ duration: opts.dur,
410
+ delay: opts.delay,
411
+ ease: opts.ease
412
+ },
413
+ opts.at
414
+ );
415
+ };
416
+ var fadeStartIn = ({ el, gsap: gsap3, opts, tl }) => {
417
+ tl.fromTo(
418
+ el,
419
+ { autoAlpha: 0, x: -24 },
420
+ {
421
+ autoAlpha: 1,
422
+ x: 0,
423
+ duration: opts.dur,
424
+ delay: opts.delay,
425
+ ease: opts.ease
426
+ },
427
+ opts.at
428
+ );
429
+ };
430
+ fadeStartIn.reverse = ({ el, gsap: gsap3, opts, tl }) => {
431
+ tl.to(
432
+ el,
433
+ {
434
+ autoAlpha: 0,
435
+ x: -12,
436
+ duration: opts.dur,
437
+ delay: opts.delay,
438
+ ease: opts.ease
439
+ },
440
+ opts.at
441
+ );
442
+ tl.set(el, { autoAlpha: 0 }, ">");
443
+ };
444
+ var fadeStartOut = ({ el, gsap: gsap3, opts, tl }) => {
445
+ tl.to(
446
+ el,
447
+ {
448
+ autoAlpha: 0,
449
+ x: -12,
450
+ duration: opts.dur,
451
+ delay: opts.delay,
452
+ ease: opts.ease
453
+ },
454
+ opts.at
455
+ );
456
+ tl.set(el, { autoAlpha: 0 }, ">");
457
+ };
458
+ fadeStartOut.reverse = ({ el, gsap: gsap3, opts, tl }) => {
459
+ tl.fromTo(
460
+ el,
461
+ { autoAlpha: 0, x: -24 },
462
+ {
463
+ autoAlpha: 1,
464
+ x: 0,
465
+ duration: opts.dur,
466
+ delay: opts.delay,
467
+ ease: opts.ease
468
+ },
469
+ opts.at
470
+ );
471
+ };
472
+ var fadeEndIn = ({ el, gsap: gsap3, opts, tl }) => {
473
+ tl.fromTo(
474
+ el,
475
+ { autoAlpha: 0, x: 24 },
476
+ {
477
+ autoAlpha: 1,
478
+ x: 0,
479
+ duration: opts.dur,
480
+ delay: opts.delay,
481
+ ease: opts.ease
482
+ },
483
+ opts.at
484
+ );
485
+ };
486
+ fadeEndIn.reverse = ({ el, gsap: gsap3, opts, tl }) => {
487
+ tl.to(
488
+ el,
489
+ {
490
+ autoAlpha: 0,
491
+ x: 12,
492
+ duration: opts.dur,
493
+ delay: opts.delay,
494
+ ease: opts.ease
495
+ },
496
+ opts.at
497
+ );
498
+ tl.set(el, { autoAlpha: 0 }, ">");
499
+ };
500
+ var fadeEndOut = ({ el, gsap: gsap3, opts, tl }) => {
501
+ tl.to(
502
+ el,
503
+ {
504
+ autoAlpha: 0,
505
+ x: 12,
506
+ duration: opts.dur,
507
+ delay: opts.delay,
508
+ ease: opts.ease
509
+ },
510
+ opts.at
511
+ );
512
+ tl.set(el, { autoAlpha: 0 }, ">");
513
+ };
514
+ fadeEndOut.reverse = ({ el, gsap: gsap3, opts, tl }) => {
515
+ tl.fromTo(
516
+ el,
517
+ { autoAlpha: 0, x: 24 },
518
+ {
519
+ autoAlpha: 1,
520
+ x: 0,
521
+ duration: opts.dur,
522
+ delay: opts.delay,
523
+ ease: opts.ease
524
+ },
525
+ opts.at
526
+ );
527
+ };
205
528
 
206
529
  // src/timeline.ts
207
- var defaultExitDuration = 0.25;
208
530
  function getDataNumber(el, name, fallback) {
209
531
  const value = el.getAttribute(name);
210
532
  if (!value) return fallback;
@@ -238,11 +560,29 @@ function findAnimationName(el) {
238
560
  }
239
561
  return null;
240
562
  }
563
+ function collectExternalControls(slide, options) {
564
+ const root = slide.closest(options.selectors.root);
565
+ if (!root) return [];
566
+ const rootId = root.getAttribute("id");
567
+ const selector = `${options.selectors.prev}, ${options.selectors.next}`;
568
+ let candidates = [];
569
+ if (rootId) {
570
+ const scopedSelector = `${selector}[data-for="${rootId}"]`;
571
+ candidates = Array.from(document.querySelectorAll(scopedSelector));
572
+ if (!candidates.length) {
573
+ candidates = Array.from(root.querySelectorAll(selector));
574
+ }
575
+ } else {
576
+ candidates = Array.from(root.querySelectorAll(selector));
577
+ }
578
+ return candidates.filter((el) => !el.closest(options.selectors.slide));
579
+ }
241
580
  function collectAnimItems(slide, options) {
242
581
  const elements = Array.from(slide.querySelectorAll("[class]"));
582
+ const externalControls = collectExternalControls(slide, options);
243
583
  const items = [];
244
- elements.forEach((el) => {
245
- var _a;
584
+ elements.concat(externalControls).forEach((el) => {
585
+ var _a, _b;
246
586
  const animName = findAnimationName(el);
247
587
  if (!animName) return;
248
588
  const seq = Math.max(1, Math.floor(getDataNumber(el, "data-seq", 1)));
@@ -250,8 +590,11 @@ function collectAnimItems(slide, options) {
250
590
  const dur = getDataNumber(el, "data-dur", options.defaults.dur);
251
591
  const delay = getDataNumber(el, "data-delay", 0);
252
592
  const ease = (_a = getDataString(el, "data-ease")) != null ? _a : options.defaults.ease;
593
+ const exitDur = getDataNumber(el, "data-exit-dur", dur);
594
+ const exitDelay = getDataNumber(el, "data-exit-delay", delay);
595
+ const exitEase = (_b = getDataString(el, "data-exit-ease")) != null ? _b : ease;
253
596
  const at = getDataString(el, "data-at");
254
- items.push({ el, animName, seq, exitSeq, dur, delay, ease, at });
597
+ items.push({ el, animName, seq, exitSeq, dur, delay, ease, exitDur, exitDelay, exitEase, at });
255
598
  });
256
599
  return items;
257
600
  }
@@ -319,16 +662,16 @@ function buildSlideExitTimeline(slide, direction, options, gsapInstance) {
319
662
  const reverseFactory = factory && "reverse" in factory ? factory.reverse : void 0;
320
663
  const offset = (_a = parsePositionOffset(item.at)) != null ? _a : 0;
321
664
  const position = cursor + offset;
322
- let usedDuration = item.dur;
665
+ let usedDuration = item.exitDur;
323
666
  if (exitName && factory) {
324
667
  factory({
325
668
  el: item.el,
326
669
  tl,
327
670
  gsap: gsapInstance,
328
671
  opts: {
329
- dur: item.dur,
330
- delay: item.delay,
331
- ease: item.ease,
672
+ dur: item.exitDur,
673
+ delay: item.exitDelay,
674
+ ease: item.exitEase,
332
675
  direction,
333
676
  at: position
334
677
  }
@@ -339,27 +682,26 @@ function buildSlideExitTimeline(slide, direction, options, gsapInstance) {
339
682
  tl,
340
683
  gsap: gsapInstance,
341
684
  opts: {
342
- dur: item.dur,
343
- delay: item.delay,
344
- ease: item.ease,
685
+ dur: item.exitDur,
686
+ delay: item.exitDelay,
687
+ ease: item.exitEase,
345
688
  direction,
346
689
  at: position
347
690
  }
348
691
  });
349
692
  } else {
350
- usedDuration = Math.min(item.dur, defaultExitDuration);
351
693
  tl.to(
352
694
  item.el,
353
695
  {
354
696
  autoAlpha: 0,
355
697
  duration: usedDuration,
356
- delay: item.delay,
357
- ease: item.ease
698
+ delay: item.exitDelay,
699
+ ease: item.exitEase
358
700
  },
359
701
  position
360
702
  );
361
703
  }
362
- groupMax = Math.max(groupMax, offset + item.delay + usedDuration);
704
+ groupMax = Math.max(groupMax, offset + item.exitDelay + usedDuration);
363
705
  });
364
706
  cursor += Math.max(groupMax, 0);
365
707
  });
@@ -377,7 +719,7 @@ function prefersReducedMotion() {
377
719
  // src/carousel.ts
378
720
  var generatedDotSelector = '[data-carousel-dot="true"]';
379
721
  function createCarousel(rootInput, options = {}) {
380
- var _a, _b, _c, _d, _e, _f, _g;
722
+ var _a, _b, _c, _d;
381
723
  ensureDefaultAnimationsRegistered();
382
724
  const root = resolveRoot(rootInput);
383
725
  const gsapInstance = (_a = options.gsap) != null ? _a : gsap.gsap;
@@ -405,7 +747,7 @@ function createCarousel(rootInput, options = {}) {
405
747
  let currentIndex = normalizeIndex(resolved.initialIndex, slides.length, resolved.loop);
406
748
  let animating = false;
407
749
  setSlidesState(slides, currentIndex, resolved.classNames.activeSlide);
408
- setDotsState(controls.dots, currentIndex, resolved.classNames.activeDot);
750
+ setAllDotsState(currentIndex);
409
751
  const onPrevClick = (event) => {
410
752
  event.preventDefault();
411
753
  prev();
@@ -423,11 +765,15 @@ function createCarousel(rootInput, options = {}) {
423
765
  if (!indexAttr) return;
424
766
  const index = Number.parseInt(indexAttr, 10);
425
767
  if (!Number.isFinite(index)) return;
426
- goTo(index);
768
+ if (animating) return;
769
+ const nextIndex = normalizeIndex(index, slides.length, resolved.loop);
770
+ if (nextIndex === currentIndex) return;
771
+ setAllDotsState(nextIndex);
772
+ goTo(nextIndex);
427
773
  };
428
- (_d = controls.prev) == null ? void 0 : _d.addEventListener("click", onPrevClick);
429
- (_e = controls.next) == null ? void 0 : _e.addEventListener("click", onNextClick);
430
- (_f = controls.dotsContainer) == null ? void 0 : _f.addEventListener("click", onDotsClick);
774
+ controls.prev.forEach((control) => control.addEventListener("click", onPrevClick));
775
+ controls.next.forEach((control) => control.addEventListener("click", onNextClick));
776
+ controls.dotsContainers.forEach((container) => container.addEventListener("click", onDotsClick));
431
777
  const instance = {
432
778
  goTo,
433
779
  next,
@@ -437,23 +783,34 @@ function createCarousel(rootInput, options = {}) {
437
783
  getCount: () => slides.length,
438
784
  isAnimating: () => animating
439
785
  };
440
- (_g = resolved.onInit) == null ? void 0 : _g.call(resolved, instance);
786
+ (_d = resolved.onInit) == null ? void 0 : _d.call(resolved, instance);
441
787
  function disableControls(disabled) {
442
788
  toggleClass(root, resolved.classNames.animatingRoot, disabled);
443
- setDisabled(controls.prev, disabled, resolved.classNames.disabledControl);
444
- setDisabled(controls.next, disabled, resolved.classNames.disabledControl);
445
- if (controls.dotsContainer) {
446
- setAriaDisabled(controls.dotsContainer, disabled);
447
- }
448
- controls.dots.forEach((dot) => {
449
- setAriaDisabled(dot, disabled);
450
- toggleClass(dot, resolved.classNames.disabledControl, disabled);
789
+ controls.prev.forEach((control) => {
790
+ setDisabled(control, disabled, resolved.classNames.disabledControl);
791
+ });
792
+ controls.next.forEach((control) => {
793
+ setDisabled(control, disabled, resolved.classNames.disabledControl);
794
+ });
795
+ controls.dotsContainers.forEach((container) => {
796
+ setAriaDisabled(container, disabled);
797
+ });
798
+ controls.dots.forEach((dotGroup) => {
799
+ dotGroup.forEach((dot) => {
800
+ setAriaDisabled(dot, disabled);
801
+ toggleClass(dot, resolved.classNames.disabledControl, disabled);
802
+ });
803
+ });
804
+ }
805
+ function setAllDotsState(activeIndex) {
806
+ controls.dots.forEach((dotGroup) => {
807
+ setDotsState(dotGroup, activeIndex, resolved.classNames.activeDot);
451
808
  });
452
809
  }
453
810
  function applyActiveState(nextIndex) {
454
811
  currentIndex = nextIndex;
455
812
  setSlidesState(slides, currentIndex, resolved.classNames.activeSlide);
456
- setDotsState(controls.dots, currentIndex, resolved.classNames.activeDot);
813
+ setAllDotsState(currentIndex);
457
814
  }
458
815
  function finalizeTransition(from, to, direction) {
459
816
  var _a2;
@@ -463,7 +820,7 @@ function createCarousel(rootInput, options = {}) {
463
820
  (_a2 = resolved.onAfterChange) == null ? void 0 : _a2.call(resolved, { from, to, direction });
464
821
  }
465
822
  function transitionTo(nextIndex, immediate) {
466
- var _a2;
823
+ var _a2, _b2;
467
824
  if (animating) return;
468
825
  if (nextIndex === currentIndex) return;
469
826
  const from = currentIndex;
@@ -487,7 +844,7 @@ function createCarousel(rootInput, options = {}) {
487
844
  })
488
845
  );
489
846
  state.activeTimeline = master;
490
- const overlap = Math.max(0, resolved.transition.overlap);
847
+ const overlap = Math.max(0, (_b2 = resolved.transition.exitOverlap) != null ? _b2 : resolved.transition.overlap);
491
848
  const enterAt = Math.max(0, exitTl.duration() - overlap);
492
849
  master.add(exitTl, 0);
493
850
  master.add(() => applyActiveState(to), enterAt);
@@ -503,59 +860,73 @@ function createCarousel(rootInput, options = {}) {
503
860
  if (animating) return;
504
861
  const nextIndex = resolveNextIndex(currentIndex, slides.length, resolved.loop);
505
862
  if (nextIndex === currentIndex) return;
863
+ setAllDotsState(nextIndex);
506
864
  transitionTo(nextIndex, opts == null ? void 0 : opts.immediate);
507
865
  }
508
866
  function prev(opts) {
509
867
  if (animating) return;
510
868
  const nextIndex = resolvePrevIndex(currentIndex, slides.length, resolved.loop);
511
869
  if (nextIndex === currentIndex) return;
870
+ setAllDotsState(nextIndex);
512
871
  transitionTo(nextIndex, opts == null ? void 0 : opts.immediate);
513
872
  }
514
873
  function destroy() {
515
- var _a2, _b2, _c2, _d2;
516
- (_a2 = controls.prev) == null ? void 0 : _a2.removeEventListener("click", onPrevClick);
517
- (_b2 = controls.next) == null ? void 0 : _b2.removeEventListener("click", onNextClick);
518
- (_c2 = controls.dotsContainer) == null ? void 0 : _c2.removeEventListener("click", onDotsClick);
519
- (_d2 = state.activeTimeline) == null ? void 0 : _d2.kill();
874
+ var _a2;
875
+ controls.prev.forEach((control) => control.removeEventListener("click", onPrevClick));
876
+ controls.next.forEach((control) => control.removeEventListener("click", onNextClick));
877
+ controls.dotsContainers.forEach((container) => container.removeEventListener("click", onDotsClick));
878
+ (_a2 = state.activeTimeline) == null ? void 0 : _a2.kill();
520
879
  animating = false;
521
880
  ctx.revert();
522
- if (controls.dotsContainer) {
523
- controls.dotsContainer.querySelectorAll(generatedDotSelector).forEach((dot) => {
881
+ controls.dotsContainers.forEach((container) => {
882
+ container.querySelectorAll(generatedDotSelector).forEach((dot) => {
524
883
  dot.remove();
525
884
  });
526
- }
527
- if (controls.dotTemplate) {
528
- controls.dotTemplate.hidden = false;
529
- }
885
+ });
886
+ controls.dotTemplates.forEach((template) => {
887
+ if (template) {
888
+ template.hidden = false;
889
+ }
890
+ });
530
891
  }
531
892
  return instance;
532
893
  }
533
894
  function resolveControls(root, options, slideCount) {
534
895
  const rootId = root.getAttribute("id");
535
- const queryWithFallback = (selector) => {
896
+ const queryAllWithFallback = (selector) => {
536
897
  if (rootId) {
537
- const scoped = document.querySelector(`${selector}[data-for="${rootId}"]`);
538
- if (scoped) return scoped;
898
+ const scoped = Array.from(document.querySelectorAll(`${selector}[data-for="${rootId}"]`));
899
+ if (scoped.length) return scoped;
539
900
  }
540
- return qs(root, selector);
901
+ return qsa(root, selector);
541
902
  };
542
- const prev = queryWithFallback(options.selectors.prev);
543
- const next = queryWithFallback(options.selectors.next);
544
- const dotsContainer = queryWithFallback(options.selectors.dots);
545
- const dotTemplate = dotsContainer ? qs(dotsContainer, options.selectors.dotTemplate) : null;
546
- const dots = dotsContainer ? setupDots(dotsContainer, dotTemplate, options, slideCount) : [];
547
- return { prev, next, dotsContainer, dotTemplate, dots };
903
+ const prev = queryAllWithFallback(options.selectors.prev);
904
+ const next = queryAllWithFallback(options.selectors.next);
905
+ const dotsContainers = queryAllWithFallback(options.selectors.dots);
906
+ const dotTemplates = [];
907
+ const dots = dotsContainers.map((container) => {
908
+ const template = qs(container, options.selectors.dotTemplate);
909
+ dotTemplates.push(template);
910
+ return setupDots(container, template, options, slideCount);
911
+ });
912
+ return { prev, next, dotsContainers, dotTemplates, dots };
548
913
  }
549
914
  function setupDots(container, template, options, slideCount) {
550
915
  const dots = qsa(container, generatedDotSelector);
551
916
  dots.forEach((dot) => dot.remove());
552
917
  if (!template) return [];
553
918
  const clones = [];
919
+ const disableOpacityAttr = template.getAttribute("data-carousel-disable-opacity");
554
920
  for (let i = 0; i < slideCount; i += 1) {
555
921
  const clone = template.cloneNode(true);
556
922
  clone.removeAttribute("id");
557
923
  clone.setAttribute("data-carousel-dot", "true");
558
924
  clone.setAttribute("data-carousel-dot-index", String(i));
925
+ if (disableOpacityAttr !== null) {
926
+ clone.setAttribute("data-carousel-disable-opacity", disableOpacityAttr);
927
+ } else {
928
+ clone.removeAttribute("data-carousel-disable-opacity");
929
+ }
559
930
  clone.setAttribute("aria-label", `Go to slide ${i + 1}`);
560
931
  clone.classList.add(options.classNames.dot);
561
932
  if (clone instanceof HTMLButtonElement && !clone.getAttribute("type")) {