@stackshift-ui/navigation 6.0.13 → 6.1.0-alpha.1
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/dist/chunk-4N6ET2I6.mjs +1 -0
- package/dist/{chunk-YNDJK4RH.mjs → chunk-67XVPRGX.mjs} +1 -1
- package/dist/chunk-6QSBJPEW.mjs +1 -0
- package/dist/{chunk-6XDFQS4J.mjs → chunk-EASZP4S2.mjs} +1 -1
- package/dist/{chunk-DJV2UTMZ.mjs → chunk-LBUYM4NV.mjs} +1 -1
- package/dist/chunk-MSVUIX4E.mjs +1 -0
- package/dist/chunk-OXF5VEOU.mjs +1 -0
- package/dist/chunk-P3TZNIE6.mjs +1 -0
- package/dist/chunk-PCTXJCVP.mjs +1 -0
- package/dist/{chunk-KB2HS5UA.mjs → chunk-SVLHEWIY.mjs} +1 -1
- package/dist/chunk-V7KKZJMX.mjs +1 -0
- package/dist/context/megaNavContext.d.ts +14 -0
- package/dist/context/megaNavContext.mjs +1 -0
- package/dist/helper/index.d.ts +2 -1
- package/dist/helper/index.mjs +1 -1
- package/dist/helper.d.ts +6 -0
- package/dist/helper.mjs +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.mjs +1 -1
- package/dist/navigation.d.ts +9 -1
- package/dist/navigation.mjs +1 -1
- package/dist/navigation_a.mjs +1 -1
- package/dist/navigation_b.mjs +1 -1
- package/dist/navigation_c.mjs +1 -1
- package/dist/navigation_d.mjs +1 -1
- package/dist/navigation_e.mjs +1 -1
- package/dist/navigation_f.d.ts +3 -0
- package/dist/navigation_f.mjs +1 -0
- package/dist/navigation_g.d.ts +3 -0
- package/dist/navigation_g.mjs +1 -0
- package/dist/navigation_h.d.ts +3 -0
- package/dist/navigation_h.mjs +1 -0
- package/dist/types.d.ts +104 -1
- package/package.json +16 -8
- package/src/context/megaNavContext.tsx +78 -0
- package/src/helper/index.tsx +130 -0
- package/src/helper.ts +14 -0
- package/src/index.ts +3 -0
- package/src/navigation.tsx +29 -1
- package/src/navigation_f.tsx +531 -0
- package/src/navigation_g.tsx +607 -0
- package/src/navigation_h.tsx +742 -0
- package/src/types.ts +113 -1
- package/dist/chunk-KQFO7OZP.mjs +0 -1
- package/dist/chunk-TTJMPYYC.mjs +0 -1
- package/dist/helper/blockStyle.js +0 -1
- package/dist/helper/index.js +0 -1
- package/dist/index.js +0 -2
- package/dist/navigation.js +0 -1
- package/dist/navigation_a.js +0 -1
- package/dist/navigation_b.js +0 -1
- package/dist/navigation_c.js +0 -1
- package/dist/navigation_d.js +0 -1
- package/dist/navigation_e.js +0 -1
- package/dist/types.js +0 -1
- package/src/helper/index.ts +0 -14
|
@@ -0,0 +1,607 @@
|
|
|
1
|
+
import { Image } from "@stackshift-ui/image";
|
|
2
|
+
import { Link } from "@stackshift-ui/link";
|
|
3
|
+
import { Section } from "@stackshift-ui/section";
|
|
4
|
+
import { SocialIcons } from "@stackshift-ui/social-icons";
|
|
5
|
+
import React, { Fragment, useState } from "react";
|
|
6
|
+
import { BsChevronDown } from "react-icons/bs";
|
|
7
|
+
|
|
8
|
+
import { animated, useSpring } from "@react-spring/web";
|
|
9
|
+
import { useWindowScroll } from "@uidotdev/usehooks";
|
|
10
|
+
import Sticky from "react-sticky-el";
|
|
11
|
+
|
|
12
|
+
import { logoLink } from "./helper";
|
|
13
|
+
import { NavigationProps } from "./navigation";
|
|
14
|
+
import { Socials } from "./types";
|
|
15
|
+
|
|
16
|
+
const navlinkStyle =
|
|
17
|
+
"small-text-style group-hover:text-white hover:text-white relative after:content-[''] after:w-0 hover:after:w-full h-5 !outline-none after:h-[0.5px] after:bg-white after:absolute after:bottom-0 after:left-0 after:transition-all after:duration-300";
|
|
18
|
+
|
|
19
|
+
export default function Navigation_G({
|
|
20
|
+
logo,
|
|
21
|
+
smallLogo,
|
|
22
|
+
socialMedia,
|
|
23
|
+
dropdownMenu,
|
|
24
|
+
}: NavigationProps) {
|
|
25
|
+
const [showDropdown, setShowDropdown] = useState(false);
|
|
26
|
+
const [menu, setMenu] = React.useState(false);
|
|
27
|
+
const [openAccordion, setOpenAccordion] = useState<string | null>(null);
|
|
28
|
+
const [isNavHovered, setIsNavHovered] = useState<boolean>(false);
|
|
29
|
+
|
|
30
|
+
let smallLogoLink;
|
|
31
|
+
if (smallLogo?.type === "linkInternal") {
|
|
32
|
+
if (smallLogo?.internalLink === undefined) {
|
|
33
|
+
smallLogoLink = `/`;
|
|
34
|
+
} else {
|
|
35
|
+
if (smallLogo?.internalLink === "Home" || smallLogo?.internalLink === "home") {
|
|
36
|
+
smallLogoLink = `/`;
|
|
37
|
+
} else {
|
|
38
|
+
smallLogoLink = `/${smallLogo?.internalLink}`;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
if (smallLogo?.externalLink === undefined) {
|
|
43
|
+
smallLogoLink = `/`;
|
|
44
|
+
} else {
|
|
45
|
+
smallLogoLink = smallLogo?.externalLink;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const showMenu = () => {
|
|
50
|
+
setMenu(prevState => !prevState);
|
|
51
|
+
|
|
52
|
+
if (!menu) {
|
|
53
|
+
document.body.style.overflow = "hidden";
|
|
54
|
+
} else {
|
|
55
|
+
document.body.style.overflow = "unset";
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
// animated burger menu button
|
|
60
|
+
const firstLine = useSpring({
|
|
61
|
+
transform: menu
|
|
62
|
+
? "translate(9px, 32px) rotate(-45deg) scaleX(1.5)"
|
|
63
|
+
: "translate(17px, 17px) rotate(0deg) scaleX(1)",
|
|
64
|
+
});
|
|
65
|
+
const secondLine = useSpring({
|
|
66
|
+
transform: menu ? "translate(12px, 11px) rotate(45deg)" : "translate(7px, 27px) rotate(0deg)",
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
const [{ x: _, y }] = useWindowScroll();
|
|
70
|
+
const sticky = y && y > 5 ? "bg-black fixed top-0" : "fixed bg-transparent";
|
|
71
|
+
const isScrolled = y && y > 5;
|
|
72
|
+
|
|
73
|
+
const toggleAccordion = (key: string | undefined) => {
|
|
74
|
+
if (!key) return;
|
|
75
|
+
setOpenAccordion(openAccordion === key ? null : key);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const handleNavHover = (hovered: boolean) => {
|
|
79
|
+
setIsNavHovered(hovered);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
return (
|
|
83
|
+
<Section className="w-full flex flex-col absolute top-0 z-50">
|
|
84
|
+
<Sticky stickyClassName="pt-[80px]" topOffset={100} isIOSFixEnabled={false}>
|
|
85
|
+
<nav
|
|
86
|
+
className={`w-full z-50 md:gap-2 gap-0 hover:bg-black/80 transition-colors duration-300 ${
|
|
87
|
+
showDropdown ? "!bg-black border-b-white" : "border-b-transparent"
|
|
88
|
+
} ${sticky}`}
|
|
89
|
+
onMouseEnter={() => handleNavHover(true)}
|
|
90
|
+
onMouseLeave={() => handleNavHover(false)}>
|
|
91
|
+
<div className={`container z-10`}>
|
|
92
|
+
<div
|
|
93
|
+
className={`w-full flex flex-wrap justify-between items-center ${
|
|
94
|
+
isScrolled ? "py-6" : "py-6"
|
|
95
|
+
}`}>
|
|
96
|
+
<div className="flex items-center space-x-[50px]">
|
|
97
|
+
<LogoSection logo={logo} smallLogo={smallLogo} smallLogoLink={smallLogoLink} />
|
|
98
|
+
<DropdownMenuSection
|
|
99
|
+
dropdownMenu={dropdownMenu}
|
|
100
|
+
isNavHovered={isNavHovered}
|
|
101
|
+
setShowDropdown={setShowDropdown}
|
|
102
|
+
/>
|
|
103
|
+
</div>
|
|
104
|
+
<BurgerMenuButton
|
|
105
|
+
menu={menu}
|
|
106
|
+
showMenu={showMenu}
|
|
107
|
+
firstLine={firstLine}
|
|
108
|
+
secondLine={secondLine}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
<MobileNavSidebar
|
|
113
|
+
menu={menu}
|
|
114
|
+
showMenu={showMenu}
|
|
115
|
+
smallLogo={smallLogo}
|
|
116
|
+
smallLogoLink={smallLogoLink}
|
|
117
|
+
dropdownMenu={dropdownMenu}
|
|
118
|
+
openAccordion={openAccordion}
|
|
119
|
+
toggleAccordion={toggleAccordion}
|
|
120
|
+
socialMedia={socialMedia}
|
|
121
|
+
/>
|
|
122
|
+
</nav>
|
|
123
|
+
</Sticky>
|
|
124
|
+
</Section>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function LogoSection({
|
|
129
|
+
logo,
|
|
130
|
+
smallLogo,
|
|
131
|
+
smallLogoLink,
|
|
132
|
+
}: {
|
|
133
|
+
logo: NavigationProps["logo"];
|
|
134
|
+
smallLogo: NavigationProps["smallLogo"];
|
|
135
|
+
smallLogoLink: string;
|
|
136
|
+
}) {
|
|
137
|
+
return (
|
|
138
|
+
<div className="w-[200px] relative z-20">
|
|
139
|
+
{logo?.image && (
|
|
140
|
+
<Link
|
|
141
|
+
aria-label={`Go to ${logoLink(logo)}`}
|
|
142
|
+
className="text-3xl font-bold leading-none"
|
|
143
|
+
href={logoLink(logo)}>
|
|
144
|
+
<Image
|
|
145
|
+
className={`md:h-[75px] hidden md:inline-block`}
|
|
146
|
+
src={logo?.image}
|
|
147
|
+
alt={logo?.alt ?? "navigation-logo"}
|
|
148
|
+
width={100}
|
|
149
|
+
height={100}
|
|
150
|
+
/>
|
|
151
|
+
</Link>
|
|
152
|
+
)}
|
|
153
|
+
|
|
154
|
+
{smallLogo?.image && (
|
|
155
|
+
<Link
|
|
156
|
+
aria-label={`Go to ${smallLogoLink === "/" ? "Homepage" : smallLogoLink}`}
|
|
157
|
+
className="text-3xl font-bold leading-none"
|
|
158
|
+
href={smallLogoLink}>
|
|
159
|
+
<Image
|
|
160
|
+
className={`h-[20px] inline-block md:hidden`}
|
|
161
|
+
src={smallLogo?.image}
|
|
162
|
+
alt={smallLogo?.alt ?? "navigation-logo"}
|
|
163
|
+
width={100}
|
|
164
|
+
height={100}
|
|
165
|
+
/>
|
|
166
|
+
</Link>
|
|
167
|
+
)}
|
|
168
|
+
</div>
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function DropdownMenuSection({
|
|
173
|
+
dropdownMenu,
|
|
174
|
+
isNavHovered,
|
|
175
|
+
setShowDropdown,
|
|
176
|
+
}: {
|
|
177
|
+
dropdownMenu: NavigationProps["dropdownMenu"];
|
|
178
|
+
isNavHovered: boolean;
|
|
179
|
+
setShowDropdown: (bool: boolean) => void;
|
|
180
|
+
}) {
|
|
181
|
+
if (!dropdownMenu || dropdownMenu?.length === 0) return null;
|
|
182
|
+
return (
|
|
183
|
+
<Fragment>
|
|
184
|
+
{dropdownMenu && dropdownMenu?.length > 0 && (
|
|
185
|
+
<ul className="hidden lg:flex flex-wrap space-x-[50px] xl:min-w-max">
|
|
186
|
+
{dropdownMenu?.map(link => (
|
|
187
|
+
<React.Fragment key={link._key}>
|
|
188
|
+
{link?.label && link?._key && (
|
|
189
|
+
<li className="static z-20 hover:z-10">
|
|
190
|
+
{link?.routeType === "singleRoute" ? (
|
|
191
|
+
<LinkComponent
|
|
192
|
+
link={link}
|
|
193
|
+
style={`${navlinkStyle} ${isNavHovered ? "text-white" : "text-black"}`}
|
|
194
|
+
/>
|
|
195
|
+
) : link?.routeType === "multipleRoute" ? (
|
|
196
|
+
<HoverMenu
|
|
197
|
+
link={link}
|
|
198
|
+
isNavHovered={isNavHovered}
|
|
199
|
+
onHover={() => setShowDropdown(true)}
|
|
200
|
+
onLeave={() => setShowDropdown(false)}
|
|
201
|
+
/>
|
|
202
|
+
) : (
|
|
203
|
+
<span
|
|
204
|
+
className={`${navlinkStyle} ${isNavHovered ? "text-white" : "text-black"}`}>
|
|
205
|
+
{link?.label}
|
|
206
|
+
</span>
|
|
207
|
+
)}
|
|
208
|
+
</li>
|
|
209
|
+
)}
|
|
210
|
+
</React.Fragment>
|
|
211
|
+
))}
|
|
212
|
+
</ul>
|
|
213
|
+
)}
|
|
214
|
+
</Fragment>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function LinkComponent({ link, style = navlinkStyle }: { link: any; style?: string }) {
|
|
219
|
+
return (
|
|
220
|
+
<>
|
|
221
|
+
{link.linkType === "linkInternal" ? (
|
|
222
|
+
<Link
|
|
223
|
+
aria-label={`Navigation ${link?.label ?? "Menu"} links which directs to ${
|
|
224
|
+
link?.internalLink === undefined ? "page-not-found" : link?.internalLink
|
|
225
|
+
}`}
|
|
226
|
+
className={style}
|
|
227
|
+
target={link?.linkTarget}
|
|
228
|
+
rel={link?.linkTarget === "_blank" ? "noopener noreferrer" : ""}
|
|
229
|
+
href={`${
|
|
230
|
+
link.internalLink?.toLowerCase() === "home"
|
|
231
|
+
? "/"
|
|
232
|
+
: `${!link.internalLink ? "page-not-found" : link?.internalLink}`
|
|
233
|
+
}`}>
|
|
234
|
+
{link?.label}
|
|
235
|
+
</Link>
|
|
236
|
+
) : link?.linkType === "linkText" && link?.linkText?.slice(0, 1) !== "/" ? (
|
|
237
|
+
<a
|
|
238
|
+
href={!link?.linkText ? "link-not-found" : link?.linkText}
|
|
239
|
+
aria-label={`Navigation ${link?.label ?? "Menu"} links which directs to ${
|
|
240
|
+
link?.linkText === undefined ? "link-not-found" : link?.linkText
|
|
241
|
+
}`}
|
|
242
|
+
className={style}
|
|
243
|
+
target={link?.linkTarget}
|
|
244
|
+
rel={link?.linkTarget === "_blank" ? "noopener noreferrer" : ""}>
|
|
245
|
+
{link?.label}
|
|
246
|
+
</a>
|
|
247
|
+
) : link?.linkType === "linkText" && link?.linkText?.slice(0, 1) === "/" ? (
|
|
248
|
+
<Link
|
|
249
|
+
aria-label={`Navigation ${link?.label ?? "Menu"} links which directs to ${
|
|
250
|
+
link?.linkText === undefined ? "link-not-found" : link?.linkText
|
|
251
|
+
}`}
|
|
252
|
+
className={style}
|
|
253
|
+
target={link?.linkTarget}
|
|
254
|
+
rel={link?.linkTarget === "_blank" ? "noopener noreferrer" : ""}
|
|
255
|
+
href={!link?.linkText ? "link-not-found" : link?.linkText}>
|
|
256
|
+
{link?.label}
|
|
257
|
+
</Link>
|
|
258
|
+
) : (
|
|
259
|
+
<a
|
|
260
|
+
aria-label={`Navigation ${link?.label ?? "Menu"} links which directs to ${
|
|
261
|
+
link?.externalLink === undefined ? "link-not-found" : link?.externalLink
|
|
262
|
+
}`}
|
|
263
|
+
className={style}
|
|
264
|
+
target={link?.linkTarget}
|
|
265
|
+
href={`${link.externalLink === undefined ? "link-not-found" : link.externalLink}`}
|
|
266
|
+
rel={link?.linkTarget === "_blank" ? "noopener noreferrer" : ""}>
|
|
267
|
+
{link?.label}
|
|
268
|
+
</a>
|
|
269
|
+
)}
|
|
270
|
+
</>
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function HoverMenu({
|
|
275
|
+
link,
|
|
276
|
+
onHover,
|
|
277
|
+
onLeave,
|
|
278
|
+
isNavHovered,
|
|
279
|
+
}: {
|
|
280
|
+
link: any;
|
|
281
|
+
onHover: () => void;
|
|
282
|
+
onLeave: () => void;
|
|
283
|
+
isNavHovered: boolean;
|
|
284
|
+
}) {
|
|
285
|
+
return (
|
|
286
|
+
<div className="group relative" onMouseEnter={onHover} onMouseLeave={onLeave}>
|
|
287
|
+
<button
|
|
288
|
+
className={`${navlinkStyle} group-hover:after:!w-full flex items-center space-x-2 ${isNavHovered ? "text-white" : "text-black"}`}>
|
|
289
|
+
<span>{link?.label}</span>
|
|
290
|
+
</button>
|
|
291
|
+
|
|
292
|
+
<div className="fixed left-0 right-0 top-[80px] pointer-events-none group-hover:pointer-events-auto opacity-0 group-hover:opacity-100 transition-opacity duration-300">
|
|
293
|
+
<div className="w-3/4 mx-auto bg-black">
|
|
294
|
+
<div className="max-w-[1440px] mx-auto px-4">
|
|
295
|
+
<div className="p-[30px]">
|
|
296
|
+
<div className="grid grid-cols-5 gap-[30px]">
|
|
297
|
+
{link?.featuredRoute && (
|
|
298
|
+
<div className="col-span-2 pr-[20px]">
|
|
299
|
+
<div className="w-full h-0 pb-[75%] relative bg-obsidian">
|
|
300
|
+
{link?.featuredRoute?.featuredLink && (
|
|
301
|
+
<div className="absolute w-full h-full inset-0 p-[15px] flex flex-col justify-end z-10">
|
|
302
|
+
<span>
|
|
303
|
+
<LinkComponent
|
|
304
|
+
link={link?.featuredRoute?.featuredLink}
|
|
305
|
+
style="small-text-style text-white underline underline-offset-4 decoration-[0.5px] opacity-50 hover:opacity-100 h-5 !outline-none transition-all duration-300 after:absolute after:inset-0"
|
|
306
|
+
/>
|
|
307
|
+
</span>
|
|
308
|
+
</div>
|
|
309
|
+
)}
|
|
310
|
+
{link?.featuredRoute?.mainImage && (
|
|
311
|
+
<Image
|
|
312
|
+
src={link?.featuredRoute?.mainImage?.image}
|
|
313
|
+
alt={link?.featuredRoute?.mainImage?.alt ?? "image"}
|
|
314
|
+
width={100}
|
|
315
|
+
height={100}
|
|
316
|
+
className="object-cover absolute inset-0 w-full h-full"
|
|
317
|
+
/>
|
|
318
|
+
)}
|
|
319
|
+
</div>
|
|
320
|
+
</div>
|
|
321
|
+
)}
|
|
322
|
+
{link?.multipleRoutes && (
|
|
323
|
+
<div className="col-span-3 py-[20px]">
|
|
324
|
+
<div className="flex flex-col space-y-10">
|
|
325
|
+
{link?.label && <p className="h3 text-white">{link?.label}</p>}
|
|
326
|
+
<ul
|
|
327
|
+
className={`grid gap-x-[60px] gap-y-3 ${
|
|
328
|
+
link?.multipleRoutes?.length > 3 ? "grid-cols-2" : "grid-cols-1"
|
|
329
|
+
}`}>
|
|
330
|
+
{link?.multipleRoutes?.map((sublink: any) => (
|
|
331
|
+
<li key={sublink._key}>
|
|
332
|
+
{sublink?.label && (
|
|
333
|
+
<LinkComponent link={sublink} style={navlinkStyle} />
|
|
334
|
+
)}
|
|
335
|
+
</li>
|
|
336
|
+
))}
|
|
337
|
+
</ul>
|
|
338
|
+
</div>
|
|
339
|
+
</div>
|
|
340
|
+
)}
|
|
341
|
+
</div>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
</div>
|
|
345
|
+
</div>
|
|
346
|
+
</div>
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function MobileNavSidebar({
|
|
351
|
+
menu,
|
|
352
|
+
showMenu,
|
|
353
|
+
smallLogo,
|
|
354
|
+
smallLogoLink,
|
|
355
|
+
dropdownMenu,
|
|
356
|
+
openAccordion,
|
|
357
|
+
toggleAccordion,
|
|
358
|
+
socialMedia,
|
|
359
|
+
}: {
|
|
360
|
+
menu: boolean;
|
|
361
|
+
showMenu: () => void;
|
|
362
|
+
smallLogo: any;
|
|
363
|
+
smallLogoLink: string;
|
|
364
|
+
dropdownMenu: NavigationProps["dropdownMenu"];
|
|
365
|
+
openAccordion: string | null;
|
|
366
|
+
toggleAccordion: (key: string) => void;
|
|
367
|
+
socialMedia: NavigationProps["socialMedia"];
|
|
368
|
+
}) {
|
|
369
|
+
return (
|
|
370
|
+
<div className={`${menu ? "block" : "hidden"} navbar-menu fixed inset-0 z-50`}>
|
|
371
|
+
<div className="fixed inset-0 bg-black/80" onClick={showMenu}></div>
|
|
372
|
+
<div className="fixed top-0 right-0 bottom-0 flex flex-col w-full sm:max-w-sm bg-black/80">
|
|
373
|
+
<nav className="flex flex-col w-full py-6 px-6 overflow-y-auto h-screen">
|
|
374
|
+
<MobileNavImage smallLogo={smallLogo} smallLogoLink={smallLogoLink} showMenu={showMenu} />
|
|
375
|
+
<MobileNavDropdown
|
|
376
|
+
dropdownMenu={dropdownMenu}
|
|
377
|
+
openAccordion={openAccordion}
|
|
378
|
+
toggleAccordion={toggleAccordion}
|
|
379
|
+
/>
|
|
380
|
+
<MobileNavSocialMedia socialMedia={socialMedia} />
|
|
381
|
+
<div className="mt-auto pt-20 text-gray-400">
|
|
382
|
+
<span className="text-sm text-center block">{`© ${new Date().getFullYear()} All rights reserved.`}</span>
|
|
383
|
+
</div>
|
|
384
|
+
</nav>
|
|
385
|
+
</div>
|
|
386
|
+
</div>
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function MobileNavImage({
|
|
391
|
+
smallLogo,
|
|
392
|
+
smallLogoLink,
|
|
393
|
+
showMenu,
|
|
394
|
+
}: {
|
|
395
|
+
smallLogo: NavigationProps["smallLogo"];
|
|
396
|
+
smallLogoLink: string;
|
|
397
|
+
showMenu: () => void;
|
|
398
|
+
}) {
|
|
399
|
+
if (!smallLogo?.image) return null;
|
|
400
|
+
return (
|
|
401
|
+
<Link
|
|
402
|
+
aria-label={`Go to ${smallLogoLink === "/" ? "Homepage" : smallLogoLink}`}
|
|
403
|
+
className="text-3xl font-bold leading-none h-[40px] w-[100px] flex items-center justify-start mt-0 md:ml-[15px]"
|
|
404
|
+
onClick={showMenu}
|
|
405
|
+
href={smallLogoLink}>
|
|
406
|
+
<Image
|
|
407
|
+
className="h-[20px] object-contain"
|
|
408
|
+
src={smallLogo?.image}
|
|
409
|
+
alt={smallLogo?.alt ?? "navigation-logo"}
|
|
410
|
+
/>
|
|
411
|
+
</Link>
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
function MobileNavDropdown({
|
|
416
|
+
dropdownMenu,
|
|
417
|
+
openAccordion,
|
|
418
|
+
toggleAccordion,
|
|
419
|
+
}: {
|
|
420
|
+
dropdownMenu: NavigationProps["dropdownMenu"];
|
|
421
|
+
openAccordion: string | null;
|
|
422
|
+
toggleAccordion: (key: string) => void;
|
|
423
|
+
}) {
|
|
424
|
+
return (
|
|
425
|
+
<div className="mt-[70px]">
|
|
426
|
+
<Accordion>
|
|
427
|
+
{dropdownMenu?.map(link => (
|
|
428
|
+
<React.Fragment key={link._key}>
|
|
429
|
+
{link?.label && link?._key && (
|
|
430
|
+
<>
|
|
431
|
+
{link?.routeType === "singleRoute" ? (
|
|
432
|
+
<span>
|
|
433
|
+
<LinkComponent
|
|
434
|
+
link={link}
|
|
435
|
+
style={`${navlinkStyle} !text-base !h-auto text-white`}
|
|
436
|
+
/>
|
|
437
|
+
</span>
|
|
438
|
+
) : link?.routeType === "multipleRoute" ? (
|
|
439
|
+
<AccordionItem>
|
|
440
|
+
<AccordionButton
|
|
441
|
+
isOpen={openAccordion === link._key}
|
|
442
|
+
onClick={() => link._key && toggleAccordion(link._key)}
|
|
443
|
+
className={`${navlinkStyle} after:!w-0 !p-0 text-white`}>
|
|
444
|
+
{link?.label}
|
|
445
|
+
</AccordionButton>
|
|
446
|
+
|
|
447
|
+
<AccordionPanel isOpen={openAccordion === link._key}>
|
|
448
|
+
<div className="py-6 flex flex-col space-y-2">
|
|
449
|
+
{link?.featuredRoute && (
|
|
450
|
+
<div>
|
|
451
|
+
<div className="w-full h-0 pb-[75%] relative bg-obsidian">
|
|
452
|
+
{link?.featuredRoute?.featuredLink && (
|
|
453
|
+
<div className="absolute w-full h-full inset-0 p-[15px] flex flex-col justify-end z-10">
|
|
454
|
+
<span>
|
|
455
|
+
<LinkComponent
|
|
456
|
+
link={link?.featuredRoute?.featuredLink}
|
|
457
|
+
style="small-text-style text-white underline underline-offset-4 decoration-[0.5px] opacity-50 hover:opacity-100 h-5 !outline-none transition-all duration-300"
|
|
458
|
+
/>
|
|
459
|
+
</span>
|
|
460
|
+
</div>
|
|
461
|
+
)}
|
|
462
|
+
{link?.featuredRoute?.mainImage && (
|
|
463
|
+
<Image
|
|
464
|
+
src={link?.featuredRoute?.mainImage?.image}
|
|
465
|
+
className="object-cover absolute inset-0 w-full h-full"
|
|
466
|
+
alt={link?.featuredRoute?.mainImage?.alt ?? "image"}
|
|
467
|
+
/>
|
|
468
|
+
)}
|
|
469
|
+
</div>
|
|
470
|
+
</div>
|
|
471
|
+
)}
|
|
472
|
+
{link?.multipleRoutes && (
|
|
473
|
+
<ul className="flex flex-col justify-center space-y-1 pl-[15px]">
|
|
474
|
+
{link?.multipleRoutes?.map(sublink => (
|
|
475
|
+
<li key={sublink._key}>
|
|
476
|
+
{sublink?.label && (
|
|
477
|
+
<LinkComponent
|
|
478
|
+
link={sublink}
|
|
479
|
+
style={`${navlinkStyle} text-white`}
|
|
480
|
+
/>
|
|
481
|
+
)}
|
|
482
|
+
</li>
|
|
483
|
+
))}
|
|
484
|
+
</ul>
|
|
485
|
+
)}
|
|
486
|
+
</div>
|
|
487
|
+
</AccordionPanel>
|
|
488
|
+
</AccordionItem>
|
|
489
|
+
) : (
|
|
490
|
+
<span className={`${navlinkStyle} text-white`}>{link?.label}</span>
|
|
491
|
+
)}
|
|
492
|
+
</>
|
|
493
|
+
)}
|
|
494
|
+
</React.Fragment>
|
|
495
|
+
))}
|
|
496
|
+
</Accordion>
|
|
497
|
+
</div>
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
function MobileNavSocialMedia({ socialMedia }: { socialMedia: NavigationProps["socialMedia"] }) {
|
|
502
|
+
if (!socialMedia) return null;
|
|
503
|
+
return (
|
|
504
|
+
<div className="mt-[70px] flex justify-center space-x-[50px]">
|
|
505
|
+
{socialMedia?.map(
|
|
506
|
+
social =>
|
|
507
|
+
social?.socialMediaLink && (
|
|
508
|
+
<Link
|
|
509
|
+
aria-label={social?.socialMedia || social?.socialMediaPlatform || "social-media-link"}
|
|
510
|
+
className="text-white hover:text-gray-2 leading-none transition"
|
|
511
|
+
style={{ fontSize: "24px" }}
|
|
512
|
+
target="_blank"
|
|
513
|
+
rel="noopener noreferrer"
|
|
514
|
+
href={social?.socialMediaLink}
|
|
515
|
+
key={social?._key}>
|
|
516
|
+
<SocialIcons social={social?.socialMedia as Socials} />
|
|
517
|
+
</Link>
|
|
518
|
+
),
|
|
519
|
+
)}
|
|
520
|
+
</div>
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
function BurgerMenuButton({
|
|
525
|
+
menu,
|
|
526
|
+
showMenu,
|
|
527
|
+
firstLine,
|
|
528
|
+
secondLine,
|
|
529
|
+
}: {
|
|
530
|
+
menu: boolean;
|
|
531
|
+
showMenu: () => void;
|
|
532
|
+
firstLine: any;
|
|
533
|
+
secondLine: any;
|
|
534
|
+
}) {
|
|
535
|
+
return (
|
|
536
|
+
<div
|
|
537
|
+
className={`block lg:hidden z-[99] ${
|
|
538
|
+
menu ? "fixed right-[20px] md:right-[50px]" : "relative"
|
|
539
|
+
}`}>
|
|
540
|
+
<svg
|
|
541
|
+
onClick={showMenu}
|
|
542
|
+
width="40"
|
|
543
|
+
height="40"
|
|
544
|
+
viewBox="0 0 44 44"
|
|
545
|
+
fill="#ffffff"
|
|
546
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
547
|
+
className="cursor-pointer">
|
|
548
|
+
<animated.rect width="20" height="3" style={firstLine} />
|
|
549
|
+
<animated.rect width="30" height="3" style={secondLine} />
|
|
550
|
+
</svg>
|
|
551
|
+
</div>
|
|
552
|
+
);
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
interface AccordionProps {
|
|
556
|
+
children: React.ReactNode;
|
|
557
|
+
className?: string;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
function Accordion({ children, className = "" }: AccordionProps) {
|
|
561
|
+
return <div className={`flex flex-col space-y-6 ${className}`}>{children}</div>;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
interface AccordionItemProps {
|
|
565
|
+
children: React.ReactNode;
|
|
566
|
+
className?: string;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
function AccordionItem({ children, className = "" }: AccordionItemProps) {
|
|
570
|
+
return <div className={`border-none ${className}`}>{children}</div>;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
interface AccordionButtonProps {
|
|
574
|
+
children: React.ReactNode;
|
|
575
|
+
className?: string;
|
|
576
|
+
isOpen: boolean;
|
|
577
|
+
onClick: () => void;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
function AccordionButton({ children, className = "", isOpen, onClick }: AccordionButtonProps) {
|
|
581
|
+
return (
|
|
582
|
+
<button onClick={onClick} className={`${className} flex items-center justify-between w-full`}>
|
|
583
|
+
{children}
|
|
584
|
+
<BsChevronDown
|
|
585
|
+
className={`transform transition-transform duration-200 ${isOpen ? "rotate-180" : ""}`}
|
|
586
|
+
/>
|
|
587
|
+
</button>
|
|
588
|
+
);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
interface AccordionPanelProps {
|
|
592
|
+
children: React.ReactNode;
|
|
593
|
+
isOpen: boolean;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
function AccordionPanel({ children, isOpen }: AccordionPanelProps) {
|
|
597
|
+
return (
|
|
598
|
+
<div
|
|
599
|
+
className={`overflow-hidden transition-all duration-200 ${
|
|
600
|
+
isOpen ? "max-h-[1000px] opacity-100" : "max-h-0 opacity-0"
|
|
601
|
+
}`}>
|
|
602
|
+
{children}
|
|
603
|
+
</div>
|
|
604
|
+
);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
export { Navigation_G };
|