Files
shadcn-ui/apps/www/components/command-menu.tsx
shadcn 8f0c26f22a feat(www): code for blocks (#5756)
* feat: update blocks

* fix: scrollbars

* fix: code viewer

* test(shadcn): fix
2024-11-07 17:09:41 +04:00

127 lines
4.2 KiB
TypeScript

"use client"
import * as React from "react"
import { useRouter } 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 { docsConfig } from "@/config/docs"
import { cn } from "@/lib/utils"
import { Button } from "@/registry/new-york/ui/button"
import {
CommandDialog,
CommandEmpty,
CommandGroup,
CommandInput,
CommandItem,
CommandList,
CommandSeparator,
} from "@/registry/new-york/ui/command"
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()
}, [])
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 documentation...</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}>
<CommandInput placeholder="Type a command or search..." />
<CommandList>
<CommandEmpty>No results found.</CommandEmpty>
<CommandGroup heading="Links">
{docsConfig.mainNav
.filter((navitem) => !navitem.external)
.map((navItem) => (
<CommandItem
key={navItem.href}
value={navItem.title}
onSelect={() => {
runCommand(() => router.push(navItem.href as string))
}}
>
<File />
{navItem.title}
</CommandItem>
))}
</CommandGroup>
{docsConfig.sidebarNav.map((group) => (
<CommandGroup key={group.title} heading={group.title}>
{group.items.map((navItem) => (
<CommandItem
key={navItem.href}
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>
))}
<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>
</>
)
}