index.tsx58 lines · main
1import { Badge, Menu } from 'ui'
2
3import type { ProductMenuGroup } from './ProductMenu.types'
4import { ProductMenuItem } from './ProductMenuItem'
5
6interface ProductMenuProps {
7 page?: string
8 menu: ProductMenuGroup[]
9 /** Called when a menu item link is clicked (e.g. to close a sheet on navigation) */
10 onItemClick?: () => void
11}
12
13export const ProductMenu = ({ page, menu, onItemClick }: ProductMenuProps) => {
14 return (
15 <div className="flex flex-col space-y-4">
16 <Menu type="pills">
17 {menu.map((group, idx) => (
18 <div key={group.key || group.title}>
19 <div className="my-4 space-y-4">
20 <div className="md:mx-3">
21 <Menu.Group
22 title={
23 group.title ? (
24 <div className="flex flex-col space-y-2 uppercase font-mono">
25 <span>{group.title}</span>
26 {group.isPreview && <Badge variant="warning">Not production ready</Badge>}
27 </div>
28 ) : null
29 }
30 />
31 <div>
32 {group.items.map((item) => {
33 const isActive = !!item.pages
34 ? item.pages.includes(page ?? '')
35 : page === item.key
36
37 return (
38 <ProductMenuItem
39 key={item.key}
40 item={item}
41 isActive={isActive}
42 target={item.isExternal ? '_blank' : '_self'}
43 onClick={onItemClick}
44 />
45 )
46 })}
47 </div>
48 </div>
49 </div>
50 {idx !== menu.length - 1 && (
51 <div className="h-px w-[calc(100%-1.5rem)] mx-auto md:w-full bg-border-overlay" />
52 )}
53 </div>
54 ))}
55 </Menu>
56 </div>
57 )
58}