66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
import { Text } from '@/ui/Text';
|
|
import { Box } from '@/ui/primitives/Box';
|
|
import { LucideIcon } from 'lucide-react';
|
|
import Link from 'next/link';
|
|
|
|
interface NavLinkProps {
|
|
href: string;
|
|
label: string;
|
|
icon?: LucideIcon;
|
|
isActive?: boolean;
|
|
variant?: 'sidebar' | 'top';
|
|
}
|
|
|
|
/**
|
|
* NavLink provides a consistent link component for navigation.
|
|
* Supports both sidebar and top navigation variants.
|
|
*/
|
|
export function NavLink({ href, label, icon: Icon, isActive, variant = 'sidebar' }: NavLinkProps) {
|
|
if (variant === 'top') {
|
|
return (
|
|
<Box
|
|
as={Link}
|
|
href={href}
|
|
display="flex"
|
|
alignItems="center"
|
|
gap={2}
|
|
px={3}
|
|
py={2}
|
|
transition
|
|
color={isActive ? 'primary-accent' : 'text-gray-400'}
|
|
hoverTextColor="white"
|
|
>
|
|
{Icon && <Icon size={18} />}
|
|
<Text size="sm" weight={isActive ? 'bold' : 'medium'}>
|
|
{label}
|
|
</Text>
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<Box
|
|
as={Link}
|
|
href={href}
|
|
display="flex"
|
|
alignItems="center"
|
|
gap={3}
|
|
px={3}
|
|
py={2}
|
|
rounded="md"
|
|
transition
|
|
bg={isActive ? 'primary-accent/10' : 'transparent'}
|
|
color={isActive ? 'primary-accent' : 'text-gray-400'}
|
|
hoverBg={isActive ? 'primary-accent/10' : 'white/5'}
|
|
hoverTextColor={isActive ? 'primary-accent' : 'white'}
|
|
group
|
|
>
|
|
{Icon && <Icon size={20} color={isActive ? '#198CFF' : '#6B7280'} />}
|
|
<Text weight="medium">{label}</Text>
|
|
{isActive && (
|
|
<Box ml="auto" w="4px" h="16px" bg="primary-accent" rounded="full" shadow="[0_0_8px_rgba(25,140,255,0.5)]" />
|
|
)}
|
|
</Box>
|
|
);
|
|
}
|