umami/src/components/common/NavMenu.tsx
Mike Cao c6dd3fb6ff Rename SideMenu to NavMenu, fix tooltips, and update react-zen.
- Rename SideMenu to NavMenu with visible group title labels and selected item highlighting
- Update react-zen to 0.242.0 and fix responsive breakpoints (xs -> base)
- Style floating tooltips with inverted background across WorldMap, charts, and WeeklyTraffic
- Add CSS variables for primary color and use IconLabel consistently
- Remove stray console.log from LoadingPanel

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 01:58:55 -08:00

78 lines
1.9 KiB
TypeScript

import { Column, Heading, Row, Text } from '@umami/react-zen';
import Link from 'next/link';
import { IconLabel } from '@/components/common/IconLabel';
interface NavMenuData {
id: string;
label: string;
icon?: any;
path: string;
}
interface NavMenuItems {
label?: string;
items: NavMenuData[];
}
export interface NavMenuProps {
items: NavMenuItems[];
title?: string;
selectedKey?: string;
allowMinimize?: boolean;
onItemClick?: () => void;
}
export function NavMenu({
items = [],
title,
selectedKey,
allowMinimize,
onItemClick,
...props
}: NavMenuProps) {
const renderItems = (items: NavMenuData[]) => {
return items?.map(({ id, label, icon, path }) => {
const isSelected = selectedKey === id;
return (
<Link key={id} href={path} onClick={onItemClick}>
<Row
padding
borderRadius
hover={{ backgroundColor: 'surface-sunken' }}
backgroundColor={isSelected ? 'surface-sunken' : undefined}
>
<IconLabel icon={icon}>
<Text weight={isSelected ? 'bold' : 'normal'}>{label}</Text>
</IconLabel>
</Row>
</Link>
);
});
};
return (
<Column gap overflowY="auto" justifyContent="space-between" position="sticky">
{title && (
<Row padding>
<Heading size="sm">{title}</Heading>
</Row>
)}
<Column gap="6" {...props}>
{items?.map(({ label, items }, index) => {
if (label) {
return (
<Column key={`${label}${index}`} gap="1" marginBottom="3" minHeight="40px">
<Row padding>
<Text weight="bold">{label}</Text>
</Row>
{renderItems(items)}
</Column>
);
}
return null;
})}
</Column>
</Column>
);
}