import { FC, forwardRef, memo, ReactNode } from 'react'; import type { AnchorHTMLAttributes, MouseEventHandler, SyntheticEvent } from 'react'; import { Link as ReactLink } from 'react-router-dom'; import clsx from 'clsx'; import { styled } from '@mui/material/styles'; import { SxProps } from '@mui/system'; import type { Theme } from '../../@styles/theme-provider'; const HYPERLINK_PREFIXES = ['http', 'mailto']; const componentStyles = ({ theme }: { theme: Theme }) => ({ color: 'inherit', '&, &:hover': { textDecoration: 'none' }, '&.table': { color: theme.palette.secondary[500], '&:hover': { color: theme.palette.secondary[600], cursor: 'pointer' } } }); const StyledAnchor = styled('a')(componentStyles); const StyledReactLink = styled(ReactLink)(componentStyles); export interface LinkProps extends Omit, 'href'> { /** * The component which display the link. */ children?: ReactNode; /** * The href the link will address to. */ href?: | string | { search?: string; pathname?: string; hash?: string } | MouseEventHandler; /** * Apply special styles for table link? */ table?: boolean; classes?: { root?: string; }; onClick?: (e: SyntheticEvent) => void; sx?: SxProps; } const Link: FC> = forwardRef>( (props, ref) => { const { children, className: cn, classes, href, table = false, onClick, ...otherProps } = props; const className = clsx((href || onClick) && [classes?.root, table && 'table'], cn); if (typeof href === 'string' && HYPERLINK_PREFIXES.some(v => href.startsWith(v))) { return ( {children} ); } return href ? ( {children} ) : onClick !== undefined ? ( {children} ) : ( // fallback in case no href/empty href is provided /* eslint-disable-next-line */ <>{children} ); } ); const m = memo(Link); export { m as Link };