{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "page-nav",
  "title": "Page Nav",
  "description": "Second-level section bar under the panel's top bar; links or tabs with sliding underline.",
  "dependencies": [
    "motion"
  ],
  "registryDependencies": [
    "@ikas/motion",
    "@ikas/utils"
  ],
  "files": [
    {
      "path": "registry/ikas/page-nav.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { LayoutGroup, motion, useReducedMotion } from \"motion/react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { springOrInstant } from \"@/lib/motion\"\n\ntype PageNavItem<T extends string = string> = {\n  value: T\n  label: React.ReactNode\n  /** Link target. Used when PageNav has no `onValueChange` (router apps). */\n  href?: string\n  /** Count shown after the label, e.g. items waiting. */\n  badge?: React.ReactNode\n  icon?: React.ReactNode\n  disabled?: boolean\n}\n\ntype PageNavProps<T extends string = string> = Omit<React.ComponentProps<\"nav\">, \"onChange\"> & {\n  /** App sections in order. Keep it to six or fewer. */\n  items: PageNavItem<T>[]\n  /** Active section. With links, pass the one matching the current route. */\n  value: T\n  /** Switches sections in place (one-page apps): items become tabs. Omit it to render `href` links. */\n  onValueChange?: (value: T) => void\n  /** Component for `href` items, e.g. `next/link`. */\n  linkComponent?: React.ElementType\n}\n\n/**\n * Second-level section bar at the top of a Page, under the panel's own top\n * bar. Links for router apps, tabs for one-page apps; the active item has a\n * sliding underline.\n */\nfunction PageNav<T extends string>({\n  items,\n  value,\n  onValueChange,\n  linkComponent: Link = \"a\",\n  className,\n  \"aria-label\": ariaLabel = \"Bölümler\",\n  ...props\n}: PageNavProps<T>) {\n  const id = React.useId()\n  const reduce = useReducedMotion()\n  const refs = React.useRef<(HTMLButtonElement | null)[]>([])\n  const tabs = onValueChange !== undefined\n  // A value that matches no enabled item still leaves one tab stop, so the keyboard can reach the bar.\n  const focusable = items.find((item) => item.value === value && !item.disabled)?.value ?? items.find((item) => !item.disabled)?.value\n\n  function onKeyDown(event: React.KeyboardEvent, index: number) {\n    const enabled = items.flatMap((item, i) => (item.disabled ? [] : [i]))\n    if (enabled.length === 0) return\n    const at = enabled.indexOf(index)\n    let next: number | undefined\n    if (event.key === \"ArrowRight\") next = enabled[(at + 1) % enabled.length]\n    if (event.key === \"ArrowLeft\") next = enabled[(at - 1 + enabled.length) % enabled.length]\n    if (event.key === \"Home\") next = enabled[0]\n    if (event.key === \"End\") next = enabled[enabled.length - 1]\n    if (next === undefined) return\n    event.preventDefault()\n    refs.current[next]?.focus()\n    onValueChange?.(items[next].value)\n  }\n\n  return (\n    <LayoutGroup id={id}>\n      <nav\n        data-slot=\"page-nav\"\n        aria-label={tabs ? undefined : ariaLabel}\n        className={cn(\"sticky top-0 z-10 -mx-4 border-b bg-background px-4 sm:-mx-6 sm:px-6\", className)}\n        {...props}\n      >\n        {/* The row overlaps the border by 1px so the underline sits on it. */}\n        <div\n          role={tabs ? \"tablist\" : undefined}\n          aria-label={tabs ? ariaLabel : undefined}\n          className=\"-mb-px flex gap-4 overflow-x-auto [scrollbar-width:none]\"\n        >\n          {items.map((item, index) => {\n            const active = item.value === value\n            const itemClassName = cn(\n              \"relative flex h-11 shrink-0 items-center gap-1.5 rounded-md px-1 text-sm font-medium whitespace-nowrap transition-colors duration-150 ease-out outline-none select-none focus-visible:ring-3 focus-visible:ring-ring/30 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n              active ? \"text-foreground\" : \"text-muted-foreground hover:text-foreground\",\n              item.disabled && \"pointer-events-none opacity-50\"\n            )\n            const content = (\n              <>\n                {active && (\n                  <motion.span\n                    layoutId=\"page-nav-underline\"\n                    aria-hidden\n                    className=\"absolute inset-x-0 bottom-0 h-0.5 rounded-full bg-foreground\"\n                    transition={springOrInstant(reduce)}\n                  />\n                )}\n                <span className=\"relative z-10 flex items-center gap-1.5\">\n                  {item.icon}\n                  {item.label}\n                  {item.badge !== undefined && (\n                    <span\n                      className={cn(\n                        \"flex h-4 min-w-4 items-center justify-center rounded-full px-1 text-[10px] font-semibold tabular-nums transition-colors\",\n                        active ? \"bg-foreground text-background\" : \"bg-foreground/10 text-muted-foreground\"\n                      )}\n                    >\n                      {item.badge}\n                    </span>\n                  )}\n                </span>\n              </>\n            )\n\n            if (tabs) {\n              return (\n                <button\n                  key={item.value}\n                  ref={(node) => {\n                    refs.current[index] = node\n                  }}\n                  type=\"button\"\n                  role=\"tab\"\n                  aria-selected={active}\n                  tabIndex={item.value === focusable ? 0 : -1}\n                  disabled={item.disabled}\n                  onClick={() => onValueChange?.(item.value)}\n                  onKeyDown={(event) => onKeyDown(event, index)}\n                  className={itemClassName}\n                >\n                  {content}\n                </button>\n              )\n            }\n            if (item.disabled || !item.href) {\n              return (\n                <span key={item.value} aria-disabled=\"true\" className={itemClassName}>\n                  {content}\n                </span>\n              )\n            }\n            return (\n              <Link key={item.value} href={item.href} aria-current={active ? \"page\" : undefined} className={itemClassName}>\n                {content}\n              </Link>\n            )\n          })}\n        </div>\n      </nav>\n    </LayoutGroup>\n  )\n}\n\nexport { PageNav, type PageNavProps, type PageNavItem }\n",
      "type": "registry:component",
      "target": "@components/ikas/page-nav.tsx"
    }
  ],
  "docs": "https://builders.ikas.com/tr/docs/app-development/ui-kit/components/page-nav",
  "categories": [
    "navigation",
    "layout"
  ],
  "type": "registry:component"
}