MobileMenu.tsx raw
1 import { Button } from '@/components/ui/button'
2 import { Drawer, DrawerContent, DrawerOverlay } from '@/components/ui/drawer'
3 import { ArrowLeft } from 'lucide-react'
4 import { MenuAction, SubMenuAction } from './useMenuActions'
5
6 interface MobileMenuProps {
7 menuActions: MenuAction[]
8 trigger: React.ReactNode
9 isDrawerOpen: boolean
10 setIsDrawerOpen: (open: boolean) => void
11 showSubMenu: boolean
12 activeSubMenu: SubMenuAction[]
13 subMenuTitle: string
14 closeDrawer: () => void
15 goBackToMainMenu: () => void
16 }
17
18 export function MobileMenu({
19 menuActions,
20 trigger,
21 isDrawerOpen,
22 setIsDrawerOpen,
23 showSubMenu,
24 activeSubMenu,
25 subMenuTitle,
26 closeDrawer,
27 goBackToMainMenu
28 }: MobileMenuProps) {
29 return (
30 <>
31 {trigger}
32 <Drawer open={isDrawerOpen} onOpenChange={setIsDrawerOpen}>
33 <DrawerOverlay onClick={closeDrawer} />
34 <DrawerContent hideOverlay className="max-h-[80vh]">
35 <div className="overflow-y-auto overscroll-contain py-2" style={{ touchAction: 'pan-y' }}>
36 {!showSubMenu ? (
37 menuActions.map((action, index) => {
38 const Icon = action.icon
39 return (
40 <Button
41 key={index}
42 onClick={action.onClick}
43 className={`w-full p-6 justify-start text-lg gap-4 [&_svg]:size-5 ${action.className || ''}`}
44 variant="ghost"
45 >
46 <Icon />
47 {action.label}
48 </Button>
49 )
50 })
51 ) : (
52 <>
53 <Button
54 onClick={goBackToMainMenu}
55 className="w-full p-6 justify-start text-lg gap-4 [&_svg]:size-5 mb-2"
56 variant="ghost"
57 >
58 <ArrowLeft />
59 {subMenuTitle}
60 </Button>
61 <div className="border-t border-border mb-2" />
62 {activeSubMenu.map((subAction, index) => (
63 <Button
64 key={index}
65 onClick={subAction.onClick}
66 className={`w-full p-6 justify-start text-lg gap-4 ${subAction.className || ''}`}
67 variant="ghost"
68 >
69 {subAction.label}
70 </Button>
71 ))}
72 </>
73 )}
74 </div>
75 </DrawerContent>
76 </Drawer>
77 </>
78 )
79 }
80