{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "topbar",
  "type": "registry:ui",
  "title": "Topbar",
  "description": "Site-wide horizontal navigation. The first pattern every landing / docs / dashboard surface needs: logo (left), primary nav (middle/right), action cluster (right). One row, sticky to the top, semi-transparent backdrop blur so content scrolls visibly…",
  "author": "ofri-peretz <https://github.com/ofri-peretz>",
  "categories": [
    "navigation",
    "pattern"
  ],
  "dependencies": [],
  "registryDependencies": [
    "https://ds.interlace.tools/r/theme.json",
    "https://ds.interlace.tools/r/cn.json"
  ],
  "files": [
    {
      "path": "registry/interlace-ui/patterns/topbar.tsx",
      "target": "components/ui/patterns/topbar.tsx",
      "type": "registry:ui",
      "content": "import * as React from 'react';\n\n// @interlace/topbar v1.0.0 — Interlace design system.\n// Docs, props and live preview: https://ds.interlace.tools/c/topbar\n// What changed since: https://ds.interlace.tools/c/topbar#history\n// Generated banner — keep it, the upgrade diff reads this version.\n\n/**\n * @interlace/ui — Topbar\n *\n * Site-wide horizontal navigation. The first pattern every landing /\n * docs / dashboard surface needs: logo (left), primary nav (middle/right),\n * action cluster (right). One row, sticky to the top, semi-transparent\n * backdrop blur so content scrolls visibly beneath without colour bleed.\n *\n * ## Anatomy\n *\n *   <header data-slot=\"topbar\" data-min-viewport=\"320\">\n *     <div className=\"container\">\n *       <div className=\"logo\">{logo}</div>\n *       <nav>{links.map(...)} </nav>\n *       <div className=\"actions\">{actions}</div>\n *     </div>\n *   </header>\n *\n * ## MIN_VIEWPORT — 320\n *\n * Below 768, primary nav collapses (consumer can wire a Sheet+Drawer\n * compose for the hamburger menu). Above 768, the nav row is visible.\n *\n * | Rule | Concept                          | Where in this file                                          |\n * | ---- | -------------------------------- | ----------------------------------------------------------- |\n * | R4   | Extends native el                | `React.ComponentProps<'header'>` + Topbar props             |\n * | R6   | data-slot on root                | `data-slot=\"topbar\"`                                        |\n * | R7   | className merged + ...rest       | `cn(BASE, className)` + `{...props}`                        |\n * | R10  | Composition seam (slots)         | `logo` / `links` / `actions` ReactNode props                |\n * | R14  | Declares min viewport            | `data-min-viewport={String(MIN_VIEWPORT)}` + exported const |\n * | R18  | Tailwind only                    | Zero inline `style`; utility classes only                   |\n * | R19  | Tokens only                      | `bg-background` / `border-border` / `text-muted-foreground` |\n * | R20  | AA contrast                      | semantic foregrounds on backdrop-blur background            |\n * | R25  | Server component                 | No hooks                                                    |\n * | R26  | A11y from native el              | `<header>` landmark, `<nav>` for the link cluster           |\n */\n\nimport { cn } from '@/lib/utils';\n\nexport const MIN_VIEWPORT = 320 as const;\n\ninterface TopbarLink {\n  href: string;\n  label: React.ReactNode;\n  external?: boolean;\n}\n\ninterface TopbarProps extends React.ComponentProps<'header'> {\n  /**\n   * Logo / wordmark. Receives a `<a href=\"/\">…</a>` or a framework-\n   * specific Link (Next.js Link, React Router NavLink, etc.) — the DS\n   * is platform-agnostic so the consumer decides which.\n   */\n  logo: React.ReactNode;\n  /** Primary nav link cluster. Hidden below md (768px). */\n  links?: TopbarLink[];\n  /** Right-aligned actions (Buttons, ThemeToggle, etc.). */\n  actions?: React.ReactNode;\n  /**\n   * Container max-width. Defaults to `'wide'` (1280px). Set to\n   * `'content'` (1024px) for narrower docs surfaces.\n   */\n  containerSize?: 'wide' | 'content' | 'prose';\n  /**\n   * Render-prop slot for internal links. Defaults to a plain `<a>`. A\n   * Next.js consumer passes `({ href, className, children }) => <Link\n   * href={href} className={className}>{children}</Link>` to enable SPA\n   * navigation. External links (`link.external === true`) always use a\n   * plain `<a target=\"_blank\">` regardless of this slot.\n   */\n  renderLink?: (props: {\n    href: string;\n    className: string;\n    children: React.ReactNode;\n  }) => React.ReactElement;\n}\n\nconst defaultRenderLink: NonNullable<TopbarProps['renderLink']> = ({\n  href,\n  className,\n  children,\n}) => (\n  <a href={href} className={className}>\n    {children}\n  </a>\n);\n\nconst CONTAINER_CLASSES = {\n  wide: 'max-w-(--container-wide)',\n  content: 'max-w-(--container-content)',\n  prose: 'max-w-(--container-prose)',\n} as const;\n\nfunction Topbar({\n  logo,\n  links = [],\n  actions,\n  containerSize = 'wide',\n  renderLink = defaultRenderLink,\n  className,\n  ...props\n}: TopbarProps) {\n  return (\n    <header\n      data-slot=\"topbar\"\n      data-min-viewport={String(MIN_VIEWPORT)}\n      className={cn(\n        'border-border bg-background/80 supports-backdrop-filter:bg-background/60 sticky top-0 z-10 border-b backdrop-blur',\n        className,\n      )}\n      {...props}\n    >\n      <div\n        className={cn(\n          'mx-auto flex h-14 items-center justify-between px-md',\n          CONTAINER_CLASSES[containerSize],\n        )}\n      >\n        <div className=\"flex items-center gap-sm\">{logo}</div>\n        {links.length > 0 ? (\n          <nav\n            aria-label=\"Primary\"\n            className=\"hidden items-center gap-md text-sm md:flex\"\n          >\n            {links.map((link) =>\n              link.external ? (\n                <a\n                  key={link.href}\n                  href={link.href}\n                  target=\"_blank\"\n                  rel=\"noopener noreferrer\"\n                  className=\"text-muted-foreground hover:text-foreground transition-colors\"\n                >\n                  {link.label} ↗\n                </a>\n              ) : (\n                <React.Fragment key={link.href}>\n                  {renderLink({\n                    href: link.href,\n                    className:\n                      'text-muted-foreground hover:text-foreground transition-colors',\n                    children: link.label,\n                  })}\n                </React.Fragment>\n              ),\n            )}\n          </nav>\n        ) : null}\n        {actions ? (\n          <div className=\"flex items-center gap-sm\">{actions}</div>\n        ) : null}\n      </div>\n    </header>\n  );\n}\nTopbar.displayName = 'Topbar';\n\nexport { Topbar };\nexport type { TopbarProps, TopbarLink };\n"
    }
  ],
  "meta": {
    "tier": "pattern",
    "client": false,
    "minViewport": 320,
    "loading": false,
    "version": "1.0.0",
    "since": "1.0.0"
  },
  "docs": "## @interlace/topbar\n\nInstalled to `components/ui/patterns/topbar.tsx`.\n\n```tsx\nimport { /* … */ } from '@/components/ui/patterns/topbar';\n```\n\nProps, a11y contract, live preview and source: https://ds.interlace.tools/c/topbar\n\nRequires the `@interlace/theme` CSS baseline (installed automatically as a registry dependency)."
}
