Skip to content

Commit 70c896e

Browse files
[Portal] Redesign header with improved mobile menu layout
1 parent 916ecf4 commit 70c896e

File tree

2 files changed

+190
-83
lines changed

2 files changed

+190
-83
lines changed

apps/portal/src/app/Header.tsx

Lines changed: 189 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ import {
2626
import { ThirdwebIcon } from "../icons/thirdweb";
2727

2828
const links = [
29+
{
30+
name: "Connect",
31+
href: "/connect",
32+
icon: TableOfContentsIcon,
33+
},
2934
{
3035
name: "Bridge",
3136
href: "/pay",
@@ -46,13 +51,13 @@ const links = [
4651
name: "Nebula",
4752
href: "/nebula",
4853
},
49-
];
50-
51-
const toolLinks = [
5254
{
5355
name: "Vault",
5456
href: "/vault",
5557
},
58+
];
59+
60+
const toolLinks = [
5661
{
5762
name: "Chain List",
5863
href: "https://thirdweb.com/chainlist",
@@ -140,6 +145,39 @@ const apisLinks = [
140145
},
141146
];
142147

148+
const sdkLinks = [
149+
{
150+
name: "TypeScript",
151+
href: "/typescript/v5",
152+
icon: TypeScriptIcon,
153+
},
154+
{
155+
name: "React",
156+
href: "/react/v5",
157+
icon: ReactIcon,
158+
},
159+
{
160+
name: "React Native",
161+
href: "/react-native/v5",
162+
icon: ReactIcon,
163+
},
164+
{
165+
name: ".NET",
166+
href: "/dotnet",
167+
icon: DotNetIcon,
168+
},
169+
{
170+
name: "Unity",
171+
href: "/unity",
172+
icon: UnityIcon,
173+
},
174+
{
175+
name: "Unreal Engine",
176+
href: "/unreal-engine",
177+
icon: UnrealEngineIcon,
178+
},
179+
];
180+
143181
const supportLinks = [
144182
{
145183
name: "Get thirdweb support",
@@ -155,58 +193,57 @@ export function Header() {
155193
const [showBurgerMenu, setShowBurgerMenu] = useState(false);
156194

157195
return (
158-
<header className="flex w-full items-center border-b bg-background">
159-
<div className="container flex items-center justify-between gap-6 p-4 xl:justify-start">
160-
<Link
161-
className="flex items-center gap-2"
162-
href="/"
163-
aria-label="thirdweb Docs"
164-
title="thirdweb Docs"
165-
>
166-
<ThirdwebIcon className="size-8" />
167-
<span className="font-bold text-[23px] text-foreground leading-none tracking-tight">
168-
Docs
169-
</span>
170-
</Link>
171-
172-
<div className="flex items-center gap-1 xl:hidden">
173-
<ThemeSwitcher className="border-none bg-transparent" />
174-
175-
<DocSearch variant="icon" />
176-
196+
<header className="flex w-full flex-col gap-2 border-b bg-background p-2 lg:px-4">
197+
<div className="container flex items-center justify-between gap-6">
198+
{/* Top row */}
199+
<div className="flex items-center gap-2">
177200
<Link
178-
href="https://github.com/thirdweb-dev"
179-
target="_blank"
180-
className="text-foreground"
201+
className="flex items-center gap-2"
202+
href="/"
203+
aria-label="thirdweb Docs"
204+
title="thirdweb Docs"
181205
>
182-
<GithubIcon className="mx-3 size-6" />
206+
<ThirdwebIcon className="size-8" />
207+
<span className="font-bold text-[23px] text-foreground leading-none tracking-tight">
208+
Docs
209+
</span>
183210
</Link>
184-
185-
{/* Mobile burger menu */}
186-
<Button
187-
variant="ghost"
188-
className="p-2"
189-
onClick={() => setShowBurgerMenu(!showBurgerMenu)}
190-
>
191-
<MenuIcon className="size-7" />
192-
</Button>
193211
</div>
194212

195-
<nav
196-
className={clsx(
197-
"grow gap-5",
198-
!showBurgerMenu ? "hidden xl:flex" : "flex",
199-
"fade-in-20 slide-in-from-top-3 fixed inset-0 top-sticky-top-height animate-in flex-col overflow-auto bg-card p-6",
200-
"xl:static xl:animate-none xl:flex-row xl:justify-between xl:bg-transparent xl:p-0",
201-
)}
202-
>
203-
<ul className="flex flex-col gap-5 xl:flex-row xl:items-center">
204-
<DropdownLinks
205-
links={connectLinks}
206-
onLinkClick={() => setShowBurgerMenu(false)}
207-
category="Connect"
208-
/>
213+
<div className="flex items-center gap-3">
214+
<div className="hidden xl:flex">
215+
<ThemeSwitcher />
216+
</div>
217+
218+
<div className="hidden xl:block">
219+
<DocSearch variant="search" />
220+
</div>
221+
222+
<div className="flex items-center gap-1 xl:hidden">
223+
<ThemeSwitcher className="border-none bg-transparent" />
224+
<DocSearch variant="icon" />
225+
<Link
226+
href="https://github.com/thirdweb-dev"
227+
target="_blank"
228+
className="text-foreground"
229+
>
230+
<GithubIcon className="mx-3 size-6" />
231+
</Link>
232+
<Button
233+
variant="ghost"
234+
className="p-2"
235+
onClick={() => setShowBurgerMenu(!showBurgerMenu)}
236+
>
237+
<MenuIcon className="size-7" />
238+
</Button>
239+
</div>
240+
</div>
241+
</div>
209242

243+
{/* Bottom row - hidden on mobile */}
244+
<div className="container hidden items-center justify-between gap-6 xl:flex">
245+
<nav className="flex grow gap-5">
246+
<ul className="flex flex-row items-center gap-5">
210247
{links.map((link) => {
211248
return (
212249
<li
@@ -230,50 +267,124 @@ export function Header() {
230267
category="Tools"
231268
/>
232269
</ul>
270+
</nav>
271+
272+
<div className="flex items-center gap-3">
273+
<div className="px-1">
274+
<DropdownLinks
275+
links={sdkLinks}
276+
onLinkClick={() => setShowBurgerMenu(false)}
277+
category="SDKs"
278+
/>
279+
</div>
280+
<div className="px-1">
281+
<DropdownLinks
282+
links={apisLinks}
283+
onLinkClick={() => setShowBurgerMenu(false)}
284+
category="APIs"
285+
/>
286+
</div>
287+
288+
<div className="px-1">
289+
<DropdownLinks
290+
links={supportLinks}
291+
onLinkClick={() => setShowBurgerMenu(false)}
292+
category="Support"
293+
/>
294+
</div>
295+
296+
<NavLink
297+
name="Changelog"
298+
href="/changelog"
299+
onClick={() => {
300+
setShowBurgerMenu(false);
301+
}}
302+
/>
303+
304+
<Link
305+
href="https://github.com/thirdweb-dev"
306+
target="_blank"
307+
className="text-muted-foreground transition-colors hover:text-foreground"
308+
>
309+
<GithubIcon className="mx-2 size-6" />
310+
</Link>
311+
</div>
312+
</div>
233313

234-
<div className="flex flex-col justify-start gap-5 xl:flex-row xl:items-center xl:gap-3">
235-
<div className="hidden xl:flex">
236-
<ThemeSwitcher />
314+
{/* Mobile menu */}
315+
{showBurgerMenu && (
316+
<div className="fixed inset-0 top-sticky-top-height z-50 overflow-auto bg-card p-6 xl:hidden">
317+
<div className="flex flex-col gap-6">
318+
<div className="flex flex-col gap-4">
319+
<h3 className="font-semibold text-lg">Products</h3>
320+
{links.map((link) => (
321+
<NavLink
322+
key={link.name}
323+
name={link.name}
324+
href={link.href}
325+
icon={link.icon}
326+
onClick={() => setShowBurgerMenu(false)}
327+
/>
328+
))}
237329
</div>
238330

239-
<div className="hidden xl:block">
240-
<DocSearch variant="search" />
331+
<div className="flex flex-col gap-4">
332+
<h3 className="font-semibold text-lg">SDKs</h3>
333+
{sdkLinks.map((link) => (
334+
<NavLink
335+
key={link.name}
336+
name={link.name}
337+
href={link.href}
338+
icon={link.icon}
339+
onClick={() => setShowBurgerMenu(false)}
340+
/>
341+
))}
241342
</div>
242343

243-
<div className="xl:px-1">
244-
<DropdownLinks
245-
links={apisLinks}
246-
onLinkClick={() => setShowBurgerMenu(false)}
247-
category="APIs"
248-
/>
344+
<div className="flex flex-col gap-4">
345+
<h3 className="font-semibold text-lg">APIs</h3>
346+
{apisLinks.map((link) => (
347+
<NavLink
348+
key={link.name}
349+
name={link.name}
350+
href={link.href}
351+
onClick={() => setShowBurgerMenu(false)}
352+
/>
353+
))}
249354
</div>
250355

251-
<div className="xl:px-1">
252-
<DropdownLinks
253-
links={supportLinks}
254-
onLinkClick={() => setShowBurgerMenu(false)}
255-
category="Support"
256-
/>
356+
<div className="flex flex-col gap-4">
357+
<h3 className="font-semibold text-lg">Support</h3>
358+
{supportLinks.map((link) => (
359+
<NavLink
360+
key={link.name}
361+
name={link.name}
362+
href={link.href}
363+
onClick={() => setShowBurgerMenu(false)}
364+
/>
365+
))}
257366
</div>
258367

259368
<NavLink
260369
name="Changelog"
261370
href="/changelog"
262-
onClick={() => {
263-
setShowBurgerMenu(false);
264-
}}
371+
onClick={() => setShowBurgerMenu(false)}
265372
/>
266373

267-
<Link
268-
href="https://github.com/thirdweb-dev"
269-
target="_blank"
270-
className="hidden text-muted-foreground transition-colors hover:text-foreground xl:block"
271-
>
272-
<GithubIcon className="mx-2 size-6" />
273-
</Link>
374+
<div className="flex flex-col gap-4">
375+
<h3 className="font-semibold text-lg">Tools</h3>
376+
{toolLinks.map((link) => (
377+
<NavLink
378+
key={link.name}
379+
name={link.name}
380+
href={link.href}
381+
onClick={() => setShowBurgerMenu(false)}
382+
/>
383+
))}
384+
</div>
274385
</div>
275-
</nav>
276-
</div>
386+
</div>
387+
)}
277388
</header>
278389
);
279390
}

apps/portal/src/components/others/DocSearch.tsx

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ export function DocSearch(props: { variant: "icon" | "search" }) {
357357
<DialogTrigger asChild>
358358
<Button
359359
variant="outline"
360-
className="flex w-56 justify-between px-3"
360+
className="flex w-64 justify-between px-3"
361361
>
362362
Search Docs
363363
<div className="flex items-center gap-1 rounded-sm border bg-background px-2 py-1 text-muted-foreground text-xs">
@@ -387,10 +387,6 @@ export function DocSearch(props: { variant: "icon" | "search" }) {
387387
);
388388
}
389389

390-
// function isNewSDK(href: string) {
391-
// return href.includes("/typescript/v5");
392-
// }
393-
394390
function getTagsFromHref(href: string): Tag[] | undefined {
395391
if (href.includes("/react-native/v0")) {
396392
if (href.includes("/references")) {

0 commit comments

Comments
 (0)