tee3apps-cms-sdk-react 0.0.20 → 0.0.23

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 (27) hide show
  1. package/dist/index.js +3 -3
  2. package/dist/index.js.map +1 -1
  3. package/dist/index.mjs +3 -3
  4. package/dist/index.mjs.map +1 -1
  5. package/package.json +1 -1
  6. package/src/Page.tsx +2 -2
  7. package/src/PageComponents/BoxComponent.tsx +123 -25
  8. package/src/PageComponents/Visual-Components/CarouselComponent.tsx +300 -167
  9. package/src/PageComponents/Visual-Components/GroupBrandComponent.tsx +396 -390
  10. package/src/PageComponents/Visual-Components/GroupCategoryComponent.tsx +21 -13
  11. package/src/PageComponents/Visual-Components/GroupImageList.tsx +642 -668
  12. package/src/PageComponents/Visual-Components/GroupProductComponent.tsx +46 -20
  13. package/src/PageComponents/Visual-Components/GroupVideoList.tsx +693 -589
  14. package/src/PageComponents/Visual-Components/ImageComponent.tsx +74 -18
  15. package/src/PageComponents/Visual-Components/LottieComponent.tsx +14 -8
  16. package/src/PageComponents/Visual-Components/NavigationComponent.tsx +74 -27
  17. package/src/PageComponents/Visual-Components/RichTextComponent.tsx +1 -1
  18. package/src/PageComponents/Visual-Components/TabComponent.tsx +1624 -876
  19. package/src/PageComponents/Visual-Components/TextComponent.tsx +24 -10
  20. package/src/PageComponents/Visual-Components/VideoComponent.tsx +33 -11
  21. package/src/PageComponents/Visual-Components/tab.css +645 -611
  22. package/src/index.css +126 -81
  23. package/src/Components/BoxRenderer.tsx +0 -108
  24. package/src/Components/ComponentRenderer.tsx +0 -29
  25. package/src/Components/ImageComponent.tsx +0 -68
  26. package/src/Components/RowComponent.tsx +0 -66
  27. package/src/Components/TextComponent.tsx +0 -47
@@ -13,7 +13,7 @@ interface Slide {
13
13
  width: number | null;
14
14
  height: number | null;
15
15
  };
16
- video: {
16
+ video?: {
17
17
  url?: string;
18
18
  alt?: string;
19
19
  };
@@ -24,7 +24,7 @@ interface Slide {
24
24
  external_link: {
25
25
  url: string;
26
26
  target: string;
27
- };
27
+ } | null;
28
28
  }
29
29
 
