@underverse-ui/underverse 1.0.61 → 1.0.62

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.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "package": "@underverse-ui/underverse",
3
- "version": "1.0.61",
3
+ "version": "1.0.62",
4
4
  "sourceEntry": "src/index.ts",
5
- "totalExports": 215,
5
+ "totalExports": 217,
6
6
  "exports": [
7
7
  {
8
8
  "name": "*",
@@ -273,6 +273,20 @@
273
273
  "reexport": true,
274
274
  "local": false
275
275
  },
276
+ {
277
+ "name": "CarouselEffectOptions",
278
+ "kind": "type",
279
+ "source": "./components/Carousel",
280
+ "reexport": true,
281
+ "local": false
282
+ },
283
+ {
284
+ "name": "CarouselEffectPreset",
285
+ "kind": "type",
286
+ "source": "./components/Carousel",
287
+ "reexport": true,
288
+ "local": false
289
+ },
276
290
  {
277
291
  "name": "Category",
278
292
  "kind": "type",
package/dist/index.cjs CHANGED
@@ -16348,20 +16348,92 @@ function Carousel({
16348
16348
  slideClassName,
16349
16349
  onSlideChange,
16350
16350
  thumbnailRenderer,
16351
- ariaLabel = "Carousel"
16351
+ ariaLabel = "Carousel",
16352
+ effectPreset,
16353
+ effectOptions
16352
16354
  }) {
16353
16355
  const [currentIndex, setCurrentIndex] = React42.useState(0);
16354
16356
  const [isPaused, setIsPaused] = React42.useState(false);
16355
- const [isDragging, setIsDragging] = React42.useState(false);
16356
- const [startPos, setStartPos] = React42.useState(0);
16357
- const [currentTranslate, setCurrentTranslate] = React42.useState(0);
16358
- const [prevTranslate, setPrevTranslate] = React42.useState(0);
16359
16357
  const progressElRef = React42.useRef(null);
16360
16358
  const carouselRef = React42.useRef(null);
16361
16359
  const rafRef = React42.useRef(null);
16362
- const totalSlides = React42.Children.count(children);
16363
- const maxIndex = Math.max(0, totalSlides - slidesToShow);
16360
+ const isDraggingRef = React42.useRef(false);
16361
+ const startPosRef = React42.useRef(0);
16362
+ const lastDragPositionRef = React42.useRef(0);
16363
+ const slides = React42.useMemo(() => React42.Children.toArray(children), [children]);
16364
+ const totalSlides = slides.length;
16364
16365
  const isHorizontal = orientation === "horizontal";
16366
+ const effectiveAnimation = slidesToShow > 1 && !["slide", "coverflow", "stack"].includes(animation) ? "slide" : animation;
16367
+ const isDeckAnimation = effectiveAnimation === "coverflow" || effectiveAnimation === "stack";
16368
+ const effectiveSlidesToShow = isDeckAnimation ? 1 : slidesToShow;
16369
+ const maxIndex = Math.max(0, totalSlides - effectiveSlidesToShow);
16370
+ const presetEffectOptions = React42.useMemo(() => {
16371
+ if (effectPreset === "cinematic") {
16372
+ return effectiveAnimation === "stack" ? {
16373
+ mainScale: 1.08,
16374
+ sideScale: 0.9,
16375
+ farScale: 0.84,
16376
+ sideOpacity: 0.68,
16377
+ farOpacity: 0.3,
16378
+ depthStep: 76,
16379
+ blur: 2.2,
16380
+ stackOffset: 16,
16381
+ stackLift: 16
16382
+ } : {
16383
+ mainScale: 1.12,
16384
+ sideScale: 0.82,
16385
+ farScale: 0.72,
16386
+ sideOpacity: 0.72,
16387
+ farOpacity: 0.24,
16388
+ sideOffset: 22,
16389
+ rotate: 20,
16390
+ depthStep: 120,
16391
+ blur: 2.6
16392
+ };
16393
+ }
16394
+ if (effectPreset === "gallery") {
16395
+ return effectiveAnimation === "stack" ? {
16396
+ mainScale: 1.03,
16397
+ sideScale: 0.94,
16398
+ farScale: 0.88,
16399
+ sideOpacity: 0.82,
16400
+ farOpacity: 0.5,
16401
+ depthStep: 50,
16402
+ blur: 0.8,
16403
+ stackOffset: 24,
16404
+ stackLift: 8
16405
+ } : {
16406
+ mainScale: 1.05,
16407
+ sideScale: 0.9,
16408
+ farScale: 0.82,
16409
+ sideOpacity: 0.84,
16410
+ farOpacity: 0.48,
16411
+ sideOffset: 30,
16412
+ rotate: 16,
16413
+ depthStep: 78,
16414
+ blur: 1
16415
+ };
16416
+ }
16417
+ return {};
16418
+ }, [effectPreset, effectiveAnimation]);
16419
+ const mergedEffectOptions = React42.useMemo(
16420
+ () => ({
16421
+ mainScale: 1.04,
16422
+ sideScale: effectiveAnimation === "stack" ? 0.93 : 0.88,
16423
+ farScale: effectiveAnimation === "stack" ? 0.86 : 0.76,
16424
+ sideOpacity: effectiveAnimation === "stack" ? 0.74 : 0.78,
16425
+ farOpacity: effectiveAnimation === "stack" ? 0.42 : 0.38,
16426
+ sideOffset: effectiveAnimation === "stack" ? 20 : 28,
16427
+ rotate: 24,
16428
+ depthStep: effectiveAnimation === "stack" ? 60 : 90,
16429
+ blur: 1.5,
16430
+ stackOffset: 20,
16431
+ stackLift: 12,
16432
+ ...presetEffectOptions,
16433
+ ...effectOptions
16434
+ }),
16435
+ [effectOptions, effectiveAnimation, presetEffectOptions]
16436
+ );
16365
16437
  const scrollPrev = React42.useCallback(() => {
16366
16438
  setCurrentIndex((prev) => {
16367
16439
  if (prev === 0) {
@@ -16384,8 +16456,8 @@ function Carousel({
16384
16456
  },
16385
16457
  [maxIndex]
16386
16458
  );
16387
- React42.useEffect(() => {
16388
- const handleKeyDown = (e) => {
16459
+ const handleKeyDown = React42.useCallback(
16460
+ (e) => {
16389
16461
  if (e.key === "ArrowLeft" || e.key === "ArrowUp") {
16390
16462
  e.preventDefault();
16391
16463
  scrollPrev();
@@ -16399,13 +16471,9 @@ function Carousel({
16399
16471
  e.preventDefault();
16400
16472
  scrollTo(maxIndex);
16401
16473
  }
16402
- };
16403
- const carousel = carouselRef.current;
16404
- if (carousel) {
16405
- carousel.addEventListener("keydown", handleKeyDown);
16406
- return () => carousel.removeEventListener("keydown", handleKeyDown);
16407
- }
16408
- }, [scrollPrev, scrollNext, scrollTo, maxIndex]);
16474
+ },
16475
+ [scrollPrev, scrollNext, scrollTo, maxIndex]
16476
+ );
16409
16477
  React42.useEffect(() => {
16410
16478
  const stop = () => {
16411
16479
  if (rafRef.current != null) {
@@ -16414,7 +16482,7 @@ function Carousel({
16414
16482
  }
16415
16483
  if (progressElRef.current) progressElRef.current.style.width = "0%";
16416
16484
  };
16417
- if (!autoScroll || isPaused || totalSlides <= slidesToShow) {
16485
+ if (!autoScroll || isPaused || totalSlides <= effectiveSlidesToShow) {
16418
16486
  stop();
16419
16487
  return;
16420
16488
  }
@@ -16433,7 +16501,7 @@ function Carousel({
16433
16501
  };
16434
16502
  rafRef.current = requestAnimationFrame(tick);
16435
16503
  return stop;
16436
- }, [autoScroll, isPaused, totalSlides, slidesToShow, autoScrollInterval, scrollNext]);
16504
+ }, [autoScroll, isPaused, totalSlides, effectiveSlidesToShow, autoScrollInterval, scrollNext]);
16437
16505
  const getPositionX = (event) => {
16438
16506
  return event.type.includes("mouse") ? event.pageX : event.touches[0].clientX;
16439
16507
  };
@@ -16441,60 +16509,100 @@ function Carousel({
16441
16509
  return event.type.includes("mouse") ? event.pageY : event.touches[0].clientY;
16442
16510
  };
16443
16511
  const touchStart = (event) => {
16444
- setIsDragging(true);
16512
+ isDraggingRef.current = true;
16445
16513
  const pos = isHorizontal ? getPositionX(event.nativeEvent) : getPositionY(event.nativeEvent);
16446
- setStartPos(pos);
16447
- setPrevTranslate(currentTranslate);
16514
+ startPosRef.current = pos;
16515
+ lastDragPositionRef.current = pos;
16448
16516
  };
16449
16517
  const touchMove = (event) => {
16450
- if (!isDragging) return;
16518
+ if (!isDraggingRef.current) return;
16451
16519
  const pos = isHorizontal ? getPositionX(event.nativeEvent) : getPositionY(event.nativeEvent);
16452
- const currentPosition = pos;
16453
- setCurrentTranslate(prevTranslate + currentPosition - startPos);
16520
+ lastDragPositionRef.current = pos;
16454
16521
  };
16455
16522
  const touchEnd = () => {
16456
- if (!isDragging) return;
16457
- setIsDragging(false);
16458
- const movedBy = currentTranslate - prevTranslate;
16523
+ if (!isDraggingRef.current) return;
16524
+ isDraggingRef.current = false;
16525
+ const movedBy = lastDragPositionRef.current - startPosRef.current;
16459
16526
  const threshold = 50;
16460
- if (movedBy < -threshold && currentIndex < maxIndex) {
16527
+ if (movedBy < -threshold) {
16461
16528
  scrollNext();
16462
- } else if (movedBy > threshold && currentIndex > 0) {
16529
+ } else if (movedBy > threshold) {
16463
16530
  scrollPrev();
16464
16531
  }
16465
- setCurrentTranslate(0);
16466
- setPrevTranslate(0);
16532
+ startPosRef.current = 0;
16533
+ lastDragPositionRef.current = 0;
16467
16534
  };
16468
16535
  React42.useEffect(() => {
16469
16536
  onSlideChange?.(currentIndex);
16470
16537
  }, [currentIndex, onSlideChange]);
16471
16538
  const getAnimationStyles2 = () => {
16472
- const baseTransform = isHorizontal ? `translateX(-${currentIndex * (100 / slidesToShow)}%)` : `translateY(-${currentIndex * (100 / slidesToShow)}%)`;
16473
- if (animation === "fade") {
16474
- return {
16475
- transition: "opacity 500ms ease-in-out"
16476
- };
16477
- }
16478
- if (animation === "scale") {
16479
- return {
16480
- transform: baseTransform,
16481
- transition: "transform 500ms ease-in-out, scale 500ms ease-in-out"
16482
- };
16539
+ if (effectiveAnimation !== "slide") {
16540
+ return {};
16483
16541
  }
16542
+ const baseTransform = isHorizontal ? `translateX(-${currentIndex * (100 / effectiveSlidesToShow)}%)` : `translateY(-${currentIndex * (100 / effectiveSlidesToShow)}%)`;
16484
16543
  return {
16485
16544
  transform: baseTransform,
16486
- transition: isDragging ? "none" : "transform 500ms ease-in-out"
16545
+ transition: "transform 500ms ease-in-out"
16487
16546
  };
16488
16547
  };
16489
- const slideWidth = 100 / slidesToShow;
16548
+ const slideWidth = 100 / effectiveSlidesToShow;
16549
+ const getLoopDistance = React42.useCallback(
16550
+ (index) => {
16551
+ if (totalSlides <= 0) return 0;
16552
+ const forward = index - currentIndex;
16553
+ if (!loop) return forward;
16554
+ const altForward = forward - totalSlides;
16555
+ const altBackward = forward + totalSlides;
16556
+ const candidates = [forward, altForward, altBackward];
16557
+ return candidates.reduce((best, candidate) => Math.abs(candidate) < Math.abs(best) ? candidate : best, candidates[0] ?? 0);
16558
+ },
16559
+ [currentIndex, loop, totalSlides]
16560
+ );
16561
+ const getDeckSlideStyles = React42.useCallback(
16562
+ (index) => {
16563
+ const distance = getLoopDistance(index);
16564
+ const absDistance = Math.abs(distance);
16565
+ const hidden = absDistance > 2;
16566
+ if (hidden) {
16567
+ return {
16568
+ opacity: 0,
16569
+ pointerEvents: "none",
16570
+ transform: `translate3d(0, 0, -${mergedEffectOptions.depthStep * 2}px) scale(${mergedEffectOptions.farScale})`,
16571
+ filter: `blur(${mergedEffectOptions.blur * 1.4}px)`
16572
+ };
16573
+ }
16574
+ if (effectiveAnimation === "stack") {
16575
+ const xOffset2 = distance * mergedEffectOptions.stackOffset;
16576
+ const yOffset = absDistance * mergedEffectOptions.stackLift;
16577
+ const scale2 = distance === 0 ? mergedEffectOptions.mainScale : distance === 1 || distance === -1 ? mergedEffectOptions.sideScale : mergedEffectOptions.farScale;
16578
+ return {
16579
+ opacity: distance === 0 ? 1 : distance === 1 || distance === -1 ? mergedEffectOptions.sideOpacity : mergedEffectOptions.farOpacity,
16580
+ transform: `translate3d(${xOffset2}px, ${yOffset}px, -${absDistance * mergedEffectOptions.depthStep}px) scale(${scale2})`,
16581
+ filter: distance === 0 ? "blur(0px)" : `blur(${Math.min(absDistance, 2) * mergedEffectOptions.blur}px)`,
16582
+ pointerEvents: distance === 0 ? "auto" : "none"
16583
+ };
16584
+ }
16585
+ const xOffset = distance * mergedEffectOptions.sideOffset;
16586
+ const rotateY = distance * -mergedEffectOptions.rotate;
16587
+ const scale = distance === 0 ? mergedEffectOptions.mainScale : distance === 1 || distance === -1 ? mergedEffectOptions.sideScale : mergedEffectOptions.farScale;
16588
+ return {
16589
+ opacity: distance === 0 ? 1 : distance === 1 || distance === -1 ? mergedEffectOptions.sideOpacity : mergedEffectOptions.farOpacity,
16590
+ transform: `translate3d(${xOffset}%, 0, -${absDistance * mergedEffectOptions.depthStep}px) rotateY(${rotateY}deg) scale(${scale})`,
16591
+ filter: distance === 0 ? "blur(0px)" : `blur(${Math.min(absDistance, 2) * mergedEffectOptions.blur}px)`,
16592
+ pointerEvents: distance === 0 ? "auto" : "none"
16593
+ };
16594
+ },
16595
+ [effectiveAnimation, getLoopDistance, mergedEffectOptions]
16596
+ );
16490
16597
  return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
16491
16598
  "div",
16492
16599
  {
16493
16600
  ref: carouselRef,
16494
16601
  className: cn(
16495
- "relative w-full overflow-hidden focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 rounded-2xl md:rounded-3xl",
16602
+ "relative w-full overflow-hidden focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 rounded-xl md:rounded-3xl",
16496
16603
  className
16497
16604
  ),
16605
+ onKeyDown: handleKeyDown,
16498
16606
  onMouseEnter: () => setIsPaused(true),
16499
16607
  onMouseLeave: () => setIsPaused(false),
16500
16608
  role: "region",
@@ -16506,8 +16614,14 @@ function Carousel({
16506
16614
  /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16507
16615
  "div",
16508
16616
  {
16509
- className: cn("flex", isHorizontal ? "flex-row" : "flex-col", containerClassName),
16510
- style: getAnimationStyles2(),
16617
+ className: cn(
16618
+ effectiveAnimation === "slide" ? "flex" : "grid",
16619
+ effectiveAnimation === "slide" && (isHorizontal ? "flex-row" : "flex-col"),
16620
+ isDeckAnimation && "place-items-center [transform-style:preserve-3d]",
16621
+ isHorizontal ? "touch-pan-y" : "touch-pan-x",
16622
+ containerClassName
16623
+ ),
16624
+ style: isDeckAnimation ? { perspective: "1400px" } : getAnimationStyles2(),
16511
16625
  onTouchStart: touchStart,
16512
16626
  onTouchMove: touchMove,
16513
16627
  onTouchEnd: touchEnd,
@@ -16518,30 +16632,30 @@ function Carousel({
16518
16632
  role: "group",
16519
16633
  "aria-atomic": "false",
16520
16634
  "aria-live": autoScroll ? "off" : "polite",
16521
- children: React42.Children.map(children, (child, idx) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16635
+ children: slides.map((child, idx) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16522
16636
  "div",
16523
16637
  {
16524
16638
  className: cn(
16525
16639
  "shrink-0",
16526
- isHorizontal ? "h-full" : "w-full",
16527
- animation === "fade" && idx !== currentIndex && "opacity-0",
16528
- animation === "scale" && idx !== currentIndex && "scale-95",
16640
+ effectiveAnimation === "slide" ? isHorizontal ? "h-full" : "w-full" : "col-start-1 row-start-1",
16641
+ effectiveAnimation === "fade" && (idx === currentIndex ? "opacity-100 z-10" : "opacity-0 pointer-events-none z-0"),
16642
+ effectiveAnimation === "scale" && (idx === currentIndex ? "opacity-100 scale-100 z-10" : "opacity-0 scale-95 pointer-events-none z-0"),
16643
+ isDeckAnimation && "w-full max-w-[78%] md:max-w-[72%] transition-[opacity,transform] duration-500 ease-out",
16644
+ effectiveAnimation !== "slide" && "transition-[opacity,transform] duration-500 ease-in-out",
16529
16645
  slideClassName
16530
16646
  ),
16531
- style: {
16532
- [isHorizontal ? "width" : "height"]: `${slideWidth}%`
16533
- },
16647
+ style: effectiveAnimation === "slide" ? { [isHorizontal ? "width" : "height"]: `${slideWidth}%` } : isDeckAnimation ? getDeckSlideStyles(idx) : void 0,
16534
16648
  role: "group",
16535
16649
  "aria-roledescription": "slide",
16536
16650
  "aria-label": `${idx + 1} of ${totalSlides}`,
16537
- "aria-hidden": idx < currentIndex || idx >= currentIndex + slidesToShow,
16651
+ "aria-hidden": effectiveAnimation === "slide" ? idx < currentIndex || idx >= currentIndex + slidesToShow : idx !== currentIndex,
16538
16652
  children: child
16539
16653
  },
16540
- idx
16654
+ React42.isValidElement(child) && child.key || idx
16541
16655
  ))
16542
16656
  }
16543
16657
  ),
16544
- showArrows && totalSlides > slidesToShow && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
16658
+ showArrows && totalSlides > effectiveSlidesToShow && /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
16545
16659
  /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16546
16660
  Button_default,
16547
16661
  {
@@ -16553,7 +16667,8 @@ function Carousel({
16553
16667
  disabled: !loop && currentIndex === 0,
16554
16668
  className: cn(
16555
16669
  "absolute top-1/2 -translate-y-1/2 hover:-translate-y-1/2 active:-translate-y-1/2 z-10 rounded-full will-change-transform backdrop-blur-0 hover:backdrop-blur-0 hover:bg-transparent border-0",
16556
- isHorizontal ? "left-4" : "top-4 left-1/2 -translate-x-1/2 rotate-90"
16670
+ "max-md:h-8 max-md:w-8 max-md:border max-md:border-border/60 max-md:bg-background/75 max-md:backdrop-blur-sm max-md:shadow-sm",
16671
+ isHorizontal ? "left-4 max-md:left-2" : "top-4 left-1/2 -translate-x-1/2 rotate-90 max-md:top-2"
16557
16672
  ),
16558
16673
  "aria-label": "Previous slide"
16559
16674
  }
@@ -16569,18 +16684,19 @@ function Carousel({
16569
16684
  disabled: !loop && currentIndex >= maxIndex,
16570
16685
  className: cn(
16571
16686
  "absolute top-1/2 -translate-y-1/2 hover:-translate-y-1/2 active:-translate-y-1/2 z-10 rounded-full will-change-transform backdrop-blur-0 hover:backdrop-blur-0 hover:bg-transparent border-0",
16572
- isHorizontal ? "right-4" : "bottom-4 left-1/2 -translate-x-1/2 rotate-90"
16687
+ "max-md:h-8 max-md:w-8 max-md:border max-md:border-border/60 max-md:bg-background/75 max-md:backdrop-blur-sm max-md:shadow-sm",
16688
+ isHorizontal ? "right-4 max-md:right-2" : "bottom-4 left-1/2 -translate-x-1/2 rotate-90 max-md:bottom-2"
16573
16689
  ),
16574
16690
  "aria-label": "Next slide"
16575
16691
  }
16576
16692
  )
16577
16693
  ] }),
16578
- showDots && totalSlides > slidesToShow && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16694
+ showDots && totalSlides > effectiveSlidesToShow && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16579
16695
  "div",
16580
16696
  {
16581
16697
  className: cn(
16582
16698
  "absolute flex gap-2 z-10",
16583
- isHorizontal ? "bottom-4 left-1/2 -translate-x-1/2 flex-row" : "right-4 top-1/2 -translate-y-1/2 flex-col"
16699
+ isHorizontal ? "bottom-4 left-1/2 -translate-x-1/2 flex-row max-md:bottom-2" : "right-4 top-1/2 -translate-y-1/2 flex-col max-md:right-2"
16584
16700
  ),
16585
16701
  role: "tablist",
16586
16702
  "aria-label": "Carousel pagination",
@@ -16590,8 +16706,9 @@ function Carousel({
16590
16706
  onClick: () => scrollTo(idx),
16591
16707
  className: cn(
16592
16708
  "rounded-full transition-all focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2",
16709
+ "max-md:w-1.5 max-md:h-1.5",
16593
16710
  isHorizontal ? "w-2 h-2" : "w-2 h-2",
16594
- idx === currentIndex ? `bg-primary ${isHorizontal ? "w-6" : "h-6"}` : "bg-muted-foreground/50 hover:bg-muted-foreground/75"
16711
+ idx === currentIndex ? `bg-primary ${isHorizontal ? "w-6 max-md:w-4" : "h-6 max-md:h-4"}` : "bg-muted-foreground/50 hover:bg-muted-foreground/75"
16595
16712
  ),
16596
16713
  "aria-label": `Go to slide ${idx + 1}`,
16597
16714
  "aria-selected": idx === currentIndex,
@@ -16601,11 +16718,12 @@ function Carousel({
16601
16718
  ))
16602
16719
  }
16603
16720
  ),
16604
- showThumbnails && totalSlides > slidesToShow && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16721
+ showThumbnails && totalSlides > effectiveSlidesToShow && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
16605
16722
  "div",
16606
16723
  {
16607
16724
  className: cn(
16608
16725
  "absolute bottom-0 left-0 right-0 flex gap-2 p-4 bg-linear-to-t from-black/50 to-transparent overflow-x-auto",
16726
+ "max-md:gap-1.5 max-md:p-2",
16609
16727
  isHorizontal ? "flex-row" : "flex-col"
16610
16728
  ),
16611
16729
  children: React42.Children.map(children, (child, idx) => /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
@@ -16614,7 +16732,8 @@ function Carousel({
16614
16732
  onClick: () => scrollTo(idx),
16615
16733
  className: cn(
16616
16734
  "shrink-0 w-16 h-16 rounded-lg overflow-hidden border-2 transition-all focus:outline-none focus:ring-2 focus:ring-primary",
16617
- idx === currentIndex ? "border-primary scale-110" : "border-transparent opacity-70 hover:opacity-100"
16735
+ "max-md:w-12 max-md:h-12",
16736
+ idx === currentIndex ? "border-primary md:scale-110" : "border-transparent opacity-70 hover:opacity-100"
16618
16737
  ),
16619
16738
  "aria-label": `Thumbnail ${idx + 1}`,
16620
16739
  children: thumbnailRenderer ? thumbnailRenderer(child, idx) : child