/* eslint-disable react/forbid-component-props */ import React, { CSSProperties, HTMLAttributeAnchorTarget, useMemo } from 'react'; import { BaseColorTokens } from '../../../foundation/Colors'; import { TypographyTokens } from '../../../foundation/Typography'; import { AttentionIndicator } from '../../AttentionIndicator'; import { Popover } from '../../Popover'; import { ToggleCaret } from '../../ToggleCaret'; import { isActiveLink } from './is-active-link'; import { NavItem, NavLinkButton, NavLinkButtonBox, NavLinkRootButton } from './NavLink.styled'; import { SubLinks, SubLinksProps } from './SubLinks/SubLinks'; import { useLocation } from './useLocation'; export type NavLinkProps = React.PropsWithChildren<{ Component?: SubLinksProps['Component']; className?: string; colorToken?: BaseColorTokens | 'rainbow'; isNew?: boolean; itemContainerStyles?: CSSProperties; link?: string; onItemClicked?: (href?: string) => void; subLinks?: { isHidden?: boolean; isNew?: boolean; link: string; target?: HTMLAttributeAnchorTarget | undefined; text: string; }[]; target?: HTMLAttributeAnchorTarget | undefined; typographyToken?: TypographyTokens; }>; export const NavLink: React.FunctionComponent = ({ className, subLinks = [], children, link, isNew, colorToken = 'white', Component, typographyToken = 'bodyMediumMedium', target, itemContainerStyles, onItemClicked, }) => { const { pathname } = useLocation(); const subLinksNotHidden = useMemo( () => (subLinks || []).filter((sL) => !sL.isHidden), [subLinks], ); const hasSubLinks = subLinksNotHidden.length !== 0; const [isSubmenuOpened, setIsSubmenuOpened] = React.useState(false); const handleSubmenuClose = () => setIsSubmenuOpened(false); const handleOnNavLinkClick = ( e: | React.MouseEvent | React.MouseEvent, ) => { if (isActive || hasSubLinks) { e.preventDefault(); e.stopPropagation(); } if (hasSubLinks) { if (isSubmenuOpened) { handleSubmenuClose(); } else { setIsSubmenuOpened(true); } } }; const isActive = isActiveLink(link, subLinksNotHidden?.map((l) => l.link), pathname); const to = link || ''; const NavLinkButtonComputed = Component ? NavLinkButton.withComponent(Component) : to ? NavLinkButton : NavLinkRootButton; const linkButton = ( { onItemClicked?.(link); if (hasSubLinks) { if (isSubmenuOpened) { handleSubmenuClose(); } else { setIsSubmenuOpened(true); } } }} > {isNew ? : null} {children} {!hasSubLinks ? null : ( ) => { e.stopPropagation(); if (hasSubLinks) { if (isSubmenuOpened) { handleSubmenuClose(); } else { setIsSubmenuOpened(true); } } }} /> )} ); return ( {hasSubLinks ? ( } data-testid="NavLinkPopover" isOpen={isSubmenuOpened} onClickOutside={handleSubmenuClose} > {linkButton} ) : ( linkButton )} ); };