{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "streak-badge",
  "title": "Streak Badge",
  "description": "React streak counter UI in a compact badge supporting daily, weekly, monthly or yearly streaks. Built on shadcn/ui + Tailwind. Open source.",
  "dependencies": [
    "class-variance-authority",
    "lucide-react"
  ],
  "files": [
    {
      "path": "registry/trophy/ui/streak-badge.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Flame } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\n\n// Types (inlined - only fields used by this component)\ninterface StreakResponse {\n  length: number\n  frequency: \"daily\" | \"weekly\" | \"monthly\"\n}\n\n// Variants\nconst streakBadgeVariants = cva(\n  \"inline-flex flex-col items-center justify-center rounded-3xl border border-border/60 bg-card text-center text-card-foreground transition-colors\",\n  {\n    variants: {\n      size: {\n        sm: \"w-28 gap-1.5 p-3\",\n        default: \"w-40 gap-2.5 p-5\",\n        lg: \"w-52 gap-3 p-6\",\n      },\n    },\n    defaultVariants: {\n      size: \"default\",\n    },\n  }\n)\n\n// Props\ninterface StreakBadgeProps\n  extends\n    React.HTMLAttributes<HTMLDivElement>,\n    VariantProps<typeof streakBadgeVariants> {\n  /** Streak length value */\n  length?: number\n  /** Streak frequency used for label rendering */\n  frequency?: StreakResponse[\"frequency\"]\n  /** Optional subtitle shown below streak length */\n  subtitle?: string\n  /** Custom icon to replace flame */\n  icon?: React.ReactNode\n}\n\nconst StreakBadge = React.forwardRef<HTMLDivElement, StreakBadgeProps>(\n  (\n    { className, size, length, frequency = \"daily\", subtitle, icon, ...props },\n    ref\n  ) => {\n    const streakLength = length ?? 0\n\n    const frequencyLabel = {\n      daily: \"day\",\n      weekly: \"week\",\n      monthly: \"month\",\n    }[frequency]\n\n    const pluralLabel =\n      streakLength === 1 ? frequencyLabel : `${frequencyLabel}s`\n\n    const iconSize = {\n      sm: \"h-10 w-10\",\n      default: \"h-16 w-16\",\n      lg: \"h-20 w-20\",\n    }[size ?? \"default\"]\n\n    const valueSize = {\n      sm: \"text-2xl\",\n      default: \"text-5xl\",\n      lg: \"text-6xl\",\n    }[size ?? \"default\"]\n\n    const subtitleSize = {\n      sm: \"text-xs\",\n      default: \"text-sm\",\n      lg: \"text-base\",\n    }[size ?? \"default\"]\n\n    const subtitleText = subtitle ?? \"streak\"\n    const valueUnit = pluralLabel\n\n    // Build accessible label\n    const ariaLabel = `${streakLength} ${pluralLabel} streak`\n\n    return (\n      <div\n        ref={ref}\n        role=\"status\"\n        aria-label={ariaLabel}\n        className={cn(streakBadgeVariants({ size }), className)}\n        {...props}\n      >\n        {icon ?? (\n          <Flame\n            className={cn(iconSize, \"text-primary shrink-0\")}\n            aria-hidden=\"true\"\n          />\n        )}\n        <span\n          className={cn(\"font-semibold tracking-tight\", valueSize)}\n          aria-hidden=\"true\"\n        >\n          {streakLength}\n          <span className=\"text-muted-foreground ml-2 font-medium\">\n            {valueUnit}\n          </span>\n        </span>\n        <span\n          className={cn(\"text-muted-foreground font-normal\", subtitleSize)}\n          aria-hidden=\"true\"\n        >\n          {subtitleText}\n        </span>\n      </div>\n    )\n  }\n)\nStreakBadge.displayName = \"StreakBadge\"\n\nexport { StreakBadge, streakBadgeVariants }\nexport type { StreakBadgeProps, StreakResponse }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}