{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "extends": "none",
  "name": "navbar",
  "title": "navbar",
  "description": "navbar",
  "dependencies": [
    "@heroicons/react",
    "motion",
    "cn"
  ],
  "registryDependencies": [
    "https://intentui.com/r/link",
    "https://intentui.com/r/use-mobile",
    "https://intentui.com/r/primitive",
    "https://intentui.com/r/button",
    "https://intentui.com/r/separator",
    "https://intentui.com/r/sheet"
  ],
  "files": [
    {
      "path": "src/components/ui/navbar.tsx",
      "content": "\"use client\"\n\nimport { Bars2Icon } from \"@heroicons/react/20/solid\"\nimport { LayoutGroup, motion } from \"motion/react\"\nimport { createContext, use, useCallback, useId, useMemo, useState } from \"react\"\nimport { twJoin, cn } from \"cn\"\nimport { Link, type LinkProps } from \"@/components/ui/link\"\nimport { useIsMobile } from \"@/hooks/use-mobile\"\nimport { cx } from \"@/lib/primitive\"\nimport { Button, type ButtonProps } from \"./button\"\nimport { Separator } from \"./separator\"\nimport { Sheet, SheetBody, SheetTrigger } from \"./sheet\"\n\nexport interface NavbarContextProps {\n  open: boolean\n  setOpen: (open: boolean) => void\n  isMobile: boolean\n  toggleNavbar: () => void\n}\n\nconst NavbarContext = createContext<NavbarContextProps | null>(null)\n\nexport function useNavbar() {\n  const context = use(NavbarContext)\n  if (!context) {\n    throw new Error(\"useNavbar must be used within a NavbarProvider.\")\n  }\n\n  return context\n}\n\nexport interface NavbarProviderProps extends React.ComponentProps<\"div\"> {\n  defaultOpen?: boolean\n  isOpen?: boolean\n  onOpenChange?: (open: boolean) => void\n}\n\nexport function NavbarProvider({\n  isOpen: openProp,\n  onOpenChange: setOpenProp,\n  defaultOpen = false,\n  className,\n  ...props\n}: NavbarProviderProps) {\n  const [openInternal, setOpenInternal] = useState(defaultOpen)\n  const open = openProp ?? openInternal\n\n  const setOpen = useCallback(\n    (value: boolean | ((value: boolean) => boolean)) => {\n      if (setOpenProp) {\n        return setOpenProp?.(typeof value === \"function\" ? value(open) : value)\n      }\n\n      setOpenInternal(value)\n    },\n    [setOpenProp, open]\n  )\n\n  const toggleNavbar = useCallback(() => {\n    setOpen((open) => !open)\n  }, [setOpen])\n\n  const isMobile = useIsMobile()\n\n  const contextValue = useMemo<NavbarContextProps>(\n    () => ({\n      open,\n      setOpen,\n      isMobile: isMobile ?? false,\n      toggleNavbar,\n    }),\n    [open, setOpen, isMobile, toggleNavbar]\n  )\n\n  if (isMobile === undefined) {\n    return null\n  }\n\n  return (\n    <NavbarContext value={contextValue}>\n      <div\n        className={cn(\n          \"peer/navbar group/navbar relative isolate z-10 flex w-full flex-col\",\n          \"has-data-navbar-inset:min-h-svh has-data-navbar-inset:bg-navbar dark:has-data-navbar-inset:bg-background\",\n          className\n        )}\n        {...props}\n      />\n    </NavbarContext>\n  )\n}\n\nexport type Intent = \"default\" | \"float\" | \"inset\"\nexport type Placement = \"top\" | \"bottom\"\nexport type Side = \"left\" | \"right\"\n\nexport interface StickyWithPlacement extends React.ComponentProps<\"div\"> {\n  isSticky: true\n  placement?: Placement\n  side?: Side\n  intent?: Intent\n}\n\nexport interface NonStickyWithoutPlacement extends React.ComponentProps<\"div\"> {\n  isSticky?: false\n  placement?: never\n  side?: Side\n  intent?: Intent\n}\n\nexport type NavbarProps = StickyWithPlacement | NonStickyWithoutPlacement\n\nexport function Navbar({\n  children,\n  isSticky,\n  placement = \"top\",\n  intent = \"default\",\n  side = \"left\",\n  className,\n  ref,\n  ...props\n}: NavbarProps) {\n  const { isMobile, open, setOpen } = useNavbar()\n  if (isMobile) {\n    return (\n      <>\n        <span\n          className=\"sr-only\"\n          aria-hidden\n          data-navbar={intent}\n          data-navbar-sticky={isSticky}\n          data-placement={placement ?? undefined}\n        />\n        <SheetTrigger isOpen={open} onOpenChange={setOpen} {...props}>\n          <Sheet\n            position={side}\n            aria-label=\"Mobile Navbar\"\n            className=\"entering:blur-in exiting:blur-out [&>button]:hidden\"\n          >\n            <SheetBody className=\"p-[calc(var(--gutter)-(--spacing(2)))] sm:p-[calc(var(--gutter)-(--spacing(4)))]\">\n              {children}\n            </SheetBody>\n          </Sheet>\n        </SheetTrigger>\n      </>\n    )\n  }\n\n  return (\n    <div\n      data-navbar={intent}\n      ref={ref}\n      data-placement={placement ?? undefined}\n      data-navbar-sticky={isSticky}\n      className={cn([\n        \"group/navbar-intent relative isolate\",\n        isSticky && \"sticky top-0 z-40\",\n        placement === \"top\" && intent === \"float\" && \"md:pt-8\",\n        placement === \"bottom\" && intent === \"float\" && \"bottom-0 md:pb-8\",\n        intent === \"float\" && \"mx-auto w-full max-w-7xl px-4 xl:max-w-(--breakpoint-xl)\",\n      ])}\n      {...props}\n    >\n      <div\n        className={cn(\n          \"relative isolate hidden py-(--navbar-gutter) [--navbar-gutter:--spacing(2.5)] md:block\",\n          intent === \"float\" &&\n            \"rounded-xl bg-background py-0 *:data-[navbar=content]:max-w-7xl *:data-[navbar=content]:rounded-xl *:data-[navbar=content]:border *:data-[navbar=content]:bg-navbar *:data-[navbar=content]:px-4 *:data-[navbar=content]:py-(--navbar-gutter) *:data-[navbar=content]:shadow-xs\",\n          [\"default\", \"inset\"].includes(intent) && \"px-4\",\n          intent === \"default\" && \"border-b bg-navbar\",\n          className\n        )}\n      >\n        <div\n          data-navbar=\"content\"\n          className=\"mx-auto w-full max-w-(--breakpoint-2xl) items-center md:flex\"\n        >\n          {children}\n        </div>\n      </div>\n    </div>\n  )\n}\n\nexport function NavbarSection({ className, ...props }: React.ComponentProps<\"div\">) {\n  const id = useId()\n  return (\n    <LayoutGroup id={id}>\n      <div\n        data-slot=\"navbar-section\"\n        className={cn(\n          \"col-span-full grid grid-cols-[auto_1fr] flex-col gap-3 gap-y-0.5 md:flex md:flex-none md:grid-cols-none md:flex-row md:items-center md:gap-2.5\",\n          className\n        )}\n        {...props}\n      >\n        {props.children}\n      </div>\n    </LayoutGroup>\n  )\n}\n\nexport interface NavbarItemProps extends LinkProps {\n  isCurrent?: boolean\n}\n\nexport function NavbarItem({ className, isCurrent, ...props }: NavbarItemProps) {\n  return (\n    <Link\n      data-slot=\"navbar-item\"\n      aria-current={isCurrent ? \"page\" : undefined}\n      className={cx(\n        [\n          \"href\" in props ? \"cursor-pointer\" : \"cursor-default\",\n          \"group/sidebar-item pressed:bg-secondary pressed:text-secondary-foreground hover:bg-secondary hover:text-secondary-foreground\",\n          \"aria-[current=page]:text-foreground aria-[current=page]*:[svg]:text-foreground\",\n          \"col-span-full grid grid-cols-[auto_1fr_1.5rem_0.5rem_auto] supports-[grid-template-columns:subgrid]:grid-cols-subgrid md:supports-[grid-template-columns:subgrid]:grid-cols-none\",\n          \"relative min-w-0 items-center gap-x-3 rounded-lg p-2 text-start font-medium text-base/6 md:gap-x-(--navbar-gutter) md:px-(--navbar-gutter) md:py-[calc(var(--navbar-gutter)---spacing(0.5))] md:text-sm/5\",\n          \"*:[svg]:size-5 *:[svg]:shrink-0 *:[svg]:text-muted-foreground md:*:[svg]:size-4\",\n          \"*:data-[slot=loader]:size-5 *:data-[slot=loader]:shrink-0 md:*:data-[slot=loader]:size-4\",\n          \"*:not-nth-2:last:[svg]:row-start-1 *:not-nth-2:last:[svg]:ms-auto *:not-nth-2:last:[svg]:size-5 md:*:not-nth-2:last:[svg]:size-4\",\n          \"*:data-[slot=avatar]:-m-0.5 *:data-[slot=avatar]:size-6 md:*:data-[slot=avatar]:size-5\",\n          \"*:[svg]:text-muted-foreground pressed:*:[svg]:text-foreground hover:*:[svg]:text-foreground\",\n          \"outline-hidden focus-visible:inset-ring focus-visible:inset-ring-ring focus-visible:ring-2 focus-visible:ring-ring/20\",\n          \"text-start disabled:cursor-default disabled:opacity-50\",\n        ],\n        className\n      )}\n      {...props}\n    >\n      {(values) => (\n        <>\n          {typeof props.children === \"function\" ? props.children(values) : props.children}\n\n          {(isCurrent || values.isCurrent) && (\n            <motion.span\n              data-slot=\"current-indicator\"\n              layoutId=\"current-indicator\"\n              transition={{ type: \"spring\", stiffness: 500, damping: 40 }}\n              className={twJoin(\n                \"absolute rounded-full bg-foreground [--gutter:--spacing(0.5)]\",\n                \"inset-y-[calc(var(--navbar-gutter)---spacing(0.5))] -start-4 w-(--gutter) md:inset-y-auto md:w-auto\",\n                \"md:inset-x-2 md:-bottom-[calc(var(--navbar-gutter)+1px)] md:h-(--gutter)\"\n              )}\n            />\n          )}\n        </>\n      )}\n    </Link>\n  )\n}\n\nexport function NavbarSpacer({ className, ref, ...props }: React.ComponentProps<\"div\">) {\n  return <div ref={ref} className={cn(\"-ms-4 flex-1\", className)} {...props} />\n}\n\nexport function NavbarStart({ className, ref, ...props }: React.ComponentProps<\"div\">) {\n  return <div ref={ref} className={cn(\"relative p-2 py-4 md:p-0.5\", className)} {...props} />\n}\n\nexport function NavbarGap({ className, ref, ...props }: React.ComponentProps<\"div\">) {\n  return <div ref={ref} className={cn(\"mx-2\", className)} {...props} />\n}\n\nexport function NavbarSeparator({ className, ...props }: React.ComponentProps<typeof Separator>) {\n  return <Separator orientation=\"vertical\" className={cn(\"h-5\", className)} {...props} />\n}\n\nexport function NavbarMobile({ className, ref, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      ref={ref}\n      data-slot=\"navbar-mobile\"\n      className={cn(\n        \"group/navbar-mobile flex items-center gap-x-3 px-4 py-2.5 md:hidden\",\n        \"group-has-data-navbar-sticky/navbar:sticky group-has-data-navbar-sticky/navbar:bg-navbar\",\n        // top\n        \"group-has-data-navbar-sticky/navbar:group-has-placement-top/navbar:top-0 group-has-data-navbar-sticky/navbar:group-has-placement-top/navbar:border-b\",\n        // bottom\n        \"group-has-data-navbar-sticky/navbar:group-has-placement-bottom/navbar:bottom-0 group-has-data-navbar-sticky/navbar:group-has-placement-bottom/navbar:border-t\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport function NavbarInset({ className, ref, children, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      ref={ref}\n      data-navbar-inset={true}\n      className={cn(\"flex flex-1 flex-col bg-navbar pb-2 md:px-2 dark:bg-background\", className)}\n      {...props}\n    >\n      <div className=\"grow bg-background p-6 md:rounded-lg md:p-16 md:shadow-xs md:ring-1 md:ring-foreground/15 md:dark:bg-navbar md:dark:ring-border md:dark:group-has-data-navbar-inset/navbar:bg-muted\">\n        <div className=\"mx-auto max-w-7xl\">{children}</div>\n      </div>\n    </div>\n  )\n}\n\nexport interface NavbarTriggerProps extends ButtonProps {\n  ref?: React.RefObject<HTMLButtonElement>\n}\n\nexport function NavbarTrigger({ className, onPress, ref, ...props }: NavbarTriggerProps) {\n  const { toggleNavbar } = useNavbar()\n  return (\n    <Button\n      ref={ref}\n      data-slot=\"navbar-trigger\"\n      intent=\"plain\"\n      aria-label={props[\"aria-label\"] || \"Toggle Navbar\"}\n      size=\"sq-sm\"\n      className={cx(\"-ms-2 lg:hidden\", className)}\n      onPress={(event) => {\n        onPress?.(event)\n        toggleNavbar()\n      }}\n      {...props}\n    >\n      <Bars2Icon />\n      <span className=\"sr-only\">Toggle Navbar</span>\n    </Button>\n  )\n}\n\nexport function NavbarLabel({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"navbar-label\"\n      className={twJoin(\"col-start-2 row-start-1 truncate\", className)}\n      {...props}\n    />\n  )\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}