- Products
- Solutions
- Resources
- Pricing
navigation-menu.tsx
globals.css
prompt.md
Collapse
Reset
Copy Code
Download
Run
1
'use client';
2
3
import React, { useState } from 'react';
4
import { motion, AnimatePresence } from 'framer-motion';
5
import { cn } from '@/lib/utils';
6
import { ChevronDown, Network, ArrowRight } from 'lucide-react';
7
8
export interface TabItem {
9
id: string;
10
label: string;
11
content?: React.ReactNode;
12
}
13
14
export function NavigationMenu({ className }: { className?: string }) {
15
const [activeTab, setActiveTab] = useState<string | null>(null);
16
const containerRef = React.useRef<HTMLDivElement>(null);
17
18
// Close dropdown on outside tap on mobile
19
React.useEffect(() => {
20
const handlePointerDown = (e: PointerEvent) => {
21
if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
22
setActiveTab(null);
23
}
24
};
25
document.addEventListener("pointerdown", handlePointerDown);
26
return () => document.removeEventListener("pointerdown", handlePointerDown);
27
}, []);
28
29
const tabs: TabItem[] = [
30
{
31
id: 'products',
32
label: 'Products',
33
content: (
34
<div className="flex p-4 gap-4 w-[600px]">
35
<div className="group cursor-pointer w-1/3 bg-gradient-to-b from-white to-zinc-50/50 dark:from-[#1C1C1E] dark:to-[#0A0A0C] hover:from-zinc-50/50 hover:to-zinc-100/50 dark:hover:from-[#27272A] dark:hover:to-[#1C1C1E] rounded-xl p-4 border border-black/5 dark:border-white/5 hover:border-black/10 dark:hover:border-white/10 flex flex-col justify-between shadow-sm hover:shadow-md dark:hover:shadow-none transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)]">
36
<Network className="w-8 h-8 text-zinc-700 dark:text-zinc-300 group-hover:text-zinc-950 dark:group-hover:text-zinc-50 mb-8 transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] group-hover:scale-110" />
37
<div>
38
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1">One platform</h4>
39
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug">Compute, storage and global delivery in a single stack.</p>
40
</div>
41
</div>
42
<div className="w-2/3 flex flex-col justify-center gap-4 py-2 pr-2">
43
<div className="group cursor-pointer p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
44
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-0.5 transition-colors group-hover:text-black dark:group-hover:text-white">Hosting</h4>
45
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Deploy any framework to a global edge network in seconds.</p>
46
</div>
47
<div className="group cursor-pointer p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
48
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-0.5 transition-colors group-hover:text-black dark:group-hover:text-white">SQL Database</h4>
49
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">A fully managed Postgres database that scales with you.</p>
50
</div>
51
<div className="group cursor-pointer p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
52
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-0.5 transition-colors group-hover:text-black dark:group-hover:text-white">CDN</h4>
53
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Cache and serve assets from hundreds of locations worldwide.</p>
54
</div>
55
</div>
56
</div>
57
)
58
},
59
{
60
id: 'solutions',
61
label: 'Solutions',
62
content: (
63
<div className="w-[560px]">
64
<div className="grid grid-cols-2 gap-x-8 gap-y-6 p-6">
65
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
66
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">Startups</h4>
67
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Everything you need to ship fast and scale when it matters.</p>
68
</div>
69
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
70
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">AI features</h4>
71
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Add search, chat and recommendations powered by AI.</p>
72
</div>
73
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
74
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">Enterprise</h4>
75
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Advanced security, SSO and SLAs for larger organizations.</p>
76
</div>
77
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
78
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">Security</h4>
79
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Block threats early with built-in WAF and bot protection.</p>
80
</div>
81
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
82
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">Agencies</h4>
83
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Manage unlimited client projects from a single dashboard.</p>
84
</div>
85
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
86
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">Performance</h4>
87
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Speed up every page with smart caching and compression.</p>
88
</div>
89
</div>
90
<div className="bg-zinc-50/50 dark:bg-zinc-900/20 border-t border-black/5 dark:border-white/5 p-4 flex items-center justify-between text-[13px] font-matter">
91
<a href="#" className="text-blue-600 dark:text-blue-400 flex items-center gap-1 font-medium hover:underline">
92
See all solutions <ArrowRight className="w-3.5 h-3.5" />
93
</a>
94
<div className="flex items-center gap-4 text-zinc-500 dark:text-zinc-400">
95
<a href="#" className="hover:text-zinc-900 dark:hover:text-zinc-50 transition-colors">Sales</a>
96
<a href="#" className="hover:text-zinc-900 dark:hover:text-zinc-50 transition-colors">Careers</a>
97
<a href="#" className="hover:text-zinc-900 dark:hover:text-zinc-50 transition-colors">Partners</a>
98
<a href="#" className="hover:text-zinc-900 dark:hover:text-zinc-50 transition-colors">Status</a>
99
<a href="#" className="hover:text-zinc-900 dark:hover:text-zinc-50 transition-colors">Support</a>
100
</div>
101
</div>
102
</div>
103
)
104
},
105
{
106
id: 'resources',
107
label: 'Resources',
108
content: (
109
<div className="w-[500px] p-6">
110
<div className="grid grid-cols-2 gap-x-8 gap-y-6">
111
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
112
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">Documentation</h4>
113
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Guides, references and examples for every feature.</p>
114
</div>
115
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
116
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">Tutorials</h4>
117
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Step-by-step lessons that take you from zero to deployed.</p>
118
</div>
119
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
120
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">API Reference</h4>
121
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Detailed docs for every endpoint and SDK method.</p>
122
</div>
123
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
124
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">Blog</h4>
125
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Product news, engineering deep dives and best practices.</p>
126
</div>
127
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
128
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">Community</h4>
129
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Ask questions and share what you build with others.</p>
130
</div>
131
<div className="cursor-pointer group p-3 -m-3 rounded-lg hover:bg-zinc-50 dark:hover:bg-zinc-800/50 transition-colors">
132
<h4 className="font-matter font-medium text-zinc-950 dark:text-zinc-50 text-[14px] mb-1 transition-colors group-hover:text-black dark:group-hover:text-white">Support</h4>
133
<p className="font-matter text-[13px] text-zinc-500 dark:text-zinc-400 leading-snug transition-colors group-hover:text-zinc-700 dark:group-hover:text-zinc-300">Get help fast from our team and the wider community.</p>
134
</div>
135
</div>
136
</div>
137
)
138
},
139
{
140
id: 'pricing',
141
label: 'Pricing'
142
}
143
];
144
145
return (
146
<div
147
ref={containerRef}
148
className={cn("relative flex flex-col items-center w-full my-0 md:my-auto pt-2 sm:pt-4 md:pt-0", className)}
149
onMouseLeave={() => {
150
if (typeof window !== "undefined" && window.innerWidth >= 768) {
151
setActiveTab(null);
152
}
153
}}
154
>
155
<ul className="flex items-center gap-0.5 sm:gap-1 bg-transparent px-2 max-w-full">
156
{tabs.map((tab) => {
157
const isActive = activeTab === tab.id;
158
return (
159
<li
160
key={tab.id}
161
onClick={() => setActiveTab(activeTab === tab.id ? null : tab.id)}
162
onMouseEnter={() => {
163
if (typeof window !== "undefined" && window.innerWidth >= 768) {
164
setActiveTab(tab.id);
165
}
166
}}
167
className="group relative px-2.5 py-1.5 sm:px-4 sm:py-2 rounded-full cursor-pointer transition-colors select-none"
168
>
169
{isActive && (
170
<motion.div
171
layoutId="nav-pill"
172
className="absolute inset-0 bg-gradient-to-b from-white from-30% to-[#EBE9EB] dark:bg-none dark:bg-white rounded-full border border-black/5 dark:border-white/10 shadow-sm dark:shadow-[0_2px_12px_rgba(255,255,255,0.2)]"
173
transition={{ type: "spring", bounce: 0, duration: 0.35 }}
174
/>
175
)}
176
<span
177
className={cn(
178
"relative z-10 flex items-center gap-1 font-matter text-[13px] sm:text-[14px] font-medium transition-colors duration-200",
179
isActive
180
? "text-[#111111] dark:text-black font-semibold"
181
: "text-zinc-600 dark:text-[#86868B] hover:text-[#111111] dark:hover:text-[#F5F5F7]"
182
)}
183
>
184
{tab.label}
185
{tab.content && (
186
<ChevronDown
187
className={cn(
188
"w-3 h-3 sm:w-3.5 sm:h-3.5 transition-all duration-300",
189
isActive
190
? "rotate-180 text-black dark:text-black"
191
: "text-zinc-400 dark:text-[#86868B] group-hover:text-black dark:group-hover:text-[#F5F5F7]"
192
)}
193
/>
194
)}
195
</span>
196
</li>
197
);
198
})}
199
</ul>
200
201
<AnimatePresence>
202
{activeTab && (
203
<motion.div
204
initial={{ opacity: 0, y: 8, scale: 0.98 }}
205
animate={{ opacity: 1, y: 0, scale: 1 }}
206
exit={{ opacity: 0, y: 8, scale: 0.98 }}
207
transition={{ duration: 0.2 }}
208
className="w-full flex justify-center mt-3 mb-16 md:mb-0 md:mt-0 md:absolute md:top-full md:left-1/2 md:-translate-x-1/2 md:pt-4 z-40"
209
>
210
<motion.div
211
layout
212
transition={{ type: "spring", bounce: 0, duration: 0.35 }}
213
className="w-full max-w-[calc(100vw-32px)] md:w-auto overflow-hidden bg-gradient-to-b from-white from-30% to-[#EBE9EB] dark:from-[#1C1C1E] dark:to-[#0A0A0C] rounded-2xl shadow-[0_12px_40px_rgba(0,0,0,0.08)] dark:shadow-[0_8px_32px_rgba(0,0,0,0.4)] border border-black/5 dark:border-white/5"
214
>
215
<AnimatePresence mode="popLayout" initial={false}>
216
<motion.div
217
key={activeTab}
218
initial={{ opacity: 0, x: -15 }}
219
animate={{ opacity: 1, x: 0 }}
220
exit={{ opacity: 0, x: 15 }}
221
transition={{ duration: 0.18 }}
222
>
223
{tabs.find(t => t.id === activeTab)?.content}
224
</motion.div>
225
</AnimatePresence>
226
</motion.div>
227
</motion.div>
228
)}
229
</AnimatePresence>
230
</div>
231
);
232
}
233

