1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
import {
Column,
Heading,
IconLabel,
NavMenu,
NavMenuGroup,
NavMenuItem,
type NavMenuProps,
Row,
} from '@umami/react-zen';
import Link from 'next/link';
interface SideMenuData {
id: string;
label: string;
icon?: any;
path: string;
}
interface SideMenuItems {
label?: string;
items: SideMenuData[];
}
export interface SideMenuProps extends NavMenuProps {
items: SideMenuItems[];
title?: string;
selectedKey?: string;
allowMinimize?: boolean;
}
export function SideMenu({
items = [],
title,
selectedKey,
allowMinimize,
...props
}: SideMenuProps) {
const renderItems = (items: SideMenuData[]) => {
return items?.map(({ id, label, icon, path }) => {
const isSelected = selectedKey === id;
return (
<Link key={id} href={path}>
<NavMenuItem isSelected={isSelected}>
<IconLabel icon={icon}>{label}</IconLabel>
</NavMenuItem>
</Link>
);
});
};
return (
<Column gap overflowY="auto" justifyContent="space-between" position="sticky" top="20px">
{title && (
<Row padding>
<Heading size="1">{title}</Heading>
</Row>
)}
<NavMenu gap="6" {...props}>
{items?.map(({ label, items }, index) => {
if (label) {
return (
<NavMenuGroup
title={label}
key={`${label}${index}`}
gap="1"
allowMinimize={allowMinimize}
marginBottom="3"
>
{renderItems(items)}
</NavMenuGroup>
);
}
return null;
})}
</NavMenu>
</Column>
);
}
|