Files

98 lines
3.3 KiB
TypeScript

import React from 'react';
import type { NavItem } from 'types/client/navigation';
import { route } from 'nextjs-routes';
import useIsMobile from 'lib/hooks/useIsMobile';
import { isInternalItem } from 'lib/hooks/useNavItems';
import { cn } from 'lib/utils/cn';
import { Link } from 'toolkit/next/link';
import { Tooltip } from '@luxfi/ui/tooltip';
import LightningLabel, { LIGHTNING_LABEL_CLASS_NAME } from '../LightningLabel';
import NavLinkIcon from '../NavLinkIcon';
import useNavLinkStyleProps from '../useNavLinkStyleProps';
import { checkRouteHighlight } from '../utils';
type Props = {
item: NavItem;
onClick?: (e: React.MouseEvent) => void;
isCollapsed?: boolean;
isDisabled?: boolean;
};
const NavLink = ({ item, onClick, isCollapsed, isDisabled }: Props) => {
const isMobile = useIsMobile();
const isInternalLink = isInternalItem(item);
const isExpanded = isCollapsed === false;
const styleProps = useNavLinkStyleProps({ isCollapsed, isExpanded, isActive: isInternalLink && item.isActive });
const [ isXLScreen, setIsXLScreen ] = React.useState(false);
React.useEffect(() => {
const mql = window.matchMedia('(min-width: 1280px)');
const handler = (e: MediaQueryListEvent) => setIsXLScreen(e.matches);
setIsXLScreen(mql.matches);
mql.addEventListener('change', handler);
return () => mql.removeEventListener('change', handler);
}, []);
const isHighlighted = checkRouteHighlight(item);
return (
<li className="list-none w-full">
<Link
href={ isInternalLink ? route(item.nextRoute) : item.url }
external={ !isInternalLink }
variant="navigation"
{ ...(isInternalLink && item.isActive ? { 'data-selected': true } : {}) }
className={ cn(
'flex relative whitespace-nowrap py-[9px] rounded-base',
'transition-[width,padding] duration-200 ease-in-out',
isExpanded ? 'w-full px-2' : 'lg:w-[60px] lg:px-[15px]',
isCollapsed ? 'xl:w-[60px] xl:px-[15px]' : 'xl:w-full xl:px-2',
) }
aria-label={ `${ item.text } link` }
onClick={ onClick }
>
<Tooltip
content={ item.text }
showArrow={ false }
disabled={ isMobile || isCollapsed === false || (isCollapsed === undefined && isXLScreen) }
positioning={{ placement: 'right', offset: { crossAxis: 0, mainAxis: 20 } }}
variant="popover"
contentProps={{
color: isInternalLink && item.isActive ? 'link.navigation.fg.selected' : 'link.navigation.fg.hover',
}}
interactive
>
<div className="flex gap-0 overflow-hidden items-center">
<NavLinkIcon item={ item }/>
<span
{ ...styleProps.textProps }
className={ cn(
'ml-3',
isExpanded ? 'inline' : 'lg:hidden',
isCollapsed ? 'xl:hidden' : 'xl:inline',
) }
>
<span>{ item.text }</span>
</span>
{ isHighlighted && (
<LightningLabel
iconColor={ isInternalLink && item.isActive ? 'link.navigation.bg.selected' : 'link.navigation.bg.group' }
isCollapsed={ isCollapsed }
/>
) }
</div>
</Tooltip>
</Link>
</li>
);
};
export default React.memo(NavLink);