@latte-macchiat-io/latte-vanilla-components 0.0.332 → 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.332",
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,42 +2,55 @@
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,
9
8
  carouselBullets,
10
9
  carouselContent,
10
+ type CarouselContentVariants,
11
11
  carouselItem,
12
12
  carouselNav,
13
13
  carouselNavButton,
14
- CarouselNavVariants,
14
+ type CarouselNavVariants,
15
15
  carouselRecipe,
16
16
  carouselSlide,
17
17
  type CarouselVariants,
18
18
  } from './styles.css';
19
-
20
19
  import { breakpoints } from '../../styles/mediaqueries';
21
-
22
20
  import { useWindowSize } from '../../utils/useWindowSize';
23
-
24
21
  import { Icon } from '../Icon';
25
22
 
26
23
  export type CarouselProps = React.HTMLAttributes<HTMLDivElement> &
27
24
  CarouselVariants &
28
- CarouselNavVariants & {
29
- gap?: number;
25
+ CarouselNavVariants &
26
+ CarouselContentVariants & {
30
27
  data: ReactNode[];
28
+ gap?: number | Partial<Record<keyof typeof breakpoints, number>>;
31
29
  itemsPerView?: number;
32
30
  showBullets?: boolean;
33
31
  showNavButtons?: boolean;
34
-
35
32
  autoplay?: boolean;
36
33
  autoplayInterval?: number;
37
34
  };
38
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
+
39
51
  export const Carousel = ({
40
52
  data,
53
+ overflow,
41
54
  itemsPerView = 1,
42
55
  showNavButtons = false,
43
56
  showBullets = false,
@@ -60,7 +73,6 @@ export const Carousel = ({
60
73
  const isTablet = windowWidth !== undefined && windowWidth > breakpoints.md;
61
74
  const isDesktop = windowWidth !== undefined && windowWidth > breakpoints.lg;
62
75
 
63
- // Adapter le nombre d’items visibles selon le viewport
64
76
  useEffect(() => {
65
77
  if (isDesktop) {
66
78
  setVisibleItems(itemsPerView);
@@ -71,12 +83,12 @@ export const Carousel = ({
71
83
  }
72
84
  }, [isTablet, isDesktop, itemsPerView]);
73
85
 
74
- // Calcul largeur d’un item
75
86
  useEffect(() => {
76
87
  const calculateItemWidth = () => {
77
88
  if (carouselRef.current) {
78
89
  const containerWidth = carouselRef.current.getBoundingClientRect().width;
79
- const totalGap = (visibleItems - 1) * gap;
90
+ const currentGap = getResponsiveValue(gap, windowWidth);
91
+ const totalGap = (visibleItems - 1) * currentGap;
80
92
  setItemWidth((containerWidth - totalGap) / visibleItems);
81
93
  }
82
94
  };
@@ -84,23 +96,19 @@ export const Carousel = ({
84
96
  calculateItemWidth();
85
97
  window.addEventListener('resize', calculateItemWidth);
86
98
  return () => window.removeEventListener('resize', calculateItemWidth);
87
- }, [visibleItems, gap]);
99
+ }, [visibleItems, gap, windowWidth]);
88
100
 
89
- // Autoplay
90
101
  useEffect(() => {
91
102
  if (!autoplay) return;
92
-
93
103
  const interval = setInterval(() => {
94
104
  setCurrentIndex((prev) => {
95
105
  const maxIndex = Math.max(0, data.length - visibleItems);
96
106
  return prev >= maxIndex ? 0 : prev + 1;
97
107
  });
98
108
  }, autoplayInterval);
99
-
100
109
  return () => clearInterval(interval);
101
110
  }, [autoplay, autoplayInterval, data.length, visibleItems]);
102
111
 
103
- // Swipe mobile
104
112
  useEffect(() => {
105
113
  const carousel = carouselRef.current;
106
114
  if (!carousel) return;
@@ -153,17 +161,18 @@ export const Carousel = ({
153
161
  setCurrentIndex(Math.min(index, maxIndex));
154
162
  };
155
163
 
156
- const translateX = -(currentIndex * (itemWidth + gap));
164
+ const currentGap = getResponsiveValue(gap, windowWidth);
165
+ const translateX = -(currentIndex * (itemWidth + currentGap));
157
166
  const maxIndex = Math.max(0, data.length - visibleItems);
158
167
 
159
168
  return (
160
169
  <div className={clsx(carouselRecipe({ isFullWidth }), className)}>
161
- <div ref={carouselRef} className={carouselContent}>
170
+ <div ref={carouselRef} className={carouselContent({ overflow })}>
162
171
  <div
163
172
  ref={slideRef}
164
173
  className={carouselSlide}
165
174
  style={{
166
- gap: `${gap}px`,
175
+ gap: `${currentGap}px`,
167
176
  transform: `translateX(${translateX}px)`,
168
177
  }}>
169
178
  {data.map((item, index) => (
@@ -56,11 +56,23 @@ export const carouselRecipe = recipe(
56
56
  'carousel'
57
57
  );
58
58
 
59
- export const carouselContent = style(
59
+ export const carouselContent = recipe(
60
60
  {
61
- width: '100%',
62
- overflow: 'hidden',
63
- position: 'relative',
61
+ base: {
62
+ width: '100%',
63
+ position: 'relative',
64
+ },
65
+
66
+ variants: {
67
+ overflow: {
68
+ hidden: { overflow: 'hidden' },
69
+ visible: { overflow: 'visible' },
70
+ },
71
+ },
72
+
73
+ defaultVariants: {
74
+ overflow: 'hidden',
75
+ },
64
76
  },
65
77
  'carousel-content'
66
78
  );
@@ -254,4 +266,5 @@ export const carouselBulletActive = style(
254
266
  );
255
267
 
256
268
  export type CarouselVariants = RecipeVariants<typeof carouselRecipe>;
269
+ export type CarouselContentVariants = RecipeVariants<typeof carouselContent>;
257
270
  export type CarouselNavVariants = RecipeVariants<typeof carouselNav>;