diff options
| author | Fuwn <[email protected]> | 2026-01-24 13:09:50 +0000 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-01-24 13:09:50 +0000 |
| commit | 396acf3bbbe00a192cb0ea0a9ccf91b1d8d2850b (patch) | |
| tree | b9df4ca6a70db45cfffbae6fdd7252e20fb8e93c /src/components/common/SideMenu.tsx | |
| download | umami-main.tar.xz umami-main.zip | |
Created from https://vercel.com/new
Diffstat (limited to 'src/components/common/SideMenu.tsx')
| -rw-r--r-- | src/components/common/SideMenu.tsx | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/components/common/SideMenu.tsx b/src/components/common/SideMenu.tsx new file mode 100644 index 0000000..92ff798 --- /dev/null +++ b/src/components/common/SideMenu.tsx @@ -0,0 +1,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> + ); +} |