{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "navbar",
  "type": "registry:component",
  "dependencies": [
    "@radix-ui/react-slot",
    "@remixicon/react",
    "class-variance-authority",
    "clsx",
    "next",
    "next-themes",
    "react",
    "tailwind-merge",
    "vaul"
  ],
  "files": [
    {
      "type": "registry:component",
      "target": "components/navbar.tsx",
      "content": "\"use client\"\n\nimport { ThemeToggle } from \"@/components/nui/theme-provider\"\nimport {\n  Drawer,\n  DrawerContent,\n  DrawerDescription,\n  DrawerHeader,\n  DrawerTitle,\n  DrawerTrigger,\n} from \"@/components/ui/drawer\"\nimport { cn } from \"@/lib/utils\"\nimport {\n  RiArrowLeftLongLine,\n  RiArrowUpSLine,\n  RiBrushAiLine,\n  RiCodeAiFill,\n  RiCodeAiLine,\n  RiGithubFill,\n  RiLinkedinBoxFill,\n  RiMenu4Fill,\n  RiTwitterXFill,\n} from \"@remixicon/react\"\nimport Link from \"next/link\"\nimport { usePathname } from \"next/navigation\"\nimport { FC, useState } from \"react\"\n\nconst doesPathMatchHref = (pathname: string, href: string): boolean => {\n  const cleanedPathname = pathname.split(/[?#]/)[0]\n\n  if (href === \"/\") {\n    return (\n      cleanedPathname === \"/\" ||\n      pathname.startsWith(\"/#\") ||\n      pathname.startsWith(\"/?\")\n    )\n  }\n\n  if (href === cleanedPathname) {\n    return true\n  }\n\n  if (href === \"/ui\") {\n    return (\n      cleanedPathname === \"/ui\" ||\n      pathname.startsWith(\"/ui#\") ||\n      pathname.startsWith(\"/ui?\")\n    )\n  }\n\n  const regex = new RegExp(`^${href}/[^/]+.*$`)\n  return regex.test(cleanedPathname)\n}\n\nconst navItems = [\n  { name: \"home\", href: \"/\" },\n  { name: \"blogs\", href: \"/blogs\" },\n  { name: \"projects\", href: \"/projects\" },\n  { name: \"contact\", href: \"/contact\" },\n]\n\nconst uiNavItems = [\n  { name: \"home\", href: \"/ui\" },\n  { name: \"docs\", href: \"/ui/docs\" },\n  { name: \"components\", href: \"/ui/components\" },\n  { name: \"blocks\", href: \"/ui/blocks\" },\n]\n\nconst socialLinks = [\n  { href: \"https://github.com/nrjdalal\", icon: RiGithubFill },\n  { href: \"https://www.linkedin.com/in/nrjdalal\", icon: RiLinkedinBoxFill },\n  { href: \"https://x.com/nrjdalal_com\", icon: RiTwitterXFill },\n]\n\ninterface NavigationLinksProps {\n  items: { name: string; href: string }[]\n  hoveredItem: string | null\n  setHoveredItem: (item: string | null) => void\n  pathname: string\n}\n\nconst NavigationLinks: FC<NavigationLinksProps> = ({\n  items,\n  hoveredItem,\n  setHoveredItem,\n  pathname,\n}) => {\n  const [open, setOpen] = useState(false)\n\n  return (\n    <>\n      <div className=\"text-muted-foreground hidden cursor-pointer items-center divide-x font-medium lg:flex\">\n        {items.map((item) => (\n          <Link\n            key={item.name}\n            href={item.href}\n            className={cn(\n              \"group relative flex h-full items-center px-7.5\",\n              doesPathMatchHref(pathname, item.href)\n                ? \"text-foreground\"\n                : \"hover:text-foreground\",\n            )}\n            onMouseEnter={() => setHoveredItem(item.href)}\n            onMouseLeave={() => setHoveredItem(null)}\n          >\n            {item.name}\n            <span\n              className={cn(\n                \"bg-foreground absolute bottom-0 left-0 h-[2px] transition-all ease-in-out\",\n                doesPathMatchHref(pathname, item.href)\n                  ? hoveredItem && hoveredItem !== item.href\n                    ? \"w-0 duration-1000\"\n                    : \"w-full duration-500\"\n                  : \"w-0 duration-1000 group-hover:w-[90%]\",\n              )}\n            />\n          </Link>\n        ))}\n        {socialLinks.map((link) => (\n          <Link\n            key={link.href}\n            href={link.href}\n            target=\"_blank\"\n            className=\"hover:text-foreground group relative flex aspect-square h-full items-center justify-center\"\n          >\n            <link.icon className=\"size-6\" />\n            <RiArrowUpSLine className=\"absolute top-0 right-0 size-4 rotate-45 opacity-0 transition-opacity duration-300 group-hover:opacity-100\" />\n            <span className=\"bg-foreground absolute bottom-0 left-0 h-[2px] w-0 transition-all duration-500 ease-in-out group-hover:w-full\" />\n          </Link>\n        ))}\n        <ThemeToggle />\n      </div>\n      <Drawer open={open} onOpenChange={setOpen}>\n        <DrawerTrigger className=\"text-foreground flex h-full w-16 cursor-pointer items-center justify-center border-l lg:hidden\">\n          <RiMenu4Fill className=\"size-6\" />\n        </DrawerTrigger>\n        <DrawerContent className=\"lg:hidden\">\n          <DrawerHeader className=\"sr-only\">\n            <DrawerTitle>Menu</DrawerTitle>\n            <DrawerDescription>Navigation links</DrawerDescription>\n          </DrawerHeader>\n          <div className=\"relative mt-8 px-14 pb-14\">\n            <span className=\"bg-border absolute top-0 left-0 h-px w-full\" />\n            <span className=\"bg-border absolute bottom-14 left-0 h-px w-full\" />\n            <span className=\"bg-border absolute -top-14 left-14 h-full w-px\" />\n            <span className=\"bg-border absolute right-14 bottom-0 h-full w-px\" />\n            <span className=\"text-foreground/50 absolute -right-8 bottom-48 flex rotate-270 items-center gap-x-2 text-xs\">\n              <RiArrowLeftLongLine className=\"size-3.5\" /> Switch dark mode\n            </span>\n            <span className=\"absolute right-0 bottom-14 aspect-square h-14\">\n              <ThemeToggle />\n            </span>\n            <div className=\"mx-auto flex w-full flex-col items-center\">\n              {items.map((item) => (\n                <Link\n                  key={item.name}\n                  href={item.href}\n                  className={cn(\n                    \"group relative flex h-14 w-full items-center justify-center px-7.5\",\n                    doesPathMatchHref(pathname, item.href)\n                      ? \"text-foreground\"\n                      : \"text-muted-foreground hover:text-foreground\",\n                  )}\n                  onMouseEnter={() => setHoveredItem(item.href)}\n                  onMouseLeave={() => setHoveredItem(null)}\n                  onClick={() => setOpen(false)}\n                >\n                  {item.name}\n                  <span\n                    className={cn(\n                      \"bg-border/50 absolute left-0 -z-10 h-14 transition-all ease-in-out\",\n                      doesPathMatchHref(pathname, item.href)\n                        ? hoveredItem && hoveredItem !== item.href\n                          ? \"w-0 duration-1000\"\n                          : \"w-full duration-1000\"\n                        : \"w-0 duration-1000 group-hover:w-[95%]\",\n                    )}\n                  />\n                </Link>\n              ))}\n              <div className=\"flex h-14 w-full justify-between divide-x border-t\">\n                {socialLinks.map((link) => (\n                  <Link\n                    key={link.href}\n                    href={link.href}\n                    target=\"_blank\"\n                    className=\"hover:text-foreground group relative flex h-full w-full items-center justify-center\"\n                  >\n                    <link.icon className=\"size-6\" />\n                    <RiArrowUpSLine className=\"absolute top-0 right-0 size-4 rotate-45 opacity-0 transition-opacity duration-300 group-hover:opacity-100\" />\n                    <span className=\"bg-foreground absolute bottom-0 left-0 h-[2px] w-0 transition-all duration-500 ease-in-out group-hover:w-full\" />\n                  </Link>\n                ))}\n              </div>\n            </div>\n          </div>\n        </DrawerContent>\n      </Drawer>\n    </>\n  )\n}\n\nexport default function Navbar() {\n  const pathname = usePathname()\n  const [hoveredItem, setHoveredItem] = useState<string | null>(null)\n\n  return (\n    <div className=\"bg-background sticky top-0 z-50 flex h-14 w-full justify-between border-b\">\n      <div className=\"flex divide-x font-mono font-medium\">\n        <Link\n          href=\"/\"\n          className={cn(\n            \"hover:bg-border/50 flex h-full min-w-48 cursor-pointer items-center gap-x-2 px-5 lg:min-w-64\",\n            pathname.startsWith(\"/ui\") && \"hidden\",\n          )}\n        >\n          <RiCodeAiLine className=\"size-6\" />\n          <p>NRJDALAL.</p>\n        </Link>\n        <Link\n          href=\"/ui\"\n          className={cn(\n            \"hover:bg-border/50 flex h-full cursor-pointer items-center gap-x-2 px-5\",\n            pathname.startsWith(\"/ui\") && \"min-w-48 lg:min-w-64\",\n          )}\n        >\n          <RiBrushAiLine className=\"size-6\" />\n          <p className={cn(!pathname.startsWith(\"/ui\") && \"hidden\")}>\n            nrjdalalUI.\n          </p>\n        </Link>\n        <Link\n          href=\"/\"\n          className={cn(\n            \"hidden\",\n            pathname.startsWith(\"/ui\") &&\n              \"hover:bg-border/50 flex h-full cursor-pointer items-center justify-center gap-x-2 border-r px-5\",\n          )}\n        >\n          <RiCodeAiFill className=\"size-6\" />\n        </Link>\n      </div>\n\n      <NavigationLinks\n        items={pathname.startsWith(\"/ui\") ? uiNavItems : navItems}\n        hoveredItem={hoveredItem}\n        setHoveredItem={setHoveredItem}\n        pathname={pathname}\n      />\n    </div>\n  )\n}\n",
      "path": "src/components/navbar.tsx"
    },
    {
      "type": "registry:component",
      "target": "components/nui/theme-provider.tsx",
      "content": "\"use client\"\n\nimport { Button } from \"@/components/ui/button\"\nimport { RiMoonFill, RiSunFill } from \"@remixicon/react\"\nimport { ThemeProvider as NextThemesProvider, useTheme } from \"next-themes\"\n\nexport const ThemeToggle = () => {\n  const { theme, setTheme } = useTheme()\n\n  const smartToggle = () => {\n    /* The smart toggle by @nrjdalal */\n    const prefersDarkScheme = window.matchMedia(\n      \"(prefers-color-scheme: dark)\",\n    ).matches\n    if (theme === \"system\") {\n      setTheme(prefersDarkScheme ? \"light\" : \"dark\")\n    } else if (\n      (theme === \"light\" && !prefersDarkScheme) ||\n      (theme === \"dark\" && prefersDarkScheme)\n    ) {\n      setTheme(theme === \"light\" ? \"dark\" : \"light\")\n    } else {\n      setTheme(\"system\")\n    }\n  }\n\n  return (\n    <Button\n      variant=\"ghost\"\n      className=\"aspect-square size-full rounded-none [&_svg]:size-5\"\n      onClick={smartToggle}\n      aria-label=\"Switch between system/light/dark version\"\n    >\n      <RiSunFill className=\"dark:hidden\" aria-hidden=\"true\" />\n      <RiMoonFill className=\"hidden dark:block\" aria-hidden=\"true\" />\n    </Button>\n  )\n}\n\nexport const ThemeProvider = ({\n  children,\n  ...props\n}: React.ComponentProps<typeof NextThemesProvider>) => {\n  return (\n    <NextThemesProvider\n      attribute=\"class\"\n      defaultTheme=\"system\"\n      enableSystem\n      disableTransitionOnChange\n      {...props}\n    >\n      {children}\n    </NextThemesProvider>\n  )\n}\n",
      "path": "src/components/nui/theme-provider.tsx"
    },
    {
      "type": "registry:ui",
      "target": "components/ui/button.tsx",
      "content": "import { cn } from \"@/lib/utils\"\nimport { Slot } from \"@radix-ui/react-slot\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport * as React from \"react\"\n\nconst buttonVariants = cva(\n  \"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,box-shadow] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive\",\n  {\n    variants: {\n      variant: {\n        default:\n          \"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90\",\n        destructive:\n          \"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40\",\n        outline:\n          \"border border-input bg-background shadow-xs hover:bg-accent hover:text-accent-foreground\",\n        secondary:\n          \"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80\",\n        ghost: \"hover:bg-accent hover:text-accent-foreground\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default: \"h-9 px-4 py-2 has-[>svg]:px-3\",\n        sm: \"h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5\",\n        lg: \"h-10 rounded-md px-6 has-[>svg]:px-4\",\n        icon: \"size-9\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  },\n)\n\nfunction Button({\n  className,\n  variant,\n  size,\n  asChild = false,\n  ...props\n}: React.ComponentProps<\"button\"> &\n  VariantProps<typeof buttonVariants> & {\n    asChild?: boolean\n  }) {\n  const Comp = asChild ? Slot : \"button\"\n\n  return (\n    <Comp\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n",
      "path": "src/components/ui/button.tsx"
    },
    {
      "type": "registry:ui",
      "target": "components/ui/drawer.tsx",
      "content": "\"use client\"\n\nimport { cn } from \"@/lib/utils\"\nimport * as React from \"react\"\nimport { Drawer as DrawerPrimitive } from \"vaul\"\n\nfunction Drawer({\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Root>) {\n  return <DrawerPrimitive.Root data-slot=\"drawer\" {...props} />\n}\n\nfunction DrawerTrigger({\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Trigger>) {\n  return <DrawerPrimitive.Trigger data-slot=\"drawer-trigger\" {...props} />\n}\n\nfunction DrawerPortal({\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Portal>) {\n  return <DrawerPrimitive.Portal data-slot=\"drawer-portal\" {...props} />\n}\n\nfunction DrawerClose({\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Close>) {\n  return <DrawerPrimitive.Close data-slot=\"drawer-close\" {...props} />\n}\n\nfunction DrawerOverlay({\n  className,\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Overlay>) {\n  return (\n    <DrawerPrimitive.Overlay\n      data-slot=\"drawer-overlay\"\n      className={cn(\n        \"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-50 bg-black/80\",\n        className,\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DrawerContent({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Content>) {\n  return (\n    <DrawerPortal data-slot=\"drawer-portal\">\n      <DrawerOverlay />\n      <DrawerPrimitive.Content\n        data-slot=\"drawer-content\"\n        className={cn(\n          \"group/drawer-content bg-background fixed z-50 flex h-auto flex-col\",\n          \"data-[vaul-drawer-direction=top]:inset-x-0 data-[vaul-drawer-direction=top]:top-0 data-[vaul-drawer-direction=top]:mb-24 data-[vaul-drawer-direction=top]:max-h-[80vh] data-[vaul-drawer-direction=top]:rounded-b-lg\",\n          \"data-[vaul-drawer-direction=bottom]:inset-x-0 data-[vaul-drawer-direction=bottom]:bottom-0 data-[vaul-drawer-direction=bottom]:mt-24 data-[vaul-drawer-direction=bottom]:max-h-[80vh] data-[vaul-drawer-direction=bottom]:rounded-t-lg\",\n          \"data-[vaul-drawer-direction=right]:inset-y-0 data-[vaul-drawer-direction=right]:right-0 data-[vaul-drawer-direction=right]:w-3/4 data-[vaul-drawer-direction=right]:sm:max-w-sm\",\n          \"data-[vaul-drawer-direction=left]:inset-y-0 data-[vaul-drawer-direction=left]:left-0 data-[vaul-drawer-direction=left]:w-3/4 data-[vaul-drawer-direction=left]:sm:max-w-sm\",\n          className,\n        )}\n        {...props}\n      >\n        <div className=\"bg-muted mx-auto mt-4 hidden h-2 w-[100px] shrink-0 rounded-full group-data-[vaul-drawer-direction=bottom]/drawer-content:block\" />\n        {children}\n      </DrawerPrimitive.Content>\n    </DrawerPortal>\n  )\n}\n\nfunction DrawerHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"drawer-header\"\n      className={cn(\"flex flex-col gap-1.5 p-4\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DrawerFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"drawer-footer\"\n      className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DrawerTitle({\n  className,\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Title>) {\n  return (\n    <DrawerPrimitive.Title\n      data-slot=\"drawer-title\"\n      className={cn(\"text-foreground font-semibold\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DrawerDescription({\n  className,\n  ...props\n}: React.ComponentProps<typeof DrawerPrimitive.Description>) {\n  return (\n    <DrawerPrimitive.Description\n      data-slot=\"drawer-description\"\n      className={cn(\"text-muted-foreground text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Drawer,\n  DrawerPortal,\n  DrawerOverlay,\n  DrawerTrigger,\n  DrawerClose,\n  DrawerContent,\n  DrawerHeader,\n  DrawerFooter,\n  DrawerTitle,\n  DrawerDescription,\n}\n",
      "path": "src/components/ui/drawer.tsx"
    },
    {
      "type": "registry:lib",
      "target": "lib/utils.ts",
      "content": "import { clsx, type ClassValue } from \"clsx\"\nimport { twMerge } from \"tailwind-merge\"\n\nexport function cn(...inputs: ClassValue[]) {\n  return twMerge(clsx(inputs))\n}\n",
      "path": "src/lib/utils.ts"
    }
  ]
}
