Skip to content

Commit 27d9d13

Browse files
committed
feat: redesign the header component
1 parent 561d64a commit 27d9d13

File tree

6 files changed

+65
-21
lines changed

6 files changed

+65
-21
lines changed

block-explorer/app/layout.tsx

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// "use client";
22
import ServiceWorkerRegistration from '@/components/ServiceWorkerRegistration';
3-
import Container from '@/components/container';
43
import QueryProvider from '@/components/layouts/query-provider';
5-
import MainSearch from '@/components/main-search';
64
import ProgressBarWrapper from '@/components/progress-bar-wrapper';
75
import SiteFooter from '@/components/site-footer';
86
import { SiteHeader } from '@/components/site-header';
@@ -65,9 +63,6 @@ export default async function RootLayout({ children }: RootLayoutProps) {
6563
<QueryProvider>
6664
<div className="relative flex min-h-screen flex-col justify-between">
6765
<SiteHeader />
68-
<Container className="lg:hidden">
69-
<MainSearch />
70-
</Container>
7166
{children}
7267
<SiteFooter />
7368
</div>
Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
'use client';
22

3-
import { ChangeEvent, KeyboardEvent, useState } from 'react';
3+
import { ChangeEvent, KeyboardEvent as ReactKeyboardEvent, useRef, useState } from 'react';
44

55
import { performSearchMainSearch } from '@/lib/helpers';
6-
import { CornerDownLeft, Search } from 'lucide-react';
6+
import { useKeyDown } from '@/lib/hooks/useKeyDown.ts';
7+
import { RiSearchLine } from '@remixicon/react';
78

89
import { Input } from './ui/input';
910

1011
export default function MainSearch() {
12+
const inputRef = useRef<HTMLInputElement>(null);
13+
1114
const [value, setValue] = useState('');
1215

13-
const handlePress = async (e: KeyboardEvent) => {
16+
const handlePress = async (e: ReactKeyboardEvent) => {
1417
if (e?.key === 'Enter') {
1518
await performSearchMainSearch(value);
1619
setValue('');
@@ -21,17 +24,31 @@ export default function MainSearch() {
2124
setValue(e.target.value);
2225
};
2326

27+
const handleFocus = (event?: KeyboardEvent) => {
28+
if (event && document.activeElement !== document.body) return;
29+
event?.preventDefault();
30+
event?.stopPropagation();
31+
setTimeout(() => inputRef.current?.focus());
32+
};
33+
34+
useKeyDown('/', handleFocus);
35+
2436
return (
2537
<div className="relative">
26-
<Search className="absolute left-2.5 top-2.5 -z-10 size-5 text-muted-foreground" />
38+
<RiSearchLine className="absolute left-4 top-3 -z-10 size-4 text-muted-foreground" />
2739
<Input
28-
onChange={handleChangeValue}
29-
value={value}
40+
ref={inputRef}
41+
className="px-10"
3042
placeholder="Search by address / txn hash / block..."
43+
value={value}
44+
onChange={handleChangeValue}
3145
onKeyDown={handlePress}
32-
className="px-10"
3346
/>
34-
<CornerDownLeft className="absolute right-2.5 top-2.5 -z-10 m-auto size-5 text-muted-foreground" />
47+
<div className="absolute right-2.5 top-2.5 -z-10 m-auto flex size-5 items-center justify-center rounded-[4px] bg-[#F5F5F5] text-muted-foreground dark:bg-[#1C1C1C]">
48+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
49+
<path d="M8.06061 2.33337H9.33334L5.9394 11.6667H4.66667L8.06061 2.33337Z" fill="currentColor" />
50+
</svg>
51+
</div>
3552
</div>
3653
);
3754
}

block-explorer/components/navigation.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,24 @@ export function Navigation() {
112112
export const MobileMenu = () => {
113113
const [open, setOpen] = useState<boolean>(false);
114114

115+
const pathname = usePathname();
116+
117+
const isHomePage = pathname === '/';
118+
115119
return (
116120
<Fragment>
117121
<div className="block lg:hidden">
118122
<div className="p-1 duration-300 animate-in animate-out fade-in fade-out" onClick={() => setOpen(!open)}>
119123
{open ? <RiCloseLargeLine className="size-6" /> : <RiMenuLine className="size-6" />}
120124
</div>
121125
</div>
122-
<div className={cn([open ? 'absolute left-0 top-[64px] !m-0 w-full' : 'hidden'])}>
126+
<div
127+
className={cn(
128+
'absolute left-0 top-[64px] !m-0 w-full',
129+
!open && 'hidden',
130+
isHomePage ? 'top-[96px]' : 'top-[128px]',
131+
)}
132+
>
123133
<Card className="rounded-b-2xl rounded-t-none dark:bg-black">
124134
<CardContent className="p-2">
125135
<div className="flex flex-col gap-0.5">
@@ -156,6 +166,7 @@ export const MobileMenu = () => {
156166
key={i}
157167
href={subitem.href}
158168
className="cursor-pointer rounded-[4px] px-3 py-2 text-[14px]/[20px] font-semibold"
169+
onClick={() => setOpen(false)}
159170
>
160171
{subitem.title}
161172
</Link>

block-explorer/components/site-header.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ import { Badge } from './ui/badge';
1111
export function SiteHeader() {
1212
return (
1313
<Fragment>
14-
<header className="z-40 flex w-full flex-col bg-white py-4 dark:bg-black">
14+
<header className="z-40 flex w-full flex-col bg-white dark:bg-black">
1515
<SiteTopBar />
16-
<div className="container flex items-center justify-between gap-4 space-x-4 px-4 pt-0 sm:space-x-0 lg:px-8 lg:pt-4">
16+
<div className="container flex items-center justify-between gap-4 space-x-4 p-4 sm:space-x-0 lg:px-8">
1717
<Link href="/" className="flex items-center gap-2">
1818
<Image
1919
src="/site-logos/rootscan-logo.png"

block-explorer/components/site-top-bar.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,20 @@ export const SiteTopBar = () => {
1212
const isHomePage = pathname === '/';
1313

1414
return (
15-
<div className="hidden border-b pb-4 lg:block">
16-
<div className="container">
15+
<div className="border-b pb-[11px] pt-3">
16+
<div className="container px-4 lg:px-8">
1717
<div className="flex items-center justify-between gap-4">
18-
<div className="flex w-full select-none items-center gap-2 text-xs text-primary/80">
18+
<div className="hidden w-full select-none items-center gap-2 text-xs text-primary/80 lg:flex">
1919
<OnlyMainnet>
2020
<RootPrice />
2121
</OnlyMainnet>
22-
{isHomePage && <div className="flex-1" />}
22+
{isHomePage && <div className="hidden lg:flex-1" />}
2323
<RiGasStationLine className="size-4 text-muted-foreground" />{' '}
2424
<span className="text-muted-foreground">EVM Gas: </span>
2525
<span>7500 Gwei</span>
2626
</div>
2727
{!isHomePage && (
28-
<div className="hidden max-w-2xl grow lg:block">
28+
<div className="w-full grow lg:max-w-[656px]">
2929
<MainSearch />
3030
</div>
3131
)}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import React from 'react'
2+
3+
export const useKeyDown = (
4+
key: string,
5+
callback: (event: KeyboardEvent) => void
6+
) => {
7+
const callbackRef = React.useRef(callback)
8+
callbackRef.current = callback
9+
10+
React.useEffect(() => {
11+
const handleKeydown = (event: KeyboardEvent) => {
12+
if (event.key === key) {
13+
callbackRef.current(event)
14+
}
15+
}
16+
document.addEventListener('keydown', handleKeydown)
17+
return () => {
18+
document.removeEventListener('keydown', handleKeydown)
19+
}
20+
}, [])
21+
}

0 commit comments

Comments
 (0)