Skip to content

Commit ef4ca0e

Browse files
committed
fix: refactor header component for improved responsiveness and layout consistency
1 parent 9d3883e commit ef4ca0e

File tree

3 files changed

+34
-26
lines changed

3 files changed

+34
-26
lines changed

src/components/glass.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export function Glass({ children, ...props }: GlassProps) {
66
return (
77
<div
88
{...props}
9-
className={cn("backdrop-blur-md bg-white/40 rounded-lg border border-gray-200 p-4", props.className)}
9+
className={cn("rounded-lg border border-gray-200 bg-white/40 p-4 backdrop-blur-md", props.className)}
1010
>
1111
{children}
1212
</div>

src/components/header.tsx

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,11 @@ function useMediaQuery(query: string): boolean {
2121

2222
React.useEffect(() => {
2323
const media = window.matchMedia(query)
24-
if (media.matches !== matches) {
25-
setMatches(media.matches)
26-
}
24+
setMatches(media.matches)
2725
const listener = () => setMatches(media.matches)
2826
media.addEventListener("change", listener)
2927
return () => media.removeEventListener("change", listener)
30-
}, [matches, query])
28+
}, [query])
3129

3230
return matches
3331
}
@@ -83,9 +81,9 @@ function handleMoonIconClick() {
8381

8482
// --- PoliNetwork Logo ---
8583
const Logo = () => (
86-
<Link href="/" className="flex items-center space-x-[9px] h-[30px]">
84+
<Link href="/" className="flex h-[30px] items-center space-x-[9px]">
8785
<Image src="/polinetwork_meta.png" alt="PoliNetwork Logo" width={24} height={24} />
88-
<h1 className="font-poppins font-normal text-[20px] leading-[100%] text-[#1156AE]">PoliNetwork</h1>
86+
<h1 className="font-normal font-poppins text-[#1156AE] text-[20px] leading-[100%]">PoliNetwork</h1>
8987
</Link>
9088
)
9189

@@ -128,8 +126,8 @@ const MobileLayout = () => {
128126
const [mobileMenuOpen, setMobileMenuOpen] = React.useState(false)
129127

130128
return (
131-
<Glass className="fixed py-[20px]! px-[24px]! max-w-[354px] w-full rounded-[36px] m-auto mb-0 mt-0 top-[40px] z-20 box-border">
132-
<div className="flex justify-between! items-center w-full">
129+
<Glass className="fixed top-[40px] z-20 m-auto mt-0 mb-0 box-border w-full max-w-[354px] rounded-[36px] px-[24px]! py-[20px]!">
130+
<div className="justify-between! flex w-full items-center">
133131
<Logo />
134132
<button
135133
type="button"
@@ -146,16 +144,16 @@ const MobileLayout = () => {
146144
<div className="mr-auto flex flex-col">
147145
{components.map((component) => (
148146
<React.Fragment key={component.title}>
149-
<span className="mt-[24px] typo-title-large font-poppins bg-linear-to-b from-blue-secondary to-blue-primary bg-clip-text text-transparent">
147+
<span className="typo-title-large mt-[24px] bg-linear-to-b from-blue-secondary to-blue-primary bg-clip-text font-poppins text-transparent">
150148
{component.title}
151149
</span>
152150
{component.menu && (
153151
<ul className="ml-[12px] flex flex-col gap-2">
154152
{component.menu.map((item) => (
155-
<li key={item.title} className="flex items-center gap-1 mt-[12px]">
153+
<li key={item.title} className="mt-[12px] flex items-center gap-1">
156154
<Link
157155
href={item.href}
158-
className="typo-body-medium text-text-primary hover:underline focus:underline decoration-1 decoration-blue-secondary"
156+
className="typo-body-medium text-text-primary decoration-1 decoration-blue-secondary hover:underline focus:underline"
159157
>
160158
{item.title}
161159
</Link>
@@ -166,7 +164,7 @@ const MobileLayout = () => {
166164
</React.Fragment>
167165
))}
168166
</div>
169-
<div className="flex flex-col pt-2 gap-[20px] mt-[29px]">
167+
<div className="mt-[29px] flex flex-col gap-[20px] pt-2">
170168
<IconButtonsMobile />
171169
</div>
172170
</nav>
@@ -181,12 +179,12 @@ const DesktopLayout = () => {
181179
const customHoverEffectClass = "hover:underline focus:underline decoration-1 decoration-blue-secondary "
182180

183181
return (
184-
<Glass className="fixed py-[20px]! px-[70px]! max-w-[1045px] w-full rounded-full m-auto mb-0 mt-0 top-[40px] z-20 box-border">
182+
<Glass className="fixed top-[40px] z-20 m-auto mt-0 mb-0 box-border w-full max-w-[1045px] rounded-full px-[70px]! py-[20px]!">
185183
<NavigationMenu
186184
viewport={false}
187-
className="flex top-0 isolate [&>div]:w-full max-w-full shrink-0 items-stretch bg-card max-h-[var(--header-height)]"
185+
className="top-0 isolate flex max-h-[var(--header-height)] max-w-full shrink-0 items-stretch bg-card [&>div]:w-full"
188186
>
189-
<NavigationMenuList className="flex justify-between! w-full">
187+
<NavigationMenuList className="justify-between! flex w-full">
190188
<NavigationMenuLink asChild className={`${removeDefaultHoverEffectClass} p-0 py-[3px]`}>
191189
<Logo />
192190
</NavigationMenuLink>
@@ -196,17 +194,17 @@ const DesktopLayout = () => {
196194
{component.menu ? (
197195
<>
198196
<NavigationMenuTrigger
199-
className={`font-red-hat typo-body-medium text-text-primary ${removeDefaultHoverEffectClass} ${customHoverEffectClass} p-0 h-fit group [&_.lucide-chevron-down]:hidden`}
197+
className={`typo-body-medium font-red-hat text-text-primary ${removeDefaultHoverEffectClass} ${customHoverEffectClass} group h-fit p-0 [&_.lucide-chevron-down]:hidden`}
200198
>
201199
<div className="flex flex-col gap-1">
202-
<span className="font-red-hat typo-body-medium text-text-primary">{component.title}</span>
200+
<span className="typo-body-medium font-red-hat text-text-primary">{component.title}</span>
203201
</div>
204202
<FiChevronDown
205203
size={24}
206204
className="color-text-primary relative top-[1px] ml-1 transition duration-300 group-data-[state=open]:rotate-180"
207205
/>
208206
</NavigationMenuTrigger>
209-
<NavigationMenuContent className="mt-[36px]! border-none! bg-transparent! shadow-none! data-[state=open]:bg-transparent! data-[state=closed]:bg-transparent!">
207+
<NavigationMenuContent className="mt-[36px]! border-none! bg-transparent! shadow-none! data-[state=closed]:bg-transparent! data-[state=open]:bg-transparent!">
210208
<ul className="w-fit text-nowrap">
211209
<Glass>
212210
{component.menu.map((item) => {
@@ -215,11 +213,11 @@ const DesktopLayout = () => {
215213
<NavigationMenuLink
216214
asChild
217215
key={item.title}
218-
className={`flex flex-row flex-nowrap justify-between items-center shrink-0 ${removeDefaultHoverEffectClass} ${customHoverEffectClass}`}
216+
className={`flex shrink-0 flex-row flex-nowrap items-center justify-between ${removeDefaultHoverEffectClass} ${customHoverEffectClass}`}
219217
>
220218
<Link href={item.href || "#"}>
221219
<div className="flex flex-col gap-1">
222-
<span className="font-red-hat typo-body-medium text-text-primary">{item.title}</span>
220+
<span className="typo-body-medium font-red-hat text-text-primary">{item.title}</span>
223221
</div>
224222
<Icon size={24} className="color-text-primary" />
225223
</Link>
@@ -251,8 +249,18 @@ const DesktopLayout = () => {
251249

252250
// --- Main Header Component ---
253251
export function Header() {
252+
const [mounted, setMounted] = React.useState(false)
254253
const isMobile = useMediaQuery("(max-width: 768px)") // TODO: Adjust breakpoint
255254

255+
React.useEffect(() => {
256+
setMounted(true)
257+
}, [])
258+
259+
// Wait for hydration to prevent flash. Default to mobile layout under the assumption that most traffic is mobile.
260+
if (!mounted) {
261+
return <MobileLayout />
262+
}
263+
256264
return isMobile ? <MobileLayout /> : <DesktopLayout />
257265
}
258266

src/components/ui/navigation-menu.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ function NavigationMenuContent({ className, ...props }: React.ComponentProps<typ
7272
<NavigationMenuPrimitive.Content
7373
data-slot="navigation-menu-content"
7474
className={cn(
75-
"top-0 left-0 w-full p-2 pr-2.5 data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 data-[motion^=from-]:animate-in data-[motion^=from-]:fade-in data-[motion^=to-]:animate-out data-[motion^=to-]:fade-out md:absolute md:w-auto",
76-
"group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:border-grey group-data-[viewport=false]/navigation-menu:bg-background group-data-[viewport=false]/navigation-menu:text-text-primary group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 **:data-[slot=navigation-menu-link]:focus:ring-0 **:data-[slot=navigation-menu-link]:focus:outline-none group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95",
75+
"data-[motion=from-end]:slide-in-from-right-52 data-[motion=from-start]:slide-in-from-left-52 data-[motion=to-end]:slide-out-to-right-52 data-[motion=to-start]:slide-out-to-left-52 data-[motion^=from-]:fade-in data-[motion^=to-]:fade-out top-0 left-0 w-full p-2 pr-2.5 data-[motion^=from-]:animate-in data-[motion^=to-]:animate-out md:absolute md:w-auto",
76+
"group-data-[viewport=false]/navigation-menu:data-[state=closed]:fade-out-0 group-data-[viewport=false]/navigation-menu:data-[state=closed]:zoom-out-95 group-data-[viewport=false]/navigation-menu:data-[state=open]:fade-in-0 group-data-[viewport=false]/navigation-menu:data-[state=open]:zoom-in-95 **:data-[slot=navigation-menu-link]:focus:outline-none **:data-[slot=navigation-menu-link]:focus:ring-0 group-data-[viewport=false]/navigation-menu:top-full group-data-[viewport=false]/navigation-menu:mt-1.5 group-data-[viewport=false]/navigation-menu:overflow-hidden group-data-[viewport=false]/navigation-menu:rounded-md group-data-[viewport=false]/navigation-menu:border group-data-[viewport=false]/navigation-menu:border-grey group-data-[viewport=false]/navigation-menu:bg-background group-data-[viewport=false]/navigation-menu:text-text-primary group-data-[viewport=false]/navigation-menu:shadow group-data-[viewport=false]/navigation-menu:duration-200 group-data-[viewport=false]/navigation-menu:data-[state=closed]:animate-out group-data-[viewport=false]/navigation-menu:data-[state=open]:animate-in",
7777
className
7878
)}
7979
{...props}
@@ -90,7 +90,7 @@ function NavigationMenuViewport({
9090
<NavigationMenuPrimitive.Viewport
9191
data-slot="navigation-menu-viewport"
9292
className={cn(
93-
"origin-top-center relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full overflow-hidden rounded-md border border-grey bg-background text-text-primary shadow data-[state=closed]:animate-out data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:zoom-in-90 md:w-[var(--radix-navigation-menu-viewport-width)]",
93+
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-90 relative mt-1.5 h-[var(--radix-navigation-menu-viewport-height)] w-full origin-top-center overflow-hidden rounded-md border border-grey bg-background text-text-primary shadow data-[state=closed]:animate-out data-[state=open]:animate-in md:w-[var(--radix-navigation-menu-viewport-width)]",
9494
className
9595
)}
9696
{...props}
@@ -104,7 +104,7 @@ function NavigationMenuLink({ className, ...props }: React.ComponentProps<typeof
104104
<NavigationMenuPrimitive.Link
105105
data-slot="navigation-menu-link"
106106
className={cn(
107-
"flex flex-col gap-1 rounded-sm p-2 text-sm text-text-primary transition-all outline-none hover:bg-grey focus:bg-grey focus-visible:ring-[3px] focus-visible:ring-text-primary/50 focus-visible:outline-1 data-[active=true]:bg-grey/50 data-[active=true]:hover:bg-grey data-[active=true]:focus:bg-grey [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-text-secondary",
107+
"flex flex-col gap-1 rounded-sm p-2 text-sm text-text-primary outline-none transition-all hover:bg-grey focus:bg-grey focus-visible:outline-1 focus-visible:ring-[3px] focus-visible:ring-text-primary/50 data-[active=true]:bg-grey/50 data-[active=true]:focus:bg-grey data-[active=true]:hover:bg-grey [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-text-secondary",
108108
className
109109
)}
110110
{...props}
@@ -120,7 +120,7 @@ function NavigationMenuIndicator({
120120
<NavigationMenuPrimitive.Indicator
121121
data-slot="navigation-menu-indicator"
122122
className={cn(
123-
"top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=hidden]:animate-out data-[state=hidden]:fade-out data-[state=visible]:animate-in data-[state=visible]:fade-in",
123+
"data-[state=hidden]:fade-out data-[state=visible]:fade-in top-full z-[1] flex h-1.5 items-end justify-center overflow-hidden data-[state=hidden]:animate-out data-[state=visible]:animate-in",
124124
className
125125
)}
126126
{...props}

0 commit comments

Comments
 (0)