@@ -19,13 +19,6 @@ interface IMobileMenuProps {
19
19
links : ILink [ ] ;
20
20
}
21
21
22
- /**
23
- * Renders the mobile menu.
24
- * Animates the X when clicked, and animates the menu items with Framer Motion
25
- * @function MobileMenu
26
- * @returns {JSX.Element } - Rendered component
27
- */
28
-
29
22
const MobileMenu = ( { links } : IMobileMenuProps ) => {
30
23
const [ isExpanded , setisExpanded ] = useCycle < boolean > ( false , true ) ;
31
24
const ref = useRef ( null ) ;
@@ -36,99 +29,101 @@ const MobileMenu = ({ links }: IMobileMenuProps) => {
36
29
37
30
useClickAway ( ref , handleClickOutside ) ;
38
31
39
- const itemVariants = {
40
- closed : {
41
- opacity : 0 ,
42
- } ,
43
- open : { opacity : 1 } ,
44
- } ;
45
-
46
- const sideVariants = {
32
+ const menuVariants = {
47
33
closed : {
34
+ x : "100%" ,
48
35
transition : {
49
- staggerChildren : 0.3 ,
50
- staggerDirection : - 1 ,
36
+ type : "spring" ,
37
+ stiffness : 400 ,
38
+ damping : 40 ,
51
39
} ,
52
40
} ,
53
41
open : {
42
+ x : 0 ,
54
43
transition : {
55
- staggerChildren : 0.3 ,
56
- staggerDirection : 1 ,
44
+ type : "spring" ,
45
+ stiffness : 400 ,
46
+ damping : 40 ,
57
47
} ,
58
48
} ,
59
49
} ;
60
50
51
+ const itemVariants = {
52
+ closed : ( i : number ) => ( {
53
+ x : i % 2 === 0 ? "-100%" : "100%" ,
54
+ opacity : 0 ,
55
+ transition : {
56
+ delay : 0.15 ,
57
+ } ,
58
+ } ) ,
59
+ open : ( i : number ) => ( {
60
+ x : 0 ,
61
+ opacity : 1 ,
62
+ transition : {
63
+ type : "spring" ,
64
+ stiffness : 300 ,
65
+ damping : 24 ,
66
+ delay : i * 0.05 ,
67
+ } ,
68
+ } ) ,
69
+ } ;
70
+
61
71
return (
62
72
< div
63
73
ref = { ref }
64
74
className = "z-50 md:hidden lg:hidden xl:hidden"
65
75
data-testid = "mobilemenu"
66
76
>
67
77
< Hamburger onClick = { setisExpanded } animatetoX = { isExpanded } />
68
- < div
69
- id = "mobile-menu"
70
- data-testid = "mobile-menu"
71
- data-cy = "mobile-menu"
72
- aria-hidden = { ! isExpanded }
73
- className = "absolute right-0 w-full text-center bg-gray-800 mt-4 w-30"
74
- >
75
- < AnimatePresence >
76
- { isExpanded && (
77
- < motion . aside
78
- initial = { { height : 0 , opacity : 0 } }
79
- animate = { {
80
- height : links . length * 62 , // Adjust the height based on the number of links
81
- opacity : 1 ,
82
- transition : { delay : 0.15 , duration : 1.6 , ease : "easeInOut" } ,
83
- } }
84
- exit = { {
85
- height : 0 ,
86
- transition : { delay : 0.15 , duration : 1.6 , ease : "easeInOut" } ,
87
- } }
88
- >
89
- < nav aria-label = "Navigasjon" >
90
- < motion . div
91
- initial = "closed"
92
- animate = "open"
93
- exit = "closed"
94
- variants = { sideVariants }
95
- >
96
- < ul >
97
- { links . map ( ( { title, name, hash, href } ) => (
98
- < motion . li
99
- key = { title }
100
- className = "block p-4 text-xl text-white hover:underline mx-auto text-center border-t border-b border-gray-600 border-solid shadow"
101
- data-cy = "mobile-menu-item"
102
- variants = { itemVariants }
78
+ < AnimatePresence >
79
+ { isExpanded && (
80
+ < motion . div
81
+ id = "mobile-menu"
82
+ data-testid = "mobile-menu"
83
+ data-cy = "mobile-menu"
84
+ aria-hidden = { ! isExpanded }
85
+ className = "fixed top-0 right-0 w-screen h-screen bg-gray-800 flex items-center justify-center -z-50"
86
+ initial = "closed"
87
+ animate = "open"
88
+ exit = "closed"
89
+ variants = { menuVariants }
90
+ >
91
+ < nav aria-label = "Navigasjon" className = "w-full" >
92
+ < ul className = "w-full" >
93
+ { links . map ( ( { title, name, hash, href } , index ) => (
94
+ < motion . li
95
+ key = { title }
96
+ className = "block p-4 text-xl text-white hover:underline mx-auto text-center border-t border-b border-gray-600 border-solid shadow"
97
+ data-cy = "mobile-menu-item"
98
+ custom = { index }
99
+ variants = { itemVariants }
100
+ >
101
+ { href . startsWith ( "http" ) ? (
102
+ < a
103
+ aria-label = { name }
104
+ href = { href }
105
+ target = "_blank"
106
+ rel = "noreferrer"
107
+ data-testid = { `mobil-${ name } ` }
108
+ >
109
+ { name }
110
+ </ a >
111
+ ) : (
112
+ < Link
113
+ href = { href }
114
+ data-testid = { `mobil-${ name } ` }
115
+ prefetch = { true }
103
116
>
104
- { href . startsWith ( "http" ) ? (
105
- < a
106
- aria-label = { name }
107
- href = { href }
108
- target = "_blank"
109
- rel = "noreferrer"
110
- data-testid = { `mobil-${ name } ` }
111
- >
112
- { name }
113
- </ a >
114
- ) : (
115
- < Link
116
- href = { href }
117
- data-testid = { `mobil-${ name } ` }
118
- prefetch = { true }
119
- >
120
- { name }
121
- </ Link >
122
- ) }
123
- </ motion . li >
124
- ) ) }
125
- </ ul >
126
- </ motion . div >
127
- </ nav >
128
- </ motion . aside >
129
- ) }
130
- </ AnimatePresence >
131
- </ div >
117
+ { name }
118
+ </ Link >
119
+ ) }
120
+ </ motion . li >
121
+ ) ) }
122
+ </ ul >
123
+ </ nav >
124
+ </ motion . div >
125
+ ) }
126
+ </ AnimatePresence >
132
127
</ div >
133
128
) ;
134
129
} ;
0 commit comments