Files
portfolio/src/widgets/Navigation/ui/MobileNav.tsx
T
Ilia Mashkov 30f8e4be95 design: two-color palette — rename all tokens to --cream / --blue
Replace ochre-clay, carbon-black, burnt-oxide, slate-indigo with clean
two-color system: --cream (#f4f0e8) and --blue (#041cf3). Update every
component, utility class, and test assertion.
2026-05-11 12:59:32 +03:00

64 lines
1.9 KiB
TypeScript

'use client';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useEffect, useState } from 'react';
import { cn } from '$shared/lib';
import type { NavItem } from '../model/types';
/**
* Props for MobileNav.
*/
interface Props {
/**
* Navigation items to render
*/
items: NavItem[];
}
/**
* Mobile navigation overlay, hidden on lg+ screens.
* Closes automatically when the URL pathname changes after navigation.
*/
export function MobileNav({ items }: Props) {
const [isOpen, setIsOpen] = useState(false);
const pathname = usePathname();
// biome-ignore lint/correctness/useExhaustiveDependencies: pathname is the trigger, not a value used inside the callback
useEffect(() => {
setIsOpen(false);
}, [pathname]);
return (
<div className="lg:hidden fixed top-0 left-0 right-0 bg-cream brutal-border-bottom z-50">
<div className="px-6 py-4 flex items-center justify-between">
<h4>allmy.work</h4>
<button
type="button"
onClick={() => setIsOpen((prev) => !prev)}
className="brutal-border px-4 py-2 bg-blue text-cream"
>
{isOpen ? 'Close' : 'Menu'}
</button>
</div>
{isOpen && (
<div className="px-6 py-6 brutal-border-top space-y-2 max-h-[80vh] overflow-y-auto">
{items.map((item) => (
<Link key={item.id} href={`/${item.id}`} className="block w-full brutal-border bg-cream px-4 py-3">
<div className={cn('flex items-baseline gap-3')}>
<span className="text-sm opacity-60 font-body">{item.number}</span>
<span
className="font-heading text-lg font-black"
style={{ fontVariationSettings: '"WONK" 1, "SOFT" 0' }}
>
{item.label}
</span>
</div>
</Link>
))}
</div>
)}
</div>
);
}