nas/app/javascript/mastodon/features/ui/components/column_link.tsx

109 lines
2.6 KiB
TypeScript

import { useCallback } from 'react';
import classNames from 'classnames';
import { useRouteMatch, NavLink } from 'react-router-dom';
import { Icon } from 'mastodon/components/icon';
import type { IconProp } from 'mastodon/components/icon';
export const ColumnLink: React.FC<{
icon: React.ReactNode;
iconComponent?: IconProp;
activeIcon?: React.ReactNode;
activeIconComponent?: IconProp;
isActive?: (match: unknown, location: { pathname: string }) => boolean;
text: string;
to?: string;
href?: string;
onClick?: () => void;
method?: string;
badge?: React.ReactNode;
transparent?: boolean;
optional?: boolean;
children?: React.ReactNode;
className?: string;
id?: string;
}> = ({
icon,
activeIcon,
iconComponent,
activeIconComponent,
text,
to,
href,
onClick,
method,
badge,
transparent,
optional,
children,
...other
}) => {
const match = useRouteMatch(to ?? '');
const className = classNames('column-link', {
'column-link--transparent': transparent,
'column-link--optional': optional,
});
const badgeElement =
typeof badge !== 'undefined' ? (
<span className='column-link__badge'>{badge}</span>
) : null;
const iconElement = iconComponent ? (
<Icon
id={typeof icon === 'string' ? icon : ''}
icon={iconComponent}
className='column-link__icon'
/>
) : (
icon
);
const activeIconElement =
activeIcon ??
(activeIconComponent ? (
<Icon
id={typeof icon === 'string' ? icon : ''}
icon={activeIconComponent}
className='column-link__icon'
/>
) : (
iconElement
));
const active = !!match;
const childElement = typeof children !== 'undefined' ? <p>{children}</p> : null;
const handleClick = useCallback((ev: React.MouseEvent<HTMLAnchorElement>) => {
ev.preventDefault();
onClick?.();
}, [onClick]);
if (href) {
return (
<a href={href} className={className} data-method={method} {...other}>
{active ? activeIconElement : iconElement}
<span>{text}</span>
{badgeElement}
{childElement}
</a>
);
} else if (to) {
return (
<NavLink to={to} className={className} {...other}>
{active ? activeIconElement : iconElement}
<span>{text}</span>
{badgeElement}
{childElement}
</NavLink>
);
} else if (onClick) {
return (
<a href={href} className={className} onClick={handleClick} {...other}>
{active ? activeIconElement : iconElement}
<span>{text}</span>
{badgeElement}
{childElement}
</a>
);
} else {
return null;
}
};