30
30
  interface SlideMode {
@@ -60,7 +60,7 @@ export interface CarouselProps {
60
60
  sliderArrowVisible: boolean;
61
61
  pagingDotVisible: boolean;
62
62
  objectFit: string;
63
- slides: SlidesData[];
63
+ slides: SlidesData[] | Slide[][]; // Support both formats: SlidesData[] or nested array Slide[][]
64
64
  }
65
65
 
66
66
  interface CarouselComponentMainProps {
@@ -75,10 +75,62 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
75
75
  const [currentSlide, setCurrentSlide] = useState(0);
76
76
  const [isPlaying, setIsPlaying] = useState(props.autoplay);
77
77
  const [isHovered, setIsHovered] = useState(false);
78
+ const [prevButtonHovered, setPrevButtonHovered] = useState(false);
79
+ const [nextButtonHovered, setNextButtonHovered] = useState(false);
80
+
81
+ // Detect data structure and safely get slides with fallback
82
+ // Check if slides[0] is an array of Slide objects (new format) or has 'all' property (old format)
83
+ const firstSlideItem = props.slides && props.slides[0] ? props.slides[0] : null;
84
+
85
+ // Check if it's the new nested array format (array of Slide objects)
86
+ const isNestedArrayFormat = Array.isArray(firstSlideItem) &&
87
+ firstSlideItem.length > 0 &&
88
+ typeof firstSlideItem[0] === 'object' &&
89
+ 'sl_id' in (firstSlideItem[0] as any);
90
+
91
+ let slides: Slide[] = [];
92
+ let slidesData: SlidesData | null = null;
93
+
94
+ if (isNestedArrayFormat) {
95
+ // New format: slides is Slide[][] - first element is an array of Slide objects
96
+ slides = (firstSlideItem as Slide[]) || [];
97
+ } else if (firstSlideItem && typeof firstSlideItem === 'object' && 'all' in firstSlideItem) {
98
+ // Old format: slides is SlidesData[] - has 'all' property
99
+ slidesData = firstSlideItem as SlidesData;
100
+ slides = slidesData?.all || [];
101
+ } else {
102
+ // Fallback: empty array
103
+ slides = [];
104
+ }
78
105
 
79
- const slides = props.slides[0].all;
80
106
  const totalSlides = slides.length;
81
107
 
108
+ // Get current mode settings
109
+ const getCurrentMode = () => {
110
+ // If using nested array format, mode data doesn't exist, use defaults
111
+ if (isNestedArrayFormat || !slidesData || !slidesData.mode) {
112
+ // Return default mode based on device
113
+ const defaultSlidesToShow = deviceMode === 'mobileweb' || deviceMode === 'mobileapp' ? 1 :
114
+ deviceMode === 'tablet' ? 2 : 1;
115
+ return { slidesToShow: defaultSlidesToShow };
116
+ }
117
+
118
+ switch(deviceMode) {
119
+ case 'mobileweb':
120
+ return slidesData.mode.mobileweb || { slidesToShow: 1 };
121
+ case 'mobileapp':
122
+ return slidesData.mode.mobileapp || { slidesToShow: 1 };
123
+ case 'tablet':
124
+ return slidesData.mode.tablet || { slidesToShow: 1 };
125
+ case 'web':
126
+ default:
127
+ return slidesData.mode.web || { slidesToShow: 1 };
128
+ }
129
+ };
130
+
131
+ const currentMode = getCurrentMode();
132
+ const slidesToShow = Math.max(1, currentMode.slidesToShow || 1);
133
+
82
134
  // Function to go to next slide (advance by 1 to support wrap pairs)
83
135
  const nextSlide = useCallback(() => {
84
136
  setCurrentSlide((prev) => (prev + 1) % totalSlides);
@@ -96,14 +148,16 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
96
148
 
97
149
  // Handle autoplay
98
150
  useEffect(() => {
99
- if (!props.autoplay || !isPlaying || isHovered) return;
151
+ // Only pause on hover if pauseOnHover is enabled
152
+ const shouldPause = props.pauseOnHover && isHovered;
153
+ if (!props.autoplay || !isPlaying || shouldPause) return;
100
154
 
101
155
  const interval = setInterval(() => {
102
156
  nextSlide();
103
157
  }, props.autoplayInterval);
104
158
 
105
159
  return () => clearInterval(interval);
106
- }, [props.autoplay, props.autoplayInterval, isPlaying, isHovered, nextSlide]);
160
+ }, [props.autoplay, props.autoplayInterval, props.pauseOnHover, isPlaying, isHovered, nextSlide]);
107
161
 
108
162
  // Handle pause on hover
109
163
  const handleMouseEnter = () => {
@@ -120,24 +174,6 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
120
174
  }
121
175
  };
122
176
 
123
- // Get current mode settings
124
- const getCurrentMode = () => {
125
- switch(deviceMode) {
126
- case 'mobileweb':
127
- return props.slides[0].mode.mobileweb;
128
- case 'mobileapp':
129
- return props.slides[0].mode.mobileapp;
130
- case 'tablet':
131
- return props.slides[0].mode.tablet;
132
- case 'web':
133
- default:
134
- return props.slides[0].mode.web;
135
- }
136
- };
137
-
138
- const currentMode = getCurrentMode();
139
- const slidesToShow = currentMode.slidesToShow;
140
-
141
177
  const resolveAssetUrl = (url?: string) => {
142
178
  if (!url) return '';
143
179
  if (url.startsWith('http://') || url.startsWith('https://')) return url;
@@ -145,7 +181,7 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
145
181
  };
146
182
 
147
183
  const buildLinkForSlide = (slide: Slide) => {
148
- console.warn(slide)
184
+ console.warn(slide);
149
185
  switch (slide.link_type) {
150
186
  case 'NONE':
151
187
  return null;
@@ -155,11 +191,11 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
155
191
  const product: any = slide.product || {};
156
192
  const pdType = product?.pd_type || product?.product_type;
157
193
  const code = product?.code || '';
158
- if (!code) return null;
194
+ if (!code) return null;
159
195
 
160
196
  return pdType === 'VARIANT'
161
- ? `/variant/${code}`
162
- : `model/${code}`;
197
+ ? `/${code}`
198
+ : `/model/${code}`;
163
199
  }
164
200
  case 'TAG': {
165
201
  const tag: any = slide.tag || {};
@@ -168,8 +204,8 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
168
204
  }
169
205
  case 'PAGE': {
170
206
  const page: any = slide.page || {};
171
- const pageId = page._id
172
- const pgType=page.page_type
207
+ const pageId = page._id;
208
+ const pgType = page.page_type;
173
209
  return `/page/${pageId}?type=${pgType}`;
174
210
  }
175
211
  default:
@@ -179,20 +215,42 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
179
215
 
180
216
  const handleSlideClick = (slide: Slide) => {
181
217
  const link = buildLinkForSlide(slide);
182
- if (link === null) return;
218
+ if (link === null) {
219
+ // If no link, navigate to next slide
220
+ nextSlide();
221
+ return;
222
+ }
183
223
  if (typeof link === 'string') {
184
224
  if (link.startsWith('http')) {
185
- window.open(link, '_blank');
225
+ window.open(link, slide.external_link?.target || '_blank');
186
226
  } else {
187
227
  window.location.href = link;
188
228
  }
189
229
  return;
190
230
  }
191
- const queryString = Object.entries((link as any).query || {})
192
- .map(([key, value]) => `${key}=${encodeURIComponent(value as string)}`)
193
- .join('&');
194
- const fullPath = `${(link as any).pathname}${queryString ? `?${queryString}` : ''}`;
195
- window.location.href = fullPath;
231
+ };
232
+
233
+ // Calculate which group the current slide belongs to
234
+ const getCurrentGroupIndex = () => {
235
+ return Math.floor(currentSlide / slidesToShow);
236
+ };
237
+
238
+ // Calculate total number of groups needed
239
+ const getTotalGroups = () => {
240
+ return Math.ceil(totalSlides / slidesToShow);
241
+ };
242
+
243
+ // Calculate transform offset for slide animation
244
+ // Transform based on group index, not slide index
245
+ const calculateTransform = () => {
246
+ const groupIndex = getCurrentGroupIndex();
247
+ if (props.vertical) {
248
+ // Vertical sliding: moves up and down
249
+ return `translateY(-${groupIndex * 100}%)`;
250
+ } else {
251
+ // Horizontal sliding: moves left and right
252
+ return `translateX(-${groupIndex * 100}%)`;
253
+ }
196
254
  };
197
255
 
198
256
  return (
@@ -200,165 +258,240 @@ const CarouselComponent: React.FC<CarouselComponentMainProps> = ({
200
258
  className="carousel-container"
201
259
  style={{
202
260
  position: 'relative',
203
- width: '100%',
204
- overflow: 'hidden'
261
+ height: props.height,
262
+ overflow: 'hidden',
263
+ width: '100%'
205
264
  }}
206
265
  onMouseEnter={handleMouseEnter}
207
266
  onMouseLeave={handleMouseLeave}
208
267
  >
209
268
  {/* Slides container */}
210
- <div
211
- className="carousel-slides"
212
- style={{
213
- display: 'flex',
214
- width: '100%',
215
- transition: `opacity ${props.speed}ms ease`,
216
- flexDirection: props.vertical ? 'column' : 'row'
217
- }}
218
- >
219
- {Array.from({ length: slidesToShow }).map((_, offset) => {
220
- const slide = slides[(currentSlide + offset) % totalSlides];
221
- const clickable = buildLinkForSlide(slide) !== null;
222
- return (
223
- <div
224
- key={`${slide.sl_id}-${offset}`}
225
- className="carousel-slide"
226
- style={{
227
- flex: `0 0 ${100 / slidesToShow}%`,
228
- width: props.vertical ? '100%' : `${100 / slidesToShow}%`,
229
- overflow: 'hidden',
230
- display: 'block',
231
- cursor: clickable ? 'pointer' : 'default'
232
- }}
233
- onClick={clickable ? () => handleSlideClick(slide) : undefined}
234
- >
235
- {slide.sl_type === 'video' ? (
236
- <video
237
- src={resolveAssetUrl(slide.video?.url)}
238
- style={{ width: '100%', height: 'auto', display: 'block' }}
239
- autoPlay={props.autoplay}
240
- muted
241
- loop
242
- controls={!props.autoplay}
243
- />
244
- ) : (
245
- <img
246
- src={resolveAssetUrl(slide.image?.url)}
247
- alt={slide.image?.alt || ''}
248
- style={{ width: '100%', height: 'auto', display: 'block' }}
249
- />
250
- )}
251
- </div>
252
- );
253
- })}
254
-
255
- </div>
269
+ {totalSlides > 0 ? (
270
+ <div
271
+ className="carousel-slides"
272
+ style={{
273
+ display: 'flex',
274
+ height: '100%',
275
+ width: '100%',
276
+ // vertical = true: slides move up/down (column direction)
277
+ // vertical = false: slides move left/right (row direction)
278
+ flexDirection: props.vertical ? 'column' : 'row',
279
+ transition: `transform ${props.speed}ms ease-in-out`,
280
+ transform: calculateTransform(),
281
+ willChange: 'transform'
282
+ }}
283
+ >
284
+ {Array.from({ length: getTotalGroups() }).map((_, groupIndex) => {
285
+ // Calculate starting slide index for this group
286
+ const startIndex = groupIndex * slidesToShow;
287
+ // Calculate how many slides are in this group (last group may have fewer)
288
+ const slidesInGroup = Math.min(slidesToShow, totalSlides - startIndex);
289
+
290
+ return (
291
+ <div
292
+ key={groupIndex}
293
+ className="carousel-group"
294
+ style={{
295
+ flexShrink: 0,
296
+ display: 'flex',
297
+ // Items within each slide are ALWAYS in a horizontal row
298
+ flexDirection: 'row',
299
+ width: '100%',
300
+ height: '100%',
301
+ gap: '0px'
302
+ }}
303
+ >
304
+ {Array.from({ length: slidesToShow }).map((_, offset) => {
305
+ const slideIndex = startIndex + offset;
306
+
307
+ // If this position is beyond available slides, render empty space
308
+ if (slideIndex >= totalSlides) {
309
+ return (
310
+ <div
311
+ key={`empty-${offset}`}
312
+ className="carousel-slide-empty"
313
+ style={{
314
+ flexShrink: 0,
315
+ width: `${100 / slidesToShow}%`,
316
+ height: '100%',
317
+ // Empty space, no content
318
+ }}
319
+ />
320
+ );
321
+ }
322
+
323
+ const slide = slides[slideIndex];
324
+
325
+ return (
326
+ <div
327
+ key={`${slide.sl_id}-${offset}`}
328
+ className="carousel-slide"
329
+ style={{
330
+ flexShrink: 0,
331
+ // Items always take equal width in horizontal row
332
+ width: `${100 / slidesToShow}%`,
333
+ height: '100%',
334
+ overflow: 'hidden',
335
+ display: 'flex',
336
+ alignItems: 'center',
337
+ justifyContent: 'center',
338
+ position: 'relative',
339
+ cursor: 'pointer'
340
+ }}
341
+ onClick={() => handleSlideClick(slide)}
342
+ >
343
+ {slide.sl_type === 'video' ? (
344
+ <video
345
+ src={resolveAssetUrl(slide.video?.url)}
346
+ style={{
347
+ width: '100%',
348
+ height: '100%',
349
+ objectFit: props.objectFit as any,
350
+ display: 'block',
351
+ pointerEvents: 'none'
352
+ }}
353
+ autoPlay={props.autoplay}
354
+ muted
355
+ loop
356
+ controls={!props.autoplay}
357
+ />
358
+ ) : (
359
+ <img
360
+ src={resolveAssetUrl(slide.image?.url)}
361
+ alt={slide.image?.alt || ''}
362
+ style={{
363
+ width: '100%',
364
+ height: '100%',
365
+ objectFit: props.objectFit as any,
366
+ display: 'block',
367
+ pointerEvents: 'none'
368
+ }}
369
+ />
370
+ )}
371
+ </div>
372
+ );
373
+ })}
374
+ </div>
375
+ );
376
+ })}
377
+ </div>
378
+ ) : (
379
+ <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', color: '#999' }}>
380
+ No slides added yet
381
+ </div>
382
+ )}
256
383
 
257
384
  {/* Navigation arrows */}
258
385
  {props.sliderArrowVisible && totalSlides > slidesToShow && (
259
386
  <>
260
- <button
261
- className="carousel-arrow carousel-arrow-prev"
262
- onClick={prevSlide}
263
- style={{
264
- position: 'absolute',
265
- ...(props.vertical
266
- ? { top: '10px', left: '50%', transform: 'translateX(-50%)' }
267
- : { top: '50%', left: '1px', transform: 'translateY(-50%)' }),
268
- zIndex: 10,
269
- background: 'white',
270
- color: 'black',
271
- border: '2px solid white',
272
- boxShadow: '0 2px 6px rgba(0,0,0,0.5)',
273
- borderRadius: '15%',
274
- width: '40px',
275
- height: '60px',
276
- cursor: 'pointer',
277
- display: 'flex',
278
- alignItems: 'center',
279
- justifyContent: 'center',
280
- fontSize: '20px',
281
- fontWeight: 'bold',
282
- transition: 'transform 0.2s ease-in-out',
283
-
284
- }}
285
- >
286
- {props.vertical ? '˄' : ''}
287
- </button>
288
-
289
- <button
290
- className="carousel-arrow carousel-arrow-next"
291
- onClick={nextSlide}
292
- style={{
293
- position: 'absolute',
294
- ...(props.vertical
295
- ? { bottom: '10px', left: '50%', transform: 'translateX(-50%)' }
296
- : { top: '50%', right: '1px', transform: 'translateY(-50%)' }),
297
- zIndex: 10,
298
- background: 'white',
299
- color: 'black',
300
- border: '2px solid white',
301
- boxShadow: '0 2px 6px rgba(0,0,0,0.5)',
302
- borderRadius: '15%',
303
- width: '40px',
304
- height: '60px',
305
- cursor: 'pointer',
306
- display: 'flex',
307
- alignItems: 'center',
308
- justifyContent: 'center',
309
- fontSize: '20px',
310
- fontWeight: 'bold',
311
- transition: 'transform 0.2s ease-in-out',
312
- }}
313
- >
314
- {props.vertical ? '˅' : '›'}
315
- </button>
316
-
387
+ <button
388
+ onClick={prevSlide}
389
+ onMouseEnter={() => setPrevButtonHovered(true)}
390
+ onMouseLeave={() => setPrevButtonHovered(false)}
391
+ style={{
392
+ position: 'absolute',
393
+ ...(props.vertical
394
+ ? { top: '8px', right: '16px' }
395
+ : { left: '8px', top: '50%', transform: 'translateY(-50%)' }
396
+ ),
397
+ background: prevButtonHovered ? 'rgba(255, 255, 255, 0.5)' : 'transparent',
398
+ transition: 'all 0.2s ease',
399
+ padding: '8px',
400
+ borderRadius: '4px',
401
+ boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
402
+ zIndex: 10,
403
+ border: 'none',
404
+ cursor: 'pointer',
405
+ display: 'flex',
406
+ alignItems: 'center',
407
+ justifyContent: 'center'
408
+ }}
409
+ >
410
+ {props.vertical ? (
411
+ <span style={{ color: '#374151', fontSize: '16px', fontWeight: 'bold' }}>^</span>
412
+ ) : (
413
+ <span style={{ color: '#374151', fontSize: '20px', fontWeight: 'bold' }}>&lt;</span>
414
+ )}
415
+ </button>
416
+ <button
417
+ onClick={nextSlide}
418
+ onMouseEnter={() => setNextButtonHovered(true)}
419
+ onMouseLeave={() => setNextButtonHovered(false)}
420
+ style={{
421
+ position: 'absolute',
422
+ ...(props.vertical
423
+ ? { bottom: '8px', right: '16px' }
424
+ : { right: '8px', top: '50%', transform: 'translateY(-50%)' }
425
+ ),
426
+ background: nextButtonHovered ? 'rgba(255, 255, 255, 0.5)' : 'transparent',
427
+ transition: 'all 0.2s ease',
428
+ padding: '8px',
429
+ borderRadius: '4px',
430
+ boxShadow: '0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)',
431
+ zIndex: 10,
432
+ border: 'none',
433
+ cursor: 'pointer',
434
+ display: 'flex',
435
+ alignItems: 'center',
436
+ justifyContent: 'center'
437
+ }}
438
+ >
439
+ {props.vertical ? (
440
+ <span style={{ color: '#374151', fontSize: '16px', fontWeight: 'bold' }}>v</span>
441
+ ) : (
442
+ <span style={{ color: '#374151', fontSize: '20px', fontWeight: 'bold' }}>&gt;</span>
443
+ )}
444
+ </button>
317
445
  </>
318
446
  )}
319
447
 
320
448
  {/* Pagination dots */}
321
- {props.pagingDotVisible && totalSlides > 1 && (
449
+ {props.pagingDotVisible && getTotalGroups() > 1 && (
322
450
  <div
323
451
  className="carousel-dots"
324
452
  style={{
325
453
  position: 'absolute',
326
454
  ...(props.vertical
327
- ? { top: '50%', right: '10px', transform: 'translateY(-50%)', bottom: 'auto', left: 'auto' }
328
- : { bottom: '15px', left: '0', right: '0' }
455
+ ? { top: '50%', right: '16px', transform: 'translateY(-50%)' }
456
+ : { bottom: '16px', left: '50%', transform: 'translateX(-50%)' }
329
457
  ),
330
458
  display: 'flex',
331
459
  justifyContent: 'center',
332
460
  alignItems: 'center',
333
461
  flexDirection: props.vertical ? 'column' : 'row',
334
462
  gap: '8px',
335
- zIndex: 100,
336
- padding: props.vertical ? '8px 6px' : '6px 10px',
337
-
338
- borderRadius: props.vertical ? '12px' : '16px'
463
+ zIndex: 100
339
464
  }}
340
465
  >
341
- {Array.from({ length: totalSlides }).map((_, index) => (
342
- <button
343
- key={index}
344
- aria-label={`Go to slide ${index + 1}`}
345
- className={`carousel-dot ${index === currentSlide ? 'active' : ''}`}
346
- onClick={() => goToSlide(index)}
347
- style={{
348
- width: index === currentSlide ? '12px' : '10px',
349
- height: index === currentSlide ? '12px' : '10px',
350
- borderRadius: '50%',
351
- border: 'none',
352
- background: index === currentSlide ? '#000' : '#ccc',
353
- cursor: 'pointer',
354
- transition: 'all 200ms ease'
355
- }}
356
- />
357
- ))}
466
+ {Array.from({ length: getTotalGroups() }).map((_, groupIndex) => {
467
+ const currentGroupIndex = getCurrentGroupIndex();
468
+ // Navigate to the first slide of the selected group
469
+ const goToGroup = () => {
470
+ const firstSlideInGroup = groupIndex * slidesToShow;
471
+ goToSlide(firstSlideInGroup);
472
+ };
473
+
474
+ return (
475
+ <button
476
+ key={groupIndex}
477
+ aria-label={`Go to group ${groupIndex + 1}`}
478
+ onClick={goToGroup}
479
+ style={{
480
+ width: currentGroupIndex === groupIndex ? '12px' : '10px',
481
+ height: currentGroupIndex === groupIndex ? '12px' : '10px',
482
+ borderRadius: '50%',
483
+ border: 'none',
484
+ background: currentGroupIndex === groupIndex ? '#000' : '#ccc',
485
+ cursor: 'pointer',
486
+ transition: 'all 200ms ease'
487
+ }}
488
+ />
489
+ );
490
+ })}
358
491
  </div>
359
492
  )}
360
493
  </div>
361
494
  );
362
495
  };
363
496
 
364
- export default CarouselComponent;
497
+ export default CarouselComponent;