diff options
| author | joonhoekim <26rote@gmail.com> | 2025-03-25 15:55:45 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-03-25 15:55:45 +0900 |
| commit | 1a2241c40e10193c5ff7008a7b7b36cc1d855d96 (patch) | |
| tree | 8a5587f10ca55b162d7e3254cb088b323a34c41b /components/layout/command-menu.tsx | |
initial commit
Diffstat (limited to 'components/layout/command-menu.tsx')
| -rw-r--r-- | components/layout/command-menu.tsx | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/components/layout/command-menu.tsx b/components/layout/command-menu.tsx new file mode 100644 index 00000000..5537a042 --- /dev/null +++ b/components/layout/command-menu.tsx @@ -0,0 +1,139 @@ +"use client" + +import * as React from "react" +import { useRouter,usePathname } from "next/navigation" +import { type DialogProps } from "@radix-ui/react-dialog" +import { Circle, File, Laptop, Moon, Sun } from "lucide-react" +import { useTheme } from "next-themes" + +import { MenuSection, mainNav, additionalNav, MenuItem, mainNavVendor, additionalNavVendor } from "@/config/menuConfig"; +import { cn } from "@/lib/utils" +import { Button } from "@/components/ui/button" +import { + CommandDialog, + CommandEmpty, + CommandGroup, + CommandInput, + CommandItem, + CommandList, + CommandSeparator, +} from "@/components/ui/command" +import { DialogTitle } from "@/components/ui/dialog" + +export function CommandMenu({ ...props }: DialogProps) { + const router = useRouter() + const [open, setOpen] = React.useState(false) + const { setTheme } = useTheme() + + React.useEffect(() => { + const down = (e: KeyboardEvent) => { + if ((e.key === "k" && (e.metaKey || e.ctrlKey)) || e.key === "/") { + if ( + (e.target instanceof HTMLElement && e.target.isContentEditable) || + e.target instanceof HTMLInputElement || + e.target instanceof HTMLTextAreaElement || + e.target instanceof HTMLSelectElement + ) { + return + } + + e.preventDefault() + setOpen((open) => !open) + } + } + + document.addEventListener("keydown", down) + return () => document.removeEventListener("keydown", down) + }, []) + + const runCommand = React.useCallback((command: () => unknown) => { + setOpen(false) + command() + }, []) + + +const pathname = usePathname(); +const isPartnerRoute = pathname.includes("/partners"); + + const main = isPartnerRoute ? mainNavVendor : mainNav; + const additional = isPartnerRoute ? additionalNavVendor : additionalNav; + + + return ( + <> + <Button + variant="outline" + className={cn( + "relative h-8 w-full justify-start rounded-[0.5rem] bg-muted/50 text-sm font-normal text-muted-foreground shadow-none sm:pr-12 md:w-40 lg:w-56 xl:w-64" + )} + onClick={() => setOpen(true)} + {...props} + > + <span className="hidden lg:inline-flex">Search Menu...</span> + <span className="inline-flex lg:hidden">Search...</span> + <kbd className="pointer-events-none absolute right-[0.3rem] top-[0.3rem] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex"> + <span className="text-xs">⌘</span>K + </kbd> + </Button> + <CommandDialog open={open} onOpenChange={setOpen}> + <DialogTitle className="sr-only">Search Menu</DialogTitle> + <CommandInput placeholder="Type a command or search..." /> + <CommandList> + <CommandEmpty>No results found.</CommandEmpty> + + {main.map((group) => ( + <CommandGroup key={group.title} heading={group.title}> + {group.items.map((navItem) => ( + <CommandItem + key={navItem.title} + value={navItem.title} + onSelect={() => { + runCommand(() => router.push(navItem.href as string)) + }} + > + <div className="mr-2 flex h-4 w-4 items-center justify-center"> + <Circle className="h-3 w-3" /> + </div> + {navItem.title} + </CommandItem> + ))} + </CommandGroup> + ))} + <CommandGroup heading=""> + {additional + // .filter((navitem) => !navitem.external) + .map((navItem) => ( + <CommandItem + key={navItem.title} + value={navItem.title} + onSelect={() => { + runCommand(() => router.push(navItem.href as string)) + }} + > + <File /> + {navItem.title} + </CommandItem> + ))} + </CommandGroup> + <CommandSeparator /> + + + <CommandGroup heading="Theme"> + <CommandItem onSelect={() => runCommand(() => setTheme("light"))}> + <Sun /> + Light + </CommandItem> + <CommandItem onSelect={() => runCommand(() => setTheme("dark"))}> + <Moon /> + Dark + </CommandItem> + <CommandItem onSelect={() => runCommand(() => setTheme("system"))}> + <Laptop /> + System + </CommandItem> + </CommandGroup> + </CommandList> + </CommandDialog> + </> + ) +} |
