@latte-macchiat-io/latte-vanilla-components 0.0.176 → 0.0.178

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.
Files changed (219) hide show
  1. package/package.json +9 -22
  2. package/src/assets/styles/mediaqueries.tsx +24 -0
  3. package/src/components/Actions/Actions.tsx +132 -0
  4. package/src/components/Actions/export.tsx +4 -0
  5. package/src/components/{Main/stories.ts → Actions/stories.tsx} +14 -13
  6. package/src/components/Button/Button.tsx +132 -0
  7. package/src/components/Button/export.tsx +5 -0
  8. package/src/components/Carousel/Carousel.tsx +328 -0
  9. package/src/components/Carousel/export.tsx +4 -0
  10. package/src/components/Columns/Columns.tsx +142 -0
  11. package/src/components/Columns/export.tsx +5 -0
  12. package/src/components/ConsentCookie/ConsentCookie.tsx +202 -0
  13. package/src/components/ConsentCookie/export.tsx +4 -0
  14. package/src/components/{Icon/stories.ts → ConsentCookie/stories.tsx} +7 -8
  15. package/src/components/Footer/Footer.tsx +130 -0
  16. package/src/components/Footer/export.tsx +4 -0
  17. package/src/components/Footer/stories.tsx +26 -0
  18. package/src/components/Form/Form.tsx +127 -0
  19. package/src/components/Form/Row/Row.tsx +137 -0
  20. package/src/components/Form/Row/stories.tsx +41 -0
  21. package/src/components/Form/TextField/Input/Input.tsx +139 -0
  22. package/src/components/Form/TextField/Input/export.tsx +6 -0
  23. package/src/components/Form/TextField/Label/Label.tsx +133 -0
  24. package/src/components/Form/TextField/Label/export.tsx +4 -0
  25. package/src/components/Form/TextField/TextField.tsx +200 -0
  26. package/src/components/Form/TextField/Textarea/Textarea.tsx +135 -0
  27. package/src/components/Form/TextField/Textarea/export.tsx +6 -0
  28. package/src/components/Form/TextField/Textarea/stories.tsx +44 -0
  29. package/src/components/Form/TextField/export.tsx +4 -0
  30. package/src/components/Form/export.tsx +4 -0
  31. package/src/components/Header/Header.tsx +158 -0
  32. package/src/components/Header/HeaderOverlay/index.tsx +32 -0
  33. package/src/components/Header/ToggleNav/index.tsx +32 -0
  34. package/src/components/Header/export.tsx +4 -0
  35. package/src/components/Header/stories.tsx +26 -0
  36. package/src/components/Icon/Icon.tsx +159 -0
  37. package/src/components/Icon/export.tsx +4 -0
  38. package/src/components/KeyNumber/KeyNumber.tsx +166 -0
  39. package/src/components/KeyNumber/export.tsx +4 -0
  40. package/src/components/LanguageSwitcher/LanguageSwitcher.tsx +168 -0
  41. package/src/components/LanguageSwitcher/export.tsx +4 -0
  42. package/src/components/Logo/Logo.tsx +137 -0
  43. package/src/components/Logo/export.tsx +4 -0
  44. package/src/components/Logo/stories.tsx +28 -0
  45. package/src/components/Main/Main.tsx +130 -0
  46. package/src/components/Main/export.tsx +4 -0
  47. package/src/components/Modal/Modal.tsx +194 -0
  48. package/src/components/Modal/export.tsx +4 -0
  49. package/src/components/Modal/types.tsx +5 -0
  50. package/src/components/Nav/Nav.tsx +129 -0
  51. package/src/components/Nav/export.tsx +4 -0
  52. package/src/components/Nav/stories.tsx +28 -0
  53. package/src/components/NavLegal/NavLegal.tsx +133 -0
  54. package/src/components/NavLegal/export.tsx +4 -0
  55. package/src/components/NavLegal/stories.tsx +28 -0
  56. package/src/components/NavSocial/NavSocial.tsx +169 -0
  57. package/src/components/NavSocial/export.tsx +5 -0
  58. package/src/components/{Columns/stories.ts → NavSocial/stories.tsx} +12 -14
  59. package/src/components/Section/Section.tsx +130 -0
  60. package/src/components/Section/export.tsx +6 -0
  61. package/src/components/ToRemove/ToRemove.tsx +3 -0
  62. package/src/components/Video/Video.tsx +243 -0
  63. package/src/components/Video/export.tsx +2 -0
  64. package/src/components/VideoFullWidth/VideoFullWidth.tsx +152 -0
  65. package/src/components/VideoFullWidth/export.tsx +2 -0
  66. package/dist/components/Actions/Actions.css.ts +0 -113
  67. package/dist/components/Button/Button.css.ts +0 -119
  68. package/dist/components/Carousel/Carousel.css.ts +0 -179
  69. package/dist/components/Columns/Columns.css.ts +0 -185
  70. package/dist/components/ConsentCookie/ConsentCookie.css.ts +0 -167
  71. package/dist/components/Footer/Footer.css.ts +0 -108
  72. package/dist/components/Form/Form.css.ts +0 -64
  73. package/dist/components/Form/Row/Row.css.ts +0 -70
  74. package/dist/components/Form/TextField/Input/Input.css.ts +0 -106
  75. package/dist/components/Form/TextField/Label/Label.css.ts +0 -58
  76. package/dist/components/Form/TextField/TextField.css.ts +0 -139
  77. package/dist/components/Form/TextField/Textarea/Textarea.css.ts +0 -121
  78. package/dist/components/Header/Header.css.ts +0 -111
  79. package/dist/components/Header/HeaderOverlay/styles.css.ts +0 -33
  80. package/dist/components/Header/ToggleNav/styles.css.ts +0 -40
  81. package/dist/components/Icon/Icon.css.ts +0 -102
  82. package/dist/components/KeyNumber/KeyNumber.css.ts +0 -158
  83. package/dist/components/LanguageSwitcher/LanguageSwitcher.css.ts +0 -120
  84. package/dist/components/Logo/Logo.css.ts +0 -98
  85. package/dist/components/Main/Main.css.ts +0 -62
  86. package/dist/components/Modal/Modal.css.ts +0 -203
  87. package/dist/components/Nav/Nav.css.ts +0 -123
  88. package/dist/components/NavLegal/NavLegal.css.ts +0 -121
  89. package/dist/components/NavSocial/NavSocial.css.ts +0 -121
  90. package/dist/components/Section/Section.css.ts +0 -101
  91. package/dist/components/Video/Video.css.ts +0 -210
  92. package/dist/components/VideoFullWidth/VideoFullWidth.css.ts +0 -50
  93. package/dist/css/index.cjs +0 -1
  94. package/dist/css/index.js +0 -34
  95. package/dist/index.cjs.js +0 -2
  96. package/dist/index.es.js +0 -3863
  97. package/dist/styles/sprinkles.css.ts +0 -84
  98. package/dist/theme/contract.css.ts +0 -83
  99. package/dist/theme.css-CNjMk-g_.cjs +0 -1
  100. package/dist/theme.css-Dj6kL9o0.js +0 -3020
  101. package/dist/types/components/Actions/Actions.css.d.ts +0 -74
  102. package/dist/types/components/Actions/Actions.d.ts +0 -7
  103. package/dist/types/components/Actions/stories.d.ts +0 -0
  104. package/dist/types/components/Button/Button.css.d.ts +0 -65
  105. package/dist/types/components/Button/Button.d.ts +0 -8
  106. package/dist/types/components/Button/export.d.ts +0 -0
  107. package/dist/types/components/Button/stories.d.ts +0 -0
  108. package/dist/types/components/Carousel/Carousel.css.d.ts +0 -33
  109. package/dist/types/components/Carousel/Carousel.d.ts +0 -15
  110. package/dist/types/components/Carousel/export.d.ts +0 -0
  111. package/dist/types/components/Columns/Columns.css.d.ts +0 -104
  112. package/dist/types/components/Columns/Columns.d.ts +0 -8
  113. package/dist/types/components/Columns/export.d.ts +0 -0
  114. package/dist/types/components/Columns/stories.d.ts +0 -0
  115. package/dist/types/components/ConsentCookie/ConsentCookie.css.d.ts +0 -15
  116. package/dist/types/components/ConsentCookie/ConsentCookie.d.ts +0 -17
  117. package/dist/types/components/ConsentCookie/export.d.ts +0 -0
  118. package/dist/types/components/ConsentCookie/stories.d.ts +0 -0
  119. package/dist/types/components/Footer/Footer.css.d.ts +0 -50
  120. package/dist/types/components/Footer/Footer.d.ts +0 -7
  121. package/dist/types/components/Footer/export.d.ts +0 -0
  122. package/dist/types/components/Footer/stories.d.ts +0 -6
  123. package/dist/types/components/Form/Form.css.d.ts +0 -46
  124. package/dist/types/components/Form/Form.d.ts +0 -7
  125. package/dist/types/components/Form/Row/Row.css.d.ts +0 -51
  126. package/dist/types/components/Form/Row/Row.d.ts +0 -9
  127. package/dist/types/components/Form/Row/index.d.ts +0 -0
  128. package/dist/types/components/Form/Row/stories.d.ts +0 -0
  129. package/dist/types/components/Form/TextField/Input/Input.css.d.ts +0 -32
  130. package/dist/types/components/Form/TextField/Input/Input.d.ts +0 -10
  131. package/dist/types/components/Form/TextField/Input/export.d.ts +0 -0
  132. package/dist/types/components/Form/TextField/Label/Label.css.d.ts +0 -23
  133. package/dist/types/components/Form/TextField/Label/Label.d.ts +0 -9
  134. package/dist/types/components/Form/TextField/Label/export.d.ts +0 -0
  135. package/dist/types/components/Form/TextField/TextField.css.d.ts +0 -19
  136. package/dist/types/components/Form/TextField/TextField.d.ts +0 -21
  137. package/dist/types/components/Form/TextField/Textarea/Textarea.css.d.ts +0 -56
  138. package/dist/types/components/Form/TextField/Textarea/Textarea.d.ts +0 -8
  139. package/dist/types/components/Form/TextField/Textarea/export.d.ts +0 -0
  140. package/dist/types/components/Form/TextField/Textarea/stories.d.ts +0 -0
  141. package/dist/types/components/Form/TextField/export.d.ts +0 -0
  142. package/dist/types/components/Form/export.d.ts +0 -0
  143. package/dist/types/components/Header/Header.css.d.ts +0 -36
  144. package/dist/types/components/Header/Header.d.ts +0 -11
  145. package/dist/types/components/Header/HeaderOverlay/index.d.ts +0 -7
  146. package/dist/types/components/Header/HeaderOverlay/styles.css.d.ts +0 -5
  147. package/dist/types/components/Header/ToggleNav/index.d.ts +0 -9
  148. package/dist/types/components/Header/ToggleNav/styles.css.d.ts +0 -5
  149. package/dist/types/components/Header/export.d.ts +0 -0
  150. package/dist/types/components/Header/stories.d.ts +0 -6
  151. package/dist/types/components/Icon/Icon.css.d.ts +0 -45
  152. package/dist/types/components/Icon/Icon.d.ts +0 -12
  153. package/dist/types/components/Icon/export.d.ts +0 -0
  154. package/dist/types/components/Icon/path.d.ts +0 -19
  155. package/dist/types/components/Icon/stories.d.ts +0 -0
  156. package/dist/types/components/KeyNumber/KeyNumber.css.d.ts +0 -40
  157. package/dist/types/components/KeyNumber/KeyNumber.d.ts +0 -15
  158. package/dist/types/components/KeyNumber/export.d.ts +0 -0
  159. package/dist/types/components/LanguageSwitcher/LanguageSwitcher.css.d.ts +0 -18
  160. package/dist/types/components/LanguageSwitcher/LanguageSwitcher.d.ts +0 -16
  161. package/dist/types/components/LanguageSwitcher/export.d.ts +0 -0
  162. package/dist/types/components/Logo/Logo.css.d.ts +0 -54
  163. package/dist/types/components/Logo/Logo.d.ts +0 -8
  164. package/dist/types/components/Logo/export.d.ts +0 -0
  165. package/dist/types/components/Logo/stories.d.ts +0 -6
  166. package/dist/types/components/Main/Main.css.d.ts +0 -32
  167. package/dist/types/components/Main/Main.d.ts +0 -7
  168. package/dist/types/components/Main/export.d.ts +0 -0
  169. package/dist/types/components/Main/stories.d.ts +0 -0
  170. package/dist/types/components/Modal/Modal.css.d.ts +0 -82
  171. package/dist/types/components/Modal/Modal.d.ts +0 -15
  172. package/dist/types/components/Modal/export.d.ts +0 -0
  173. package/dist/types/components/Modal/types.d.ts +0 -5
  174. package/dist/types/components/Nav/Nav.css.d.ts +0 -52
  175. package/dist/types/components/Nav/Nav.d.ts +0 -7
  176. package/dist/types/components/Nav/export.d.ts +0 -0
  177. package/dist/types/components/Nav/stories.d.ts +0 -6
  178. package/dist/types/components/NavLegal/NavLegal.css.d.ts +0 -57
  179. package/dist/types/components/NavLegal/NavLegal.d.ts +0 -7
  180. package/dist/types/components/NavLegal/export.d.ts +0 -0
  181. package/dist/types/components/NavLegal/stories.d.ts +0 -6
  182. package/dist/types/components/NavSocial/NavSocial.css.d.ts +0 -30
  183. package/dist/types/components/NavSocial/NavSocial.d.ts +0 -15
  184. package/dist/types/components/NavSocial/export.d.ts +0 -0
  185. package/dist/types/components/NavSocial/stories.d.ts +0 -0
  186. package/dist/types/components/Section/Section.css.d.ts +0 -60
  187. package/dist/types/components/Section/Section.d.ts +0 -7
  188. package/dist/types/components/Section/export.d.ts +0 -0
  189. package/dist/types/components/Section/stories.d.ts +0 -0
  190. package/dist/types/components/ToRemove/ToRemove.d.ts +0 -1
  191. package/dist/types/components/Video/Video.css.d.ts +0 -43
  192. package/dist/types/components/Video/Video.d.ts +0 -17
  193. package/dist/types/components/Video/export.d.ts +0 -0
  194. package/dist/types/components/VideoFullWidth/VideoFullWidth.css.d.ts +0 -18
  195. package/dist/types/components/VideoFullWidth/VideoFullWidth.d.ts +0 -14
  196. package/dist/types/components/VideoFullWidth/export.d.ts +0 -0
  197. package/dist/types/css/index.d.ts +0 -28
  198. package/dist/types/index.d.ts +0 -58
  199. package/dist/types/styles/mediaqueries.d.ts +0 -16
  200. package/dist/types/styles/sprinkles.css.d.ts +0 -3423
  201. package/dist/types/theme/baseThemeValues.d.ts +0 -158
  202. package/dist/types/theme/contract.css.d.ts +0 -79
  203. package/dist/types/theme/index.d.ts +0 -3
  204. package/dist/types/theme/utils.d.ts +0 -86
  205. package/dist/types/utils/cookie.d.ts +0 -2
  206. package/dist/types/utils/deep-merge-objects.d.ts +0 -2
  207. package/dist/types/utils/theme.css.d.ts +0 -173
  208. package/dist/types/utils/use-breakpoint-key.d.ts +0 -1
  209. package/dist/types/utils/use-window-size.d.ts +0 -5
  210. package/dist/utils/theme.css.ts +0 -129
  211. package/src/components/Button/stories.ts +0 -127
  212. package/src/components/Section/stories.ts +0 -64
  213. package/src/css/index.ts +0 -33
  214. package/src/themes/dark.ts +0 -3
  215. package/src/themes/index.ts +0 -5
  216. package/src/themes/light.ts +0 -3
  217. /package/{dist/types/components/Actions/export.d.ts → src/components/Form/Row/index.tsx} +0 -0
  218. /package/{dist/types/components/NavLegal/types.d.ts → src/components/NavLegal/types.tsx} +0 -0
  219. /package/{dist/types/components/NavSocial/types.d.ts → src/components/NavSocial/types.tsx} +0 -0
