import { type LucideIcon } from 'lucide-react';
import clsx from 'clsx';
import { MouseEventHandler, PropsWithChildren } from 'react';
import { AutomationTestingProps } from '@/types';
import { Icon } from '@@/Icon';
import { Badge } from '@@/Badge';
import { useSidebarState } from '../useSidebarState';
import { Wrapper } from './Wrapper';
import { SidebarTooltip } from './SidebarTooltip';
import { useSidebarSrefActive } from './useSidebarSrefActive';
interface Props extends AutomationTestingProps {
icon?: LucideIcon;
to: string;
params?: object;
label: string;
isSubMenu?: boolean;
ignorePaths?: string[];
/** When a create or detail path id differs from the list path, includePaths can be used to specify which paths should also mark the item as active.
*
* E.g. including the portainer.wizard.endpoints (create environment) path to activate the portainer.endpoints sidebar item. */
includePaths?: string[];
count?: number;
}
export function SidebarItem({
icon,
to,
params,
label,
isSubMenu = false,
ignorePaths = [],
includePaths = [],
count,
'data-cy': dataCy,
}: Props) {
const { isOpen } = useSidebarState();
const anchorProps = useSidebarSrefActive(to, undefined, params, undefined, {
ignorePaths,
includePaths,
});
const sidebarAnchor = (
{!!icon && svg]:w-4')} />}
{(isOpen || isSubMenu) && {label}}
);
if (isOpen || isSubMenu) return sidebarAnchor;
return (
{label}
}
>
{sidebarAnchor}
);
}
type ItemAnchorProps = {
href?: string;
onClick: MouseEventHandler;
className: string;
isOpen: boolean;
isSubMenu: boolean;
dataCy: string;
count?: number;
};
function ItemAnchor({
href,
onClick,
className,
isOpen,
isSubMenu,
dataCy,
count,
children,
}: PropsWithChildren) {
return (
{children}
{(isOpen || isSubMenu) && count !== undefined && count > 0 && (
// 99 is for a conventional badge overflow cap, same pattern as GitHub/Slack notification badges
{count > 99 ? '99+' : count}
)}
);
}