1
- import React , { useState , useEffect , useRef } from "react" ;
1
+ import React , { useEffect , useRef , useState } from "react" ;
2
2
import { AnimatePresence , motion , MotionConfig } from "framer-motion" ;
3
3
import { ChevronLeftIcon , ChevronRightIcon } from "lucide-react" ;
4
4
5
- // code adapted from https://buildui.com/courses/framer-motion-recipes/carousel-part-1
6
-
7
5
export type ImageProps = {
8
6
url : string ;
9
7
alt : string ;
@@ -23,7 +21,7 @@ const Carousel = ({ images }: { images: ImageProps[] }) => {
23
21
clearExistingInterval ( ) ;
24
22
intervalRef . current = setInterval ( ( ) => {
25
23
setIndex ( ( prevIndex ) => ( prevIndex + 1 ) % images . length ) ;
26
- } , 3000 ) ;
24
+ } , 5000 ) ;
27
25
} ;
28
26
29
27
const prevSlide = ( ) => {
@@ -42,30 +40,25 @@ const Carousel = ({ images }: { images: ImageProps[] }) => {
42
40
startInterval ( ) ;
43
41
44
42
return ( ) => clearExistingInterval ( ) ;
45
- } ) ;
46
-
47
- // TODO: make it infinite scroll to not show white background
48
- // TODO: use bigger pictures
43
+ } , [ images . length ] ) ;
49
44
50
45
return (
51
- < div className = "m-auto flex flex-auto items-center" >
46
+ < div className = "m-auto flex max-w-screen-md flex-auto items-center" >
52
47
< MotionConfig transition = { { duration : 0.7 , ease : [ 0.32 , 0.72 , 0 , 1 ] } } >
53
- < div className = "relative w-full max-w-7xl overflow-hidden" >
48
+ < div className = "relative w-full overflow-hidden" >
54
49
< div className = "relative flex justify-center" >
55
50
< motion . div
56
- animate = { { x : `-${ index * 33 } %` } }
57
- className = "flex"
58
- initial = { "center" }
59
- // style={{ width: `${200 * images.length}%` }}
51
+ animate = { { x : `-${ index * 100 } %` } }
52
+ className = "w-[100 * images.length]% flex"
60
53
>
61
- { images . map ( ( image , i ) => (
54
+ { [ ... images , ... images ] . map ( ( image , i ) => (
62
55
< motion . img
63
56
key = { i }
64
57
src = { image . url }
65
58
alt = { image . alt }
66
59
width = { 800 }
67
60
height = { 800 }
68
- className = "h-auto w-full rounded-md border-2 border-white object-cover"
61
+ className = "w-[100 / images.length]% h-auto rounded-md border-2 border-white object-cover"
69
62
/>
70
63
) ) }
71
64
</ motion . div >
@@ -75,10 +68,10 @@ const Carousel = ({ images }: { images: ImageProps[] }) => {
75
68
animate = { { opacity : 0.7 } }
76
69
exit = { { opacity : 0 , pointerEvents : "none" } }
77
70
whileHover = { { opacity : 1 } }
78
- className = "absolute left-4 top-1/2 flex h-8 w-8 items-center justify-center rounded-full bg-white"
71
+ className = "absolute left-4 top-1/2 flex h-8 w-8 items-center justify-center rounded-full border border-gray-3 bg-white"
79
72
onClick = { prevSlide }
80
73
>
81
- < ChevronLeftIcon className = "h-6 w-6" />
74
+ < ChevronLeftIcon className = "h-6 w-6" color = { "black" } />
82
75
</ motion . button >
83
76
</ AnimatePresence >
84
77
< AnimatePresence initial = { false } >
@@ -87,10 +80,10 @@ const Carousel = ({ images }: { images: ImageProps[] }) => {
87
80
animate = { { opacity : 0.7 } }
88
81
exit = { { opacity : 0 , pointerEvents : "none" } }
89
82
whileHover = { { opacity : 1 } }
90
- className = "absolute right-4 top-1/2 flex h-8 w-8 items-center justify-center rounded-full bg-white"
83
+ className = "absolute right-4 top-1/2 flex h-8 w-8 items-center justify-center rounded-full border border-gray-3 bg-white hover:border-gray-2 "
91
84
onClick = { nextSlide }
92
85
>
93
- < ChevronRightIcon className = "h-6 w-6" />
86
+ < ChevronRightIcon className = "h-6 w-6" color = { "black" } />
94
87
</ motion . button >
95
88
</ AnimatePresence >
96
89
</ div >
@@ -100,4 +93,4 @@ const Carousel = ({ images }: { images: ImageProps[] }) => {
100
93
) ;
101
94
} ;
102
95
103
- export default Carousel ;
96
+ export default Carousel ;
0 commit comments