{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "tab-bar",
  "title": "Tab Bar",
  "description": "Bottom navigation for three to five destinations in four looks (iOS, Material, pill, glass) with badges, safe-area padding and aria-current.",
  "files": [
    {
      "path": "registry/tealmac/tab-bar.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface TabBarItem {\n  id: string\n  label: string\n  icon: React.ReactNode\n  /** Icon shown when the tab is selected (for example a filled version). */\n  activeIcon?: React.ReactNode\n  /** A count. `0` hides it. Use `dot` for an unlabelled marker. */\n  badge?: number\n  /** A small dot with no number. */\n  dot?: boolean\n  /** Makes the tab a link. Without it the tab is a button. */\n  href?: string\n}\n\nexport type TabBarVariant = \"ios\" | \"material\" | \"pill\" | \"glass\"\n\nexport interface TabBarProps extends Omit<\n  React.ComponentProps<\"nav\">,\n  \"onChange\"\n> {\n  items: TabBarItem[]\n  value: string\n  onValueChange?: (id: string) => void\n  /** The look: `ios` (icon over label), `material` (indicator pill behind the icon), `pill` (selected tab expands) or `glass` (floating, blurred). */\n  variant?: TabBarVariant\n  /** Accessible name of the navigation landmark. */\n  label?: string\n  /** `fixed` pins it to the bottom of the screen. Default `static`. */\n  position?: \"fixed\" | \"static\"\n}\n\nconst BAR: Record<TabBarVariant, string> = {\n  ios: \"bg-background/90 border-t backdrop-blur\",\n  material: \"bg-card border-t\",\n  pill: \"bg-background border-t\",\n  glass:\n    \"mx-3 mb-2 rounded-full border bg-background/60 shadow-lg backdrop-blur-xl supports-[backdrop-filter]:bg-background/50\",\n}\n\nfunction badgeText(item: TabBarItem) {\n  if (item.badge && item.badge > 0) return `, ${item.badge} new`\n  if (item.dot) return \", has updates\"\n  return \"\"\n}\n\nfunction Badge({ item }: { item: TabBarItem }) {\n  if (item.badge && item.badge > 0) {\n    return (\n      <>\n        <span\n          aria-hidden\n          className=\"bg-destructive absolute start-full -top-1 -ms-2 grid min-w-4 place-items-center rounded-full px-1 text-[10px] leading-4 font-semibold text-white\"\n        >\n          {item.badge > 99 ? \"99+\" : item.badge}\n        </span>\n      </>\n    )\n  }\n  if (item.dot) {\n    return (\n      <>\n        <span\n          aria-hidden\n          className=\"bg-destructive absolute start-full -top-0.5 -ms-1.5 size-2 rounded-full\"\n        />\n      </>\n    )\n  }\n  return null\n}\n\n/**\n * Bottom navigation for 3 to 5 top-level destinations. It is a `nav`\n * landmark; the selected tab has `aria-current=\"page\"`. It keeps clear of the\n * home indicator with the safe-area inset.\n */\nexport function TabBar({\n  items,\n  value,\n  onValueChange,\n  variant = \"ios\",\n  label = \"Main\",\n  position = \"static\",\n  className,\n  ...props\n}: TabBarProps) {\n  return (\n    <nav\n      aria-label={label}\n      data-slot=\"tab-bar\"\n      data-variant={variant}\n      className={cn(\n        \"z-30 w-full\",\n        position === \"fixed\" && \"fixed inset-x-0 bottom-0\",\n        variant !== \"glass\" && \"pb-[env(safe-area-inset-bottom)]\",\n        variant === \"glass\" && \"mb-[max(0.5rem,env(safe-area-inset-bottom))]\",\n        BAR[variant],\n        className\n      )}\n      {...props}\n    >\n      <ul className=\"mx-auto flex max-w-xl items-stretch\">\n        {items.map((item) => {\n          const selected = item.id === value\n          const content = (\n            <>\n              <span\n                className={cn(\n                  \"relative grid place-items-center [&_svg]:size-6\",\n                  variant === \"material\" &&\n                    \"h-8 w-16 rounded-full transition-colors motion-reduce:transition-none\",\n                  variant === \"material\" && selected && \"bg-primary/15\",\n                  variant === \"pill\" &&\n                    selected &&\n                    \"bg-primary text-primary-foreground h-9 w-auto gap-2 rounded-full px-4 [&_svg]:size-5\",\n                  variant === \"pill\" && !selected && \"h-9\"\n                )}\n              >\n                {selected ? (item.activeIcon ?? item.icon) : item.icon}\n                {variant === \"pill\" && selected && (\n                  <span className=\"text-sm font-medium\">{item.label}</span>\n                )}\n                <Badge item={item} />\n              </span>\n              {!(variant === \"pill\" && selected) && (\n                <span\n                  className={cn(\n                    \"text-[11px] leading-none\",\n                    variant === \"pill\" && \"sr-only\"\n                  )}\n                >\n                  {item.label}\n                </span>\n              )}\n              <span className=\"sr-only\">{badgeText(item)}</span>\n            </>\n          )\n          const itemClass = cn(\n            \"focus-visible:ring-ring flex min-h-14 flex-1 flex-col items-center justify-center gap-1 px-2 py-1.5 outline-none focus-visible:ring-2 focus-visible:ring-inset\",\n            variant === \"glass\" && \"rounded-full\",\n            selected ? \"text-primary font-medium\" : \"text-muted-foreground\"\n          )\n          return (\n            <li key={item.id} className=\"flex min-w-0 flex-1\">\n              {item.href ? (\n                <a\n                  href={item.href}\n                  aria-current={selected ? \"page\" : undefined}\n                  onClick={() => onValueChange?.(item.id)}\n                  className={itemClass}\n                >\n                  {content}\n                </a>\n              ) : (\n                <button\n                  type=\"button\"\n                  aria-current={selected ? \"page\" : undefined}\n                  onClick={() => onValueChange?.(item.id)}\n                  className={itemClass}\n                >\n                  {content}\n                </button>\n              )}\n            </li>\n          )\n        })}\n      </ul>\n    </nav>\n  )\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}