@@ -0,0 +1,328 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { clsx } from 'clsx';
3
+ import { forwardRef, ReactNode, useEffect, useRef, useState } from 'react';
4
+ import {
5
+ carouselBullet,
6
+ carouselBulletActive,
7
+ carouselBullets,
8
+ carouselContent,
9
+ carouselItem,
10
+ carouselNav,
11
+ carouselNavButton,
12
+ carouselRecipe,
13
+ carouselSlide,
14
+ type CarouselVariants,
15
+ } from './Carousel.css';
16
+ import { breakpoints } from '../../styles/mediaqueries';
17
+ import { sprinkles, type Sprinkles } from '../../styles/sprinkles.css';
18
+ import { Icon } from '../Icon/Icon';
19
+
20
+ interface UseWindowSizeReturn {
21
+ width: number | undefined;
22
+ height: number | undefined;
23
+ }
24
+
25
+ const useWindowSize = (): UseWindowSizeReturn => {
26
+ const [windowSize, setWindowSize] = useState<UseWindowSizeReturn>({
27
+ width: undefined,
28
+ height: undefined,
29
+ });
30
+
31
+ useEffect(() => {
32
+ const handleResize = () => {
33
+ setWindowSize({
34
+ width: window.innerWidth,
35
+ height: window.innerHeight,
36
+ });
37
+ };
38
+
39
+ window.addEventListener('resize', handleResize);
40
+ handleResize();
41
+
42
+ return () => window.removeEventListener('resize', handleResize);
43
+ }, []);
44
+
45
+ return windowSize;
46
+ };
47
+
48
+ export interface CarouselProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color' | 'gap'>, Sprinkles, NonNullable<CarouselVariants> {
49
+ css?: string;
50
+ data: ReactNode[];
51
+ itemsPerView?: number;
52
+ showNavButtons?: boolean;
53
+ showBullets?: boolean;
54
+ autoplay?: boolean;
55
+ autoplayInterval?: number;
56
+ gap?: any;
57
+ as?: 'div' | 'section';
58
+ }
59
+
60
+ export const Carousel = forwardRef<HTMLDivElement, CarouselProps>(
61
+ (
62
+ {
63
+ data,
64
+ itemsPerView = 1,
65
+ showNavButtons = false,
66
+ showBullets = false,
67
+ autoplay = false,
68
+ autoplayInterval = 3000,
69
+ gap = 16,
70
+ fullWidth,
71
+ as: Component = 'div',
72
+ css,
73
+ className,
74
+ // Extract sprinkles props
75
+ margin,
76
+ marginTop,
77
+ marginBottom,
78
+ marginLeft,
79
+ marginRight,
80
+ padding,
81
+ paddingTop,
82
+ paddingBottom,
83
+ paddingLeft,
84
+ paddingRight,
85
+ display,
86
+ flexDirection,
87
+ justifyContent,
88
+ flexWrap,
89
+ flex,
90
+ width,
91
+ height,
92
+ minWidth,
93
+ maxWidth,
94
+ minHeight,
95
+ position,
96
+ top,
97
+ bottom,
98
+ left,
99
+ right,
100
+ zIndex,
101
+ fontSize,
102
+ fontFamily,
103
+ lineHeight,
104
+ textAlign,
105
+ fontWeight,
106
+ color,
107
+ backgroundColor,
108
+ borderRadius,
109
+ borderWidth,
110
+ borderStyle,
111
+ borderColor,
112
+ boxShadow,
113
+ opacity,
114
+ overflow,
115
+ overflowX,
116
+ overflowY,
117
+ ...htmlProps
118
+ },
119
+ ref
120
+ ) => {
121
+ const { width: windowWidth } = useWindowSize();
122
+ const [currentIndex, setCurrentIndex] = useState(0);
123
+ const [itemWidth, setItemWidth] = useState(0);
124
+ const [visibleItems, setVisibleItems] = useState(itemsPerView);
125
+
126
+ const carouselRef = useRef<HTMLDivElement>(null);
127
+ const slideRef = useRef<HTMLDivElement>(null);
128
+
129
+ const isTablet = windowWidth !== undefined && windowWidth > breakpoints.md;
130
+ const isDesktop = windowWidth !== undefined && windowWidth > breakpoints.lg;
131
+
132
+ // Calculate visible items based on screen size
133
+ useEffect(() => {
134
+ if (isDesktop) {
135
+ setVisibleItems(itemsPerView);
136
+ } else if (isTablet) {
137
+ setVisibleItems(Math.max(1, Math.floor(itemsPerView / 2)));
138
+ } else {
139
+ setVisibleItems(1);
140
+ }
141
+ }, [isTablet, isDesktop, itemsPerView]);
142
+
143
+ // Calculate item width
144
+ useEffect(() => {
145
+ const calculateItemWidth = () => {
146
+ if (carouselRef.current) {
147
+ const containerWidth = carouselRef.current.getBoundingClientRect().width;
148
+ const totalGap = (visibleItems - 1) * gap;
149
+ setItemWidth((containerWidth - totalGap) / visibleItems);
150
+ }
151
+ };
152
+
153
+ calculateItemWidth();
154
+ window.addEventListener('resize', calculateItemWidth);
155
+ return () => window.removeEventListener('resize', calculateItemWidth);
156
+ }, [visibleItems, gap]);
157
+
158
+ // Autoplay functionality
159
+ useEffect(() => {
160
+ if (!autoplay) return;
161
+
162
+ const interval = setInterval(() => {
163
+ setCurrentIndex((prev) => {
164
+ const maxIndex = Math.max(0, data.length - visibleItems);
165
+ return prev >= maxIndex ? 0 : prev + 1;
166
+ });
167
+ }, autoplayInterval);
168
+
169
+ return () => clearInterval(interval);
170
+ }, [autoplay, autoplayInterval, data.length, visibleItems]);
171
+
172
+ // Touch/swipe handling
173
+ useEffect(() => {
174
+ const carousel = carouselRef.current;
175
+ if (!carousel) return;
176
+
177
+ let touchStartX = 0;
178
+ let touchEndX = 0;
179
+
180
+ const handleTouchStart = (e: TouchEvent) => {
181
+ touchStartX = e.changedTouches[0].screenX;
182
+ };
183
+
184
+ const handleTouchEnd = (e: TouchEvent) => {
185
+ touchEndX = e.changedTouches[0].screenX;
186
+ handleSwipe();
187
+ };
188
+
189
+ const handleSwipe = () => {
190
+ const swipeThreshold = 100;
191
+ const diff = touchStartX - touchEndX;
192
+
193
+ if (Math.abs(diff) > swipeThreshold) {
194
+ if (diff > 0) {
195
+ // Swipe left - next
196
+ handleNext();
197
+ } else {
198
+ // Swipe right - previous
199
+ handlePrevious();
200
+ }
201
+ }
202
+ };
203
+
204
+ carousel.addEventListener('touchstart', handleTouchStart, { passive: true });
205
+ carousel.addEventListener('touchend', handleTouchEnd, { passive: true });
206
+
207
+ return () => {
208
+ carousel.removeEventListener('touchstart', handleTouchStart);
209
+ carousel.removeEventListener('touchend', handleTouchEnd);
210
+ };
211
+ }, []);
212
+
213
+ const handlePrevious = () => {
214
+ setCurrentIndex((prev) => Math.max(0, prev - 1));
215
+ };
216
+
217
+ const handleNext = () => {
218
+ const maxIndex = Math.max(0, data.length - visibleItems);
219
+ setCurrentIndex((prev) => Math.min(maxIndex, prev + 1));
220
+ };
221
+
222
+ const handleBulletClick = (index: number) => {
223
+ const maxIndex = Math.max(0, data.length - visibleItems);
224
+ setCurrentIndex(Math.min(index, maxIndex));
225
+ };
226
+
227
+ const translateX = -(currentIndex * (itemWidth + gap));
228
+ const maxIndex = Math.max(0, data.length - visibleItems);
229
+
230
+ return (
231
+ <Component
232
+ ref={ref as any}
233
+ className={clsx(
234
+ carouselRecipe({ fullWidth }),
235
+ sprinkles({
236
+ margin,
237
+ marginTop,
238
+ marginBottom,
239
+ marginLeft,
240
+ marginRight,
241
+ padding,
242
+ paddingTop,
243
+ paddingBottom,
244
+ paddingLeft,
245
+ paddingRight,
246
+ display,
247
+ flexDirection,
248
+ justifyContent,
249
+ flexWrap,
250
+ flex,
251
+ width,
252
+ height,
253
+ minWidth,
254
+ maxWidth,
255
+ minHeight,
256
+ position,
257
+ top,
258
+ bottom,
259
+ left,
260
+ right,
261
+ zIndex,
262
+ fontSize,
263
+ fontFamily,
264
+ lineHeight,
265
+ textAlign,
266
+ fontWeight,
267
+ color,
268
+ backgroundColor,
269
+ borderRadius,
270
+ borderWidth,
271
+ borderStyle,
272
+ borderColor,
273
+ boxShadow,
274
+ opacity,
275
+ overflow,
276
+ overflowX,
277
+ overflowY,
278
+ }),
279
+ css,
280
+ className
281
+ )}
282
+ {...htmlProps}>
283
+ <div ref={carouselRef} className={carouselContent}>
284
+ <div
285
+ ref={slideRef}
286
+ className={carouselSlide}
287
+ style={{
288
+ transform: `translateX(${translateX}px)`,
289
+ gap: `${gap}px`,
290
+ }}>
291
+ {data.map((item, index) => (
292
+ <div key={index} className={carouselItem} style={{ width: `${itemWidth}px` }}>
293
+ {item}
294
+ </div>
295
+ ))}
296
+ </div>
297
+ </div>
298
+
299
+ {showNavButtons && (
300
+ <div className={carouselNav}>
301
+ <button type="button" className={carouselNavButton} onClick={handlePrevious} disabled={currentIndex === 0} aria-label="Previous slide">
302
+ <Icon icon="arrowBack" size="md" />
303
+ </button>
304
+ <button type="button" className={carouselNavButton} onClick={handleNext} disabled={currentIndex >= maxIndex} aria-label="Next slide">
305
+ <Icon icon="arrowForward" size="md" />
306
+ </button>
307
+ </div>
308
+ )}
309
+
310
+ {showBullets && (
311
+ <div className={carouselBullets}>
312
+ {Array.from({ length: maxIndex + 1 }, (_, index) => (
313
+ <button
314
+ key={index}
315
+ type="button"
316
+ className={clsx(carouselBullet, index === currentIndex && carouselBulletActive)}
317
+ onClick={() => handleBulletClick(index)}
318
+ aria-label={`Go to slide ${index + 1}`}
319
+ />
320
+ ))}
321
+ </div>
322
+ )}
323
+ </Component>
324
+ );
325
+ }
326
+ );
327
+
328
+ Carousel.displayName = 'Carousel';
@@ -0,0 +1,4 @@
1
+ // export { Carousel } from '.';
2
+ // export type { CarouselProps } from '.';
3
+
4
+ // export { styles as CarouselStyles } from './styles.css';
@@ -0,0 +1,142 @@
1
+ import { clsx } from 'clsx';
2
+ import { forwardRef } from 'react';
3
+ import { columnsRecipe, type ColumnsVariants, columnWidths } from './Columns.css';
4
+ import { sprinkles, type Sprinkles } from '../../styles/sprinkles.css';
5
+
6
+ export interface ColumnsProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>, Sprinkles, NonNullable<ColumnsVariants> {
7
+ css?: string;
8
+ columns?: (keyof typeof columnWidths)[];
9
+ as?: 'div' | 'section' | 'article';
10
+ }
11
+
12
+ export const Columns = forwardRef<HTMLDivElement, ColumnsProps>(
13
+ (
14
+ {
15
+ children,
16
+ columns,
17
+ align,
18
+ spacing,
19
+ wrap,
20
+ reverse,
21
+ alignItems,
22
+ as: Component = 'div',
23
+ css,
24
+ className,
25
+ // Extract sprinkles props
26
+ margin,
27
+ marginTop,
28
+ marginBottom,
29
+ marginLeft,
30
+ marginRight,
31
+ padding,
32
+ paddingTop,
33
+ paddingBottom,
34
+ paddingLeft,
35
+ paddingRight,
36
+ gap,
37
+ display,
38
+ flexDirection,
39
+ justifyContent,
40
+ flexWrap,
41
+ flex,
42
+ width,
43
+ height,
44
+ minWidth,
45
+ maxWidth,
46
+ minHeight,
47
+ position,
48
+ top,
49
+ bottom,
50
+ left,
51
+ right,
52
+ zIndex,
53
+ fontSize,
54
+ fontFamily,
55
+ lineHeight,
56
+ textAlign,
57
+ fontWeight,
58
+ color,
59
+ backgroundColor,
60
+ borderRadius,
61
+ borderWidth,
62
+ borderStyle,
63
+ borderColor,
64
+ boxShadow,
65
+ opacity,
66
+ overflow,
67
+ overflowX,
68
+ overflowY,
69
+ ...htmlProps
70
+ },
71
+ ref
72
+ ) => {
73
+ const childrenArray = Array.isArray(children) ? children : [children];
74
+
75
+ return (
76
+ <Component
77
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
+ ref={ref as any}
79
+ className={clsx(
80
+ columnsRecipe({ align, spacing, wrap, reverse, alignItems }),
81
+ sprinkles({
82
+ margin,
83
+ marginTop,
84
+ marginBottom,
85
+ marginLeft,
86
+ marginRight,
87
+ padding,
88
+ paddingTop,
89
+ paddingBottom,
90
+ paddingLeft,
91
+ paddingRight,
92
+ gap,
93
+ display,
94
+ flexDirection,
95
+ justifyContent,
96
+ flexWrap,
97
+ flex,
98
+ width,
99
+ height,
100
+ minWidth,
101
+ maxWidth,
102
+ minHeight,
103
+ position,
104
+ top,
105
+ bottom,
106
+ left,
107
+ right,
108
+ zIndex,
109
+ fontSize,
110
+ fontFamily,
111
+ lineHeight,
112
+ textAlign,
113
+ fontWeight,
114
+ color,
115
+ backgroundColor,
116
+ borderRadius,
117
+ borderWidth,
118
+ borderStyle,
119
+ borderColor,
120
+ boxShadow,
121
+ opacity,
122
+ overflow,
123
+ overflowX,
124
+ overflowY,
125
+ }),
126
+ css,
127
+ className
128
+ )}
129
+ {...htmlProps}>
130
+ {columns && columns.length > 0
131
+ ? childrenArray.map((child, index) => (
132
+ <div key={index} className={clsx(columns[index] && columnWidths[columns[index]])}>
133
+ {child}
134
+ </div>
135
+ ))
136
+ : children}
137
+ </Component>
138
+ );
139
+ }
140
+ );
141
+
142
+ Columns.displayName = 'Columns';
@@ -0,0 +1,5 @@
1
+ // export { Columns } from '.';
2
+ // export type { ColumnsProps } from '.';
3
+ // export { Align as ColumnsAlign } from './types';
4
+
5
+ // export { styles as ColumnsStyles } from './styles.css'
@@ -0,0 +1,202 @@
1
+ import { clsx } from 'clsx';
2
+ import { forwardRef, useEffect, useState } from 'react';
3
+ import { consentActions, consentContent, type ConsentCookieVariants, consentRecipe } from './ConsentCookie.css';
4
+ import { sprinkles, type Sprinkles } from '../../styles/sprinkles.css';
5
+ import { getCookie, setCookie } from '../../utils/cookie';
6
+ import { Button } from '../Button/Button';
7
+
8
+ // Declare window object including gtag to avoid TypeScript errors
9
+ declare const window: Window &
10
+ typeof globalThis & {
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ gtag: any;
13
+ };
14
+
15
+ export interface ConsentCookieProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'color'>, Sprinkles, NonNullable<ConsentCookieVariants> {
16
+ css?: string;
17
+ cookieName?: string;
18
+ cookieExpirationDays?: number;
19
+ onAccept?: () => void;
20
+ onReject?: () => void;
21
+ translations?: {
22
+ actions: {
23
+ accept: string;
24
+ reject: string;
25
+ };
26
+ };
27
+ enableGoogleAnalytics?: boolean;
28
+ }
29
+
30
+ export const ConsentCookie = forwardRef<HTMLDivElement, ConsentCookieProps>(
31
+ (
32
+ {
33
+ children,
34
+ variant,
35
+ cookieName = 'consent',
36
+ cookieExpirationDays = 365,
37
+ onAccept,
38
+ onReject,
39
+ translations,
40
+ enableGoogleAnalytics = true,
41
+ css,
42
+ className,
43
+ // Extract sprinkles props
44
+ margin,
45
+ marginTop,
46
+ marginBottom,
47
+ marginLeft,
48
+ marginRight,
49
+ padding,
50
+ paddingTop,
51
+ paddingBottom,
52
+ paddingLeft,
53
+ paddingRight,
54
+ gap,
55
+ display,
56
+ flexDirection,
57
+ justifyContent,
58
+ flexWrap,
59
+ flex,
60
+ width,
61
+ height,
62
+ minWidth,
63
+ maxWidth,
64
+ minHeight,
65
+ zIndex,
66
+ fontSize,
67
+ fontFamily,
68
+ lineHeight,
69
+ textAlign,
70
+ fontWeight,
71
+ color,
72
+ backgroundColor,
73
+ borderRadius,
74
+ borderWidth,
75
+ borderStyle,
76
+ borderColor,
77
+ boxShadow,
78
+ opacity,
79
+ overflow,
80
+ overflowX,
81
+ overflowY,
82
+ ...htmlProps
83
+ },
84
+ ref
85
+ ) => {
86
+ const [showConsent, setShowConsent] = useState(false);
87
+
88
+ const handleAccept = () => {
89
+ setShowConsent(false);
90
+ setCookie(cookieName, 'true', cookieExpirationDays);
91
+
92
+ if (enableGoogleAnalytics && typeof window !== 'undefined' && typeof window.gtag !== 'undefined') {
93
+ window.gtag('consent', 'update', {
94
+ analytics_storage: 'granted',
95
+ });
96
+ }
97
+
98
+ onAccept?.();
99
+ };
100
+
101
+ const handleReject = () => {
102
+ setShowConsent(false);
103
+ setCookie(cookieName, 'false', cookieExpirationDays);
104
+
105
+ if (enableGoogleAnalytics && typeof window !== 'undefined' && typeof window.gtag !== 'undefined') {
106
+ window.gtag('consent', 'update', {
107
+ analytics_storage: 'denied',
108
+ });
109
+ }
110
+
111
+ onReject?.();
112
+ };
113
+
114
+ useEffect(() => {
115
+ const consentValue = getCookie(cookieName);
116
+ const shouldShowConsent = consentValue !== 'true' && consentValue !== 'false';
117
+ const areCookiesAccepted = consentValue === 'true';
118
+
119
+ if (shouldShowConsent) {
120
+ setShowConsent(true);
121
+ }
122
+
123
+ // Set initial Google Analytics consent
124
+ if (enableGoogleAnalytics && typeof window !== 'undefined' && typeof window.gtag !== 'undefined') {
125
+ const gAnalyticsConsent = areCookiesAccepted ? 'granted' : 'denied';
126
+ window.gtag('consent', 'update', {
127
+ analytics_storage: gAnalyticsConsent,
128
+ });
129
+ }
130
+ }, [cookieName, enableGoogleAnalytics]);
131
+
132
+ if (!showConsent) return null;
133
+
134
+ return (
135
+ <div
136
+ ref={ref}
137
+ className={clsx(
138
+ consentRecipe({ variant }),
139
+ sprinkles({
140
+ margin,
141
+ marginTop,
142
+ marginBottom,
143
+ marginLeft,
144
+ marginRight,
145
+ padding,
146
+ paddingTop,
147
+ paddingBottom,
148
+ paddingLeft,
149
+ paddingRight,
150
+ gap,
151
+ display,
152
+ flexDirection,
153
+ justifyContent,
154
+ flexWrap,
155
+ flex,
156
+ width,
157
+ height,
158
+ minWidth,
159
+ maxWidth,
160
+ minHeight,
161
+ zIndex,
162
+ fontSize,
163
+ fontFamily,
164
+ lineHeight,
165
+ textAlign,
166
+ fontWeight,
167
+ color,
168
+ backgroundColor,
169
+ borderRadius,
170
+ borderWidth,
171
+ borderStyle,
172
+ borderColor,
173
+ boxShadow,
174
+ opacity,
175
+ overflow,
176
+ overflowX,
177
+ overflowY,
178
+ }),
179
+ css,
180
+ className
181
+ )}
182
+ role="dialog"
183
+ aria-modal="true"
184
+ aria-labelledby="consent-title"
185
+ {...htmlProps}>
186
+ <div className={consentContent}>
187
+ {children}
188
+ <div className={consentActions}>
189
+ <Button variant="outline" size="sm" onClick={handleReject}>
190
+ {translations?.actions.reject || 'Reject'}
191
+ </Button>
192
+ <Button variant="primary" size="sm" onClick={handleAccept}>
193
+ {translations?.actions.accept || 'Accept'}
194
+ </Button>
195
+ </div>
196
+ </div>
197
+ </div>
198
+ );
199
+ }
200
+ );
201
+
202
+ ConsentCookie.displayName = 'ConsentCookie';
@@ -0,0 +1,4 @@
1
+ // export { ConsentCookie } from '.';
2
+ // export type { ConsentCookieProps } from '.';
3
+
4
+ // export { styles as ConsentCookieStyles } from './styles.css';