@latte-macchiat-io/latte-vanilla-components 0.0.333 → 0.0.334

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@latte-macchiat-io/latte-vanilla-components",
3
- "version": "0.0.333",
3
+ "version": "0.0.334",
4
4
  "description": "Beautiful components for amazing projects, with a touch of Vanilla 🥤",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { clsx } from 'clsx';
4
4
  import { ReactNode, useEffect, useRef, useState } from 'react';
5
-
6
5
  import {
7
6
  carouselBullet,
8
7
  carouselBulletActive,
@@ -17,27 +16,38 @@ import {
17
16
  carouselSlide,
18
17
  type CarouselVariants,
19
18
  } from './styles.css';
20
-
21
19
  import { breakpoints } from '../../styles/mediaqueries';
22
-
23
20
  import { useWindowSize } from '../../utils/useWindowSize';
24
-
25
21
  import { Icon } from '../Icon';
26
22
 
27
23
  export type CarouselProps = React.HTMLAttributes<HTMLDivElement> &
28
24
  CarouselVariants &
29
25
  CarouselNavVariants &
30
26
  CarouselContentVariants & {
31
- gap?: number;
32
27
  data: ReactNode[];
28
+ gap?: number | Partial<Record<keyof typeof breakpoints, number>>;
33
29
  itemsPerView?: number;
34
30
  showBullets?: boolean;
35
31
  showNavButtons?: boolean;
36
-
37
32
  autoplay?: boolean;
38
33
  autoplayInterval?: number;
39
34
  };
40
35
 
36
+ const getResponsiveValue = (values: number | Partial<Record<keyof typeof breakpoints, number>>, width: number | undefined): number => {
37
+ if (typeof values === 'number') return values;
38
+
39
+ const bpOrder: (keyof typeof breakpoints)[] = ['mobile', 'sm', 'md', 'lg', 'xl', '2xl'];
40
+ let currentValue: number = values.mobile ?? 0;
41
+
42
+ for (const bp of bpOrder) {
43
+ if (width && width >= breakpoints[bp] && values[bp] !== undefined) {
44
+ currentValue = values[bp]!;
45
+ }
46
+ }
47
+
48
+ return currentValue;
49
+ };
50
+
41
51
  export const Carousel = ({
42
52
  data,
43
53
  overflow,
@@ -63,7 +73,6 @@ export const Carousel = ({
63
73
  const isTablet = windowWidth !== undefined && windowWidth > breakpoints.md;
64
74
  const isDesktop = windowWidth !== undefined && windowWidth > breakpoints.lg;
65
75
 
66
- // Adapter le nombre d’items visibles selon le viewport
67
76
  useEffect(() => {
68
77
  if (isDesktop) {
69
78
  setVisibleItems(itemsPerView);
@@ -74,12 +83,12 @@ export const Carousel = ({
74
83
  }
75
84
  }, [isTablet, isDesktop, itemsPerView]);
76
85
 
77
- // Calcul largeur d’un item
78
86
  useEffect(() => {
79
87
  const calculateItemWidth = () => {
80
88
  if (carouselRef.current) {
81
89
  const containerWidth = carouselRef.current.getBoundingClientRect().width;
82
- const totalGap = (visibleItems - 1) * gap;
90
+ const currentGap = getResponsiveValue(gap, windowWidth);
91
+ const totalGap = (visibleItems - 1) * currentGap;
83
92
  setItemWidth((containerWidth - totalGap) / visibleItems);
84
93
  }
85
94
  };
@@ -87,23 +96,19 @@ export const Carousel = ({
87
96
  calculateItemWidth();
88
97
  window.addEventListener('resize', calculateItemWidth);
89
98
  return () => window.removeEventListener('resize', calculateItemWidth);
90
- }, [visibleItems, gap]);
99
+ }, [visibleItems, gap, windowWidth]);
91
100
 
92
- // Autoplay
93
101
  useEffect(() => {
94
102
  if (!autoplay) return;
95
-
96
103
  const interval = setInterval(() => {
97
104
  setCurrentIndex((prev) => {
98
105
  const maxIndex = Math.max(0, data.length - visibleItems);
99
106
  return prev >= maxIndex ? 0 : prev + 1;
100
107
  });
101
108
  }, autoplayInterval);
102
-
103
109
  return () => clearInterval(interval);
104
110
  }, [autoplay, autoplayInterval, data.length, visibleItems]);
105
111
 
106
- // Swipe mobile
107
112
  useEffect(() => {
108
113
  const carousel = carouselRef.current;
109
114
  if (!carousel) return;
@@ -156,7 +161,8 @@ export const Carousel = ({
156
161
  setCurrentIndex(Math.min(index, maxIndex));
157
162
  };
158
163
 
159
- const translateX = -(currentIndex * (itemWidth + gap));
164
+ const currentGap = getResponsiveValue(gap, windowWidth);
165
+ const translateX = -(currentIndex * (itemWidth + currentGap));
160
166
  const maxIndex = Math.max(0, data.length - visibleItems);
161
167
 
162
168
  return (
@@ -166,7 +172,7 @@ export const Carousel = ({
166
172
  ref={slideRef}
167
173
  className={carouselSlide}
168
174
  style={{
169
- gap: `${gap}px`,
175
+ gap: `${currentGap}px`,
170
176
  transform: `translateX(${translateX}px)`,
171
177
  }}>
172
178
  {data.map((item, index) => (